1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.database;
17
18 import java.sql.Connection;
19 import java.sql.PreparedStatement;
20 import java.sql.SQLException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.hibernate.HibernateException;
30 import org.hibernate.cfg.Configuration;
31 import org.hibernate.dialect.Dialect;
32 import org.hibernate.mapping.ForeignKey;
33 import org.hibernate.mapping.Table;
34 import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
35 import org.seasar.tuigwaa.model.core.TgwEntity;
36 import org.seasar.tuigwaa.util.TgwUtils;
37
38 import com.isenshi.util.TableMap;
39
40 /***
41 * @author nishioka
42 */
43 public class DynaDatabaseServiceImpl implements DynaDatabaseService {
44
45 private Log log = LogFactory.getLog(getClass());
46
47 private BasicDatabaseService db;
48
49 private DynaSessionFactory factory_;
50
51 private TableMap tableNameMap = new TableMap();
52
53 public DynaDatabaseServiceImpl(BasicDatabaseService basicDBService,
54 DynaSessionFactory factory) {
55 this.db = basicDBService;
56 this.factory_ = factory;
57 }
58
59 public void createSchema(String domainName) throws Exception {
60 if (db.useBaseDatabase(domainName) && !db.existSchema(domainName)) {
61 DynaConfiguration cfg = factory_.getConfiguration(domainName);
62 String sql = cfg.getCreateSchemaSQLString(domainName);
63 executeSQL(domainName, sql);
64 }
65 }
66
67 public void dropSchema(String domainName) throws Exception {
68 if (db.useBaseDatabase(domainName) && db.existSchema(domainName)) {
69 DynaConfiguration cfg = factory_.getConfiguration(domainName);
70 String sql = cfg.getDropSchemaSQLString(domainName);
71 executeSQL(domainName, sql);
72 }else{
73 db.removeExternalDatabaseMapping(domainName);
74 }
75 factory_.deleteConfiguration(domainName);
76 }
77
78 public void createTable(TgwEntity entity) {
79 String domainName = entity.getDomainName();
80 DynaConfiguration cfg = factory_.getConfiguration(domainName);
81
82 try {
83
84 Table table = addTable(cfg, domainName, entity, true);
85
86
87 if (!existTable(entity)) {
88 doCreateTable(cfg, domainName, table);
89 doCreateForeignKey(cfg, domainName, table);
90 }
91 } catch (SQLException e) {
92 e.printStackTrace();
93 throw new RuntimeException(e);
94 } catch (HibernateException e) {
95 e.printStackTrace();
96 throw new RuntimeException(e);
97 } catch (ClassNotFoundException e) {
98 e.printStackTrace();
99 throw new RuntimeException(e);
100 }
101 }
102
103 public void createTables(String domainName, Collection entityList) {
104 DynaConfiguration cfg = factory_.getConfiguration(domainName);
105 List tableList = new ArrayList();
106 try {
107
108 Iterator itr = entityList.iterator();
109 while (itr.hasNext()) {
110 TgwEntity entity = (TgwEntity) itr.next();
111 Table table = addTable(cfg, domainName, entity, false);
112 if (!existTable(entity)) {
113 tableList.add(table);
114 }
115 }
116 cfg.build();
117
118
119 itr = tableList.iterator();
120 while (itr.hasNext()) {
121 Table table = (Table) itr.next();
122 doCreateTable(cfg, domainName, table);
123 doCreateForeignKey(cfg, domainName, table);
124 }
125 } catch (HibernateException e) {
126 e.printStackTrace();
127 } catch (ClassNotFoundException e) {
128 e.printStackTrace();
129 } catch (SQLException e) {
130 e.printStackTrace();
131 }
132 }
133
134 public List readTables(String domainName) {
135 List list = new ArrayList();
136 try {
137 Map map = db.createEntityMap(domainName);
138 list.addAll(map.values());
139 } catch (SQLException e) {
140
141 log.info("Can't read database");
142 }
143 return list;
144 }
145
146 public void alterTable(TgwEntity entity) throws Exception {
147 String domainName = entity.getDomainName();
148
149 DynaConfiguration cfg = factory_.getConfiguration(domainName);
150
151 String schema = db.getSchemaName(domainName);
152
153
154 Table table = cfg.alterTable(schema, entity);
155
156
157 DatabaseMetadata metadata = getDatabaseMetadata(domainName);
158
159 Iterator itr = cfg.getAlterSQLString(table, metadata, schema);
160 while (itr.hasNext()) {
161 String sql = (String) itr.next();
162 executeSQL(domainName, sql);
163 }
164 }
165
166 public void dropTable(String domainName, String entityName)
167 throws Exception {
168 DynaConfiguration cfg = factory_.getConfiguration(domainName);
169
170 if (db.useBaseDatabase(domainName)) {
171 String schema = db.getSchemaName(domainName);
172 cfg.deleteTable(schema, entityName);
173 doDropTable(cfg, domainName, schema, entityName);
174 }
175 }
176
177 public void dropTables(String domainName, String[] entityNames)
178 throws Exception {
179 DynaConfiguration cfg = factory_.getConfiguration(domainName);
180 if (db.useBaseDatabase(domainName)) {
181 String schema = db.getSchemaName(domainName);
182 cfg.deleteTable(schema, entityNames);
183 for (int i = 0; i < entityNames.length; i++) {
184 doDropTable(cfg, domainName, schema, entityNames[i]);
185 }
186 }
187 }
188
189
190
191 private void executeSQL(String domainName, String sql) throws SQLException,
192 HibernateException {
193 Connection conn = db.getConnection(domainName);
194 PreparedStatement stmt = conn.prepareStatement(sql);
195 log.info("execute SQL: " + sql);
196 stmt.executeUpdate();
197 }
198
199 private DatabaseMetadata getDatabaseMetadata(String domainName)
200 throws SQLException {
201 Connection conn = db.getConnection(domainName);
202 Configuration cfg = factory_.getConfiguration(domainName);
203 Dialect dialect = Dialect.getDialect(cfg.getProperties());
204 DatabaseMetadata metadata = new DatabaseMetadata(conn, dialect);
205 return metadata;
206 }
207
208 private void doCreateTable(DynaConfiguration cfg, String domainName,
209 Table table) throws HibernateException, SQLException {
210 String sql = cfg.getCreateSQLString(table);
211 executeSQL(domainName, sql);
212 }
213
214 private boolean existTable(TgwEntity entity) {
215 String domainName = entity.getDomainName();
216 String tableName = TgwUtils.toTableName(entity);
217 return db.existTable(domainName, tableName);
218 }
219
220 private void doCreateForeignKey(DynaConfiguration cfg, String schema,
221 Table table) throws HibernateException, SQLException {
222 Iterator fks = table.getForeignKeyIterator();
223 while (fks.hasNext()) {
224 ForeignKey fk = (ForeignKey) fks.next();
225 executeSQL(schema, cfg.getForeignKeySQLString(fk));
226 }
227 }
228
229 private void doDropTable(DynaConfiguration cfg, String domainName,
230 String schema, String entityName) throws HibernateException,
231 SQLException {
232 Table table = new Table();
233 if (schema != null) {
234 table.setSchema(schema);
235 }
236
237 String tableName = (String) tableNameMap.get(domainName, entityName);
238 if (tableName != null) {
239 table.setName(tableName);
240 String sql = cfg.getDropSQLString(table);
241 executeSQL(domainName, sql);
242 }
243 }
244
245 private Table addTable(DynaConfiguration cfg, String domainName,
246 TgwEntity entity, boolean needRebuild) throws HibernateException,
247 ClassNotFoundException {
248 String tableName = TgwUtils.toTableName(entity);
249 String schema = db.getSchemaName(domainName);
250
251 tableNameMap.put(tableName, domainName, entity.getName());
252 return cfg.addTable(schema, entity, needRebuild);
253 }
254 }