1 23 24 package org.continuent.sequoia.controller.virtualdatabase; 25 26 import java.sql.DatabaseMetaData ; 27 import java.sql.ResultSet ; 28 import java.sql.ResultSetMetaData ; 29 import java.sql.SQLException ; 30 import java.sql.Types ; 31 import java.util.ArrayList ; 32 import java.util.Collection ; 33 import java.util.Iterator ; 34 import java.util.Map ; 35 36 import org.continuent.hedera.adapters.MulticastRequestAdapter; 37 import org.continuent.hedera.adapters.MulticastResponse; 38 import org.continuent.hedera.channel.NotConnectedException; 39 import org.continuent.sequoia.common.exceptions.ControllerException; 40 import org.continuent.sequoia.common.exceptions.NoMoreBackendException; 41 import org.continuent.sequoia.common.exceptions.UnreachableBackendException; 42 import org.continuent.sequoia.common.log.Trace; 43 import org.continuent.sequoia.common.protocol.Field; 44 import org.continuent.sequoia.common.users.VirtualDatabaseUser; 45 import org.continuent.sequoia.controller.authentication.AuthenticationManager; 46 import org.continuent.sequoia.controller.backend.DatabaseBackend; 47 import org.continuent.sequoia.controller.backend.result.ControllerResultSet; 48 import org.continuent.sequoia.controller.connection.AbstractConnectionManager; 49 import org.continuent.sequoia.controller.connection.PooledConnection; 50 import org.continuent.sequoia.controller.core.ControllerConstants; 51 import org.continuent.sequoia.controller.requestmanager.RAIDbLevels; 52 import org.continuent.sequoia.controller.requestmanager.RequestManager; 53 import org.continuent.sequoia.controller.requests.AbstractRequest; 54 import org.continuent.sequoia.controller.requests.UnknownReadRequest; 55 import org.continuent.sequoia.controller.sql.schema.DatabaseColumn; 56 import org.continuent.sequoia.controller.sql.schema.DatabaseProcedure; 57 import org.continuent.sequoia.controller.sql.schema.DatabaseProcedureParameter; 58 import org.continuent.sequoia.controller.sql.schema.DatabaseSchema; 59 import org.continuent.sequoia.controller.sql.schema.DatabaseTable; 60 import org.continuent.sequoia.controller.virtualdatabase.protocol.GetMetadata; 61 62 71 public class VirtualDatabaseDynamicMetaData 72 { 73 74 75 public static final int NULL_VALUE = -999; 76 77 private VirtualDatabase vdb; 78 private String vdbName; 79 private RequestManager requestManager; 80 81 82 private Trace logger = null; 83 84 90 public VirtualDatabaseDynamicMetaData(VirtualDatabase database) 91 { 92 this.vdb = database; 93 this.vdbName = database.getDatabaseName(); 94 requestManager = database.getRequestManager(); 95 if (requestManager == null) 96 throw new RuntimeException ( 97 "Null request manager in VirtualDatabaseMetaData"); 98 99 this.logger = Trace 100 .getLogger("org.continuent.sequoia.controller.virtualdatabase.VirtualDatabaseWorkerThread." 101 + vdbName + ".metadata"); 102 } 103 104 108 public ControllerResultSet getAttributes(ConnectionContext connContext, 109 String catalog, String schemaPattern, String typeNamePattern, 110 String attributeNamePattern) throws SQLException 111 { 112 try 114 { 115 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 116 if ((raidbLevel == RAIDbLevels.RAIDb1) 117 || (raidbLevel == RAIDbLevels.SingleDB)) 118 { return doGetAttributes(connContext, catalog, schemaPattern, 120 typeNamePattern, attributeNamePattern); 121 } 122 } 123 catch (NoMoreBackendException ignore) 124 { 125 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 127 String .class, String .class}; 128 Object [] args = {connContext, catalog, schemaPattern, typeNamePattern, 129 attributeNamePattern}; 130 ControllerResultSet crs = getMetaDataFromRemoteController( 131 "doGetAttributes", argTypes, args); 132 if (crs != null) 133 return crs; 134 } 135 136 138 ArrayList data = new ArrayList (); 139 ControllerResultSet rs = new ControllerResultSet(getAttributesFields, data); 140 return rs; 141 } 142 143 146 private ControllerResultSet doGetAttributes(ConnectionContext connContext, 147 String catalog, String schemaPattern, String typeNamePattern, 148 String attributeNamePattern) throws SQLException 149 { 150 ConnectionAndDatabaseMetaData info = null; 151 try 152 { 153 info = getMetaDataFromFirstAvailableBackend(connContext); 154 DatabaseMetaData m = info.getDatabaseMetaData(); 155 ResultSet cols = m.getAttributes(catalog, schemaPattern, typeNamePattern, 156 attributeNamePattern); 157 ArrayList data = new ArrayList (); 158 while (cols.next()) 159 { Object [] row = new Object [21]; 161 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); row[14] = cols.getObject(15); row[15] = cols.getObject(16); row[16] = cols.getObject(17); row[17] = cols.getObject(18); row[18] = cols.getObject(19); row[19] = cols.getObject(20); row[20] = cols.getObject(21); data.add(row); 183 } 184 Field[] fields; 185 if (vdb.useStaticResultSetMetaData()) 186 fields = getAttributesFields; 187 else 188 { ResultSetMetaData metaData = cols.getMetaData(); 190 if (metaData == null) 191 fields = getAttributesFields; 192 else 193 fields = ControllerConstants.CONTROLLER_FACTORY 194 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 195 null); 196 } 197 return new ControllerResultSet(fields, data); 198 } 199 catch (SQLException e) 200 { 201 throw e; 202 } 203 finally 204 { 205 releaseConnection(info); 206 } 207 } 208 209 213 public ControllerResultSet getBestRowIdentifier( 214 ConnectionContext connContext, String catalog, String schema, 215 String table, int scope, boolean nullable) throws SQLException 216 { 217 try 218 { 219 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 220 if ((raidbLevel == RAIDbLevels.RAIDb1) 221 || (raidbLevel == RAIDbLevels.SingleDB)) 222 { return doGetBestRowIdentifier(connContext, catalog, schema, table, 224 scope, nullable); 225 } 226 } 227 catch (NoMoreBackendException ignore) 228 { 229 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 231 String .class, int.class, boolean.class}; 232 Object [] args = {connContext, catalog, schema, table, new Integer (scope), 233 Boolean.valueOf(nullable)}; 234 ControllerResultSet crs = getMetaDataFromRemoteController( 235 "doGetBestRowIdentifier", argTypes, args); 236 if (crs != null) 237 return crs; 238 } 239 240 242 ArrayList data = new ArrayList (); 243 ControllerResultSet rs = new ControllerResultSet( 244 getBestRowIdentifierAndVersionColumnsFields, data); 245 return rs; 246 } 247 248 252 public ControllerResultSet doGetBestRowIdentifier( 253 ConnectionContext connContext, String catalog, String schema, 254 String table, int scope, boolean nullable) throws SQLException 255 { 256 ConnectionAndDatabaseMetaData info = null; 257 try 258 { 259 info = getMetaDataFromFirstAvailableBackend(connContext); 260 DatabaseMetaData m = info.getDatabaseMetaData(); 261 ResultSet cols = m.getBestRowIdentifier(catalog, schema, table, scope, 262 nullable); 263 ArrayList data = new ArrayList (); 264 while (cols.next()) 265 { Object [] row = new Object [8]; 267 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); data.add(row); 276 } 277 Field[] fields; 278 if (vdb.useStaticResultSetMetaData()) 279 fields = getBestRowIdentifierAndVersionColumnsFields; 280 else 281 { ResultSetMetaData metaData = cols.getMetaData(); 283 if (metaData == null) 284 fields = getBestRowIdentifierAndVersionColumnsFields; 285 else 286 fields = ControllerConstants.CONTROLLER_FACTORY 287 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 288 null); 289 } 290 return new ControllerResultSet(fields, data); 291 } 292 catch (SQLException e) 293 { 294 throw e; 295 } 296 finally 297 { 298 releaseConnection(info); 299 } 300 } 301 302 308 public ControllerResultSet getCatalogs(ArrayList list) 309 { 310 int size = list.size(); 311 ArrayList data = new ArrayList (size); 312 for (int i = 0; i < size; i++) 313 { 314 Object [] row = new Object [1]; 315 row[0] = list.get(i); 316 data.add(row); 317 } 318 ControllerResultSet rs = new ControllerResultSet(getCatalogsFields, data); 319 return rs; 320 } 321 322 326 public ControllerResultSet getColumnPrivileges(ConnectionContext connContext, 327 String catalog, String schema, String table, String columnNamePattern) 328 throws SQLException 329 { 330 try 331 { 332 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 333 if ((raidbLevel == RAIDbLevels.RAIDb1) 334 || (raidbLevel == RAIDbLevels.SingleDB)) 335 { return doGetColumnPrivileges(connContext, catalog, schema, table, 337 columnNamePattern); 338 } 339 } 340 catch (NoMoreBackendException ignore) 341 { 342 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 344 String .class, String .class}; 345 Object [] args = {connContext, catalog, schema, table, columnNamePattern}; 346 ControllerResultSet crs = getMetaDataFromRemoteController( 347 "doGetColumnPrivileges", argTypes, args); 348 if (crs != null) 349 return crs; 350 } 351 352 AuthenticationManager manager = requestManager.getVirtualDatabase() 353 .getAuthenticationManager(); 354 355 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 356 if (dbs == null) 357 throw new SQLException ("Unable to fetch the virtual database schema"); 358 359 if (columnNamePattern == null) 360 columnNamePattern = "%"; 362 363 DatabaseTable dbTable = dbs.getTable(table); 364 if (dbTable == null) 365 throw new SQLException ("Unable to find table " + table); 366 367 ArrayList columns = dbTable.getColumns(); 368 int size = columns.size(); 369 ArrayList data = new ArrayList (); 370 371 ArrayList virtualLogins = manager.getVirtualLogins(); 372 int vsize = virtualLogins.size(); 373 VirtualDatabaseUser vu; 374 375 for (int i = 0; i < size; i++) 376 { 377 DatabaseColumn c = (DatabaseColumn) columns.get(i); 378 if (columnNamePattern.equals("%") 379 || columnNamePattern.equals(c.getName())) 380 { 381 for (int j = 0; j < vsize; j++) 382 { 383 vu = (VirtualDatabaseUser) virtualLogins.get(0); 384 385 if (logger.isDebugEnabled()) 386 logger.debug("Found privilege for user:" + vu.getLogin() 387 + " on column:" + c.getName()); 388 Object [] row = new Object [8]; 389 row[0] = vdbName; row[1] = null; row[2] = table; row[3] = c.getName(); row[4] = null; row[5] = vu.getLogin(); row[6] = "UPDATE"; row[7] = "NO"; data.add(row); 398 } 399 } 400 } 401 402 ControllerResultSet rs = new ControllerResultSet(getColumnPrivilegesFields, 403 data); 404 return rs; 405 } 406 407 411 public ControllerResultSet doGetColumnPrivileges( 412 ConnectionContext connContext, String catalog, String schema, 413 String table, String columnNamePattern) throws SQLException 414 { 415 ConnectionAndDatabaseMetaData info = null; 416 try 417 { 418 info = getMetaDataFromFirstAvailableBackend(connContext); 419 DatabaseMetaData m = info.getDatabaseMetaData(); 420 ResultSet cols = m.getColumnPrivileges(catalog, schema, table, 421 columnNamePattern); 422 ArrayList data = new ArrayList (); 423 while (cols.next()) 424 { Object [] row = new Object [8]; 426 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); data.add(row); 435 } 436 return new ControllerResultSet(getColumnPrivilegesFields, data); 437 } 438 catch (SQLException e) 439 { 440 throw e; 441 } 442 finally 443 { 444 releaseConnection(info); 445 } 446 } 447 448 452 public ControllerResultSet getColumns(ConnectionContext connContext, 453 String catalog, String schemaPattern, String tableNamePattern, 454 String columnNamePattern) throws SQLException 455 { 456 if (logger.isDebugEnabled()) 457 logger.debug("Getting columns for " + vdbName); 458 459 try 460 { 461 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 462 if ((raidbLevel == RAIDbLevels.RAIDb1) 463 || (raidbLevel == RAIDbLevels.SingleDB)) 464 { return doGetColumns(connContext, catalog, schemaPattern, 466 tableNamePattern, columnNamePattern); 467 } 468 } 469 catch (NoMoreBackendException ignore) 470 { 471 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 473 String .class, String .class}; 474 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern, 475 columnNamePattern}; 476 ControllerResultSet crs = getMetaDataFromRemoteController("doGetColumns", 477 argTypes, args); 478 if (crs != null) 479 return crs; 480 } 481 482 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 485 if (dbs == null) 486 throw new SQLException ("Unable to fetch the virtual database schema"); 487 488 if (tableNamePattern == null) 489 tableNamePattern = "%"; 492 if (columnNamePattern == null) 493 columnNamePattern = "%"; 495 Collection tables = dbs.getTables().values(); 497 ArrayList data = new ArrayList (tables.size()); 498 499 for (Iterator iter = tables.iterator(); iter.hasNext();) 500 { 501 DatabaseTable t = (DatabaseTable) iter.next(); 502 503 if (tableNamePattern.equals("%") || tableNamePattern.equals(t.getName())) 504 { 505 if (logger.isDebugEnabled()) 506 logger.debug("Found table " + t.getName()); 507 ArrayList columns = t.getColumns(); 508 for (int j = 0; j < columns.size(); j++) 509 { 510 DatabaseColumn c = (DatabaseColumn) columns.get(j); 511 if (columnNamePattern.equals("%") 512 || columnNamePattern.equals(c.getName())) 513 { 514 if (logger.isDebugEnabled()) 515 logger.debug("Found column " + c.getName()); 516 Object [] row = new Object [22]; 517 row[0] = vdbName; row[1] = null; row[2] = t.getName(); row[3] = c.getName(); row[4] = new Integer (c.getType()); row[5] = null; row[6] = null; row[7] = null; row[8] = null; row[9] = null; row[10] = null; row[11] = null; row[12] = null; row[13] = null; row[14] = null; row[15] = null; row[16] = null; row[17] = ""; row[18] = null; row[19] = null; row[20] = null; row[21] = null; data.add(row); 540 } 541 } 542 } 543 } 544 ControllerResultSet rs = new ControllerResultSet(getColumnsFields, data); 545 return rs; 546 } 547 548 551 public ControllerResultSet doGetColumns(ConnectionContext connContext, 552 String catalog, String schemaPattern, String tableNamePattern, 553 String columnNamePattern) throws SQLException 554 { 555 ConnectionAndDatabaseMetaData info = null; 556 try 557 { 558 info = getMetaDataFromFirstAvailableBackend(connContext); 559 DatabaseMetaData m = info.getDatabaseMetaData(); 560 ResultSet cols = m.getColumns(catalog, schemaPattern, tableNamePattern, 561 columnNamePattern); 562 ArrayList data = new ArrayList (); 563 while (cols.next()) 564 { Object [] row = new Object [22]; 566 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); row[14] = cols.getObject(15); row[15] = cols.getObject(16); row[16] = cols.getObject(17); row[17] = cols.getObject(18); try 586 { 587 row[18] = cols.getObject(19); row[19] = cols.getObject(20); row[20] = cols.getObject(21); row[21] = cols.getObject(22); } 592 catch (Exception e) 593 { row[18] = null; row[19] = null; row[20] = null; row[21] = null; } 599 data.add(row); 600 } 601 Field[] fields; 602 if (vdb.useStaticResultSetMetaData()) 603 fields = getColumnsFields; 604 else 605 { ResultSetMetaData metaData = cols.getMetaData(); 607 if (metaData == null) 608 fields = getColumnsFields; 609 else 610 fields = ControllerConstants.CONTROLLER_FACTORY 611 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 612 null); 613 } 614 return new ControllerResultSet(fields, data); 615 } 616 catch (SQLException e) 617 { 618 throw e; 619 } 620 finally 621 { 622 releaseConnection(info); 623 } 624 } 625 626 631 public ControllerResultSet getCrossReference(ConnectionContext connContext, 632 String primaryCatalog, String primarySchema, String primaryTable, 633 String foreignCatalog, String foreignSchema, String foreignTable) 634 throws SQLException 635 { 636 try 637 { 638 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 639 if ((raidbLevel == RAIDbLevels.RAIDb1) 640 || (raidbLevel == RAIDbLevels.SingleDB)) 641 { return doGetCrossReference(connContext, primaryCatalog, primarySchema, 643 primaryTable, foreignCatalog, foreignSchema, foreignTable); 644 } 645 } 646 catch (NoMoreBackendException ignore) 647 { 648 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 650 String .class, String .class, String .class, String .class}; 651 Object [] args = {connContext, primaryCatalog, primarySchema, 652 primaryTable, foreignCatalog, foreignSchema, foreignTable}; 653 ControllerResultSet crs = getMetaDataFromRemoteController( 654 "doGetCrossReference", argTypes, args); 655 if (crs != null) 656 return crs; 657 } 658 659 661 ArrayList data = new ArrayList (); 662 ControllerResultSet rs = new ControllerResultSet( 663 getCrossReferenceOrImportExportedKeysFields, data); 664 return rs; 665 } 666 667 671 public ControllerResultSet doGetCrossReference(ConnectionContext connContext, 672 String primaryCatalog, String primarySchema, String primaryTable, 673 String foreignCatalog, String foreignSchema, String foreignTable) 674 throws SQLException 675 { 676 ConnectionAndDatabaseMetaData info = null; 677 try 678 { 679 info = getMetaDataFromFirstAvailableBackend(connContext); 680 DatabaseMetaData m = info.getDatabaseMetaData(); 681 ResultSet cols = m.getCrossReference(primaryCatalog, primarySchema, 682 primaryTable, foreignCatalog, foreignSchema, foreignTable); 683 ArrayList data = new ArrayList (); 684 while (cols.next()) 685 { Object [] row = new Object [14]; 687 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); data.add(row); 702 } 703 Field[] fields; 704 if (vdb.useStaticResultSetMetaData()) 705 fields = getCrossReferenceOrImportExportedKeysFields; 706 else 707 { ResultSetMetaData metaData = cols.getMetaData(); 709 if (metaData == null) 710 fields = getCrossReferenceOrImportExportedKeysFields; 711 else 712 fields = ControllerConstants.CONTROLLER_FACTORY 713 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 714 null); 715 } 716 return new ControllerResultSet(fields, data); 717 } 718 catch (SQLException e) 719 { 720 throw e; 721 } 722 finally 723 { 724 releaseConnection(info); 725 } 726 } 727 728 732 public ControllerResultSet getExportedKeys(ConnectionContext connContext, 733 String catalog, String schema, String table) throws SQLException 734 { 735 try 736 { 737 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 738 if ((raidbLevel == RAIDbLevels.RAIDb1) 739 || (raidbLevel == RAIDbLevels.SingleDB)) 740 { return doGetExportedKeys(connContext, catalog, schema, table); 742 } 743 } 744 catch (NoMoreBackendException ignore) 745 { 746 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 748 String .class}; 749 Object [] args = {connContext, catalog, schema, table}; 750 ControllerResultSet crs = getMetaDataFromRemoteController( 751 "doGetExportedKeys", argTypes, args); 752 if (crs != null) 753 return crs; 754 } 755 756 758 ArrayList data = new ArrayList (); 759 ControllerResultSet rs = new ControllerResultSet( 760 getCrossReferenceOrImportExportedKeysFields, data); 761 return rs; 762 } 763 764 767 public ControllerResultSet doGetExportedKeys(ConnectionContext connContext, 768 String catalog, String schema, String table) throws SQLException 769 { 770 ConnectionAndDatabaseMetaData info = null; 771 try 772 { 773 info = getMetaDataFromFirstAvailableBackend(connContext); 774 DatabaseMetaData m = info.getDatabaseMetaData(); 775 ResultSet cols = m.getExportedKeys(catalog, schema, table); 776 ArrayList data = new ArrayList (); 777 while (cols.next()) 778 { Object [] row = new Object [14]; 780 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); data.add(row); 795 } 796 Field[] fields; 797 if (vdb.useStaticResultSetMetaData()) 798 fields = getCrossReferenceOrImportExportedKeysFields; 799 else 800 { ResultSetMetaData metaData = cols.getMetaData(); 802 if (metaData == null) 803 fields = getCrossReferenceOrImportExportedKeysFields; 804 else 805 fields = ControllerConstants.CONTROLLER_FACTORY 806 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 807 null); 808 } 809 return new ControllerResultSet(fields, data); 810 } 811 catch (SQLException e) 812 { 813 throw e; 814 } 815 finally 816 { 817 releaseConnection(info); 818 } 819 } 820 821 825 public ControllerResultSet getImportedKeys(ConnectionContext connContext, 826 String catalog, String schema, String table) throws SQLException 827 { 828 try 829 { 830 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 831 if ((raidbLevel == RAIDbLevels.RAIDb1) 832 || (raidbLevel == RAIDbLevels.SingleDB)) 833 { return doGetImportedKeys(connContext, catalog, schema, table); 835 } 836 } 837 catch (NoMoreBackendException ignore) 838 { 839 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 841 String .class}; 842 Object [] args = {connContext, catalog, schema, table}; 843 ControllerResultSet crs = getMetaDataFromRemoteController( 844 "doGetImportedKeys", argTypes, args); 845 if (crs != null) 846 return crs; 847 } 848 849 851 ArrayList data = new ArrayList (); 852 ControllerResultSet rs = new ControllerResultSet( 853 getCrossReferenceOrImportExportedKeysFields, data); 854 return rs; 855 } 856 857 860 public ControllerResultSet doGetImportedKeys(ConnectionContext connContext, 861 String catalog, String schema, String table) throws SQLException 862 { 863 ConnectionAndDatabaseMetaData info = null; 864 try 865 { 866 info = getMetaDataFromFirstAvailableBackend(connContext); 867 DatabaseMetaData m = info.getDatabaseMetaData(); 868 ResultSet cols = m.getImportedKeys(catalog, schema, table); 869 ArrayList data = new ArrayList (); 870 while (cols.next()) 871 { Object [] row = new Object [14]; 873 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); data.add(row); 888 } 889 Field[] fields; 890 if (vdb.useStaticResultSetMetaData()) 891 fields = getCrossReferenceOrImportExportedKeysFields; 892 else 893 { ResultSetMetaData metaData = cols.getMetaData(); 895 if (metaData == null) 896 fields = getCrossReferenceOrImportExportedKeysFields; 897 else 898 fields = ControllerConstants.CONTROLLER_FACTORY 899 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 900 null); 901 } 902 return new ControllerResultSet(fields, data); 903 } 904 catch (SQLException e) 905 { 906 throw e; 907 } 908 finally 909 { 910 releaseConnection(info); 911 } 912 } 913 914 918 public ControllerResultSet getIndexInfo(ConnectionContext connContext, 919 String catalog, String schema, String table, boolean unique, 920 boolean approximate) throws SQLException 921 { 922 try 923 { 924 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 925 if ((raidbLevel == RAIDbLevels.RAIDb1) 926 || (raidbLevel == RAIDbLevels.SingleDB)) 927 { return doGetIndexInfo(connContext, catalog, schema, table, unique, 929 approximate); 930 } 931 } 932 catch (NoMoreBackendException ignore) 933 { 934 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 936 String .class, boolean.class, boolean.class}; 937 Object [] args = {connContext, catalog, schema, table, 938 Boolean.valueOf(unique), Boolean.valueOf(approximate)}; 939 ControllerResultSet crs = getMetaDataFromRemoteController( 940 "doGetIndexInfo", argTypes, args); 941 if (crs != null) 942 return crs; 943 } 944 945 ArrayList data = new ArrayList (); 947 ControllerResultSet rs = new ControllerResultSet(getIndexInfoFields, data); 948 return rs; 949 } 950 951 955 public ControllerResultSet doGetIndexInfo(ConnectionContext connContext, 956 String catalog, String schema, String table, boolean unique, 957 boolean approximate) throws SQLException 958 { 959 ConnectionAndDatabaseMetaData info = null; 960 try 961 { 962 info = getMetaDataFromFirstAvailableBackend(connContext); 963 DatabaseMetaData m = info.getDatabaseMetaData(); 964 ResultSet cols = m.getIndexInfo(catalog, schema, table, unique, 965 approximate); 966 ArrayList data = new ArrayList (); 967 while (cols.next()) 968 { Object [] row = new Object [13]; 970 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); data.add(row); 984 } 985 Field[] fields; 986 if (vdb.useStaticResultSetMetaData()) 987 fields = getIndexInfoFields; 988 else 989 { ResultSetMetaData metaData = cols.getMetaData(); 991 if (metaData == null) 992 fields = getIndexInfoFields; 993 else 994 fields = ControllerConstants.CONTROLLER_FACTORY 995 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 996 null); 997 } 998 return new ControllerResultSet(fields, data); 999 } 1000 catch (SQLException e) 1001 { 1002 throw e; 1003 } 1004 finally 1005 { 1006 releaseConnection(info); 1007 } 1008 } 1009 1010 1017 public ControllerResultSet getPrimaryKeys(ConnectionContext connContext, 1018 String catalog, String schema, String table) throws SQLException 1019 { 1020 if (logger.isDebugEnabled()) 1021 logger.debug("Getting getPrimaryKeys for " + vdbName); 1022 1023 try 1024 { 1025 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1026 if ((raidbLevel == RAIDbLevels.RAIDb1) 1027 || (raidbLevel == RAIDbLevels.SingleDB)) 1028 { return doGetPrimaryKeys(connContext, catalog, schema, table); 1030 } 1031 } 1032 catch (NoMoreBackendException ignore) 1033 { 1034 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1036 String .class}; 1037 Object [] args = {connContext, catalog, schema, table}; 1038 ControllerResultSet crs = getMetaDataFromRemoteController( 1039 "doGetPrimaryKeys", argTypes, args); 1040 if (crs != null) 1041 return crs; 1042 } 1043 1044 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 1047 if (dbs == null) 1048 throw new SQLException ("Unable to fetch the virtual database schema"); 1049 1050 if (table == null) 1051 table = "%"; 1054 Collection tables = dbs.getTables().values(); 1056 ArrayList data = new ArrayList (tables.size()); 1057 1058 for (Iterator iter = tables.iterator(); iter.hasNext();) 1059 { 1060 DatabaseTable t = (DatabaseTable) iter.next(); 1061 if (table.equals("%") || table.equals(t.getName())) 1062 { 1063 ArrayList columns = t.getColumns(); 1064 for (int j = 0; j < columns.size(); j++) 1065 { 1066 DatabaseColumn c = (DatabaseColumn) columns.get(j); 1067 if (c.isUnique()) 1068 { 1069 if (logger.isDebugEnabled()) 1070 logger.debug("Found primary key" + c.getName()); 1071 Object [] row = new Object [6]; 1072 row[0] = vdbName; row[1] = null; row[2] = t.getName(); row[3] = c.getName(); row[4] = new Integer (c.getType()); row[5] = c.getName(); data.add(row); 1079 } 1080 else 1081 { 1082 if (logger.isDebugEnabled()) 1083 logger.debug("Key " + c.getName() + " is not unique"); 1084 } 1085 } 1086 } 1087 } 1088 ControllerResultSet rs = new ControllerResultSet(getPrimaryKeysFields, data); 1089 return rs; 1090 } 1091 1092 1095 public ControllerResultSet doGetPrimaryKeys(ConnectionContext connContext, 1096 String catalog, String schema, String table) throws SQLException 1097 { 1098 ConnectionAndDatabaseMetaData info = null; 1099 try 1100 { 1101 info = getMetaDataFromFirstAvailableBackend(connContext); 1102 DatabaseMetaData m = info.getDatabaseMetaData(); 1103 ResultSet pks = m.getPrimaryKeys(catalog, schema, table); 1104 ArrayList data = new ArrayList (); 1105 while (pks.next()) 1106 { Object [] row = new Object [6]; 1108 row[0] = pks.getObject(1); row[1] = pks.getObject(2); row[2] = pks.getObject(3); row[3] = pks.getObject(4); row[4] = pks.getObject(5); row[5] = pks.getObject(6); data.add(row); 1115 } 1116 return new ControllerResultSet(getPrimaryKeysFields, data); 1117 } 1118 catch (SQLException e) 1119 { 1120 throw e; 1121 } 1122 finally 1123 { 1124 releaseConnection(info); 1125 } 1126 } 1127 1128 1131 public ControllerResultSet getProcedureColumns(ConnectionContext connContext, 1132 String catalog, String schemaPattern, String procedureNamePattern, 1133 String columnNamePattern) throws SQLException 1134 { 1135 try 1136 { 1137 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1138 if ((raidbLevel == RAIDbLevels.RAIDb1) 1139 || (raidbLevel == RAIDbLevels.SingleDB)) 1140 { return doGetProcedureColumns(connContext, catalog, schemaPattern, 1142 procedureNamePattern, columnNamePattern); 1143 } 1144 } 1145 catch (NoMoreBackendException ignore) 1146 { 1147 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1149 String .class, String .class}; 1150 Object [] args = {connContext, catalog, schemaPattern, 1151 procedureNamePattern, columnNamePattern}; 1152 ControllerResultSet crs = getMetaDataFromRemoteController( 1153 "doGetProcedureColumns", argTypes, args); 1154 if (crs != null) 1155 return crs; 1156 } 1157 1158 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 1159 if (dbs == null) 1160 throw new SQLException ("Unable to fetch the virtual database schema"); 1161 1162 if (procedureNamePattern == null) 1163 procedureNamePattern = "%"; 1164 1165 if (columnNamePattern == null) 1166 columnNamePattern = "%"; 1167 1168 Collection procedures = dbs.getProcedures().values(); 1170 ArrayList data = new ArrayList (procedures.size()); 1171 1172 for (Iterator iter = procedures.iterator(); iter.hasNext();) 1173 { 1174 DatabaseProcedure sp = (DatabaseProcedure) iter.next(); 1175 if (procedureNamePattern.equals("%") 1176 || procedureNamePattern.equals(sp.getName())) 1177 { 1178 if (logger.isDebugEnabled()) 1179 logger.debug("Found matching procedure " + sp.getName()); 1180 1181 ArrayList params = sp.getParameters(); 1182 int sizep = params.size(); 1183 DatabaseProcedureParameter param; 1184 for (int k = 0; k < sizep; k++) 1185 { 1186 param = (DatabaseProcedureParameter) params.get(k); 1187 if (columnNamePattern.equals("%") 1188 || columnNamePattern.equals(sp.getName())) 1189 { 1190 if (logger.isDebugEnabled()) 1191 logger.debug("Found matching procedure parameter" 1192 + param.getName()); 1193 1194 Object [] row = new Object [13]; 1195 row[0] = vdbName; row[1] = null; row[2] = sp.getName(); row[3] = param.getName(); row[4] = new Integer (param.getColumnType()); row[5] = new Integer (param.getDataType()); row[6] = param.getTypeName(); row[7] = new Float (param.getPrecision()); row[8] = new Integer (param.getLength()); row[9] = new Integer (param.getScale()); row[10] = new Integer (param.getRadix()); row[11] = new Integer (param.getNullable()); row[12] = param.getRemarks(); 1208 1209 data.add(row); 1210 } 1211 } 1212 } 1213 } 1214 ControllerResultSet rs = new ControllerResultSet(getProcedureColumnsFields, 1215 data); 1216 return rs; 1217 } 1218 1219 1223 public ControllerResultSet doGetProcedureColumns( 1224 ConnectionContext connContext, String catalog, String schemaPattern, 1225 String procedureNamePattern, String columnNamePattern) 1226 throws SQLException 1227 { 1228 ConnectionAndDatabaseMetaData info = null; 1229 try 1230 { 1231 info = getMetaDataFromFirstAvailableBackend(connContext); 1232 DatabaseMetaData m = info.getDatabaseMetaData(); 1233 ResultSet cols = m.getColumns(catalog, schemaPattern, 1234 procedureNamePattern, columnNamePattern); 1235 ArrayList data = new ArrayList (); 1236 while (cols.next()) 1237 { Object [] row = new Object [13]; 1239 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); data.add(row); 1253 } 1254 Field[] fields; 1255 if (vdb.useStaticResultSetMetaData()) 1256 fields = getProcedureColumnsFields; 1257 else 1258 { ResultSetMetaData metaData = cols.getMetaData(); 1260 if (metaData == null) 1261 fields = getProcedureColumnsFields; 1262 else 1263 fields = ControllerConstants.CONTROLLER_FACTORY 1264 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1265 null); 1266 } 1267 return new ControllerResultSet(fields, data); 1268 } 1269 catch (SQLException e) 1270 { 1271 throw e; 1272 } 1273 finally 1274 { 1275 releaseConnection(info); 1276 } 1277 } 1278 1279 1283 public ControllerResultSet getProcedures(ConnectionContext connContext, 1284 String catalog, String schemaPattern, String procedureNamePattern) 1285 throws SQLException 1286 { 1287 try 1288 { 1289 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1290 if ((raidbLevel == RAIDbLevels.RAIDb1) 1291 || (raidbLevel == RAIDbLevels.SingleDB)) 1292 { return doGetProcedures(connContext, catalog, schemaPattern, 1294 procedureNamePattern); 1295 } 1296 } 1297 catch (NoMoreBackendException ignore) 1298 { 1299 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1301 String .class}; 1302 Object [] args = {connContext, catalog, schemaPattern, 1303 procedureNamePattern}; 1304 ControllerResultSet crs = getMetaDataFromRemoteController( 1305 "doGetProcedures", argTypes, args); 1306 if (crs != null) 1307 return crs; 1308 } 1309 1310 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 1311 if (dbs == null) 1312 throw new SQLException ("Unable to fetch the virtual database schema"); 1313 1314 if (procedureNamePattern == null) 1315 procedureNamePattern = "%"; 1318 Collection procedures = dbs.getProcedures().values(); 1320 ArrayList data = new ArrayList (procedures.size()); 1321 1322 for (Iterator iter = procedures.iterator(); iter.hasNext();) 1323 { 1324 DatabaseProcedure sp = (DatabaseProcedure) iter.next(); 1325 if (procedureNamePattern.equals("%") 1326 || procedureNamePattern.equals(sp.getName())) 1327 { 1328 if (logger.isDebugEnabled()) 1329 logger.debug("Found procedure " + sp.getName()); 1330 Object [] row = new Object [8]; 1331 row[0] = vdbName; row[1] = null; row[2] = sp.getName(); row[3] = null; row[4] = null; row[5] = null; row[6] = sp.getRemarks(); row[7] = new Integer (sp.getProcedureType()); data.add(row); 1340 } 1341 } 1342 ControllerResultSet rs = new ControllerResultSet(getProceduresFields, data); 1343 return rs; 1344 } 1345 1346 1349 public ControllerResultSet doGetProcedures(ConnectionContext connContext, 1350 String catalog, String schemaPattern, String procedureNamePattern) 1351 throws SQLException 1352 { 1353 ConnectionAndDatabaseMetaData info = null; 1354 try 1355 { 1356 info = getMetaDataFromFirstAvailableBackend(connContext); 1357 DatabaseMetaData m = info.getDatabaseMetaData(); 1358 ResultSet cols = m.getProcedures(catalog, schemaPattern, 1359 procedureNamePattern); 1360 ArrayList data = new ArrayList (); 1361 while (cols.next()) 1362 { Object [] row = new Object [8]; 1364 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); data.add(row); 1373 } 1374 Field[] fields; 1375 if (vdb.useStaticResultSetMetaData()) 1376 fields = getProceduresFields; 1377 else 1378 { ResultSetMetaData metaData = cols.getMetaData(); 1380 if (metaData == null) 1381 fields = getProceduresFields; 1382 else 1383 fields = ControllerConstants.CONTROLLER_FACTORY 1384 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1385 null); 1386 } 1387 return new ControllerResultSet(fields, data); 1388 } 1389 catch (SQLException e) 1390 { 1391 throw e; 1392 } 1393 finally 1394 { 1395 releaseConnection(info); 1396 } 1397 } 1398 1399 1405 public ControllerResultSet getSchemas(ConnectionContext connContext) 1406 throws SQLException 1407 { 1408 try 1409 { return doGetSchemas(connContext); 1411 } 1412 catch (NoMoreBackendException ignore) 1413 { 1414 Class [] argTypes = {ConnectionContext.class}; 1416 Object [] args = {connContext}; 1417 ControllerResultSet crs = getMetaDataFromRemoteController("doGetSchemas", 1418 argTypes, args); 1419 if (crs != null) 1420 return crs; 1421 } 1422 1423 Object [] row = new Object [2]; 1424 row[0] = vdbName; row[1] = null; ArrayList data = new ArrayList (); 1427 data.add(row); 1428 return new ControllerResultSet(getSchemasFields, data); 1429 } 1430 1431 1434 public ControllerResultSet doGetSchemas(ConnectionContext connContext) 1435 throws SQLException 1436 { 1437 ConnectionAndDatabaseMetaData info = null; 1438 try 1439 { 1440 info = getMetaDataFromFirstAvailableBackend(connContext); 1441 DatabaseMetaData m = info.getDatabaseMetaData(); 1442 ResultSet cols = m.getSchemas(); 1443 ArrayList data = new ArrayList (); 1444 while (cols.next()) 1445 { Object [] row = new Object [2]; 1447 row[0] = cols.getObject(1); try 1450 { 1451 row[1] = cols.getObject(2); } 1453 catch (Exception e) 1454 { row[1] = null; } 1457 data.add(row); 1458 } 1459 Field[] fields; 1460 if (vdb.useStaticResultSetMetaData()) 1461 fields = getSchemasFields; 1462 else 1463 { ResultSetMetaData metaData = cols.getMetaData(); 1465 if (metaData == null) 1466 fields = getSchemasFields; 1467 else 1468 fields = ControllerConstants.CONTROLLER_FACTORY 1469 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1470 null); 1471 } 1472 return new ControllerResultSet(fields, data); 1473 } 1474 catch (SQLException e) 1475 { 1476 throw e; 1477 } 1478 finally 1479 { 1480 releaseConnection(info); 1481 } 1482 } 1483 1484 1488 public ControllerResultSet getSuperTables(ConnectionContext connContext, 1489 String catalog, String schemaPattern, String tableNamePattern) 1490 throws SQLException 1491 { 1492 try 1493 { 1494 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1495 if ((raidbLevel == RAIDbLevels.RAIDb1) 1496 || (raidbLevel == RAIDbLevels.SingleDB)) 1497 { return doGetSuperTables(connContext, catalog, schemaPattern, 1499 tableNamePattern); 1500 } 1501 } 1502 catch (NoMoreBackendException ignore) 1503 { 1504 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1506 String .class}; 1507 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern}; 1508 ControllerResultSet crs = getMetaDataFromRemoteController( 1509 "doGetSuperTables", argTypes, args); 1510 if (crs != null) 1511 return crs; 1512 } 1513 1514 1516 ArrayList data = new ArrayList (); 1517 ControllerResultSet rs = new ControllerResultSet(getSuperTablesFields, data); 1518 return rs; 1519 } 1520 1521 1524 public ControllerResultSet doGetSuperTables(ConnectionContext connContext, 1525 String catalog, String schemaPattern, String tableNamePattern) 1526 throws SQLException 1527 { 1528 ConnectionAndDatabaseMetaData info = null; 1529 try 1530 { 1531 info = getMetaDataFromFirstAvailableBackend(connContext); 1532 DatabaseMetaData m = info.getDatabaseMetaData(); 1533 ResultSet cols = m.getSuperTables(catalog, schemaPattern, 1534 tableNamePattern); 1535 ArrayList data = new ArrayList (); 1536 while (cols.next()) 1537 { Object [] row = new Object [4]; 1539 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); data.add(row); 1544 } 1545 Field[] fields; 1546 if (vdb.useStaticResultSetMetaData()) 1547 fields = getSuperTablesFields; 1548 else 1549 { ResultSetMetaData metaData = cols.getMetaData(); 1551 if (metaData == null) 1552 fields = getSuperTablesFields; 1553 else 1554 fields = ControllerConstants.CONTROLLER_FACTORY 1555 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1556 null); 1557 } 1558 return new ControllerResultSet(fields, data); 1559 } 1560 catch (SQLException e) 1561 { 1562 throw e; 1563 } 1564 finally 1565 { 1566 releaseConnection(info); 1567 } 1568 } 1569 1570 1574 public ControllerResultSet getSuperTypes(ConnectionContext connContext, 1575 String catalog, String schemaPattern, String tableNamePattern) 1576 throws SQLException 1577 { 1578 try 1579 { 1580 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1581 if ((raidbLevel == RAIDbLevels.RAIDb1) 1582 || (raidbLevel == RAIDbLevels.SingleDB)) 1583 { return doGetSuperTypes(connContext, catalog, schemaPattern, 1585 tableNamePattern); 1586 } 1587 } 1588 catch (NoMoreBackendException ignore) 1589 { 1590 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1592 String .class}; 1593 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern}; 1594 ControllerResultSet crs = getMetaDataFromRemoteController( 1595 "doGetSuperTypes", argTypes, args); 1596 if (crs != null) 1597 return crs; 1598 } 1599 1600 1602 ArrayList data = new ArrayList (); 1603 ControllerResultSet rs = new ControllerResultSet(getSuperTypesFields, data); 1604 return rs; 1605 } 1606 1607 1610 public ControllerResultSet doGetSuperTypes(ConnectionContext connContext, 1611 String catalog, String schemaPattern, String tableNamePattern) 1612 throws SQLException 1613 { 1614 ConnectionAndDatabaseMetaData info = null; 1615 try 1616 { 1617 info = getMetaDataFromFirstAvailableBackend(connContext); 1618 DatabaseMetaData m = info.getDatabaseMetaData(); 1619 ResultSet cols = m 1620 .getSuperTypes(catalog, schemaPattern, tableNamePattern); 1621 ArrayList data = new ArrayList (); 1622 while (cols.next()) 1623 { Object [] row = new Object [5]; 1625 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); data.add(row); 1631 } 1632 Field[] fields; 1633 if (vdb.useStaticResultSetMetaData()) 1634 fields = getSuperTypesFields; 1635 else 1636 { ResultSetMetaData metaData = cols.getMetaData(); 1638 if (metaData == null) 1639 fields = getSuperTypesFields; 1640 else 1641 fields = ControllerConstants.CONTROLLER_FACTORY 1642 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1643 null); 1644 } 1645 return new ControllerResultSet(fields, data); 1646 } 1647 catch (SQLException e) 1648 { 1649 throw e; 1650 } 1651 finally 1652 { 1653 releaseConnection(info); 1654 } 1655 } 1656 1657 1661 public ControllerResultSet getTablePrivileges(ConnectionContext connContext, 1662 String catalog, String schemaPattern, String tableNamePattern) 1663 throws SQLException 1664 { 1665 try 1666 { 1667 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1668 if ((raidbLevel == RAIDbLevels.RAIDb1) 1669 || (raidbLevel == RAIDbLevels.SingleDB)) 1670 { return doGetTablePrivileges(connContext, catalog, schemaPattern, 1672 tableNamePattern); 1673 } 1674 } 1675 catch (NoMoreBackendException ignore) 1676 { 1677 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1679 String .class}; 1680 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern}; 1681 ControllerResultSet crs = getMetaDataFromRemoteController( 1682 "doGetTablePrivileges", argTypes, args); 1683 if (crs != null) 1684 return crs; 1685 } 1686 1687 AuthenticationManager manager = requestManager.getVirtualDatabase() 1688 .getAuthenticationManager(); 1689 1690 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 1691 if (dbs == null) 1692 throw new SQLException ("Unable to fetch the virtual database schema"); 1693 1694 if (tableNamePattern == null) 1695 tableNamePattern = "%"; 1697 1698 ArrayList virtualLogins = manager.getVirtualLogins(); 1699 int vsize = virtualLogins.size(); 1700 VirtualDatabaseUser vu; 1701 1702 Collection tables = dbs.getTables().values(); 1703 ArrayList data = new ArrayList (tables.size()); 1704 for (Iterator iter = tables.iterator(); iter.hasNext();) 1705 { 1706 DatabaseTable t = (DatabaseTable) iter.next(); 1707 if (tableNamePattern.equals("%") || tableNamePattern.equals(t.getName())) 1708 { 1709 for (int j = 0; j < vsize; j++) 1710 { 1711 vu = (VirtualDatabaseUser) virtualLogins.get(0); 1712 1713 if (logger.isDebugEnabled()) 1714 logger.debug("Found privilege for user:" + vu.getLogin() 1715 + " on table:" + t.getName()); 1716 Object [] row = new Object [7]; 1717 row[0] = vdbName; row[1] = null; row[2] = t.getName(); row[3] = null; row[4] = vu.getLogin(); row[5] = "UPDATE"; row[6] = "NO"; data.add(row); 1725 } 1726 } 1727 } 1728 1729 ControllerResultSet rs = new ControllerResultSet(getTablePrivilegesFields, 1730 data); 1731 return rs; 1732 } 1733 1734 1737 public ControllerResultSet doGetTablePrivileges( 1738 ConnectionContext connContext, String catalog, String schemaPattern, 1739 String tableNamePattern) throws SQLException 1740 { 1741 ConnectionAndDatabaseMetaData info = null; 1742 try 1743 { 1744 info = getMetaDataFromFirstAvailableBackend(connContext); 1745 DatabaseMetaData m = info.getDatabaseMetaData(); 1746 ResultSet cols = m.getTablePrivileges(catalog, schemaPattern, 1747 tableNamePattern); 1748 ArrayList data = new ArrayList (); 1749 while (cols.next()) 1750 { Object [] row = new Object [7]; 1752 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); data.add(row); 1760 } 1761 Field[] fields; 1762 if (vdb.useStaticResultSetMetaData()) 1763 fields = getTablePrivilegesFields; 1764 else 1765 { ResultSetMetaData metaData = cols.getMetaData(); 1767 if (metaData == null) 1768 fields = getTablePrivilegesFields; 1769 else 1770 fields = ControllerConstants.CONTROLLER_FACTORY 1771 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1772 null); 1773 } 1774 return new ControllerResultSet(fields, data); 1775 } 1776 catch (SQLException e) 1777 { 1778 throw e; 1779 } 1780 finally 1781 { 1782 releaseConnection(info); 1783 } 1784 } 1785 1786 1790 public ControllerResultSet getTables(ConnectionContext connContext, 1791 String catalog, String schemaPattern, String tableNamePattern, 1792 String [] types) throws SQLException 1793 { 1794 try 1795 { 1796 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1797 if ((raidbLevel == RAIDbLevels.RAIDb1) 1798 || (raidbLevel == RAIDbLevels.SingleDB)) 1799 { return doGetTables(connContext, catalog, schemaPattern, 1801 tableNamePattern, types); 1802 } 1803 } 1804 catch (NoMoreBackendException ignore) 1805 { 1806 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 1808 String .class, String [].class}; 1809 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern, 1810 types}; 1811 ControllerResultSet crs = getMetaDataFromRemoteController("doGetTables", 1812 argTypes, args); 1813 if (crs != null) 1814 return crs; 1815 } 1816 1817 DatabaseSchema dbs = requestManager.getDatabaseSchema(); 1818 if (dbs == null) 1819 throw new SQLException ( 1820 "No virtual database schema can be found possibly because no backend is enabled on that controller"); 1821 1822 if (tableNamePattern == null) 1823 tableNamePattern = "%"; 1825 1826 Collection tables = dbs.getTables().values(); 1828 ArrayList data = new ArrayList (tables.size()); 1829 1830 for (Iterator iter = tables.iterator(); iter.hasNext();) 1831 { 1832 DatabaseTable t = (DatabaseTable) iter.next(); 1833 if (tableNamePattern.equals("%") 1834 || t.getName().indexOf(tableNamePattern) != -1) 1835 { 1836 if (logger.isDebugEnabled()) 1837 logger.debug("Found table " + t.getName()); 1838 Object [] row = new Object [10]; 1839 row[0] = vdbName; row[1] = null; row[2] = t.getName(); row[3] = "TABLE"; row[4] = null; row[5] = null; row[6] = null; row[7] = null; row[8] = null; row[9] = "SYSTEM"; data.add(row); 1850 } 1851 } 1852 ControllerResultSet rs = new ControllerResultSet(getTablesFields, data); 1853 return rs; 1854 } 1855 1856 1859 public ControllerResultSet doGetTables(ConnectionContext connContext, 1860 String catalog, String schemaPattern, String tableNamePattern, 1861 String [] types) throws SQLException 1862 { 1863 ConnectionAndDatabaseMetaData info = null; 1864 try 1865 { 1866 info = getMetaDataFromFirstAvailableBackend(connContext); 1867 DatabaseMetaData m = info.getDatabaseMetaData(); 1868 ResultSet cols = m.getTables(catalog, schemaPattern, tableNamePattern, 1869 types); 1870 ArrayList data = new ArrayList (); 1871 while (cols.next()) 1872 { Object [] row = new Object [10]; 1874 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); 1880 try 1882 { 1883 row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); } 1889 catch (Exception e) 1890 { row[5] = null; 1892 row[6] = null; 1893 row[7] = null; 1894 row[8] = null; 1895 row[9] = null; 1896 } 1897 data.add(row); 1898 } 1899 Field[] fields; 1900 if (vdb.useStaticResultSetMetaData()) 1901 fields = getTablesFields; 1902 else 1903 { ResultSetMetaData metaData = cols.getMetaData(); 1905 if (metaData == null) 1906 fields = getTablesFields; 1907 else 1908 fields = ControllerConstants.CONTROLLER_FACTORY 1909 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1910 null); 1911 } 1912 return new ControllerResultSet(fields, data); 1913 } 1914 catch (SQLException e) 1915 { 1916 throw e; 1917 } 1918 finally 1919 { 1920 releaseConnection(info); 1921 } 1922 } 1923 1924 1927 public ControllerResultSet getTableTypes(ConnectionContext connContext) 1928 throws SQLException 1929 { 1930 try 1931 { 1932 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 1933 if ((raidbLevel == RAIDbLevels.RAIDb1) 1934 || (raidbLevel == RAIDbLevels.SingleDB)) 1935 { return doGetTableTypes(connContext); 1937 } 1938 } 1939 catch (NoMoreBackendException ignore) 1940 { 1941 Class [] argTypes = {ConnectionContext.class}; 1943 Object [] args = {connContext}; 1944 ControllerResultSet crs = getMetaDataFromRemoteController( 1945 "doGetTableTypes", argTypes, args); 1946 if (crs != null) 1947 return crs; 1948 } 1949 1950 ArrayList list = new ArrayList (1); 1951 Object [] row = new Object [1]; 1952 row[0] = "TABLE"; list.add(row); 1954 ControllerResultSet rs = new ControllerResultSet(getTableTypesFields, list); 1955 return rs; 1956 } 1957 1958 1961 public ControllerResultSet doGetTableTypes(ConnectionContext connContext) 1962 throws SQLException 1963 { 1964 ConnectionAndDatabaseMetaData info = null; 1965 try 1966 { 1967 info = getMetaDataFromFirstAvailableBackend(connContext); 1968 DatabaseMetaData m = info.getDatabaseMetaData(); 1969 ResultSet cols = m.getTableTypes(); 1970 ArrayList data = new ArrayList (); 1971 while (cols.next()) 1972 { Object [] row = new Object [1]; 1974 row[0] = cols.getObject(1); data.add(row); 1976 } 1977 Field[] fields; 1978 if (vdb.useStaticResultSetMetaData()) 1979 fields = getTableTypesFields; 1980 else 1981 { ResultSetMetaData metaData = cols.getMetaData(); 1983 if (metaData == null) 1984 fields = getTableTypesFields; 1985 else 1986 fields = ControllerConstants.CONTROLLER_FACTORY 1987 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 1988 null); 1989 } 1990 return new ControllerResultSet(fields, data); 1991 } 1992 catch (SQLException e) 1993 { 1994 throw e; 1995 } 1996 finally 1997 { 1998 releaseConnection(info); 1999 } 2000 } 2001 2002 2005 public ControllerResultSet getTypeInfo(ConnectionContext connContext) 2006 throws SQLException 2007 { 2008 try 2009 { 2010 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 2011 if ((raidbLevel == RAIDbLevels.RAIDb1) 2012 || (raidbLevel == RAIDbLevels.SingleDB)) 2013 { return doGetTypeInfo(connContext); 2015 } 2016 } 2017 catch (NoMoreBackendException ignore) 2018 { 2019 Class [] argTypes = {ConnectionContext.class}; 2021 Object [] args = {connContext}; 2022 ControllerResultSet crs = getMetaDataFromRemoteController( 2023 "doGetTypeInfo", argTypes, args); 2024 if (crs != null) 2025 return crs; 2026 } 2027 2028 2030 ArrayList data = new ArrayList (); 2031 ControllerResultSet rs = new ControllerResultSet(getTypeInfoFields, data); 2032 return rs; 2033 } 2034 2035 2038 public ControllerResultSet doGetTypeInfo(ConnectionContext connContext) 2039 throws SQLException 2040 { 2041 ConnectionAndDatabaseMetaData info = null; 2042 try 2043 { 2044 info = getMetaDataFromFirstAvailableBackend(connContext); 2045 DatabaseMetaData m = info.getDatabaseMetaData(); 2046 ResultSet cols = m.getTypeInfo(); 2047 ArrayList data = new ArrayList (); 2048 while (cols.next()) 2049 { Object [] row = new Object [18]; 2051 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); row[8] = cols.getObject(9); row[9] = cols.getObject(10); row[10] = cols.getObject(11); row[11] = cols.getObject(12); row[12] = cols.getObject(13); row[13] = cols.getObject(14); row[14] = cols.getObject(15); row[15] = cols.getObject(16); row[16] = cols.getObject(17); row[17] = cols.getObject(18); data.add(row); 2070 } 2071 Field[] fields; 2072 if (vdb.useStaticResultSetMetaData()) 2073 fields = getTypeInfoFields; 2074 else 2075 { ResultSetMetaData metaData = cols.getMetaData(); 2077 if (metaData == null) 2078 fields = getTypeInfoFields; 2079 else 2080 fields = ControllerConstants.CONTROLLER_FACTORY 2081 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 2082 null); 2083 } 2084 return new ControllerResultSet(fields, data); 2085 } 2086 catch (SQLException e) 2087 { 2088 throw e; 2089 } 2090 finally 2091 { 2092 releaseConnection(info); 2093 } 2094 } 2095 2096 2100 public ControllerResultSet getUDTs(ConnectionContext connContext, 2101 String catalog, String schemaPattern, String tableNamePattern, int[] types) 2102 throws SQLException 2103 { 2104 try 2105 { 2106 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 2107 if ((raidbLevel == RAIDbLevels.RAIDb1) 2108 || (raidbLevel == RAIDbLevels.SingleDB)) 2109 { return doGetUDTs(connContext, catalog, schemaPattern, tableNamePattern, 2111 types); 2112 } 2113 } 2114 catch (NoMoreBackendException ignore) 2115 { 2116 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 2118 String .class, int[].class}; 2119 Object [] args = {connContext, catalog, schemaPattern, tableNamePattern, 2120 types}; 2121 ControllerResultSet crs = getMetaDataFromRemoteController("doGetUDTs", 2122 argTypes, args); 2123 if (crs != null) 2124 return crs; 2125 } 2126 2127 2129 ArrayList data = new ArrayList (); 2130 ControllerResultSet rs = new ControllerResultSet(getUDTsFields, data); 2131 return rs; 2132 } 2133 2134 2137 public ControllerResultSet doGetUDTs(ConnectionContext connContext, 2138 String catalog, String schemaPattern, String tableNamePattern, int[] types) 2139 throws SQLException 2140 { 2141 ConnectionAndDatabaseMetaData info = null; 2142 try 2143 { 2144 info = getMetaDataFromFirstAvailableBackend(connContext); 2145 DatabaseMetaData m = info.getDatabaseMetaData(); 2146 ResultSet cols = m.getUDTs(catalog, schemaPattern, tableNamePattern, 2147 types); 2148 ArrayList data = new ArrayList (); 2149 while (cols.next()) 2150 { Object [] row = new Object [7]; 2152 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); 2159 try 2161 { 2162 row[6] = cols.getObject(7); } 2164 catch (Exception e) 2165 { row[6] = null; } 2168 2169 data.add(row); 2170 } 2171 Field[] fields; 2172 if (vdb.useStaticResultSetMetaData()) 2173 fields = getUDTsFields; 2174 else 2175 { ResultSetMetaData metaData = cols.getMetaData(); 2177 if (metaData == null) 2178 fields = getUDTsFields; 2179 else 2180 fields = ControllerConstants.CONTROLLER_FACTORY 2181 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 2182 null); 2183 } 2184 return new ControllerResultSet(fields, data); 2185 } 2186 catch (SQLException e) 2187 { 2188 throw e; 2189 } 2190 finally 2191 { 2192 releaseConnection(info); 2193 } 2194 } 2195 2196 2200 public ControllerResultSet getVersionColumns(ConnectionContext connContext, 2201 String catalog, String schema, String table) throws SQLException 2202 { 2203 try 2204 { 2205 int raidbLevel = requestManager.getLoadBalancer().getRAIDbLevel(); 2206 if ((raidbLevel == RAIDbLevels.RAIDb1) 2207 || (raidbLevel == RAIDbLevels.SingleDB)) 2208 { return doGetVersionColumns(connContext, catalog, schema, table); 2210 } 2211 } 2212 catch (NoMoreBackendException ignore) 2213 { 2214 Class [] argTypes = {ConnectionContext.class, String .class, String .class, 2216 String .class}; 2217 Object [] args = {connContext, catalog, schema, table}; 2218 ControllerResultSet crs = getMetaDataFromRemoteController( 2219 "doGetVersionColumns", argTypes, args); 2220 if (crs != null) 2221 return crs; 2222 } 2223 2224 2226 ArrayList data = new ArrayList (); 2227 ControllerResultSet rs = new ControllerResultSet( 2228 getBestRowIdentifierAndVersionColumnsFields, data); 2229 return rs; 2230 } 2231 2232 2235 public ControllerResultSet doGetVersionColumns(ConnectionContext connContext, 2236 String catalog, String schema, String table) throws SQLException 2237 { 2238 ConnectionAndDatabaseMetaData info = null; 2239 try 2240 { 2241 info = getMetaDataFromFirstAvailableBackend(connContext); 2242 DatabaseMetaData m = info.getDatabaseMetaData(); 2243 ResultSet cols = m.getVersionColumns(catalog, schema, table); 2244 ArrayList data = new ArrayList (); 2245 while (cols.next()) 2246 { Object [] row = new Object [8]; 2248 row[0] = cols.getObject(1); row[1] = cols.getObject(2); row[2] = cols.getObject(3); row[3] = cols.getObject(4); row[4] = cols.getObject(5); row[5] = cols.getObject(6); row[6] = cols.getObject(7); row[7] = cols.getObject(8); data.add(row); 2257 } 2258 Field[] fields; 2259 if (vdb.useStaticResultSetMetaData()) 2260 fields = getBestRowIdentifierAndVersionColumnsFields; 2261 else 2262 { ResultSetMetaData metaData = cols.getMetaData(); 2264 if (metaData == null) 2265 fields = getBestRowIdentifierAndVersionColumnsFields; 2266 else 2267 fields = ControllerConstants.CONTROLLER_FACTORY 2268 .getResultSetMetaDataFactory().copyResultSetMetaData(metaData, 2269 null); 2270 } 2271 return new ControllerResultSet(fields, data); 2272 } 2273 catch (SQLException e) 2274 { 2275 throw e; 2276 } 2277 finally 2278 { 2279 releaseConnection(info); 2280 } 2281 } 2282 2283 2292 private ConnectionAndDatabaseMetaData getMetaDataFromFirstAvailableBackend( 2293 ConnectionContext connContext) throws NoMoreBackendException, 2294 SQLException 2295 { 2296 DatabaseBackend b = requestManager.getVirtualDatabase() 2297 .getFirstAvailableBackend(); 2298 if (b == null) 2299 throw new NoMoreBackendException( 2300 "No backend is enabled for virtual database " + vdbName); 2301 AbstractConnectionManager cm = b.getConnectionManager(connContext 2302 .getLogin()); 2303 if (cm == null) 2304 throw new SQLException ("Invalid login " + connContext.getLogin() 2305 + " on backend " + b.getName()); 2306 2307 PooledConnection c = null; 2308 try 2309 { 2310 if (connContext.isStartedTransaction()) 2311 { c = cm.retrieveConnectionForTransaction(connContext.getTransactionId()); 2313 } 2316 if (c == null) 2317 { AbstractRequest fakeRequest = new UnknownReadRequest("metadata", false, 2320 0, "\n"); 2321 fakeRequest.setIsAutoCommit(true); 2322 fakeRequest.setPersistentConnection(connContext 2323 .isPersistentConnection()); 2324 fakeRequest.setPersistentConnectionId(connContext 2325 .getPersistentConnectionId()); 2326 connContext.setStartedTransaction(false); 2330 c = cm.retrieveConnectionInAutoCommit(fakeRequest); 2331 } 2332 } 2333 catch (UnreachableBackendException e) 2334 { 2335 throw new SQLException ("Unable to get a connection for login " 2336 + connContext); 2337 } 2338 return new ConnectionAndDatabaseMetaData(c, cm, c.getConnection() 2339 .getMetaData(), connContext); 2340 } 2341 2342 2349 private void releaseConnection(ConnectionAndDatabaseMetaData info) 2350 { 2351 if (info == null) 2352 return; 2353 2354 2359 if (info.getConnectionContext().isPersistentConnection() 2360 || info.getConnectionContext().isStartedTransaction()) 2361 return; 2362 info.getConnectionManager().releaseConnectionInAutoCommit(null, 2363 info.getConnection()); 2364 } 2365 2366 private ControllerResultSet getMetaDataFromRemoteController( 2367 String methodName, Class [] argTypes, Object [] args) throws SQLException 2368 { 2369 if (!vdb.isDistributed()) 2371 return null; 2372 2373 DistributedVirtualDatabase dvdb = (DistributedVirtualDatabase) vdb; 2374 try 2375 { 2376 MulticastResponse rspList = dvdb.getMulticastRequestAdapter() 2377 .multicastMessage( 2378 dvdb.getAllMemberButUs(), 2379 new GetMetadata(methodName, argTypes, args), 2380 MulticastRequestAdapter.WAIT_ALL, 2381 dvdb.getMessageTimeouts() 2382 .getVirtualDatabaseConfigurationTimeout()); 2383 2384 Map results = rspList.getResults(); 2385 if (results.size() == 0) 2386 if (logger.isWarnEnabled()) 2387 logger 2388 .warn("No response while getting metadata from remote controller"); 2389 for (Iterator iter = results.values().iterator(); iter.hasNext();) 2390 { 2391 Object response = iter.next(); 2392 if (response instanceof ControllerException) 2393 { 2394 if (logger.isErrorEnabled()) 2395 { 2396 logger.error("Error while getting metadata from remote controller"); 2397 } 2398 } 2399 else 2400 { 2401 return (ControllerResultSet) response; 2403 } 2404 } 2405 } 2406 catch (NotConnectedException e) 2407 { 2408 if (logger.isErrorEnabled()) 2409 logger 2410 .error( 2411 "Channel unavailable while getting metadata from remote controller", 2412 e); 2413 } 2414 2415 throw new SQLException ( 2418 "Unable to fetch metadata from any backend in the cluster (probably no backend is enabled)"); 2419 } 2420 2421 2429 private class ConnectionAndDatabaseMetaData 2430 { 2431 DatabaseMetaData databaseMetaData; 2432 AbstractConnectionManager connectionManager; 2433 PooledConnection connection; 2434 ConnectionContext connContext; 2435 2436 2444 public ConnectionAndDatabaseMetaData(PooledConnection c, 2445 AbstractConnectionManager cm, DatabaseMetaData metadata, 2446 ConnectionContext connContext) 2447 { 2448 this.connection = c; 2449 this.connectionManager = cm; 2450 this.databaseMetaData = metadata; 2451 this.connContext = connContext; 2452 } 2453 2454 2459 public PooledConnection getConnection() 2460 { 2461 return connection; 2462 } 2463 2464 2469 public final ConnectionContext getConnectionContext() 2470 { 2471 return connContext; 2472 } 2473 2474 2479 public AbstractConnectionManager getConnectionManager() 2480 { 2481 return connectionManager; 2482 } 2483 2484 2489 public DatabaseMetaData getDatabaseMetaData() 2490 { 2491 return databaseMetaData; 2492 } 2493 2494 } 2495 2496 2500 private static Field[] getAttributesFields = new Field[]{ 2501 new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2502 new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2503 "String"), 2504 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2505 "String"), 2506 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2507 "Short"), 2508 new Field("ATTR_NAME", "ATTR_NAME", 10, Types.VARCHAR, "VARCHAR", 2509 "String"), 2510 new Field("ATTR_TYPE_NAME", "ATTR_TYPE_NAME", 10, Types.VARCHAR, 2511 "VARCHAR", "String"), 2512 new Field("ATTR_SIZE", "ATTR_SIZE", 10, Types.INTEGER, "INTEGER", 2513 "Integer"), 2514 new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10, Types.INTEGER, 2515 "INTEGER", "Integer"), 2516 new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10, Types.INTEGER, 2517 "INTEGER", "Integer"), 2518 new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER, "INTEGER", "Integer"), 2519 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String"), 2520 new Field("ATTR_DEF", "ATTR_DEF", 10, Types.VARCHAR, "VARCHAR", "String"), 2521 new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10, Types.INTEGER, "INTEGER", 2522 "Integer"), 2523 new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10, Types.INTEGER, 2524 "INTEGER", "Integer"), 2525 new Field("CHAR_OCTET_LENGTH", "CHAR_OCTET_LENGTH", 10, Types.INTEGER, 2526 "INTEGER", "Integer"), 2527 new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10, Types.INTEGER, 2528 "INTEGER", "Integer"), 2529 new Field("IS_NULLABLE", "IS_NULLABLE", 10, Types.VARCHAR, "VARCHAR", 2530 "String"), 2531 new Field("SCOPE_CATALOG", "SCOPE_CATALOG", 10, Types.VARCHAR, "VARCHAR", 2532 "String"), 2533 new Field("SCOPE_SCHEMA", "SCOPE_SCHEMA", 10, Types.VARCHAR, "VARCHAR", 2534 "String"), 2535 new Field("SCOPE_TABLE", "SCOPE_TABLE", 10, Types.VARCHAR, "VARCHAR", 2536 "String") }; 2537 2538 2542 private static Field[] getBestRowIdentifierAndVersionColumnsFields = new Field[]{ 2543 new Field("SCOPE", "SCOPE", 10, Types.SMALLINT, "SMALLINT", "Short"), 2544 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2545 "String"), 2546 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2547 "Short"), 2548 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2549 "String"), 2550 new Field("COLUMN_SIZE", "COLUMN_SIZE", 10, Types.INTEGER, "INTEGER", 2551 "Integer"), 2552 new Field("BUFFER_LENGTH", "BUFFER_LENGTH", 10, Types.INTEGER, "INTEGER", 2553 "Integer"), 2554 new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10, Types.SMALLINT, 2555 "SMALLINT", "Short"), 2556 new Field("PSEUDO_COLUMN", "PSEUDO_COLUMN", 10, Types.SMALLINT, 2557 "SMALLINT", "Short") }; 2558 2559 2562 private static Field[] getCatalogsFields = new Field[]{new Field( 2563 "TABLE_CAT", 2564 "TABLE_CAT", 2565 9, 2566 Types.VARCHAR, 2567 "VARCHAR", 2568 "String")}; 2569 2570 2574 private static Field[] getColumnPrivilegesFields = new Field[]{ 2575 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2576 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2577 "String"), 2578 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2579 "String"), 2580 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2581 "String"), 2582 new Field("GRANTOR", "GRANTOR", 10, Types.VARCHAR, "VARCHAR", "String"), 2583 new Field("GRANTEE", "GRANTEE", 10, Types.VARCHAR, "VARCHAR", "String"), 2584 new Field("PRIVILEGE", "PRIVILEGE", 10, Types.VARCHAR, "VARCHAR", 2585 "String"), 2586 new Field("IS_GRANTABLE", "IS_GRANTABLE", 10, Types.VARCHAR, "VARCHAR", 2587 "String"), }; 2588 2589 2593 private static Field[] getColumnsFields = new Field[]{ 2594 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2595 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2596 "String"), 2597 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2598 "String"), 2599 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2600 "String"), 2601 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2602 "Short"), 2603 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2604 "String"), 2605 new Field("COLUMN_SIZE", "COLUMN_SIZE", 10, Types.INTEGER, "INTEGER", 2606 "Integer"), 2607 new Field("BUFFER_LENGTH", "BUFFER_LENGTH", 10, Types.INTEGER, "INTEGER", 2608 "Integer"), 2609 new Field("DECIMAL_DIGITS", "DECIMAL_DIGITS", 10, Types.INTEGER, 2610 "INTEGER", "Integer"), 2611 new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10, Types.INTEGER, 2612 "INTEGER", "Integer"), 2613 new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER, "INTEGER", "Integer"), 2614 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String"), 2615 new Field("COLUMN_DEF", "COLUMN_DEF", 10, Types.VARCHAR, "VARCHAR", 2616 "String"), 2617 new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10, Types.INTEGER, "INTEGER", 2618 "Integer"), 2619 new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10, Types.INTEGER, 2620 "INTEGER", "Integer"), 2621 new Field("CHAR_OCTET_LENGTH", "CHAR_OCTET_LENGTH", 10, Types.INTEGER, 2622 "INTEGER", "Integer"), 2623 new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10, Types.INTEGER, 2624 "INTEGER", "Integer"), 2625 new Field("IS_NULLABLE", "IS_NULLABLE", 10, Types.VARCHAR, "VARCHAR", 2626 "String"), 2627 new Field("SCOPE_CATALOG", "SCOPE_CATALOG", 10, Types.VARCHAR, "VARCHAR", 2628 "String"), 2629 new Field("SCOPE_SCHEMA", "SCOPE_SCHEMA", 10, Types.VARCHAR, "VARCHAR", 2630 "String"), 2631 new Field("SCOPE_TABLE", "SCOPE_TABLE", 10, Types.VARCHAR, "VARCHAR", 2632 "String"), 2633 new Field("SOURCE_DATA_TYPE", "SOURCE_DATA_TYPE", 10, Types.SMALLINT, 2634 "SMALLINT", "Short") }; 2635 2636 2643 private static Field[] getCrossReferenceOrImportExportedKeysFields = new Field[]{ 2644 new Field("PKTABLE_CAT", "PKTABLE_CAT", 9, Types.VARCHAR, "VARCHAR", 2645 "String"), 2646 new Field("PKTABLE_SCHEM", "PKTABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2647 "String"), 2648 new Field("PKTABLE_NAME", "PKTABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2649 "String"), 2650 new Field("PKCOLUMN_NAME", "PKCOLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2651 "String"), 2652 new Field("FKTABLE_CAT", "FKTABLE_CAT", 9, Types.VARCHAR, "VARCHAR", 2653 "String"), 2654 new Field("FKTABLE_SCHEM", "FKTABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2655 "String"), 2656 new Field("FKTABLE_NAME", "FKTABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2657 "String"), 2658 new Field("FKCOLUMN_NAME", "FKCOLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2659 "String"), 2660 new Field("KEY_SEQ", "KEY_SEQ", 10, Types.SMALLINT, "SMALLINT", "Short"), 2661 new Field("UPDATE_RULE", "UPDATE_RULE", 10, Types.SMALLINT, "SMALLINT", 2662 "Short"), 2663 new Field("DELETE_RULE", "DELETE_RULE", 10, Types.SMALLINT, "SMALLINT", 2664 "Short"), 2665 new Field("FK_NAME", "FK_NAME", 10, Types.VARCHAR, "VARCHAR", "String"), 2666 new Field("PK_NAME", "PK_NAME", 10, Types.VARCHAR, "VARCHAR", "String"), 2667 new Field("DEFERRABILITY", "DEFERRABILITY", 10, Types.SMALLINT, 2668 "SMALLINT", "Short") }; 2669 2670 2674 private static Field[] getIndexInfoFields = new Field[]{ 2675 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2676 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2677 "String"), 2678 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2679 "String"), 2680 new Field("NON_UNIQUE", "NON_UNIQUE", 10, Types.INTEGER, "INTEGER", 2681 "Integer"), 2682 new Field("INDEX_QUALIFIER", "INDEX_QUALIFIER", 10, Types.VARCHAR, 2683 "VARCHAR", "String"), 2684 new Field("INDEX_NAME", "INDEX_NAME", 10, Types.VARCHAR, "VARCHAR", 2685 "String"), 2686 new Field("TYPE", "TYPE", 10, Types.SMALLINT, "SMALLINT", "Short"), 2687 new Field("ORDINAL_POSITION", "ORDINAL_POSITION", 10, Types.SMALLINT, 2688 "SMALLINT", "Short"), 2689 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2690 "String"), 2691 new Field("ASC_OR_DESC", "ASC_OR_DESC", 10, Types.VARCHAR, "VARCHAR", 2692 "String"), 2693 new Field("CARDINALITY", "CARDINALITY", 10, Types.INTEGER, "INTEGER", 2694 "Integer"), 2695 new Field("PAGES", "PAGES", 10, Types.INTEGER, "INTEGER", "Integer"), 2696 new Field("FILTER_CONDITION", "FILTER_CONDITION", 10, Types.VARCHAR, 2697 "VARCHAR", "String") }; 2698 2699 2703 private static Field[] getPrimaryKeysFields = new Field[]{ 2704 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2705 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2706 "String"), 2707 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2708 "String"), 2709 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2710 "String"), 2711 new Field("KEY_SEQ", "KEY_SEQ", 10, Types.SMALLINT, "SMALLINT", "Short"), 2712 new Field("PK_NAME", "PK_NAME", 10, Types.VARCHAR, "VARCHAR", "String")}; 2713 2717 private static Field[] getProcedureColumnsFields = new Field[]{ 2718 new Field("PROCEDURE_CAT", "PROCEDURE_CAT", 9, Types.VARCHAR, "VARCHAR", 2719 "String"), 2720 new Field("PROCEDURE_SCHEM", "PROCEDURE_SCHEM", 10, Types.VARCHAR, 2721 "VARCHAR", "String"), 2722 new Field("PROCEDURE_NAME", "PROCEDURE_NAME", 10, Types.VARCHAR, 2723 "VARCHAR", "String"), 2724 new Field("COLUMN_NAME", "COLUMN_NAME", 10, Types.VARCHAR, "VARCHAR", 2725 "String"), 2726 new Field("COLUMN_TYPE", "COLUMN_TYPE", 10, Types.SMALLINT, "SMALLINT", 2727 "Short"), 2728 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2729 "Short"), 2730 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2731 "String"), 2732 new Field("PRECISION", "PRECISION", 10, Types.FLOAT, "FLOAT", "Float"), 2733 new Field("LENGTH", "LENGTH", 10, Types.INTEGER, "INTEGER", "Integer"), 2734 new Field("SCALE", "SCALE", 10, Types.SMALLINT, "SMALLINT", "Short"), 2735 new Field("RADIX", "RADIX", 10, Types.SMALLINT, "SMALLINT", "Short"), 2736 new Field("NULLABLE", "NULLABLE", 10, Types.SMALLINT, "SMALLINT", "Short"), 2737 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String")}; 2738 2739 2743 private static Field[] getProceduresFields = new Field[]{ 2744 new Field("PROCEDURE_CAT", "PROCEDURE_CAT", 9, Types.VARCHAR, "VARCHAR", 2745 "String"), 2746 new Field("PROCEDURE_SCHEM", "PROCEDURE_SCHEM", 10, Types.VARCHAR, 2747 "VARCHAR", "String"), 2748 new Field("PROCEDURE_NAME", "PROCEDURE_NAME", 10, Types.VARCHAR, 2749 "VARCHAR", "String"), 2750 new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"), 2751 new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"), 2752 new Field("", "", 0, Types.VARCHAR, "VARCHAR", "String"), 2753 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String"), 2754 new Field("PROCEDURE_TYPE", "PROCEDURE_TYPE", 10, Types.SMALLINT, 2755 "SMALLINT", "Short") }; 2756 2757 2760 private static Field[] getSchemasFields = new Field[]{ 2761 new Field("TABLE_SCHEM", "TABLE_SCHEM", 9, Types.VARCHAR, "VARCHAR", 2762 "String"), 2763 new Field("TABLE_CATALOG", "TABLE_CATALOG", 9, Types.VARCHAR, "VARCHAR", 2764 "String") }; 2765 2766 2770 private static Field[] getSuperTablesFields = new Field[]{ 2771 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2772 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2773 "String"), 2774 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2775 "String"), 2776 new Field("SUPERTABLE_NAME", "SUPERTABLE_NAME", 10, Types.VARCHAR, 2777 "VARCHAR", "String") }; 2778 2779 2783 private static Field[] getSuperTypesFields = new Field[]{ 2784 new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2785 new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2786 "String"), 2787 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2788 "String"), 2789 new Field("SUPERTYPE_CAT", "SUPERTYPE_CAT", 10, Types.VARCHAR, "VARCHAR", 2790 "String"), 2791 new Field("SUPERTYPE_SCHEM", "SUPERTYPE_SCHEM", 10, Types.VARCHAR, 2792 "VARCHAR", "String") }; 2793 2794 2798 private static Field[] getTablePrivilegesFields = new Field[]{ 2799 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2800 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2801 "String"), 2802 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2803 "String"), 2804 new Field("GRANTOR", "GRANTOR", 10, Types.VARCHAR, "VARCHAR", "String"), 2805 new Field("GRANTEE", "GRANTEE", 10, Types.VARCHAR, "VARCHAR", "String"), 2806 new Field("PRIVILEGE", "PRIVILEGE", 10, Types.VARCHAR, "VARCHAR", 2807 "String"), 2808 new Field("IS_GRANTABLE", "IS_GRANTABLE", 10, Types.VARCHAR, "VARCHAR", 2809 "String"), }; 2810 2811 2814 private static Field[] getTablesFields = new Field[]{ 2815 new Field("TABLE_CAT", "TABLE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2816 new Field("TABLE_SCHEM", "TABLE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2817 "String"), 2818 new Field("TABLE_NAME", "TABLE_NAME", 10, Types.VARCHAR, "VARCHAR", 2819 "String"), 2820 new Field("TABLE_TYPE", "TABLE_TYPE", 10, Types.VARCHAR, "VARCHAR", 2821 "String"), 2822 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String"), 2823 new Field("TYPE_CAT", "TYPE_CAT", 10, Types.VARCHAR, "VARCHAR", "String"), 2824 new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2825 "String"), 2826 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2827 "String"), 2828 new Field("SELF_REFERENCING_COL_NAME", "SELF_REFERENCING_COL_NAME", 25, 2829 Types.VARCHAR, "VARCHAR", "String"), 2830 new Field("REF_GENERATION", "REF_GENERATION", 15, Types.VARCHAR, 2831 "VARCHAR", "String") }; 2832 2833 2836 private static Field[] getTableTypesFields = new Field[]{new Field( 2837 "TABLE_TYPE", 2838 "TABLE_TYPE", 2839 9, 2840 Types.VARCHAR, 2841 "VARCHAR", 2842 "String")}; 2843 2844 2847 private static Field[] getTypeInfoFields = new Field[]{ 2848 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2849 "String"), 2850 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2851 "Short"), 2852 new Field("PRECISION", "PRECISION", 10, Types.INTEGER, "INTEGER", 2853 "Integer"), 2854 new Field("LITERAL_PREFIX", "LITERAL_PREFIX", 10, Types.VARCHAR, 2855 "VARCHAR", "String"), 2856 new Field("LITERAL_SUFFIX", "LITERAL_SUFFIX", 10, Types.VARCHAR, 2857 "VARCHAR", "String"), 2858 new Field("CREATE_PARAMS", "CREATE_PARAMS", 10, Types.VARCHAR, "VARCHAR", 2859 "String"), 2860 new Field("NULLABLE", "NULLABLE", 10, Types.INTEGER, "INTEGER", "Integer"), 2861 new Field("CASE_SENSITIVE", "CASE_SENSITIVE", 10, Types.INTEGER, 2862 "INTEGER", "Integer"), 2863 new Field("SEARCHABLE", "SEARCHABLE", 10, Types.SMALLINT, "SMALLINT", 2864 "Short"), 2865 new Field("UNSIGNED_ATTRIBUTE", "UNSIGNED_ATTRIBUTE", 10, Types.INTEGER, 2866 "INTEGER", "Integer"), 2867 new Field("FIXED_PREC_SCALE", "FIXED_PREC_SCALE", 10, Types.INTEGER, 2868 "INTEGER", "Integer"), 2869 new Field("AUTO_INCREMENT", "AUTO_INCREMENT", 10, Types.INTEGER, 2870 "INTEGER", "Integer"), 2871 new Field("LOCAL_TYPE_NAME", "LOCAL_TYPE_NAME", 10, Types.VARCHAR, 2872 "VARCHAR", "String"), 2873 new Field("MINIMUM_SCALE", "MINIMUM_SCALE", 10, Types.SMALLINT, 2874 "SMALLINT", "Short"), 2875 new Field("MAXIMUM_SCALE", "MAXIMUM_SCALE", 10, Types.SMALLINT, 2876 "SMALLINT", "Short"), 2877 new Field("SQL_DATA_TYPE", "SQL_DATA_TYPE", 10, Types.INTEGER, "INTEGER", 2878 "Integer"), 2879 new Field("SQL_DATETIME_SUB", "SQL_DATETIME_SUB", 10, Types.INTEGER, 2880 "INTEGER", "Integer"), 2881 new Field("NUM_PREC_RADIX", "NUM_PREC_RADIX", 10, Types.INTEGER, 2882 "INTEGER", "Integer") }; 2883 2884 2888 private static Field[] getUDTsFields = new Field[]{ 2889 new Field("TYPE_CAT", "TYPE_CAT", 9, Types.VARCHAR, "VARCHAR", "String"), 2890 new Field("TYPE_SCHEM", "TYPE_SCHEM", 10, Types.VARCHAR, "VARCHAR", 2891 "String"), 2892 new Field("TYPE_NAME", "TYPE_NAME", 10, Types.VARCHAR, "VARCHAR", 2893 "String"), 2894 new Field("CLASS_NAME", "CLASS_NAME", 10, Types.VARCHAR, "VARCHAR", 2895 "String"), 2896 new Field("DATA_TYPE", "DATA_TYPE", 10, Types.SMALLINT, "SMALLINT", 2897 "Short"), 2898 new Field("REMARKS", "REMARKS", 10, Types.VARCHAR, "VARCHAR", "String"), 2899 new Field("BASE_TYPE", "BASE_TYPE", 10, Types.SMALLINT, "SMALLINT", 2900 "Short") }; 2901 2902} | Popular Tags |