1 64 65 package com.jcorporate.expresso.core.db; 66 67 import com.jcorporate.expresso.core.dataobjects.Securable; 68 import com.jcorporate.expresso.core.dataobjects.jdbc.JDBCObjectMetaData; 69 import com.jcorporate.expresso.core.db.config.JDBCConfig; 70 import com.jcorporate.expresso.core.dbobj.DBIndex; 71 import com.jcorporate.expresso.core.dbobj.DBObject; 72 import com.jcorporate.expresso.core.dbobj.DBObjectDef; 73 import com.jcorporate.expresso.core.dbobj.Schema; 74 import com.jcorporate.expresso.core.misc.ConfigManager; 75 import com.jcorporate.expresso.core.misc.StringUtil; 76 import com.jcorporate.expresso.kernel.management.ExpressoRuntimeMap; 77 import com.jcorporate.expresso.kernel.util.FastStringBuffer; 78 import com.jcorporate.expresso.kernel.util.LocatorUtils; 79 import com.jcorporate.expresso.services.dbobj.DBOtherMap; 80 import com.jcorporate.expresso.services.dbobj.Setup; 81 import org.apache.log4j.Logger; 82 83 import java.lang.ref.WeakReference ; 84 import java.util.Enumeration ; 85 import java.util.Iterator ; 86 import java.util.Vector ; 87 88 97 98 public class TableCreator { 99 100 105 private Logger log = Logger.getLogger(TableCreator.class); 106 107 110 static WeakReference theInstance = null; 111 114 public static final String USE_CACHED_HSQL = "UseCachedHSQL"; 115 116 protected TableCreator() { 117 } 118 119 127 public static synchronized TableCreator getInstance() { 128 synchronized (TableCreator.class) { 129 if (theInstance == null) { 130 TableCreator tc = new TableCreator(); 131 theInstance = new WeakReference (tc); 132 return tc; 133 } else { 134 TableCreator returnValue = (TableCreator) theInstance.get(); 135 if (returnValue == null) { 136 returnValue = new TableCreator(); 137 theInstance = new WeakReference (returnValue); 138 } 139 140 return returnValue; 141 } 142 } 143 } 144 145 160 public synchronized void createTable(DBObject dbObj) throws DBException { 161 FastStringBuffer sqlStatement = FastStringBuffer.getInstance(); 162 FastStringBuffer pkStatement = FastStringBuffer.getInstance(); 165 166 JDBCObjectMetaData metadata = dbObj.getJDBCMetaData(); 167 168 try { 169 170 DBConnectionPool myPool = null; 171 DBConnection myConnection = null; 172 boolean addComma = false; 173 174 try { 175 176 sqlStatement = createTableSQLDefinition(dbObj 177 , sqlStatement); 178 179 myPool = DBConnectionPool.getInstance(dbObj.getDataContext()); 180 myConnection = myPool.getConnection("Table Creator"); 181 182 String myDBDriver = myConnection.getDBDriver(); 183 Iterator e2 = metadata.getKeyFieldListArray().iterator(); 184 185 if (e2.hasNext()) { 187 188 189 190 if (myDBDriver.equals("postgresql.Driver") || 194 myDBDriver.equals("org.postgresql.Driver")) { 195 sqlStatement.append(", CONSTRAINT pk"); 196 sqlStatement.append(metadata.getTargetSQLTable(dbObj.getDataContext())); 197 sqlStatement.append(" PRIMARY KEY ("); 198 addComma = false; 199 200 while (e2.hasNext()) { 201 String OneKey = (String ) e2.next(); 202 203 if (addComma) { 204 sqlStatement.append(", "); 205 } 206 207 sqlStatement.append(OneKey); 208 addComma = true; 209 } 210 211 sqlStatement.append(")"); 212 } else if ((myDBDriver.equals("org.hsql.jdbcDriver")) || 213 (myDBDriver.equals("org.hsqldb.jdbcDriver"))) { 214 sqlStatement.append(", PRIMARY KEY ("); 215 addComma = false; 216 217 while (e2.hasNext()) { 218 String OneKey = (String ) e2.next(); 219 220 if (addComma) { 221 sqlStatement.append(", "); 222 } 223 224 sqlStatement.append(OneKey); 225 addComma = true; 226 } 227 228 sqlStatement.append(")"); 229 } else { 230 pkStatement.append("alter table "); 231 pkStatement.append(metadata.getTargetSQLTable(dbObj.getDataContext())); 232 pkStatement.append(" add primary key("); 233 addComma = false; 234 235 while (e2.hasNext()) { 236 String OneKey = (String ) e2.next(); 237 238 if (addComma) { 239 pkStatement.append(", "); 240 } 241 242 pkStatement.append(OneKey); 243 addComma = true; 244 } 245 246 pkStatement.append(")"); 247 } 248 249 } 250 251 252 sqlStatement.append(")"); 253 254 if (log.isInfoEnabled()) { 256 log.info("Executing:" + sqlStatement.toString()); 257 } 258 myConnection.executeUpdate(sqlStatement.toString()); 259 260 String thepkSQL = pkStatement.toString(); 262 if (thepkSQL != null && thepkSQL.length() > 0) { 263 if (log.isInfoEnabled()) { 264 log.info("Executing:" + thepkSQL); 265 } 266 267 myConnection.executeUpdate(thepkSQL); 268 } 269 createIndices(dbObj, myConnection, true); 273 } catch (Throwable t) { 274 t.printStackTrace(); 275 throw new DBException(t); 276 } finally { 277 if (myPool != null) { 278 myPool.release(myConnection); 279 } 280 } 281 } finally { 282 pkStatement.release(); 283 sqlStatement.release(); 284 } 285 286 } 287 288 301 protected FastStringBuffer createTableSQLDefinition(DBObject dbObj, 302 FastStringBuffer sqlStatement) throws DBException { 303 boolean addComma = false; 304 305 String dataContext = dbObj.getMappedDataContext(); 307 TypeMapper typeMapper = TypeMapper.getInstance(dataContext); 308 JDBCConfig myConfig = null; 309 JDBCObjectMetaData metadata = dbObj.getJDBCMetaData(); 310 311 try { 312 myConfig = ConfigManager.getJdbcRequired(dbObj.getDataContext()); 313 } catch (com.jcorporate.expresso.core.misc.ConfigurationException ce) { 314 throw new DBException(ce); 315 } 316 sqlStatement.append("CREATE"); 317 if ("org.hsqldb.jdbcDriver".equals(myConfig.getDriver())) { 318 String useCachedHSQL = Setup.getValueUnrequired(dbObj.getDataContext(), USE_CACHED_HSQL); 321 if (StringUtil.toBoolean(useCachedHSQL)) { 322 sqlStatement.append(" CACHED "); 323 } 324 } 325 sqlStatement.append(" TABLE "); 326 sqlStatement.append(metadata.getTargetSQLTable(dbObj.getDataContext())); 327 sqlStatement.append("("); 328 329 for (Iterator lf = metadata.getFieldListArray().iterator(); lf.hasNext();) { 330 String fieldName = (String ) lf.next(); 331 332 if (!dbObj.getJDBCMetaData().isVirtual(fieldName)) { 333 FastStringBuffer oneType = FastStringBuffer.getInstance(); 334 try { 335 if (addComma) { 336 sqlStatement.append(", "); 337 } 338 339 oneType.append(typeMapper.getTypeForDB(metadata.getType(fieldName))); 340 341 if (!metadata.getLength(fieldName).equals("0")) { 342 oneType.append("(" + dbObj.getLength(fieldName)); 343 344 if (metadata.getPrecision(fieldName) > 0) { 345 oneType.append(", " + 346 metadata.getPrecision(fieldName)); 347 } 348 349 oneType.append(")"); 350 } 351 352 sqlStatement.append(fieldName); 353 sqlStatement.append(" "); 354 sqlStatement.append(oneType.toString()); 355 356 if (!dbObj.getFieldMetaData(fieldName).allowsNull()) { 357 sqlStatement.append(" not null"); 358 } else { 359 if (myConfig.useNullOnCreate()) { 360 sqlStatement.append(" null"); } 362 } 363 364 addComma = true; 365 } finally { 366 oneType.release(); 367 } 368 } 369 } 370 return sqlStatement; 371 } 372 373 385 public synchronized Vector createAsNeeded(Schema oneSchema, String dataContext) 386 throws DBException { 387 Vector newObjs = new Vector (1); 388 DBObject oneMember = null; 389 String oneOtherDbName = null; 390 391 JDBCObjectMetaData metadata; 392 for (Enumeration e = oneSchema.getMembers(); e.hasMoreElements();) { 393 oneMember = (DBObject) e.nextElement(); 394 if (oneMember instanceof Securable) { 395 ((Securable) oneMember).setRequestingUid(Securable.SYSTEM_ACCOUNT); 396 } 397 metadata = oneMember.getJDBCMetaData(); 398 399 oneOtherDbName = (String ) oneSchema.getDBObjMap().get(oneMember.getClass().getName()); 403 404 if (oneOtherDbName != null) { 410 oneMember.setDataContext(oneOtherDbName); 411 } else { 412 oneMember.setDataContext(dataContext); 413 } 414 415 if (log.isInfoEnabled()) { 416 log.info("Verifying table " + metadata.getTargetSQLTable(oneMember.getDataContext()) + " exists"); 417 } 418 419 try { 420 oneMember.count(); 421 422 createIndices(oneMember, null, false); 424 425 if (log.isInfoEnabled()) { 426 log.info("Table " + metadata.getTargetSQLTable(oneMember.getDataContext()) + " is OK"); 427 } 428 } catch (DBException de) { 429 log.debug(de); 430 newObjs.addElement(metadata.getName()); 431 if (log.isInfoEnabled()) { 432 log.info("Table for object " + metadata.getName() + 433 " did not exist in db '" + oneMember.getDataContext() + 434 "' - creating"); 435 } 436 createTable(oneMember); 437 438 439 try { 440 oneMember.count(); 441 } catch (DBException de2) { 442 throw new DBException("Table '" + 443 metadata.getTargetSQLTable(oneMember.getDataContext()) + 444 "' was not created successfully in db '" + 445 oneMember.getDataContext() + "'", de2); 446 } 447 } 448 if (oneOtherDbName != null) { 451 try { 452 DBOtherMap otherdb = new DBOtherMap(); 453 otherdb.setDataContext(dataContext); 454 otherdb.setField("DBObjName", 455 oneMember.getClass().getName()); 456 457 if (!otherdb.find()) { 458 otherdb.setField("DBConnName", oneOtherDbName); 459 otherdb.setField("Descrip", 460 metadata.getDescription()); 461 otherdb.add(); 462 } 463 } catch (DBException dbo) { 464 log.error(dbo); 465 log.error("Could not create an entry in the DBOtherMap " + 466 "table for object ' " + 467 oneMember.getClass().getName() + "'"); 468 } 469 } 470 } 471 472 return newObjs; 473 } 474 475 483 protected JDBCConfig getJDBCConfig(String dataContext) throws DBException { 484 if (ExpressoRuntimeMap.getDefaultRuntime() == null) { 485 try { 486 return ConfigManager.getContext(dataContext).getJdbc(); 487 } catch (com.jcorporate.expresso.core.misc.ConfigurationException ex) { 488 log.error("Error getting configuration for context: " + dataContext); 489 throw new DBException("Error getting configuration for context", ex); 490 } 491 } else { 492 LocatorUtils lc = new LocatorUtils(ExpressoRuntimeMap.getDefaultRuntime()); 493 DBConfig config = (DBConfig) lc.locateComponent(dataContext + ".PersistenceManager.DBConfig"); 494 if (config == null) { 495 throw new DBException("Unable to find DB Config in the default runtime."); 496 } 497 498 return config.getCurrentConfig(); 499 } 500 } 501 502 511 protected void createIndices(DBObject dbObj, 512 DBConnection providedConn, 513 boolean shouldComplain) throws DBException { 514 515 if (dbObj.getJDBCMetaData().hasIndex()) { 516 JDBCConfig myConfig = null; 517 518 try { 519 myConfig = ConfigManager.getJdbcRequired(dbObj.getDataContext()); 520 } catch (com.jcorporate.expresso.core.misc.ConfigurationException ce) { 521 throw new DBException(ce); 522 } 523 if (myConfig.createTableIndicies()) { 524 Object [] indexArray = ((DBObjectDef) dbObj.getMetaData()).getIndexArray(); 525 526 if (indexArray != null) { 527 528 DBConnection usedConn = providedConn; 529 DBConnection localConn = null; 530 DBConnectionPool myPool = null; 531 try { 532 if (usedConn == null) { 533 myPool = DBConnectionPool.getInstance(dbObj.getDataContext()); 535 localConn = myPool.getConnection("Table Creator"); 536 usedConn = localConn; 537 } 538 for (int i = 0; i < indexArray.length; i++) { 539 String createIndexString = ((DBIndex) indexArray[i]).constructSQL(); 540 541 if (log.isDebugEnabled() == true) { 542 log.debug("Executing " + createIndexString); 543 } 544 545 try { 546 usedConn.executeUpdate(createIndexString); 547 } catch (DBException ex) { 548 549 if (shouldComplain) { 554 log.warn("Unable to create index. ", ex); 555 } 556 } 557 } 558 } finally { 559 if (localConn != null) { 560 myPool.release(localConn); 561 } 562 } 563 } 564 } 565 } 566 567 } 568 569 } 570 | Popular Tags |