1 19 package org.netbeans.mdr.persistence.jdbcimpl; 20 21 import org.netbeans.mdr.persistence.*; 22 import org.netbeans.mdr.util.*; 23 24 import java.sql.*; 25 import java.util.*; 26 import java.io.*; 27 28 34 class JdbcStorage implements Storage 35 { 36 public static final String MOFID_SEQ_TABLE_NAME = "MOFID_SEQ"; 37 38 public static final String MOFID_SEQ_COL_NAME = "MOFID_SEQ_NEXT"; 39 40 public static final String KEY_COL_PREFIX = "IDX_KEY"; 41 42 public static final String SINGLE_VAL_COL_PREFIX = "IDX_SVAL"; 43 44 public static final String MULTI_VAL_COL_PREFIX = "IDX_MVAL"; 45 46 public static final String ORDINAL_COL_NAME = "IDX_ORD"; 47 48 public static final String SURROGATE_COL_NAME = "IDX_SUR"; 49 50 public static final String PRIMARY_INDEX_NAME = "PRIMARY_INDEX"; 51 52 private Connection jdbcConnection; 53 54 private final DatabaseMetaData dbMetaData; 55 56 private final String idQuote; 57 58 private final String schemaName; 59 60 private final String schemaAuthName; 61 62 private final String userName; 63 64 private final String storageId; 65 66 private final boolean realSchema; 67 68 private final boolean debugPrint; 69 70 private final boolean queryDuplicates; 71 72 private final Map entryTypeToDataTypeMap; 73 74 private Statement jdbcStmt; 75 76 private ResultSet jdbcResultSet; 77 78 private long firstSerialNumber; 79 80 private long nextSerialNumber; 81 82 private Map nameToIndexMap; 83 84 private LazyPreparedStatement sqlUpdateSerialNumber; 85 86 private Map sqlToPreparedStatementMap; 89 90 private List lazyPreparedStatements; 91 92 private JdbcPrimaryIndex primaryIndex; 93 94 JdbcStorage( 95 Properties properties, 96 String storageId) 97 throws StorageException 98 { 99 this.storageId = storageId; 100 101 schemaName = properties.getProperty( 102 JdbcStorageFactory.STORAGE_SCHEMA_NAME); 103 schemaAuthName = properties.getProperty( 104 JdbcStorageFactory.STORAGE_SCHEMA_AUTH_NAME); 105 userName = properties.getProperty( 106 JdbcStorageFactory.STORAGE_USER_NAME); 107 108 entryTypeToDataTypeMap = new HashMap(); 109 createTypeMap(properties); 110 111 String url = properties.getProperty( 112 JdbcStorageFactory.STORAGE_URL); 113 String password = properties.getProperty( 114 JdbcStorageFactory.STORAGE_PASSWORD); 115 String firstSerialNumberString = properties.getProperty( 116 JdbcStorageFactory.STORAGE_FIRST_SERIAL_NUMBER); 117 if (firstSerialNumberString == null) { 118 firstSerialNumber = 1; 119 } else { 120 try { 121 firstSerialNumber = 122 Long.decode(firstSerialNumberString).longValue(); 123 } catch (NumberFormatException ex) { 124 throw new StorageBadRequestException(ex.toString()); 125 } 126 } 127 debugPrint = getBooleanProperty( 128 properties, 129 JdbcStorageFactory.STORAGE_DEBUG_PRINT, 130 false); 131 queryDuplicates = getBooleanProperty( 132 properties, 133 JdbcStorageFactory.STORAGE_QUERY_DUPLICATES, 134 false); 135 136 sqlToPreparedStatementMap = new HashMap(); 137 lazyPreparedStatements = new ArrayList(); 138 139 boolean success = false; 140 141 try { 142 jdbcConnection = 145 DriverManager.getConnection(url,userName,password); 146 jdbcConnection.setAutoCommit(false); 147 jdbcStmt = jdbcConnection.createStatement(); 148 dbMetaData = jdbcConnection.getMetaData(); 149 realSchema = dbMetaData.supportsSchemasInTableDefinitions(); 150 idQuote = dbMetaData.getIdentifierQuoteString(); 151 success = true; 152 } catch (SQLException ex) { 153 throw newJdbcException(ex); 154 } finally { 155 if (!success) { 156 rollbackConnection(); 157 closeConnection(); 158 } 159 } 160 } 161 162 private static boolean getBooleanProperty( 163 Properties properties, 164 String propName, 165 boolean defaultValue) 166 { 167 String value = properties.getProperty(propName); 168 if (value == null) { 169 return defaultValue; 170 } 171 return value.equalsIgnoreCase("true"); 172 } 173 174 private JdbcStorageException newJdbcException(SQLException ex) 175 { 176 if (debugPrint) { 177 ex.printStackTrace(); 178 } 179 return new JdbcStorageException(ex); 180 } 181 182 private void createTypeMap(Properties properties) 183 { 184 entryTypeToDataTypeMap.put( 185 EntryType.MOFID, 186 properties.getProperty( 187 JdbcStorageFactory.STORAGE_DATATYPE_MOFID, 188 "BIGINT")); 189 190 entryTypeToDataTypeMap.put( 191 EntryType.STREAMABLE, 192 properties.getProperty( 193 JdbcStorageFactory.STORAGE_DATATYPE_STREAMABLE, 194 "LONGVARBINARY")); 195 196 entryTypeToDataTypeMap.put( 197 EntryType.STRING, 198 properties.getProperty( 199 JdbcStorageFactory.STORAGE_DATATYPE_STRING, 200 "VARCHAR(2000)")); 201 202 entryTypeToDataTypeMap.put( 203 EntryType.INT, 204 properties.getProperty( 205 JdbcStorageFactory.STORAGE_DATATYPE_INT, 206 "BIGINT")); 207 } 208 209 public String getName() 211 { 212 return schemaName + ".jdbc"; 213 } 214 215 public String getStorageId () 217 { 218 return storageId; 219 } 220 221 private void writeSerialNumber(long serialNumber) 222 throws StorageException 223 { 224 executeUpdate( 225 sqlUpdateSerialNumber, 226 new Object []{new Long (serialNumber)}); 227 } 228 229 public synchronized long getSerialNumber() 231 { 232 return nextSerialNumber++; 233 } 234 235 public MOFID readMOFID (java.io.InputStream inputStream) 237 throws StorageException 238 { 239 try { 241 String storageId = IOUtils.readString(inputStream); 242 if (storageId == null) { 243 storageId = this.storageId; 244 } 245 long serial = IOUtils.readLong(inputStream); 246 return new MOFID(serial, storageId); 247 } catch (java.io.IOException ioException) { 248 throw new StorageIOException(ioException); 249 } 250 } 251 252 public void writeMOFID (java.io.OutputStream outputStream, MOFID mofid) 254 throws StorageException 255 { 256 try { 258 if (storageId.equals(mofid.getStorageID())) { 259 IOUtils.writeString(outputStream, null); 260 } else { 261 IOUtils.writeString(outputStream, mofid.getStorageID()); 262 } 263 IOUtils.writeLong(outputStream, mofid.getSerialNumber()); 264 } catch (IOException ioException) { 265 throw new StorageIOException(ioException); 266 } 267 } 268 269 DatabaseMetaData getDatabaseMetaData() 270 { 271 return dbMetaData; 272 } 273 274 private String getQualifiedTableName(String tableName) 275 { 276 if (realSchema) { 277 return idQuote + schemaName + idQuote + "." + idQuote 278 + tableName + idQuote; 279 } else { 280 return idQuote + schemaName + "_" + tableName + idQuote; 281 } 282 } 283 284 private String getQualifiedSchemaName() 285 { 286 return idQuote + schemaName + idQuote; 287 } 288 289 private void rollbackConnection() 290 { 291 closeResultSet(); 292 if (jdbcConnection != null) { 293 try { 294 jdbcConnection.rollback(); 295 } catch (SQLException ex) { 296 } 298 } 299 } 300 301 private long readSerialNumber() 302 { 303 try { 304 jdbcResultSet = jdbcStmt.executeQuery( 305 "select * from "+getQualifiedTableName(MOFID_SEQ_TABLE_NAME)); 306 jdbcResultSet.next(); 307 long x = jdbcResultSet.getLong(1); 308 return x; 309 } catch (SQLException ex) { 310 return -1; 311 } 312 } 313 314 public synchronized boolean exists() throws StorageException 316 { 317 long x = readSerialNumber(); 318 return x != -1; 319 } 320 321 public synchronized boolean delete() throws StorageException 323 { 324 rollbackConnection(); 325 try { 326 if (realSchema) { 327 jdbcResultSet = dbMetaData.getSchemas(); 328 boolean found = false; 329 while (jdbcResultSet.next()) { 330 String name = jdbcResultSet.getString(1); 331 if (name.equals(schemaName)) { 332 found = true; 333 break; 334 } 335 } 336 closeResultSet(); 337 if (!found) { 338 return true; 340 } 341 jdbcStmt.execute( 342 "drop schema " + getQualifiedSchemaName() + " cascade"); 343 } else { 344 jdbcResultSet = dbMetaData.getTables( 345 null,null,schemaName + "%",null); 346 List tables = new ArrayList(); 347 while (jdbcResultSet.next()) { 348 tables.add(jdbcResultSet.getString("TABLE_NAME")); 349 } 350 closeResultSet(); 351 Iterator iter = tables.iterator(); 352 while (iter.hasNext()) { 353 String tableName = (String ) iter.next(); 354 jdbcStmt.execute( 355 "drop table " + idQuote + tableName + idQuote); 356 } 357 } 358 jdbcConnection.commit(); 359 return true; 360 } catch (SQLException ex) { 361 rollbackConnection(); 362 return false; 363 } 364 } 365 366 private boolean isBlank(String s) 367 { 368 return (s == null) || (s.length() == 0); 369 } 370 371 public synchronized void create(boolean replace, ObjectResolver resolver) 373 throws StorageException 374 { 375 try { 376 if (replace) { 377 delete(); 378 } 379 rollbackConnection(); 380 if (realSchema) { 381 String sql = "create schema " + getQualifiedSchemaName(); 382 String authName = null; 383 if (!isBlank(schemaAuthName)) { 384 if (!schemaAuthName.equals("!NONE")) { 385 authName = schemaAuthName; 386 } 387 } else if (!isBlank(userName)) { 388 authName = userName; 389 } 390 if (authName != null) { 391 sql = sql + " authorization " + authName; 392 } 393 jdbcStmt.execute(sql); 394 } 395 String intType = getDataType(EntryType.INT); 396 jdbcStmt.execute( 397 "create table " + getQualifiedTableName(MOFID_SEQ_TABLE_NAME) 398 + "(" + MOFID_SEQ_COL_NAME + " " + intType 399 + " not null primary key)"); 400 jdbcStmt.executeUpdate( 401 "insert into " + getQualifiedTableName(MOFID_SEQ_TABLE_NAME) 402 + " values(1)"); 403 nextSerialNumber = firstSerialNumber; 404 openImpl(); 405 createSinglevaluedIndex( 406 PRIMARY_INDEX_NAME, 407 EntryType.MOFID, 408 EntryType.STREAMABLE); 409 loadPrimaryIndex(); 410 jdbcConnection.commit(); 411 } catch (SQLException ex) { 412 rollbackConnection(); 413 throw newJdbcException(ex); 414 } 415 } 416 417 public synchronized void open( 419 boolean createOnNoExist, ObjectResolver resolver) 420 throws StorageException 421 { 422 nextSerialNumber = readSerialNumber(); 423 if (nextSerialNumber == -1) { 424 if (createOnNoExist) { 425 create(false,resolver); 426 return; 427 } else { 428 throw new StorageBadRequestException( 429 "Storage " + getName() + " does not exist."); 430 } 431 } 432 try { 433 openImpl(); 434 loadPrimaryIndex(); 435 } catch (SQLException ex) { 436 throw newJdbcException(ex); 437 } 438 } 439 440 private void openImpl() throws SQLException 441 { 442 nameToIndexMap = new HashMap(); 443 sqlUpdateSerialNumber = new LazyPreparedStatement( 444 "update " + getQualifiedTableName(MOFID_SEQ_TABLE_NAME) 445 + " set " + MOFID_SEQ_COL_NAME + " = ?"); 446 } 447 448 private void loadPrimaryIndex() 449 throws StorageException 450 { 451 primaryIndex = (JdbcPrimaryIndex) getIndex(PRIMARY_INDEX_NAME); 452 } 453 454 public synchronized void close() throws StorageException 456 { 457 nameToIndexMap = null; 458 sqlUpdateSerialNumber = null; 459 closeAllPreparedStatements(); 460 rollbackConnection(); 461 } 462 463 private void closeAllPreparedStatements() 464 { 465 Iterator iter = sqlToPreparedStatementMap.values().iterator(); 466 while (iter.hasNext()) { 467 PreparedStatement ps = (PreparedStatement) iter.next(); 468 closePreparedStatement(ps); 469 } 470 iter = lazyPreparedStatements.iterator(); 471 while (iter.hasNext()) { 472 LazyPreparedStatement lps = (LazyPreparedStatement) iter.next(); 473 lps.ps = null; 474 } 475 sqlToPreparedStatementMap = new HashMap(); 476 lazyPreparedStatements = new ArrayList(); 477 } 478 479 private void closePreparedStatement(PreparedStatement ps) 480 { 481 if (ps == null) { 482 return; 483 } 484 try { 485 ps.close(); 486 } catch (SQLException ex) { 487 } 489 } 490 491 private void closeStatement() 492 { 493 if (jdbcStmt == null) { 494 return; 495 } 496 try { 497 jdbcStmt.close(); 498 } catch (SQLException ex) { 499 } finally { 501 jdbcStmt = null; 502 } 503 } 504 505 private void closeResultSet() 506 { 507 if (jdbcResultSet == null) { 508 return; 509 } 510 try { 511 jdbcResultSet.close(); 512 } catch (SQLException ex) { 513 } finally { 515 jdbcResultSet = null; 516 } 517 } 518 519 private void closeConnection() 520 { 521 if (jdbcConnection == null) { 522 return; 523 } 524 try { 525 jdbcConnection.close(); 526 } catch (SQLException ex) { 527 } finally { 529 jdbcConnection = null; 530 } 531 } 532 533 public synchronized SinglevaluedIndex createSinglevaluedIndex( 535 String name, EntryType keyType, 536 EntryType valueType) throws StorageException 537 { 538 createIndex(name,keyType,valueType,true,true,false); 539 return getSinglevaluedIndex(name); 540 } 541 542 public synchronized MultivaluedOrderedIndex createMultivaluedOrderedIndex( 544 String name, EntryType keyType, EntryType valueType, boolean unique) 545 throws StorageException 546 { 547 createIndex(name,keyType,valueType,false,false,true); 549 return getMultivaluedOrderedIndex(name); 550 } 551 552 public synchronized MultivaluedIndex createMultivaluedIndex( 554 String name, EntryType keyType, EntryType valueType, boolean unique) 555 throws StorageException 556 { 557 createIndex(name,keyType,valueType,false,unique,false); 558 return getMultivaluedIndex(name); 559 } 560 561 private String getDataType(EntryType entryType) 562 { 563 return (String ) entryTypeToDataTypeMap.get(entryType); 564 } 565 566 private EntryType getEntryType(ResultSetMetaData md,int i) 567 throws SQLException 568 { 569 String colName = md.getColumnName(i).toUpperCase(); 570 int lastUnderscore = colName.lastIndexOf('_'); 571 String entryTypeName = 572 colName.substring(lastUnderscore + 1); 573 return EntryType.decodeEntryType(entryTypeName); 574 } 575 576 private String stripMofId(String indexName) 577 { 578 int i = indexName.indexOf(storageId); 579 if (i == -1) { 580 return indexName; 581 } 582 int j = i + storageId.length(); 583 if (indexName.charAt(j) != ':') { 584 return indexName; 585 } 586 int n = indexName.length(); 587 for (++j; j < n; ++j) { 588 if (indexName.charAt(j) != '0') { 589 break; 590 } 591 } 592 return indexName.substring(0,i) + indexName.substring(j); 593 } 594 595 private String getTableNameForIndex(String indexName) 596 { 597 indexName = stripMofId(indexName); 602 indexName = stripMofId(indexName); 603 indexName = indexName.replace(':','_'); 606 return getQualifiedTableName(indexName); 607 } 608 609 private void createIndex( 610 String name, EntryType keyType, EntryType valueType, 611 boolean singleValued,boolean uniqueValued,boolean ordered) 612 throws StorageException 613 { 614 try { 615 StringBuffer sb = new StringBuffer (); 616 sb.append("create table "); 617 sb.append(getTableNameForIndex(name)); 618 sb.append("("); 619 620 String keyColName = KEY_COL_PREFIX + "_" + keyType; 621 sb.append(keyColName); 622 sb.append(" "); 623 sb.append(getDataType(keyType)); 624 sb.append(" not null, "); 625 626 String valColName; 627 if (singleValued) { 628 valColName = SINGLE_VAL_COL_PREFIX; 629 } else { 630 valColName = MULTI_VAL_COL_PREFIX; 631 } 632 valColName = valColName + "_" + valueType; 633 sb.append(valColName); 634 sb.append(" "); 635 sb.append(getDataType(valueType)); 636 sb.append(" not null,"); 637 638 String intType = getDataType(EntryType.INT); 639 640 if (ordered) { 641 sb.append(ORDINAL_COL_NAME); 642 sb.append(" "); 643 sb.append(intType); 644 sb.append(" not null,"); 645 } 646 647 if (!uniqueValued) { 648 sb.append(SURROGATE_COL_NAME); 649 sb.append(" "); 650 sb.append(intType); 651 sb.append(" not null,"); 652 } 653 654 sb.append(" primary key("); 655 sb.append(keyColName); 656 if (singleValued) { 657 } else if (uniqueValued) { 659 sb.append(","); 660 sb.append(valColName); 661 } else { 662 if (ordered) { 663 sb.append(","); 670 sb.append(ORDINAL_COL_NAME); 671 } 672 sb.append(","); 673 sb.append(SURROGATE_COL_NAME); 674 } 675 sb.append(")"); 676 677 sb.append(")"); 678 jdbcStmt.execute(sb.toString()); 679 } catch (SQLException ex) { 680 throw newJdbcException(ex); 681 } 682 } 683 684 public synchronized SinglevaluedIndex getPrimaryIndex() 686 throws StorageException 687 { 688 return getSinglevaluedIndex(PRIMARY_INDEX_NAME); 689 } 690 691 private Index loadIndex(String name) 692 throws StorageException 693 { 694 PreparedStatement ps = null; 695 try { 696 ps = jdbcConnection.prepareStatement( 697 "select * from "+getTableNameForIndex(name)); 698 ResultSetMetaData md = null; 699 try { 700 md = ps.getMetaData(); 701 } catch (SQLException ex) { 702 } 705 if (md == null) { 706 jdbcResultSet = ps.executeQuery(); 707 md = jdbcResultSet.getMetaData(); 708 } 709 EntryType keyType = getEntryType(md,1); 710 EntryType valueType = getEntryType(md,2); 711 boolean singleValued = false; 712 boolean ordered = false; 713 boolean needSurrogate = false; 714 String keyColName = md.getColumnName(1).toUpperCase(); 715 String valColName = md.getColumnName(2).toUpperCase(); 716 if (valColName.startsWith(SINGLE_VAL_COL_PREFIX)) { 717 singleValued = true; 718 } 719 for (int i = 3; i <= md.getColumnCount(); ++i) { 720 String colName = md.getColumnName(i).toUpperCase(); 721 if (colName.equals(ORDINAL_COL_NAME)) { 722 ordered = true; 723 } else if (colName.equals(SURROGATE_COL_NAME)) { 724 needSurrogate = true; 725 } else { 726 } 728 } 729 JdbcIndex index; 730 if (singleValued) { 731 if (name.equals(PRIMARY_INDEX_NAME)) { 732 index = new JdbcPrimaryIndex(); 733 } else { 734 index = new JdbcSinglevaluedIndex(); 735 } 736 } else { 737 if (ordered) { 738 index = new JdbcMultivaluedOrderedIndex(); 739 } else { 740 index = new JdbcMultivaluedIndex(); 741 } 742 if (queryDuplicates && !needSurrogate) { 743 ((JdbcMultivaluedIndex) index).queryDuplicates = true; 744 } 745 } 746 index.init( 747 this, 748 getTableNameForIndex(name), 749 name,keyColName,valColName,keyType,valueType, 750 needSurrogate); 751 nameToIndexMap.put(name,index); 752 return index; 753 } catch (SQLException ex) { 754 throw newJdbcException(ex); 755 } finally { 756 closeResultSet(); 757 closePreparedStatement(ps); 758 } 759 } 760 761 public synchronized Index getIndex(String name) throws StorageException 763 { 764 synchronized(nameToIndexMap) { 765 Index index = (Index) nameToIndexMap.get(name); 766 if (index == null) { 767 index = loadIndex(name); 768 } 769 return index; 770 } 771 } 772 773 public synchronized SinglevaluedIndex getSinglevaluedIndex(String name) 775 throws StorageException 776 { 777 return (SinglevaluedIndex) getIndex(name); 778 } 779 780 public synchronized MultivaluedIndex getMultivaluedIndex(String name) 782 throws StorageException 783 { 784 return (MultivaluedIndex) getIndex(name); 785 } 786 787 public synchronized MultivaluedOrderedIndex getMultivaluedOrderedIndex( 789 String name) throws StorageException 790 { 791 return (MultivaluedOrderedIndex) getIndex(name); 792 } 793 794 public synchronized void dropIndex(String name) throws StorageException 796 { 797 try { 798 jdbcStmt.execute("drop table "+getTableNameForIndex(name)); 799 } catch (SQLException ex) { 800 throw newJdbcException(ex); 801 } 802 nameToIndexMap.remove(name); 803 } 804 805 public void objectStateWillChange(Object key) throws StorageException 807 { 808 } 810 811 public synchronized void objectStateChanged(Object key) 813 throws StorageException 814 { 815 primaryIndex.objectStateChanged(key); 816 } 817 818 public synchronized void commitChanges() throws StorageException 820 { 821 try { 822 writeSerialNumber(nextSerialNumber); 823 primaryIndex.flushChanges(); 824 if (!dbMetaData.supportsOpenStatementsAcrossCommit()) { 825 closeAllPreparedStatements(); 826 } 827 jdbcConnection.commit(); 828 } catch (SQLException ex) { 829 throw newJdbcException(ex); 830 } 831 } 832 833 public synchronized void rollBackChanges () throws StorageException 835 { 836 try { 837 if (!dbMetaData.supportsOpenStatementsAcrossRollback()) { 838 closeAllPreparedStatements(); 839 } 840 jdbcConnection.rollback(); 841 } catch (SQLException ex) { 842 throw newJdbcException(ex); 843 } 844 if (primaryIndex != null) { 845 primaryIndex.shutDown(); 846 } 847 nameToIndexMap = new HashMap(); 848 loadPrimaryIndex(); 849 } 850 851 public synchronized void shutDown() throws StorageException 853 { 854 if (sqlUpdateSerialNumber != null) { 855 commitChanges(); 856 } 857 closeStatement(); 858 closeConnection(); 859 } 860 861 private PreparedStatement prepareStatement( 862 LazyPreparedStatement lps) 863 throws StorageException 864 { 865 if (lps.ps != null) { 866 return lps.ps; 868 } 869 lazyPreparedStatements.add(lps); 870 PreparedStatement ps = (PreparedStatement) 871 sqlToPreparedStatementMap.get(lps.sql); 872 if (ps != null) { 873 lps.ps = ps; 874 return ps; 875 } 876 try { 877 ps = jdbcConnection.prepareStatement(lps.sql); 878 sqlToPreparedStatementMap.put(lps.sql,ps); 879 lps.ps = ps; 880 return ps; 881 } catch (SQLException ex) { 882 throw newJdbcException(ex); 883 } 884 } 885 886 private void bindArgs(PreparedStatement ps,Object [] args) 887 throws SQLException, StorageException 888 { 889 if (args == null) { 890 return; 891 } 892 for (int i = 0; i < args.length; ++i) { 893 Object arg = args[i]; 894 int iParam = i + 1; 895 if (arg instanceof MOFID) { 896 MOFID mofid = (MOFID) arg; 897 if (!mofid.getStorageID().equals(storageId)) { 898 throw new IllegalArgumentException ("Foreign MOFID"); 899 } 900 ps.setLong( 901 iParam, 902 mofid.getSerialNumber()); 903 } else if (arg instanceof Streamable) { 904 ps.setBytes( 905 iParam, 906 writeByteArray((Streamable) arg)); 907 } else { 908 ps.setObject( 909 iParam, 910 arg); 911 } 912 } 913 } 914 915 private Object getResultObj(EntryType entryType) 916 throws StorageException, SQLException 917 { 918 if (entryType == EntryType.MOFID) { 919 return new MOFID( 920 jdbcResultSet.getLong(1), 921 storageId); 922 } else if (entryType == EntryType.STRING) { 923 return jdbcResultSet.getString(1); 924 } else if (entryType == EntryType.INT) { 925 return new Long (jdbcResultSet.getLong(1)); 926 } else { 927 byte [] bytes = jdbcResultSet.getBytes(1); 928 byte [] copy = new byte[bytes.length]; 930 System.arraycopy(bytes,0,copy,0,bytes.length); 931 return copy; 932 } 933 } 934 935 synchronized ListIterator getResultSetIterator( 936 LazyPreparedStatement lps,Object [] args,EntryType entryType) 937 throws StorageException 938 { 939 try { 940 PreparedStatement ps = prepareStatement(lps); 941 bindArgs(ps,args); 942 jdbcResultSet = ps.executeQuery(); 943 List list = new ArrayList(); 945 try { 946 while (jdbcResultSet.next()) { 947 Object obj = getResultObj(entryType); 948 list.add(obj); 949 } 950 } finally { 951 closeResultSet(); 952 } 953 if (entryType == EntryType.STREAMABLE) { 954 ListIterator listIter = list.listIterator(); 958 while (listIter.hasNext()) { 959 byte [] bytes = (byte []) listIter.next(); 960 listIter.set(readByteArray(bytes)); 961 } 962 } 963 return list.listIterator(); 964 } catch (SQLException ex) { 965 throw newJdbcException(ex); 966 } 967 } 968 969 synchronized int getResultSetCount( 970 LazyPreparedStatement lps,Object [] args) 971 throws StorageException 972 { 973 try { 974 PreparedStatement ps = prepareStatement(lps); 975 bindArgs(ps,args); 976 jdbcResultSet = ps.executeQuery(); 977 try { 978 int n = 0; 979 while (jdbcResultSet.next()) { 980 ++n; 981 } 982 return n; 983 } finally { 984 closeResultSet(); 985 } 986 } catch (SQLException ex) { 987 throw newJdbcException(ex); 988 } 989 } 990 991 synchronized int getSingletonInt( 992 LazyPreparedStatement lps,Object [] args) 993 throws StorageException 994 { 995 try { 996 PreparedStatement ps = prepareStatement(lps); 997 bindArgs(ps,args); 998 jdbcResultSet = ps.executeQuery(); 999 try { 1000 if (!jdbcResultSet.next()) { 1002 return -1; 1003 } 1004 int n = jdbcResultSet.getInt(1); 1005 return n; 1006 } finally { 1007 closeResultSet(); 1008 } 1009 } catch (SQLException ex) { 1010 throw newJdbcException(ex); 1011 } 1012 } 1013 1014 private byte [] writeByteArray(Streamable data) 1015 throws StorageException 1016 { 1017 try { 1018 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 1019 DataOutputStream dataStream = new DataOutputStream(byteStream); 1020 dataStream.writeUTF(data.getClass().getName()); 1021 data.write(dataStream); 1022 dataStream.flush(); 1023 return byteStream.toByteArray(); 1024 } catch (IOException ex) { 1025 throw new StorageIOException(ex); 1026 } 1027 } 1028 1029 private Streamable readByteArray(byte [] bytes) 1030 throws StorageException 1031 { 1032 ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes); 1033 DataInputStream dataStream = new DataInputStream(byteStream); 1034 1035 String className; 1037 Streamable data; 1038 1039 try { 1040 className = dataStream.readUTF(); 1041 } catch (IOException ex) { 1042 throw new StorageIOException(ex); 1043 } 1044 try { 1045 Class cls = Class.forName(className); 1046 data = (Streamable)cls.newInstance(); 1047 } catch (Exception ex) { 1048 throw new StoragePersistentDataException(ex.getMessage()); 1049 } 1050 if (data instanceof StorageClient) { 1051 ((StorageClient)data).setStorage(this); 1052 } 1053 data.read(dataStream); 1054 return data; 1055 } 1056 1057 synchronized int executeUpdate(LazyPreparedStatement lps,Object [] args) 1058 throws StorageException 1059 { 1060 try { 1061 PreparedStatement ps = prepareStatement(lps); 1062 bindArgs(ps,args); 1063 return ps.executeUpdate(); 1064 } catch (SQLException ex) { 1065 throw newJdbcException(ex); 1066 } 1067 } 1068} 1069 1070 | Popular Tags |