1 package org.apache.ojb.broker.util.dbhandling; 2 3 17 18 import java.io.*; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.StringTokenizer ; 22 import java.util.zip.GZIPInputStream ; 23 import java.util.zip.GZIPOutputStream ; 24 25 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor; 26 import org.apache.ojb.broker.platforms.PlatformException; 27 import org.apache.ojb.broker.util.logging.LoggerFactory; 28 import org.apache.tools.ant.Project; 29 import org.apache.tools.ant.taskdefs.SQLExec; 30 import org.apache.tools.ant.types.FileSet; 31 import org.apache.torque.task.TorqueDataModelTask; 32 import org.apache.torque.task.TorqueSQLExec; 33 import org.apache.torque.task.TorqueSQLTask; 34 35 40 public class TorqueDBHandling implements DBHandling 41 { 42 43 protected static final String TORQUE_PLATFORM_DB2 = "db2"; 44 protected static final String TORQUE_PLATFORM_HYPERSONIC = "hypersonic"; 45 protected static final String TORQUE_PLATFORM_INTERBASE = "interbase"; 46 protected static final String TORQUE_PLATFORM_MSSQL = "mssql"; 47 protected static final String TORQUE_PLATFORM_MYSQL = "mysql"; 48 protected static final String TORQUE_PLATFORM_ORACLE = "oracle"; 49 protected static final String TORQUE_PLATFORM_POSTGRESQL = "postgresql"; 50 protected static final String TORQUE_PLATFORM_SAPDB = "sapdb"; 51 protected static final String TORQUE_PLATFORM_SYBASE = "sybase"; 52 53 54 private static final String CREATION_SCRIPT_NAME = "create-db.sql"; 55 56 private static final String SQL_DB_MAP_NAME = "sqldb.map"; 57 58 59 private static HashMap _dbmsToTorqueDb = new HashMap (); 60 61 static 62 { 63 _dbmsToTorqueDb.put("db2", TORQUE_PLATFORM_DB2); 64 _dbmsToTorqueDb.put("hsqldb", TORQUE_PLATFORM_HYPERSONIC); 65 _dbmsToTorqueDb.put("firebird", TORQUE_PLATFORM_INTERBASE); 66 _dbmsToTorqueDb.put("mssqlserver", TORQUE_PLATFORM_MSSQL); 67 _dbmsToTorqueDb.put("mysql", TORQUE_PLATFORM_MYSQL); 68 _dbmsToTorqueDb.put("oracle", TORQUE_PLATFORM_ORACLE); 69 _dbmsToTorqueDb.put("oracle9i", TORQUE_PLATFORM_ORACLE); 70 _dbmsToTorqueDb.put("postgresql", TORQUE_PLATFORM_POSTGRESQL); 71 _dbmsToTorqueDb.put("sapdb", TORQUE_PLATFORM_SAPDB); 72 _dbmsToTorqueDb.put("sybaseasa", TORQUE_PLATFORM_SYBASE); 73 _dbmsToTorqueDb.put("sybasease", TORQUE_PLATFORM_SYBASE); 74 _dbmsToTorqueDb.put("sybase", TORQUE_PLATFORM_SYBASE); 75 } 76 77 78 private JdbcConnectionDescriptor _jcd; 79 80 private String _targetDatabase; 81 82 private File _workDir; 83 84 private HashMap _torqueSchemata = new HashMap (); 85 86 private byte[] _creationScript; 87 88 private HashMap _initScripts = new HashMap (); 89 90 93 public TorqueDBHandling() 94 {} 95 96 102 public void setConnection(JdbcConnectionDescriptor jcd) throws PlatformException 103 { 104 _jcd = jcd; 105 106 String targetDatabase = (String )_dbmsToTorqueDb.get(_jcd.getDbms().toLowerCase()); 107 108 if (targetDatabase == null) 109 { 110 throw new PlatformException("Database "+_jcd.getDbms()+" is not supported by torque"); 111 } 112 if (!targetDatabase.equals(_targetDatabase)) 113 { 114 _targetDatabase = targetDatabase; 115 _creationScript = null; 116 _initScripts.clear(); 117 } 118 } 119 120 125 public JdbcConnectionDescriptor getConnection() 126 { 127 return _jcd; 128 } 129 130 135 public String getTargetTorquePlatform() 136 { 137 return _targetDatabase; 138 } 139 140 146 public void addDBDefinitionFiles(String srcDir, String listOfFilenames) throws IOException 147 { 148 StringTokenizer tokenizer = new StringTokenizer (listOfFilenames, ","); 149 File dir = new File(srcDir); 150 String filename; 151 152 while (tokenizer.hasMoreTokens()) 153 { 154 filename = tokenizer.nextToken().trim(); 155 if (filename.length() > 0) 156 { 157 _torqueSchemata.put("schema"+_torqueSchemata.size()+".xml", 158 readTextCompressed(new File(dir, filename))); 159 } 160 } 161 } 162 163 168 public void addDBDefinitionFile(InputStream schemaStream) throws IOException 169 { 170 _torqueSchemata.put("schema"+_torqueSchemata.size()+".xml", 171 readStreamCompressed(schemaStream)); 172 } 173 174 182 private String writeSchemata(File dir) throws IOException 183 { 184 writeCompressedTexts(dir, _torqueSchemata); 185 186 StringBuffer includes = new StringBuffer (); 187 188 for (Iterator it = _torqueSchemata.keySet().iterator(); it.hasNext();) 189 { 190 includes.append((String )it.next()); 191 if (it.hasNext()) 192 { 193 includes.append(","); 194 } 195 } 196 return includes.toString(); 197 } 198 199 204 public void createCreationScript() throws PlatformException 205 { 206 Project project = new Project(); 207 TorqueDataModelTask modelTask = new TorqueDataModelTask(); 208 File tmpDir = null; 209 File scriptFile = null; 210 211 _creationScript = null; 212 try 213 { 214 tmpDir = new File(getWorkDir(), "schemas"); 215 tmpDir.mkdir(); 216 217 String includes = writeSchemata(tmpDir); 218 219 scriptFile = new File(tmpDir, CREATION_SCRIPT_NAME); 220 221 project.setBasedir(tmpDir.getAbsolutePath()); 222 223 modelTask.setProject(project); 225 modelTask.setUseClasspath(true); 226 modelTask.setControlTemplate("sql/db-init/Control.vm"); 227 modelTask.setOutputDirectory(tmpDir); 228 modelTask.setOutputFile(CREATION_SCRIPT_NAME); 229 modelTask.setTargetDatabase(_targetDatabase); 230 231 FileSet files = new FileSet(); 232 233 files.setDir(tmpDir); 234 files.setIncludes(includes); 235 modelTask.addFileset(files); 236 modelTask.execute(); 237 238 _creationScript = readTextCompressed(scriptFile); 239 240 deleteDir(tmpDir); 241 } 242 catch (Exception ex) 243 { 244 if ((tmpDir != null) && tmpDir.exists()) 246 { 247 deleteDir(tmpDir); 248 } 249 throw new PlatformException(ex); 250 } 251 } 252 253 258 public void createDB() throws PlatformException 259 { 260 if (_creationScript == null) 261 { 262 createCreationScript(); 263 } 264 265 Project project = new Project(); 266 TorqueDataModelTask modelTask = new TorqueDataModelTask(); 267 File tmpDir = null; 268 File scriptFile = null; 269 270 try 271 { 272 tmpDir = new File(getWorkDir(), "schemas"); 273 tmpDir.mkdir(); 274 275 scriptFile = new File(tmpDir, CREATION_SCRIPT_NAME); 276 277 writeCompressedText(scriptFile, _creationScript); 278 279 project.setBasedir(tmpDir.getAbsolutePath()); 280 281 SQLExec sqlTask = new SQLExec(); 283 SQLExec.OnError onError = new SQLExec.OnError(); 284 285 onError.setValue("continue"); 286 sqlTask.setProject(project); 287 sqlTask.setAutocommit(true); 288 sqlTask.setDriver(_jcd.getDriver()); 289 sqlTask.setOnerror(onError); 290 sqlTask.setUserid(_jcd.getUserName()); 291 sqlTask.setPassword(_jcd.getPassWord() == null ? "" : _jcd.getPassWord()); 292 sqlTask.setUrl(getDBCreationUrl()); 293 sqlTask.setSrc(scriptFile); 294 sqlTask.execute(); 295 296 deleteDir(tmpDir); 297 } 298 catch (Exception ex) 299 { 300 if ((tmpDir != null) && tmpDir.exists()) 302 { 303 try 304 { 305 scriptFile.delete(); 306 } 307 catch (NullPointerException e) 308 { 309 LoggerFactory.getLogger(this.getClass()).error("NPE While deleting scriptFile [" + scriptFile.getName() + "]", e); 310 } 311 } 312 throw new PlatformException(ex); 313 } 314 } 315 316 322 public void createInitScripts() throws PlatformException 323 { 324 Project project = new Project(); 325 TorqueSQLTask sqlTask = new TorqueSQLTask(); 326 File schemaDir = null; 327 File sqlDir = null; 328 329 _initScripts.clear(); 330 try 331 { 332 File tmpDir = getWorkDir(); 333 334 schemaDir = new File(tmpDir, "schemas"); 335 sqlDir = new File(tmpDir, "sql"); 336 schemaDir.mkdir(); 337 sqlDir.mkdir(); 338 339 String includes = writeSchemata(schemaDir); 340 File sqlDbMapFile = new File(sqlDir, SQL_DB_MAP_NAME); 341 342 sqlDbMapFile.createNewFile(); 343 project.setBasedir(sqlDir.getAbsolutePath()); 344 345 sqlTask.setProject(project); 347 sqlTask.setUseClasspath(true); 348 sqlTask.setBasePathToDbProps("sql/base/"); 349 sqlTask.setControlTemplate("sql/base/Control.vm"); 350 sqlTask.setOutputDirectory(sqlDir); 351 sqlTask.setOutputFile("../report.sql.generation"); 354 sqlTask.setSqlDbMap(SQL_DB_MAP_NAME); 355 sqlTask.setTargetDatabase(_targetDatabase); 356 357 FileSet files = new FileSet(); 358 359 files.setDir(schemaDir); 360 files.setIncludes(includes); 361 sqlTask.addFileset(files); 362 sqlTask.execute(); 363 364 readTextsCompressed(sqlDir, _initScripts); 365 deleteDir(schemaDir); 366 deleteDir(sqlDir); 367 } 368 catch (Exception ex) 369 { 370 if ((schemaDir != null) && schemaDir.exists()) 372 { 373 deleteDir(schemaDir); 374 } 375 if ((sqlDir != null) && sqlDir.exists()) 376 { 377 deleteDir(sqlDir); 378 } 379 throw new PlatformException(ex); 380 } 381 } 382 383 388 public void initDB() throws PlatformException 389 { 390 if (_initScripts.isEmpty()) 391 { 392 createInitScripts(); 393 } 394 395 Project project = new Project(); 396 TorqueSQLTask sqlTask = new TorqueSQLTask(); 397 File outputDir = null; 398 399 try 400 { 401 outputDir = new File(getWorkDir(), "sql"); 402 403 outputDir.mkdir(); 404 writeCompressedTexts(outputDir, _initScripts); 405 406 project.setBasedir(outputDir.getAbsolutePath()); 407 408 TorqueSQLExec sqlExec = new TorqueSQLExec(); 410 TorqueSQLExec.OnError onError = new TorqueSQLExec.OnError(); 411 412 sqlExec.setProject(project); 413 onError.setValue("continue"); 414 sqlExec.setAutocommit(true); 415 sqlExec.setDriver(_jcd.getDriver()); 416 sqlExec.setOnerror(onError); 417 sqlExec.setUserid(_jcd.getUserName()); 418 sqlExec.setPassword(_jcd.getPassWord() == null ? "" : _jcd.getPassWord()); 419 sqlExec.setUrl(getDBManipulationUrl()); 420 sqlExec.setSrcDir(outputDir.getAbsolutePath()); 421 sqlExec.setSqlDbMap(SQL_DB_MAP_NAME); 422 sqlExec.execute(); 423 424 deleteDir(outputDir); 425 } 426 catch (Exception ex) 427 { 428 if (outputDir != null) 430 { 431 deleteDir(outputDir); 432 } 433 throw new PlatformException(ex); 434 } 435 } 436 437 443 protected String getDBCreationUrl() 444 { 445 JdbcConnectionDescriptor jcd = getConnection(); 446 447 if (TORQUE_PLATFORM_MYSQL.equals(getTargetTorquePlatform())) 449 { 450 String dbAliasPrefix = jcd.getDbAlias(); 454 String dbAliasSuffix = ""; 455 int questionPos = dbAliasPrefix.indexOf('?'); 456 457 if (questionPos > 0) 458 { 459 dbAliasSuffix = dbAliasPrefix.substring(questionPos); 460 dbAliasPrefix = dbAliasPrefix.substring(0, questionPos); 461 } 462 463 int slashPos = dbAliasPrefix.lastIndexOf('/'); 464 465 if (slashPos > 0) 466 { 467 dbAliasPrefix = dbAliasPrefix.substring(0, slashPos + 1); 469 } 470 return jcd.getProtocol()+":"+jcd.getSubProtocol()+":"+dbAliasPrefix+dbAliasSuffix; 471 } 472 else if (TORQUE_PLATFORM_POSTGRESQL.equals(getTargetTorquePlatform())) 473 { 474 String dbAliasPrefix = jcd.getDbAlias(); 477 String dbAliasSuffix = ""; 478 int questionPos = dbAliasPrefix.indexOf('?'); 479 480 if (questionPos > 0) 481 { 482 dbAliasSuffix = dbAliasPrefix.substring(questionPos); 483 dbAliasPrefix = dbAliasPrefix.substring(0, questionPos); 484 } 485 486 int slashPos = dbAliasPrefix.lastIndexOf('/'); 487 488 if (slashPos > 0) 489 { 490 dbAliasPrefix = dbAliasPrefix.substring(0, slashPos + 1); 492 } 493 else 494 { 495 dbAliasPrefix += "/"; 496 } 497 dbAliasPrefix += "template1"; 498 if (dbAliasSuffix.length() > 0) 499 { 500 dbAliasPrefix += "/"; 501 } 502 return jcd.getProtocol()+":"+jcd.getSubProtocol()+":"+dbAliasPrefix+dbAliasSuffix; 503 504 } 505 else 506 { 507 return jcd.getProtocol()+":"+jcd.getSubProtocol()+":"+jcd.getDbAlias(); 508 } 509 } 510 511 516 protected String getDBManipulationUrl() 517 { 518 JdbcConnectionDescriptor jcd = getConnection(); 519 520 return jcd.getProtocol()+":"+jcd.getSubProtocol()+":"+jcd.getDbAlias(); 521 } 522 523 530 private byte[] readTextCompressed(File file) throws IOException 531 { 532 return readStreamCompressed(new FileInputStream(file)); 533 } 534 535 542 private byte[] readStreamCompressed(InputStream stream) throws IOException 543 { 544 ByteArrayOutputStream bao = new ByteArrayOutputStream(); 545 GZIPOutputStream gos = new GZIPOutputStream (bao); 546 OutputStreamWriter output = new OutputStreamWriter(gos); 547 BufferedReader input = new BufferedReader(new InputStreamReader(stream)); 548 String line; 549 550 while ((line = input.readLine()) != null) 551 { 552 output.write(line); 553 output.write('\n'); 554 } 555 input.close(); 556 stream.close(); 557 output.close(); 558 gos.close(); 559 bao.close(); 560 return bao.toByteArray(); 561 } 562 563 572 private void readTextsCompressed(File dir, HashMap results) throws IOException 573 { 574 if (dir.exists() && dir.isDirectory()) 575 { 576 File[] files = dir.listFiles(); 577 578 for (int idx = 0; idx < files.length; idx++) 579 { 580 if (files[idx].isDirectory()) 581 { 582 continue; 583 } 584 results.put(files[idx].getName(), readTextCompressed(files[idx])); 585 } 586 } 587 } 588 589 596 private void writeCompressedText(File file, byte[] compressedContent) throws IOException 597 { 598 ByteArrayInputStream bais = new ByteArrayInputStream(compressedContent); 599 GZIPInputStream gis = new GZIPInputStream (bais); 600 BufferedReader input = new BufferedReader(new InputStreamReader(gis)); 601 BufferedWriter output = new BufferedWriter(new FileWriter(file)); 602 String line; 603 604 while ((line = input.readLine()) != null) 605 { 606 output.write(line); 607 output.write('\n'); 608 } 609 input.close(); 610 gis.close(); 611 bais.close(); 612 output.close(); 613 } 614 615 623 private void writeCompressedTexts(File dir, HashMap contents) throws IOException 624 { 625 String filename; 626 627 for (Iterator nameIt = contents.keySet().iterator(); nameIt.hasNext();) 628 { 629 filename = (String )nameIt.next(); 630 writeCompressedText(new File(dir, filename), (byte[])contents.get(filename)); 631 } 632 } 633 634 640 public void setWorkDir(String dir) throws IOException 641 { 642 File workDir = new File(dir); 643 644 if (!workDir.exists() || !workDir.canWrite() || !workDir.canRead()) 645 { 646 throw new IOException("Cannot access directory "+dir); 647 } 648 _workDir = workDir; 649 } 650 651 657 private File getWorkDir() throws IOException 658 { 659 if (_workDir == null) 660 { 661 File dummy = File.createTempFile("dummy", ".log"); 662 String workDir = dummy.getPath().substring(0, dummy.getPath().lastIndexOf(File.separatorChar)); 663 664 if ((workDir == null) || (workDir.length() == 0)) 665 { 666 workDir = "."; 667 } 668 dummy.delete(); 669 _workDir = new File(workDir); 670 } 671 return _workDir; 672 } 673 674 679 private void deleteDir(File dir) 680 { 681 if (dir.exists() && dir.isDirectory()) 682 { 683 File[] files = dir.listFiles(); 684 685 for (int idx = 0; idx < files.length; idx++) 686 { 687 if (!files[idx].exists()) 688 { 689 continue; 690 } 691 if (files[idx].isDirectory()) 692 { 693 deleteDir(files[idx]); 694 } 695 else 696 { 697 files[idx].delete(); 698 } 699 } 700 dir.delete(); 701 } 702 } 703 } 704 | Popular Tags |