1 package org.jbpm.db; 2 3 import java.io.*; 4 import java.lang.reflect.*; 5 import java.sql.*; 6 import java.util.*; 7 import java.util.List ; 8 9 import org.apache.commons.logging.*; 10 import org.hibernate.cfg.*; 11 import org.hibernate.connection.*; 12 import org.hibernate.dialect.*; 13 import org.hibernate.engine.*; 14 import org.hibernate.mapping.*; 15 import org.hibernate.tool.hbm2ddl.*; 16 import org.hibernate.util.*; 17 18 21 public class JbpmSchema implements Serializable { 22 23 private static final long serialVersionUID = 1L; 24 25 private static final String JBPM_TABLE_PREFIX = "JBPM_"; 26 27 Configuration configuration = null; 28 Properties properties = null; 29 Dialect dialect = null; 30 Mapping mapping = null; 31 String [] createSql = null; 32 String [] dropSql = null; 33 String [] cleanSql = null; 34 35 ConnectionProvider connectionProvider = null; 36 Connection connection = null; 37 Statement statement = null; 38 39 public JbpmSchema(Configuration configuration) { 40 this.configuration = configuration; 41 this.properties = configuration.getProperties(); 42 this.dialect = Dialect.getDialect(properties); 43 try { 44 Field mappingField = Configuration.class.getDeclaredField("mapping"); 46 mappingField.setAccessible(true); 47 this.mapping = (Mapping) mappingField.get(configuration); 48 } catch (Exception e) { 49 throw new RuntimeException ("couldn't get the hibernate mapping", e); 50 } 51 } 52 53 public String [] getCreateSql() { 54 if (createSql==null) { 55 createSql = configuration.generateSchemaCreationScript(dialect); 56 } 57 return createSql; 58 } 59 60 public String [] getDropSql() { 61 if (dropSql==null) { 62 dropSql = configuration.generateDropSchemaScript(dialect); 63 } 64 return dropSql; 65 } 66 67 public String [] getCleanSql() { 68 if (cleanSql==null) { 69 List dropForeignKeysSql = new ArrayList(); 71 List createForeignKeysSql = new ArrayList(); 72 Iterator iter = configuration.getTableMappings(); 73 while ( iter.hasNext() ) { 74 Table table = ( Table ) iter.next(); 75 if ( table.isPhysicalTable() ) { 76 Iterator subIter = table.getForeignKeyIterator(); 77 while ( subIter.hasNext() ) { 78 ForeignKey fk = ( ForeignKey ) subIter.next(); 79 if ( fk.isPhysicalConstraint() ) { 80 dropForeignKeysSql.add( fk.sqlDropString( 82 dialect, 83 properties.getProperty(Environment.DEFAULT_CATALOG), 84 properties.getProperty(Environment.DEFAULT_SCHEMA) ) ); 85 createForeignKeysSql.add( fk.sqlCreateString( 87 dialect, 88 mapping, 89 properties.getProperty(Environment.DEFAULT_CATALOG), 90 properties.getProperty(Environment.DEFAULT_SCHEMA) ) ); 91 } 92 } 93 } 94 } 95 96 List deleteSql = new ArrayList(); 97 iter = configuration.getTableMappings(); 98 while (iter.hasNext()) { 99 Table table = (Table) iter.next(); 100 deleteSql.add("delete from "+table.getName()); 101 } 102 103 List cleanSqlList = new ArrayList(); 109 cleanSqlList.addAll(dropForeignKeysSql); 110 cleanSqlList.addAll(deleteSql); 111 cleanSqlList.addAll(createForeignKeysSql); 112 113 cleanSql = (String []) cleanSqlList.toArray(new String [cleanSqlList.size()]); 114 } 115 return cleanSql; 116 } 117 118 public boolean hasJbpmTables() { 119 return (getJbpmTables().size()>0); 120 } 121 122 public List getJbpmTables() { 123 List jbpmTableNames = new ArrayList(); 125 try { 126 createConnection(); 127 ResultSet resultSet = connection.getMetaData().getTables(null, null, null, null); 128 while(resultSet.next()) { 129 String tableName = resultSet.getString("TABLE_NAME"); 130 if ( (tableName!=null) 131 && (tableName.length()>5) 132 && (JBPM_TABLE_PREFIX.equalsIgnoreCase(tableName.substring(0,5))) ) { 133 jbpmTableNames.add(tableName); 134 } 135 } 136 } catch (SQLException e) { 137 throw new RuntimeException ("couldn't get the jbpm table names"); 138 } finally { 139 closeConnection(); 140 } 141 return jbpmTableNames; 142 } 143 144 public void dropSchema() { 145 execute( getDropSql() ); 146 } 147 148 public void createSchema() { 149 execute( getCreateSql() ); 150 } 151 152 public void cleanSchema() { 153 execute( getCleanSql() ); 154 } 155 156 public void saveSqlScripts(String dir, String prefix) { 157 try { 158 new File(dir).mkdirs(); 159 saveSqlScript(dir+"/"+prefix+".drop.sql", getDropSql()); 160 saveSqlScript(dir+"/"+prefix+".create.sql", getCreateSql()); 161 saveSqlScript(dir+"/"+prefix+".clean.sql", getCleanSql()); 162 new SchemaExport(configuration) 163 .setDelimiter(getSqlDelimiter()) 164 .setOutputFile(dir+"/"+prefix+".drop.create.sql") 165 .create(true, false); 166 } catch (Exception e) { 167 throw new RuntimeException ("couldn't generate scripts", e); 168 } 169 } 170 171 public static void main(String [] args) { 172 try { 173 if ( (args!=null) 174 && (args.length==1) 175 && ("create".equalsIgnoreCase(args[0])) ) { 176 new JbpmSchema(JbpmSessionFactory.createConfiguration()).createSchema(); 177 } else if ( (args!=null) 178 && (args.length==1) 179 && ("drop".equalsIgnoreCase(args[0])) ) { 180 new JbpmSchema(JbpmSessionFactory.createConfiguration()).dropSchema(); 181 } else if ( (args!=null) 182 && (args.length==1) 183 && ("clean".equalsIgnoreCase(args[0])) ) { 184 new JbpmSchema(JbpmSessionFactory.createConfiguration()).cleanSchema(); 185 } else if ( (args!=null) 186 && (args.length==3) 187 && ("scripts".equalsIgnoreCase(args[0])) ) { 188 new JbpmSchema(JbpmSessionFactory.createConfiguration()).saveSqlScripts(args[1], args[2]); 189 } else { 190 System.err.println("syntax: JbpmSchema create"); 191 System.err.println("syntax: JbpmSchema drop"); 192 System.err.println("syntax: JbpmSchema clean"); 193 System.err.println("syntax: JbpmSchema scripts <dir> <prefix>"); 194 } 195 } catch (Exception e) { 196 e.printStackTrace(); 197 throw new RuntimeException (e); 198 } 199 } 200 201 private void saveSqlScript(String fileName, String [] sql) throws FileNotFoundException { 202 FileOutputStream fileOutputStream = new FileOutputStream(fileName); 203 try { 204 PrintStream printStream = new PrintStream(fileOutputStream); 205 for (int i=0; i<sql.length; i++) { 206 printStream.println(sql[i]+getSqlDelimiter()); 207 } 208 } finally { 209 try { 210 fileOutputStream.close(); 211 } catch (IOException e) { 212 e.printStackTrace(); 213 } 214 } 215 } 216 217 public void execute(String [] sqls) { 218 String sql = null; 219 String showSqlText = properties.getProperty("hibernate.show_sql"); 220 boolean showSql = ("true".equalsIgnoreCase(showSqlText)); 221 222 try { 223 createConnection(); 224 statement = connection.createStatement(); 225 226 for (int i=0; i<sqls.length; i++) { 227 sql = sqls[i]; 228 229 if (showSql) log.debug(sql); 230 statement.executeUpdate(sql); 231 } 232 233 } catch (SQLException e) { 234 e.printStackTrace(); 235 throw new RuntimeException ("couldn't execute sql '"+sql+"'", e); 236 } finally { 237 closeConnection(); 238 } 239 } 240 241 private void closeConnection() { 242 try { 243 if (statement!=null) statement.close(); 244 if (connection!=null) { 245 JDBCExceptionReporter.logWarnings( connection.getWarnings() ); 246 connection.clearWarnings(); 247 connectionProvider.closeConnection(connection); 248 connectionProvider.close(); 249 } 250 } 251 catch(Exception e) { 252 System.err.println( "Could not close connection" ); 253 e.printStackTrace(); 254 } 255 } 256 257 private void createConnection() throws SQLException { 258 connectionProvider = ConnectionProviderFactory.newConnectionProvider(properties); 259 connection = connectionProvider.getConnection(); 260 if ( !connection.getAutoCommit() ) { 261 connection.commit(); 262 connection.setAutoCommit(true); 263 } 264 } 265 266 public Properties getProperties() { 267 return properties; 268 } 269 270 272 private static String sqlDelimiter = null; 273 private synchronized String getSqlDelimiter() { 274 if (sqlDelimiter==null) { 275 sqlDelimiter = properties.getProperty("jbpm.sql.delimiter", ";"); 276 } 277 return sqlDelimiter; 278 } 279 280 282 private static final Log log = LogFactory.getLog(JbpmSchema.class); 283 } 284 | Popular Tags |