1 30 31 32 package org.hsqldb.util; 33 34 import java.sql.Connection ; 35 import java.sql.DatabaseMetaData ; 36 import java.sql.PreparedStatement ; 37 import java.sql.ResultSet ; 38 import java.sql.ResultSetMetaData ; 39 import java.sql.SQLException ; 40 import java.sql.Statement ; 41 import java.sql.Types ; 42 import java.util.Vector ; 43 44 49 54 class TransferDb extends DataAccessPoint { 55 56 Connection conn; 57 DatabaseMetaData meta; 58 protected Statement srcStatement = null; 59 60 TransferDb(Connection c, Traceable t) throws DataAccessPointException { 61 62 super(t); 63 64 conn = c; 65 66 if (c != null) { 67 String productLowerName; 68 69 try { 70 meta = c.getMetaData(); 71 databaseToConvert = c.getCatalog(); 72 productLowerName = meta.getDatabaseProductName(); 73 74 if (productLowerName == null) { 75 productLowerName = ""; 76 } else { 77 productLowerName = productLowerName.toLowerCase(); 78 } 79 80 helper = HelperFactory.getHelper(productLowerName); 81 82 helper.set(this, t, meta.getIdentifierQuoteString()); 83 } catch (SQLException e) { 84 throw new DataAccessPointException(e.getMessage()); 85 } 86 } 87 } 88 89 boolean isConnected() { 90 return (conn != null); 91 } 92 93 boolean getAutoCommit() throws DataAccessPointException { 94 95 boolean result = false; 96 97 try { 98 result = conn.getAutoCommit(); 99 } catch (SQLException e) { 100 throw new DataAccessPointException(e.getMessage()); 101 } 102 103 return result; 104 } 105 106 void commit() throws DataAccessPointException { 107 108 if (srcStatement != null) { 109 try { 110 srcStatement.close(); 111 } catch (SQLException e) {} 112 113 srcStatement = null; 114 } 115 116 try { 117 conn.commit(); 118 } catch (SQLException e) { 119 throw new DataAccessPointException(e.getMessage()); 120 } 121 } 122 123 void rollback() throws DataAccessPointException { 124 125 if (srcStatement != null) { 126 try { 127 srcStatement.close(); 128 } catch (SQLException e) {} 129 130 srcStatement = null; 131 } 132 133 try { 134 conn.rollback(); 135 } catch (SQLException e) { 136 throw new DataAccessPointException(e.getMessage()); 137 } 138 } 139 140 void setAutoCommit(boolean flag) throws DataAccessPointException { 141 142 try { 143 conn.setAutoCommit(flag); 144 } catch (SQLException e) { 145 throw new DataAccessPointException(e.getMessage()); 146 } 147 } 148 149 boolean execute(String statement) throws DataAccessPointException { 150 151 boolean result = false; 152 Statement stmt = null; 153 154 try { 155 stmt = conn.createStatement(); 156 result = stmt.execute(statement); 157 } catch (SQLException e) { 158 throw new DataAccessPointException(e.getMessage()); 159 } finally { 160 if (stmt != null) { 161 try { 162 stmt.close(); 163 } catch (SQLException e) {} 164 } 165 } 166 167 return result; 168 } 169 170 TransferResultSet getData(String statement) 171 throws DataAccessPointException { 172 173 ResultSet rsData = null; 174 175 try { 176 if (srcStatement != null) { 177 srcStatement.close(); 178 } 179 180 srcStatement = conn.createStatement(); 181 rsData = srcStatement.executeQuery(statement); 182 } catch (SQLException e) { 183 try { 184 srcStatement.close(); 185 } catch (Exception e1) {} 186 187 srcStatement = null; 188 rsData = null; 189 190 throw new DataAccessPointException(e.getMessage()); 191 } 192 193 return new TransferResultSet(rsData); 194 } 195 196 void putData(String statement, TransferResultSet r, 197 int iMaxRows) throws DataAccessPointException { 198 199 if ((statement == null) || statement.equals("") || (r == null)) { 200 return; 201 } 202 203 PreparedStatement destPrep = null; 204 205 try { 206 destPrep = conn.prepareStatement(statement); 207 208 int i = 0; 209 int tmpLength; 210 int len = r.getColumnCount(); 211 int[] tmpTypes = null; 212 213 while (r.next()) { 214 if (tmpTypes == null) { 215 tmpTypes = new int[len + 1]; 216 217 for (int j = 1; j <= len; j++) { 218 tmpTypes[j] = r.getColumnType(j); 219 } 220 } 221 222 transferRow(r, destPrep, len, tmpTypes); 223 224 if (iMaxRows != 0 && i == iMaxRows) { 225 break; 226 } 227 228 i++; 229 230 if (iMaxRows != 0 || i % 100 == 0) { 231 tracer.trace("Transfered " + i + " rows"); 232 } 233 } 234 } catch (SQLException e) { 235 throw new DataAccessPointException(e.getMessage()); 236 } finally { 237 if (destPrep != null) { 238 try { 239 destPrep.close(); 240 } catch (SQLException e) {} 241 } 242 } 243 } 244 245 291 Vector getSchemas() throws DataAccessPointException { 292 293 Vector ret = new Vector (); 294 ResultSet result = null; 295 296 try { 297 result = meta.getSchemas(); 298 } catch (SQLException e) { 299 result = null; 300 } 301 302 try { 303 if (result != null) { 304 while (result.next()) { 305 ret.addElement(result.getString(1)); 306 } 307 308 result.close(); 309 } 310 } catch (SQLException e) { 311 throw new DataAccessPointException(e.getMessage()); 312 } 313 314 return (ret); 315 } 316 317 Vector getCatalog() throws DataAccessPointException { 318 319 Vector ret = new Vector (); 320 ResultSet result = null; 321 322 if (databaseToConvert != null && databaseToConvert.length() > 0) { 323 ret.addElement(databaseToConvert); 324 325 return (ret); 326 } 327 328 try { 329 result = meta.getCatalogs(); 330 } catch (SQLException e) { 331 result = null; 332 } 333 334 try { 335 if (result != null) { 336 while (result.next()) { 337 ret.addElement(result.getString(1)); 338 } 339 340 result.close(); 341 } 342 } catch (SQLException e) { 343 throw new DataAccessPointException(e.getMessage()); 344 } 345 346 return (ret); 347 } 348 349 void setCatalog(String sCatalog) throws DataAccessPointException { 350 351 if (sCatalog != null && sCatalog.length() > 0) { 352 try { 353 conn.setCatalog(sCatalog); 354 } catch (SQLException e) { 355 throw new DataAccessPointException(e.getMessage()); 356 } 357 } 358 } 359 360 Vector getTables(String sCatalog, 361 String [] sSchemas) throws DataAccessPointException { 362 363 Vector tTable = new Vector (); 364 ResultSet result = null; 365 366 tracer.trace("Reading source tables"); 367 368 int nbloops = 1; 369 370 if (sSchemas != null) { 371 nbloops = sSchemas.length; 372 } 373 374 try { 375 376 for (int SchemaIdx = 0; SchemaIdx < nbloops; SchemaIdx++) { 378 if (sSchemas != null && sSchemas[SchemaIdx] != null) { 379 result = meta.getTables(sCatalog, sSchemas[SchemaIdx], 380 null, null); 381 } else { 382 try { 383 result = meta.getTables(sCatalog, "", null, null); 384 } catch (SQLException e) { 385 result = meta.getTables(sCatalog, null, null, null); 386 } 387 } 388 389 while (result.next()) { 390 String name = result.getString(3); 391 String type = result.getString(4); 392 String schema = ""; 393 394 if (sSchemas != null && sSchemas[SchemaIdx] != null) { 395 schema = sSchemas[SchemaIdx]; 396 } 397 398 403 if ((type.compareTo("TABLE") == 0) 404 || (type.compareTo("VIEW") == 0)) { 405 TransferTable t = new TransferTable(this, name, 406 schema, type, 407 tracer); 408 409 tTable.addElement(t); 410 } else { 411 tracer.trace("Found table of type :" + type 412 + " - this type is ignored"); 413 } 414 } 415 } 416 } catch (SQLException e) { 417 throw new DataAccessPointException(e.getMessage()); 418 } finally { 419 if (result != null) { 420 try { 421 result.close(); 422 } catch (SQLException e) {} 423 } 424 } 425 426 return (tTable); 427 } 428 429 void getTableStructure(TransferTable TTable, 430 DataAccessPoint Dest) 431 throws DataAccessPointException { 432 433 String create = "CREATE " + TTable.Stmts.sType + " " 434 + Dest.helper.formatName(TTable.Stmts.sDestTable); 435 String insert = ""; 436 ResultSet ImportedKeys = null; 437 boolean importedkeys = false; 438 String alterCreate = new String (""); 439 String alterDrop = new String (""); 440 String ConstraintName = new String (""); 441 String RefTableName = new String (""); 442 String foreignKeyName = new String (""); 443 String columnName = new String (""); 444 445 TTable.Stmts.sDestDrop = 446 "DROP " + TTable.Stmts.sType + " " 447 + Dest.helper.formatName(TTable.Stmts.sDestTable) + ";"; 448 449 if (TTable.Stmts.sType.compareTo("TABLE") == 0) { 450 TTable.Stmts.sDestDelete = 451 "DELETE FROM " 452 + Dest.helper.formatName(TTable.Stmts.sDestTable) + ";"; 453 create += "("; 454 } else if (TTable.Stmts.sType.compareTo("VIEW") == 0) { 455 TTable.Stmts.bDelete = false; 456 TTable.Stmts.sDestDelete = ""; 457 create += " AS SELECT "; 458 } 459 460 if (TTable.Stmts.sType.compareTo("TABLE") == 0) { 461 insert = "INSERT INTO " 462 + Dest.helper.formatName(TTable.Stmts.sDestTable) 463 + " VALUES("; 464 } else if (TTable.Stmts.sType.compareTo("VIEW") == 0) { 465 TTable.Stmts.bInsert = false; 466 insert = ""; 467 } 468 469 if (TTable.Stmts.sType.compareTo("VIEW") == 0) { 470 474 TTable.Stmts.bTransfer = false; 475 TTable.Stmts.bCreate = true; 476 TTable.Stmts.bDelete = false; 477 TTable.Stmts.bDrop = true; 478 TTable.Stmts.bCreateIndex = false; 479 TTable.Stmts.bDropIndex = false; 480 TTable.Stmts.bInsert = false; 481 TTable.Stmts.bAlter = false; 482 483 return; 484 } 485 486 ImportedKeys = null; 487 488 try { 489 ImportedKeys = 490 meta.getImportedKeys(TTable.Stmts.sDatabaseToConvert, 491 TTable.Stmts.sSchema, 492 TTable.Stmts.sSourceTable); 493 } catch (SQLException e) { 494 ImportedKeys = null; 495 } 496 497 try { 498 if (ImportedKeys != null) { 499 while (ImportedKeys.next()) { 500 importedkeys = true; 501 502 if (!ImportedKeys.getString(12).equals(ConstraintName)) { 503 if (!ConstraintName.equals("")) { 504 alterCreate += 505 Dest.helper 506 .formatIdentifier(columnName 507 .substring(0, columnName 508 .length() - 1)) + ") REFERENCES " 509 + Dest.helper 510 .formatName(RefTableName); 511 512 if (foreignKeyName.length() > 0) { 513 alterCreate += 514 " (" 515 + Dest.helper.formatIdentifier( 516 foreignKeyName.substring( 517 0, foreignKeyName.length() 518 - 1)) + ")"; 519 } 520 521 alterCreate += ";"; 522 alterDrop = 523 alterDrop.substring(0, alterDrop.length() - 1) 524 + ";"; 525 foreignKeyName = ""; 526 columnName = ""; 527 } 528 529 RefTableName = ImportedKeys.getString(3); 530 ConstraintName = ImportedKeys.getString(12); 531 alterCreate += 532 "ALTER TABLE " 533 + Dest.helper.formatName(TTable.Stmts.sDestTable) 534 + " ADD CONSTRAINT "; 535 536 if ((TTable.Stmts.bFKForced) 537 && (!ConstraintName.startsWith("FK_"))) { 538 alterCreate += 539 Dest.helper.formatIdentifier( 540 "FK_" + ConstraintName) + " "; 541 } else { 542 alterCreate += 543 Dest.helper.formatIdentifier(ConstraintName) 544 + " "; 545 } 546 547 alterCreate += "FOREIGN KEY ("; 548 alterDrop += 549 "ALTER TABLE " 550 + Dest.helper.formatName(TTable.Stmts.sDestTable) 551 + " DROP CONSTRAINT "; 552 553 if ((TTable.Stmts.bFKForced) 554 && (!ConstraintName.startsWith("FK_"))) { 555 alterDrop += 556 Dest.helper.formatIdentifier( 557 "FK_" + ConstraintName) + " "; 558 } else { 559 alterDrop += 560 Dest.helper.formatIdentifier(ConstraintName) 561 + " "; 562 } 563 } 564 565 columnName += ImportedKeys.getString(8) + ","; 566 foreignKeyName += ImportedKeys.getString(4) + ","; 567 } 568 569 ImportedKeys.close(); 570 } 571 572 if (importedkeys) { 573 alterCreate += 574 columnName.substring(0, columnName.length() - 1) 575 + ") REFERENCES " + Dest.helper.formatName(RefTableName); 576 577 if (foreignKeyName.length() > 0) { 578 alterCreate += 579 " (" 580 + Dest.helper.formatIdentifier( 581 foreignKeyName.substring( 582 0, foreignKeyName.length() - 1)) + ")"; 583 } 584 585 alterCreate += ";"; 586 alterDrop = alterDrop.substring(0, alterDrop.length() - 1) 587 + ";"; 588 TTable.Stmts.sDestDrop = alterDrop + TTable.Stmts.sDestDrop; 589 } 590 } catch (SQLException e) { 591 throw new DataAccessPointException(e.getMessage()); 592 } 593 594 boolean primarykeys = false; 595 String PrimaryKeysConstraint = new String (); 596 597 PrimaryKeysConstraint = ""; 598 599 ResultSet PrimaryKeys = null; 600 601 try { 602 PrimaryKeys = meta.getPrimaryKeys(TTable.Stmts.sDatabaseToConvert, 603 TTable.Stmts.sSchema, 604 TTable.Stmts.sSourceTable); 605 } catch (SQLException e) { 606 PrimaryKeys = null; 607 } 608 609 try { 610 if (PrimaryKeys != null) { 611 while (PrimaryKeys.next()) { 612 if (primarykeys) { 613 PrimaryKeysConstraint += ", "; 614 } else { 615 if (PrimaryKeys.getString(6) != null) { 616 PrimaryKeysConstraint = 617 " CONSTRAINT " 618 + Dest.helper.formatIdentifier( 619 PrimaryKeys.getString(6)); 620 } 621 622 PrimaryKeysConstraint += " PRIMARY KEY ("; 623 } 624 625 PrimaryKeysConstraint += Dest.helper.formatIdentifier( 626 PrimaryKeys.getString(4)); 627 primarykeys = true; 628 } 629 630 PrimaryKeys.close(); 631 632 if (primarykeys) { 633 PrimaryKeysConstraint += ") "; 634 } 635 } 636 } catch (SQLException e) { 637 throw new DataAccessPointException(e.getMessage()); 638 } 639 640 boolean indices = false; 641 ResultSet Indices = null; 642 String IndiceName = new String (""); 643 String CreateIndex = new String (""); 644 String DropIndex = new String (""); 645 646 try { 647 Indices = meta.getIndexInfo(TTable.Stmts.sDatabaseToConvert, 648 TTable.Stmts.sSchema, 649 TTable.Stmts.sSourceTable, false, 650 false); 651 } catch (SQLException e) { 652 Indices = null; 653 } 654 655 try { 656 if (Indices != null) { 657 while (Indices.next()) { 658 String tmpIndexName = null; 659 660 try { 661 tmpIndexName = Indices.getString(6); 662 } catch (SQLException e) { 663 tmpIndexName = null; 664 } 665 666 if (tmpIndexName == null) { 667 continue; 668 } 669 670 if (!tmpIndexName.equals(IndiceName)) { 671 if (!IndiceName.equals("")) { 672 CreateIndex = 673 CreateIndex.substring( 674 0, CreateIndex.length() - 1) + ");"; 675 DropIndex += ";"; 676 } 677 678 IndiceName = tmpIndexName; 679 DropIndex += "DROP INDEX "; 680 681 if ((TTable.Stmts.bIdxForced) 682 && (!IndiceName.startsWith("Idx_"))) { 683 DropIndex += Dest.helper.formatIdentifier("Idx_" 684 + IndiceName); 685 } else { 686 DropIndex += 687 Dest.helper.formatIdentifier(IndiceName); 688 } 689 690 CreateIndex += "CREATE "; 691 692 if (!Indices.getBoolean(4)) { 693 CreateIndex += "UNIQUE "; 694 } 695 696 CreateIndex += "INDEX "; 697 698 if ((TTable.Stmts.bIdxForced) 699 && (!IndiceName.startsWith("Idx_"))) { 700 CreateIndex += Dest.helper.formatIdentifier("Idx_" 701 + IndiceName); 702 } else { 703 CreateIndex += 704 Dest.helper.formatIdentifier(IndiceName); 705 } 706 707 CreateIndex += 708 " ON " 709 + Dest.helper.formatName(TTable.Stmts.sDestTable) 710 + "("; 711 } 712 713 CreateIndex += 714 Dest.helper.formatIdentifier(Indices.getString(9)) 715 + ","; 716 indices = true; 717 } 718 719 Indices.close(); 720 721 if (indices) { 722 CreateIndex = 723 CreateIndex.substring(0, CreateIndex.length() - 1) 724 + ");"; 725 DropIndex += ";"; 726 } 727 } 728 } catch (SQLException e) { 729 throw new DataAccessPointException(e.getMessage()); 730 } 731 732 Vector v = new Vector (); 733 734 tracer.trace("Reading source columns for table " 735 + TTable.Stmts.sSourceTable); 736 737 ResultSet col = null; 738 int colnum = 1; 739 Statement stmt = null; 740 ResultSet select_rs = null; 741 ResultSetMetaData select_rsmdata = null; 742 743 try { 744 stmt = conn.createStatement(); 745 select_rs = stmt.executeQuery(TTable.Stmts.sSourceSelect); 746 select_rsmdata = select_rs.getMetaData(); 747 col = meta.getColumns(TTable.Stmts.sDatabaseToConvert, 748 TTable.Stmts.sSchema, 749 TTable.Stmts.sSourceTable, null); 750 } catch (SQLException eSchema) { 751 752 if (TTable.Stmts.sSchema.equals("")) { 754 try { 755 col = meta.getColumns(TTable.Stmts.sDatabaseToConvert, 756 null, TTable.Stmts.sSourceTable, 757 null); 758 } catch (SQLException eSchema1) {} 759 } 760 } 761 762 try { 763 while (col.next()) { 764 String name = Dest.helper.formatIdentifier(col.getString(4)); 765 int type = col.getShort(5); 766 String source = col.getString(6); 767 int column_size = col.getInt(7); 768 String DefaultVal = col.getString(13); 769 boolean rsmdata_NoNulls = 770 (select_rsmdata.isNullable(colnum) 771 == java.sql.DatabaseMetaData.columnNoNulls); 772 boolean rsmdata_isAutoIncrement = false; 773 774 try { 775 rsmdata_isAutoIncrement = 776 select_rsmdata.isAutoIncrement(colnum); 777 } catch (SQLException e) { 778 rsmdata_isAutoIncrement = false; 779 } 780 781 int rsmdata_precision = select_rsmdata.getPrecision(colnum); 782 int rsmdata_scale = select_rsmdata.getScale(colnum); 783 784 type = helper.convertFromType(type); 785 type = Dest.helper.convertToType(type); 786 787 Integer inttype = new Integer (type); 788 String datatype = (String ) TTable.hTypes.get(inttype); 789 790 if (datatype == null) { 791 datatype = source; 792 793 tracer.trace("No mapping for type: " + name + " type: " 794 + type + " source: " + source); 795 } 796 797 if (type == Types.NUMERIC) { 798 datatype += "(" + Integer.toString(rsmdata_precision); 799 800 if (rsmdata_scale > 0) { 801 datatype += "," + Integer.toString(rsmdata_scale); 802 } 803 804 datatype += ")"; 805 } else if (type == Types.CHAR) { 806 datatype += "(" + Integer.toString(column_size) + ")"; 807 } else if (rsmdata_isAutoIncrement) { 808 datatype = "SERIAL"; 809 } 810 811 if (DefaultVal != null) { 812 if (type == Types.CHAR || type == Types.VARCHAR 813 || type == Types.LONGVARCHAR 814 || type == Types.BINARY || type == Types.DATE 815 || type == Types.TIME 816 || type == Types.TIMESTAMP) { 817 DefaultVal = "\'" + DefaultVal + "\'"; 818 } 819 820 datatype += " DEFAULT " + DefaultVal; 821 } 822 823 if (rsmdata_NoNulls) { 824 datatype += " NOT NULL "; 825 } 826 827 v.addElement(inttype); 828 829 datatype = helper.fixupColumnDefRead(TTable, select_rsmdata, 830 datatype, col, colnum); 831 datatype = Dest.helper.fixupColumnDefWrite(TTable, 832 select_rsmdata, datatype, col, colnum); 833 create += name + " " + datatype + ","; 834 insert += "?,"; 835 836 colnum++; 837 } 838 839 select_rs.close(); 840 stmt.close(); 841 col.close(); 842 } catch (SQLException e) { 843 throw new DataAccessPointException(e.getMessage()); 844 } 845 846 if (primarykeys) { 847 create += PrimaryKeysConstraint + ","; 848 } 849 850 TTable.Stmts.sDestCreate = create.substring(0, create.length() - 1) 851 + ")"; 852 TTable.Stmts.sDestInsert = insert.substring(0, insert.length() - 1) 853 + ")"; 854 855 if (importedkeys) { 856 TTable.Stmts.bAlter = true; 857 TTable.Stmts.sDestAlter = alterCreate; 858 } else { 859 TTable.Stmts.bAlter = false; 860 } 861 862 if (indices) { 863 TTable.Stmts.bCreateIndex = true; 864 TTable.Stmts.bDropIndex = true; 865 TTable.Stmts.sDestCreateIndex = CreateIndex; 866 TTable.Stmts.sDestDropIndex = DropIndex; 867 } else { 868 TTable.Stmts.bCreateIndex = false; 869 TTable.Stmts.bDropIndex = false; 870 } 871 872 } 877 878 void close() throws DataAccessPointException { 879 880 if (srcStatement != null) { 881 try { 882 srcStatement.close(); 883 } catch (SQLException e) {} 884 885 srcStatement = null; 886 } 887 888 if (conn != null) { 889 try { 890 conn.close(); 891 } catch (SQLException e) {} 892 893 conn = null; 894 } 895 } 896 897 907 private void transferRow(TransferResultSet r, PreparedStatement p, 908 int len, 909 int[] types) 910 throws DataAccessPointException, SQLException { 911 912 for (int i = 1; i <= len; i++) { 913 int t = types[i]; 914 Object o = r.getObject(i); 915 916 if (o == null) { 917 if (p != null) { 918 p.setNull(i, t); 919 } 920 } else { 921 o = helper.convertColumnValue(o, i, t); 922 923 p.setObject(i, o); 924 } 925 } 926 927 if (p != null) { 928 p.execute(); 929 } 930 } 931 932 935 public DatabaseMetaData getMeta() { 936 return meta; 937 } 938 939 942 public Connection getConn() { 943 return conn; 944 } 945 } 946 | Popular Tags |