1 package SQLite.JDBC2z; 2 3 import java.sql.*; 4 import java.util.Hashtable; 5 6 public class JDBCDatabaseMetaData implements DatabaseMetaData { 7 8 private JDBCConnection conn; 9 JDBCDatabaseMetaData(JDBCConnection conn)10 public JDBCDatabaseMetaData(JDBCConnection conn) { 11 this.conn = conn; 12 } 13 allProceduresAreCallable()14 public boolean allProceduresAreCallable() throws SQLException { 15 return false; 16 } 17 allTablesAreSelectable()18 public boolean allTablesAreSelectable() throws SQLException { 19 return true; 20 } 21 getURL()22 public String getURL() throws SQLException { 23 return conn.url; 24 } 25 getUserName()26 public String getUserName() throws SQLException { 27 return ""; 28 } 29 isReadOnly()30 public boolean isReadOnly() throws SQLException { 31 return false; 32 } 33 nullsAreSortedHigh()34 public boolean nullsAreSortedHigh() throws SQLException { 35 return false; 36 } 37 nullsAreSortedLow()38 public boolean nullsAreSortedLow() throws SQLException { 39 return false; 40 } 41 nullsAreSortedAtStart()42 public boolean nullsAreSortedAtStart() throws SQLException { 43 return false; 44 } 45 nullsAreSortedAtEnd()46 public boolean nullsAreSortedAtEnd() throws SQLException { 47 return false; 48 } 49 getDatabaseProductName()50 public String getDatabaseProductName() throws SQLException { 51 return "SQLite"; 52 } 53 getDatabaseProductVersion()54 public String getDatabaseProductVersion() throws SQLException { 55 return SQLite.Database.version(); 56 } 57 getDriverName()58 public String getDriverName() throws SQLException { 59 return "SQLite/JDBC"; 60 } 61 getDriverVersion()62 public String getDriverVersion() throws SQLException { 63 return "" + SQLite.JDBCDriver.MAJORVERSION + "." + 64 SQLite.Constants.drv_minor; 65 } 66 getDriverMajorVersion()67 public int getDriverMajorVersion() { 68 return SQLite.JDBCDriver.MAJORVERSION; 69 } 70 getDriverMinorVersion()71 public int getDriverMinorVersion() { 72 return SQLite.Constants.drv_minor; 73 } 74 usesLocalFiles()75 public boolean usesLocalFiles() throws SQLException { 76 return true; 77 } 78 usesLocalFilePerTable()79 public boolean usesLocalFilePerTable() throws SQLException { 80 return false; 81 } 82 supportsMixedCaseIdentifiers()83 public boolean supportsMixedCaseIdentifiers() throws SQLException { 84 return false; 85 } 86 storesUpperCaseIdentifiers()87 public boolean storesUpperCaseIdentifiers() throws SQLException { 88 return false; 89 } 90 storesLowerCaseIdentifiers()91 public boolean storesLowerCaseIdentifiers() throws SQLException { 92 return false; 93 } 94 storesMixedCaseIdentifiers()95 public boolean storesMixedCaseIdentifiers() throws SQLException { 96 return true; 97 } 98 supportsMixedCaseQuotedIdentifiers()99 public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { 100 return false; 101 } 102 storesUpperCaseQuotedIdentifiers()103 public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { 104 return false; 105 } 106 storesLowerCaseQuotedIdentifiers()107 public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { 108 return false; 109 } 110 storesMixedCaseQuotedIdentifiers()111 public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { 112 return true; 113 } 114 getIdentifierQuoteString()115 public String getIdentifierQuoteString() throws SQLException { 116 return "\""; 117 } 118 getSQLKeywords()119 public String getSQLKeywords() throws SQLException { 120 return "SELECT,UPDATE,CREATE,TABLE,VIEW,DELETE,FROM,WHERE" + 121 ",COMMIT,ROLLBACK,TRIGGER"; 122 } 123 getNumericFunctions()124 public String getNumericFunctions() throws SQLException { 125 return ""; 126 } 127 getStringFunctions()128 public String getStringFunctions() throws SQLException { 129 return ""; 130 } 131 getSystemFunctions()132 public String getSystemFunctions() throws SQLException { 133 return ""; 134 } 135 getTimeDateFunctions()136 public String getTimeDateFunctions() throws SQLException { 137 return ""; 138 } 139 getSearchStringEscape()140 public String getSearchStringEscape() throws SQLException { 141 return "\\"; 142 } 143 getExtraNameCharacters()144 public String getExtraNameCharacters() throws SQLException { 145 return ""; 146 } 147 supportsAlterTableWithAddColumn()148 public boolean supportsAlterTableWithAddColumn() throws SQLException { 149 return false; 150 } 151 supportsAlterTableWithDropColumn()152 public boolean supportsAlterTableWithDropColumn() throws SQLException { 153 return false; 154 } 155 supportsColumnAliasing()156 public boolean supportsColumnAliasing() throws SQLException { 157 return true; 158 } 159 nullPlusNonNullIsNull()160 public boolean nullPlusNonNullIsNull() throws SQLException { 161 return false; 162 } 163 supportsConvert()164 public boolean supportsConvert() throws SQLException { 165 return false; 166 } 167 supportsConvert(int fromType, int toType)168 public boolean supportsConvert(int fromType, int toType) 169 throws SQLException { 170 return false; 171 } 172 supportsTableCorrelationNames()173 public boolean supportsTableCorrelationNames() throws SQLException { 174 return true; 175 } 176 supportsDifferentTableCorrelationNames()177 public boolean supportsDifferentTableCorrelationNames() 178 throws SQLException { 179 return false; 180 } 181 supportsExpressionsInOrderBy()182 public boolean supportsExpressionsInOrderBy() throws SQLException { 183 return true; 184 } 185 supportsOrderByUnrelated()186 public boolean supportsOrderByUnrelated() throws SQLException { 187 return true; 188 } 189 supportsGroupBy()190 public boolean supportsGroupBy() throws SQLException { 191 return true; 192 } 193 supportsGroupByUnrelated()194 public boolean supportsGroupByUnrelated() throws SQLException { 195 return true; 196 } 197 supportsGroupByBeyondSelect()198 public boolean supportsGroupByBeyondSelect() throws SQLException { 199 return false; 200 } 201 supportsLikeEscapeClause()202 public boolean supportsLikeEscapeClause() throws SQLException { 203 return false; 204 } 205 supportsMultipleResultSets()206 public boolean supportsMultipleResultSets() throws SQLException { 207 return false; 208 } 209 supportsMultipleTransactions()210 public boolean supportsMultipleTransactions() throws SQLException { 211 return false; 212 } 213 supportsNonNullableColumns()214 public boolean supportsNonNullableColumns() throws SQLException { 215 return true; 216 } 217 supportsMinimumSQLGrammar()218 public boolean supportsMinimumSQLGrammar() throws SQLException { 219 return true; 220 } 221 supportsCoreSQLGrammar()222 public boolean supportsCoreSQLGrammar() throws SQLException { 223 return false; 224 } 225 supportsExtendedSQLGrammar()226 public boolean supportsExtendedSQLGrammar() throws SQLException { 227 return false; 228 } 229 supportsANSI92EntryLevelSQL()230 public boolean supportsANSI92EntryLevelSQL() throws SQLException { 231 return true; 232 } 233 supportsANSI92IntermediateSQL()234 public boolean supportsANSI92IntermediateSQL() throws SQLException { 235 return false; 236 } 237 supportsANSI92FullSQL()238 public boolean supportsANSI92FullSQL() throws SQLException { 239 return false; 240 } 241 supportsIntegrityEnhancementFacility()242 public boolean supportsIntegrityEnhancementFacility() 243 throws SQLException { 244 return false; 245 } 246 supportsOuterJoins()247 public boolean supportsOuterJoins() throws SQLException { 248 return false; 249 } 250 supportsFullOuterJoins()251 public boolean supportsFullOuterJoins() throws SQLException { 252 return false; 253 } 254 supportsLimitedOuterJoins()255 public boolean supportsLimitedOuterJoins() throws SQLException { 256 return false; 257 } 258 getSchemaTerm()259 public String getSchemaTerm() throws SQLException { 260 return ""; 261 } 262 getProcedureTerm()263 public String getProcedureTerm() throws SQLException { 264 return ""; 265 } 266 getCatalogTerm()267 public String getCatalogTerm() throws SQLException { 268 return ""; 269 } 270 isCatalogAtStart()271 public boolean isCatalogAtStart() throws SQLException { 272 return false; 273 } 274 getCatalogSeparator()275 public String getCatalogSeparator() throws SQLException { 276 return ""; 277 } 278 supportsSchemasInDataManipulation()279 public boolean supportsSchemasInDataManipulation() throws SQLException { 280 return false; 281 } 282 supportsSchemasInProcedureCalls()283 public boolean supportsSchemasInProcedureCalls() throws SQLException { 284 return false; 285 } 286 supportsSchemasInTableDefinitions()287 public boolean supportsSchemasInTableDefinitions() throws SQLException { 288 return false; 289 } 290 supportsSchemasInIndexDefinitions()291 public boolean supportsSchemasInIndexDefinitions() throws SQLException { 292 return false; 293 } 294 supportsSchemasInPrivilegeDefinitions()295 public boolean supportsSchemasInPrivilegeDefinitions() 296 throws SQLException { 297 return false; 298 } 299 supportsCatalogsInDataManipulation()300 public boolean supportsCatalogsInDataManipulation() throws SQLException { 301 return false; 302 } 303 supportsCatalogsInProcedureCalls()304 public boolean supportsCatalogsInProcedureCalls() throws SQLException { 305 return false; 306 } 307 supportsCatalogsInTableDefinitions()308 public boolean supportsCatalogsInTableDefinitions() throws SQLException { 309 return false; 310 } 311 supportsCatalogsInIndexDefinitions()312 public boolean supportsCatalogsInIndexDefinitions() throws SQLException { 313 return false; 314 } 315 supportsCatalogsInPrivilegeDefinitions()316 public boolean supportsCatalogsInPrivilegeDefinitions() 317 throws SQLException { 318 return false; 319 } 320 supportsPositionedDelete()321 public boolean supportsPositionedDelete() throws SQLException { 322 return false; 323 } 324 supportsPositionedUpdate()325 public boolean supportsPositionedUpdate() throws SQLException { 326 return false; 327 } 328 supportsSelectForUpdate()329 public boolean supportsSelectForUpdate() throws SQLException { 330 return false; 331 } 332 supportsStoredProcedures()333 public boolean supportsStoredProcedures() throws SQLException { 334 return false; 335 } 336 supportsSubqueriesInComparisons()337 public boolean supportsSubqueriesInComparisons() throws SQLException { 338 return true; 339 } 340 supportsSubqueriesInExists()341 public boolean supportsSubqueriesInExists() throws SQLException { 342 return true; 343 } 344 supportsSubqueriesInIns()345 public boolean supportsSubqueriesInIns() throws SQLException { 346 return true; 347 } 348 supportsSubqueriesInQuantifieds()349 public boolean supportsSubqueriesInQuantifieds() throws SQLException { 350 return false; 351 } 352 supportsCorrelatedSubqueries()353 public boolean supportsCorrelatedSubqueries() throws SQLException { 354 return false; 355 } 356 supportsUnion()357 public boolean supportsUnion() throws SQLException { 358 return true; 359 } 360 supportsUnionAll()361 public boolean supportsUnionAll() throws SQLException { 362 return true; 363 } 364 supportsOpenCursorsAcrossCommit()365 public boolean supportsOpenCursorsAcrossCommit() throws SQLException { 366 return false; 367 } 368 supportsOpenCursorsAcrossRollback()369 public boolean supportsOpenCursorsAcrossRollback() throws SQLException { 370 return false; 371 } 372 supportsOpenStatementsAcrossCommit()373 public boolean supportsOpenStatementsAcrossCommit() throws SQLException { 374 return false; 375 } 376 supportsOpenStatementsAcrossRollback()377 public boolean supportsOpenStatementsAcrossRollback() throws SQLException { 378 return false; 379 } 380 getMaxBinaryLiteralLength()381 public int getMaxBinaryLiteralLength() throws SQLException { 382 return 0; 383 } 384 getMaxCharLiteralLength()385 public int getMaxCharLiteralLength() throws SQLException { 386 return 0; 387 } 388 getMaxColumnNameLength()389 public int getMaxColumnNameLength() throws SQLException { 390 return 0; 391 } 392 getMaxColumnsInGroupBy()393 public int getMaxColumnsInGroupBy() throws SQLException { 394 return 0; 395 } 396 getMaxColumnsInIndex()397 public int getMaxColumnsInIndex() throws SQLException { 398 return 0; 399 } 400 getMaxColumnsInOrderBy()401 public int getMaxColumnsInOrderBy() throws SQLException { 402 return 0; 403 } 404 getMaxColumnsInSelect()405 public int getMaxColumnsInSelect() throws SQLException { 406 return 0; 407 } 408 getMaxColumnsInTable()409 public int getMaxColumnsInTable() throws SQLException { 410 return 0; 411 } 412 getMaxConnections()413 public int getMaxConnections() throws SQLException { 414 return 0; 415 } 416 getMaxCursorNameLength()417 public int getMaxCursorNameLength() throws SQLException { 418 return 8; 419 } 420 getMaxIndexLength()421 public int getMaxIndexLength() throws SQLException { 422 return 0; 423 } 424 getMaxSchemaNameLength()425 public int getMaxSchemaNameLength() throws SQLException { 426 return 0; 427 } 428 getMaxProcedureNameLength()429 public int getMaxProcedureNameLength() throws SQLException { 430 return 0; 431 } 432 getMaxCatalogNameLength()433 public int getMaxCatalogNameLength() throws SQLException { 434 return 0; 435 } 436 getMaxRowSize()437 public int getMaxRowSize() throws SQLException { 438 return 0; 439 } 440 doesMaxRowSizeIncludeBlobs()441 public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { 442 return true; 443 } 444 getMaxStatementLength()445 public int getMaxStatementLength() throws SQLException { 446 return 0; 447 } 448 getMaxStatements()449 public int getMaxStatements() throws SQLException { 450 return 0; 451 } 452 getMaxTableNameLength()453 public int getMaxTableNameLength() throws SQLException { 454 return 0; 455 } 456 getMaxTablesInSelect()457 public int getMaxTablesInSelect() throws SQLException { 458 return 0; 459 } 460 getMaxUserNameLength()461 public int getMaxUserNameLength() throws SQLException { 462 return 0; 463 } 464 getDefaultTransactionIsolation()465 public int getDefaultTransactionIsolation() throws SQLException { 466 return Connection.TRANSACTION_SERIALIZABLE; 467 } 468 supportsTransactions()469 public boolean supportsTransactions() throws SQLException { 470 return true; 471 } 472 supportsTransactionIsolationLevel(int level)473 public boolean supportsTransactionIsolationLevel(int level) 474 throws SQLException { 475 return level == Connection.TRANSACTION_SERIALIZABLE; 476 } 477 supportsDataDefinitionAndDataManipulationTransactions()478 public boolean supportsDataDefinitionAndDataManipulationTransactions() 479 throws SQLException { 480 return true; 481 } 482 supportsDataManipulationTransactionsOnly()483 public boolean supportsDataManipulationTransactionsOnly() 484 throws SQLException { 485 return false; 486 } 487 dataDefinitionCausesTransactionCommit()488 public boolean dataDefinitionCausesTransactionCommit() 489 throws SQLException { 490 return false; 491 } 492 dataDefinitionIgnoredInTransactions()493 public boolean dataDefinitionIgnoredInTransactions() throws SQLException { 494 return false; 495 } 496 getProcedures(String catalog, String schemaPattern, String procedureNamePattern)497 public ResultSet getProcedures(String catalog, String schemaPattern, 498 String procedureNamePattern) 499 throws SQLException { 500 return null; 501 } 502 getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern)503 public ResultSet getProcedureColumns(String catalog, 504 String schemaPattern, 505 String procedureNamePattern, 506 String columnNamePattern) 507 throws SQLException { 508 return null; 509 } 510 getTables(String catalog, String schemaPattern, String tableNamePattern, String types[])511 public ResultSet getTables(String catalog, String schemaPattern, 512 String tableNamePattern, String types[]) 513 throws SQLException { 514 JDBCStatement s = new JDBCStatement(conn); 515 StringBuffer sb = new StringBuffer(); 516 sb.append("SELECT '' AS 'TABLE_CAT', " + 517 "'' AS 'TABLE_SCHEM', " + 518 "tbl_name AS 'TABLE_NAME', " + 519 "upper(type) AS 'TABLE_TYPE', " + 520 "'' AS REMARKS FROM sqlite_master " + 521 "WHERE tbl_name like "); 522 if (tableNamePattern != null) { 523 sb.append(SQLite.Shell.sql_quote(tableNamePattern)); 524 } else { 525 sb.append("'%'"); 526 } 527 sb.append(" AND "); 528 if (types == null || types.length == 0) { 529 sb.append("(type = 'table' or type = 'view')"); 530 } else { 531 sb.append("("); 532 String sep = ""; 533 for (int i = 0; i < types.length; i++) { 534 sb.append(sep); 535 sb.append("type = "); 536 sb.append(SQLite.Shell.sql_quote(types[i].toLowerCase())); 537 sep = " or "; 538 } 539 sb.append(")"); 540 } 541 ResultSet rs = null; 542 try { 543 rs = s.executeQuery(sb.toString()); 544 s.close(); 545 } catch (SQLException e) { 546 throw e; 547 } finally { 548 s.close(); 549 } 550 return rs; 551 } 552 getSchemas()553 public ResultSet getSchemas() throws SQLException { 554 String cols[] = { "TABLE_SCHEM" }; 555 SQLite.TableResult tr = new SQLite.TableResult(); 556 tr.columns(cols); 557 String row[] = { "" }; 558 tr.newrow(row); 559 JDBCResultSet rs = new JDBCResultSet(tr, null); 560 return (ResultSet) rs; 561 } 562 getCatalogs()563 public ResultSet getCatalogs() throws SQLException { 564 String cols[] = { "TABLE_CAT" }; 565 SQLite.TableResult tr = new SQLite.TableResult(); 566 tr.columns(cols); 567 String row[] = { "" }; 568 tr.newrow(row); 569 JDBCResultSet rs = new JDBCResultSet(tr, null); 570 return (ResultSet) rs; 571 } 572 getTableTypes()573 public ResultSet getTableTypes() throws SQLException { 574 String cols[] = { "TABLE_TYPE" }; 575 SQLite.TableResult tr = new SQLite.TableResult(); 576 tr.columns(cols); 577 String row[] = new String[1]; 578 row[0] = "TABLE"; 579 tr.newrow(row); 580 row = new String[1]; 581 row[0] = "VIEW"; 582 tr.newrow(row); 583 JDBCResultSet rs = new JDBCResultSet(tr, null); 584 return (ResultSet) rs; 585 } 586 getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)587 public ResultSet getColumns(String catalog, String schemaPattern, 588 String tableNamePattern, 589 String columnNamePattern) 590 throws SQLException { 591 if (conn.db == null) { 592 throw new SQLException("connection closed."); 593 } 594 JDBCStatement s = new JDBCStatement(conn); 595 JDBCResultSet rs0 = null; 596 try { 597 try { 598 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 599 } catch (SQLite.Exception se) { 600 throw new SQLException("schema reload failed"); 601 } 602 rs0 = (JDBCResultSet) 603 (s.executeQuery("PRAGMA table_info(" + 604 SQLite.Shell.sql_quote(tableNamePattern) + 605 ")")); 606 s.close(); 607 } catch (SQLException e) { 608 throw e; 609 } finally { 610 s.close(); 611 } 612 if (rs0.tr.nrows < 1) { 613 throw new SQLException("no such table: " + tableNamePattern); 614 } 615 String cols[] = { 616 "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", 617 "COLUMN_NAME", "DATA_TYPE", "TYPE_NAME", 618 "COLUMN_SIZE", "BUFFER_LENGTH", "DECIMAL_DIGITS", 619 "NUM_PREC_RADIX", "NULLABLE", "REMARKS", 620 "COLUMN_DEF", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", 621 "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE" 622 }; 623 int types[] = { 624 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 625 Types.VARCHAR, Types.SMALLINT, Types.VARCHAR, 626 Types.INTEGER, Types.INTEGER, Types.INTEGER, 627 Types.INTEGER, Types.INTEGER, Types.VARCHAR, 628 Types.VARCHAR, Types.INTEGER, Types.INTEGER, 629 Types.INTEGER, Types.INTEGER, Types.VARCHAR 630 }; 631 TableResultX tr = new TableResultX(); 632 tr.columns(cols); 633 tr.sql_types(types); 634 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 635 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 636 Hashtable<String, Integer> h = new Hashtable<String, Integer>(); 637 for (int i = 0; i < rs0.tr.ncolumns; i++) { 638 h.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed 639 } 640 if (columnNamePattern != null && 641 columnNamePattern.charAt(0) == '%') { 642 columnNamePattern = null; 643 } 644 for (int i = 0; i < rs0.tr.nrows; i++) { 645 String r0[] = (String [])(rs0.tr.rows.elementAt(i)); 646 int col = ((Integer) h.get("name")).intValue(); 647 if (columnNamePattern != null) { 648 if (r0[col].compareTo(columnNamePattern) != 0) { 649 continue; 650 } 651 } 652 String row[] = new String[cols.length]; 653 row[0] = ""; 654 row[1] = ""; 655 row[2] = tableNamePattern; 656 row[3] = r0[col]; 657 col = ((Integer) h.get("type")).intValue(); 658 String typeStr = r0[col]; 659 int type = mapSqlType(typeStr); 660 row[4] = "" + type; 661 row[5] = mapTypeName(type); 662 row[6] = "" + getD(typeStr, type); 663 row[7] = "" + getM(typeStr, type); 664 row[8] = "10"; 665 row[9] = "0"; 666 row[11] = null; 667 col = ((Integer) h.get("dflt_value")).intValue(); 668 row[12] = r0[col]; 669 row[13] = "0"; 670 row[14] = "0"; 671 row[15] = "65536"; 672 col = ((Integer) h.get("cid")).intValue(); 673 row[16] = Integer.toString(Integer.parseInt(r0[col]) + 1); // android-changed 674 col = ((Integer) h.get("notnull")).intValue(); 675 row[17] = (r0[col].charAt(0) == '0') ? "YES" : "NO"; 676 row[10] = (r0[col].charAt(0) == '0') ? "" + columnNullable : 677 "" + columnNoNulls; 678 tr.newrow(row); 679 } 680 } 681 return rs; 682 } 683 getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)684 public ResultSet getColumnPrivileges(String catalog, String schema, 685 String table, 686 String columnNamePattern) 687 throws SQLException { 688 String cols[] = { 689 "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", 690 "COLUMN_NAME", "GRANTOR", "GRANTEE", 691 "PRIVILEGE", "IS_GRANTABLE" 692 }; 693 int types[] = { 694 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 695 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 696 Types.VARCHAR, Types.VARCHAR 697 }; 698 TableResultX tr = new TableResultX(); 699 tr.columns(cols); 700 tr.sql_types(types); 701 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 702 return rs; 703 } 704 getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)705 public ResultSet getTablePrivileges(String catalog, String schemaPattern, 706 String tableNamePattern) 707 throws SQLException { 708 String cols[] = { 709 "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", 710 "COLUMN_NAME", "GRANTOR", "GRANTEE", 711 "PRIVILEGE", "IS_GRANTABLE" 712 }; 713 int types[] = { 714 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 715 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 716 Types.VARCHAR, Types.VARCHAR 717 }; 718 TableResultX tr = new TableResultX(); 719 tr.columns(cols); 720 tr.sql_types(types); 721 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 722 return rs; 723 } 724 getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)725 public ResultSet getBestRowIdentifier(String catalog, String schema, 726 String table, int scope, 727 boolean nullable) 728 throws SQLException { 729 JDBCStatement s0 = new JDBCStatement(conn); 730 JDBCResultSet rs0 = null; 731 JDBCStatement s1 = new JDBCStatement(conn); 732 JDBCResultSet rs1 = null; 733 try { 734 try { 735 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 736 } catch (SQLite.Exception se) { 737 throw new SQLException("schema reload failed"); 738 } 739 rs0 = (JDBCResultSet) 740 (s0.executeQuery("PRAGMA index_list(" + 741 SQLite.Shell.sql_quote(table) + ")")); 742 rs1 = (JDBCResultSet) 743 (s1.executeQuery("PRAGMA table_info(" + 744 SQLite.Shell.sql_quote(table) + ")")); 745 } catch (SQLException e) { 746 throw e; 747 } finally { 748 s0.close(); 749 s1.close(); 750 } 751 String cols[] = { 752 "SCOPE", "COLUMN_NAME", "DATA_TYPE", 753 "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", 754 "DECIMAL_DIGITS", "PSEUDO_COLUMN" 755 }; 756 int types[] = { 757 Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, 758 Types.VARCHAR, Types.INTEGER, Types.INTEGER, 759 Types.SMALLINT, Types.SMALLINT 760 }; 761 TableResultX tr = new TableResultX(); 762 tr.columns(cols); 763 tr.sql_types(types); 764 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 765 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0 && 766 rs1 != null && rs1.tr != null && rs1.tr.nrows > 0) { 767 Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); 768 for (int i = 0; i < rs0.tr.ncolumns; i++) { 769 h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed 770 } 771 Hashtable<String, Integer> h1 = new Hashtable<String, Integer>(); 772 for (int i = 0; i < rs1.tr.ncolumns; i++) { 773 h1.put(rs1.tr.column[i], Integer.valueOf(i)); // android-changed 774 } 775 for (int i = 0; i < rs0.tr.nrows; i++) { 776 String r0[] = (String [])(rs0.tr.rows.elementAt(i)); 777 int col = ((Integer) h0.get("unique")).intValue(); 778 String uniq = r0[col]; 779 col = ((Integer) h0.get("name")).intValue(); 780 String iname = r0[col]; 781 if (uniq.charAt(0) == '0') { 782 continue; 783 } 784 JDBCStatement s2 = new JDBCStatement(conn); 785 JDBCResultSet rs2 = null; 786 try { 787 rs2 = (JDBCResultSet) 788 (s2.executeQuery("PRAGMA index_info(" + 789 SQLite.Shell.sql_quote(iname) + ")")); 790 } catch (SQLException e) { 791 } finally { 792 s2.close(); 793 } 794 if (rs2 == null || rs2.tr == null || rs2.tr.nrows <= 0) { 795 continue; 796 } 797 Hashtable<String, Integer> h2 = 798 new Hashtable<String, Integer>(); 799 for (int k = 0; k < rs2.tr.ncolumns; k++) { 800 h2.put(rs2.tr.column[k], Integer.valueOf(k)); // android-changed 801 } 802 for (int k = 0; k < rs2.tr.nrows; k++) { 803 String r2[] = (String [])(rs2.tr.rows.elementAt(k)); 804 col = ((Integer) h2.get("name")).intValue(); 805 String cname = r2[col]; 806 for (int m = 0; m < rs1.tr.nrows; m++) { 807 String r1[] = (String [])(rs1.tr.rows.elementAt(m)); 808 col = ((Integer) h1.get("name")).intValue(); 809 if (cname.compareTo(r1[col]) == 0) { 810 String row[] = new String[cols.length]; 811 row[0] = "" + scope; 812 row[1] = cname; 813 row[2] = "" + Types.VARCHAR; 814 row[3] = "VARCHAR"; 815 row[4] = "65536"; 816 row[5] = "0"; 817 row[6] = "0"; 818 row[7] = "" + bestRowNotPseudo; 819 tr.newrow(row); 820 } 821 } 822 } 823 } 824 } 825 if (tr.nrows <= 0) { 826 String row[] = new String[cols.length]; 827 row[0] = "" + scope; 828 row[1] = "_ROWID_"; 829 row[2] = "" + Types.INTEGER; 830 row[3] = "INTEGER"; 831 row[4] = "10"; 832 row[5] = "0"; 833 row[6] = "0"; 834 row[7] = "" + bestRowPseudo; 835 tr.newrow(row); 836 } 837 return rs; 838 } 839 getVersionColumns(String catalog, String schema, String table)840 public ResultSet getVersionColumns(String catalog, String schema, 841 String table) throws SQLException { 842 String cols[] = { 843 "SCOPE", "COLUMN_NAME", "DATA_TYPE", 844 "TYPE_NAME", "COLUMN_SIZE", "BUFFER_LENGTH", 845 "DECIMAL_DIGITS", "PSEUDO_COLUMN" 846 }; 847 int types[] = { 848 Types.SMALLINT, Types.VARCHAR, Types.SMALLINT, 849 Types.VARCHAR, Types.INTEGER, Types.INTEGER, 850 Types.SMALLINT, Types.SMALLINT 851 }; 852 TableResultX tr = new TableResultX(); 853 tr.columns(cols); 854 tr.sql_types(types); 855 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 856 return rs; 857 } 858 getPrimaryKeys(String catalog, String schema, String table)859 public ResultSet getPrimaryKeys(String catalog, String schema, 860 String table) throws SQLException { 861 JDBCStatement s0 = new JDBCStatement(conn); 862 JDBCResultSet rs0 = null; 863 try { 864 try { 865 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 866 } catch (SQLite.Exception se) { 867 throw new SQLException("schema reload failed"); 868 } 869 rs0 = (JDBCResultSet) 870 (s0.executeQuery("PRAGMA index_list(" + 871 SQLite.Shell.sql_quote(table) + ")")); 872 } catch (SQLException e) { 873 throw e; 874 } finally { 875 s0.close(); 876 } 877 String cols[] = { 878 "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", 879 "COLUMN_NAME", "KEY_SEQ", "PK_NAME" 880 }; 881 int types[] = { 882 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 883 Types.VARCHAR, Types.SMALLINT, Types.VARCHAR 884 }; 885 TableResultX tr = new TableResultX(); 886 tr.columns(cols); 887 tr.sql_types(types); 888 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 889 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 890 Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); 891 for (int i = 0; i < rs0.tr.ncolumns; i++) { 892 h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed 893 } 894 for (int i = 0; i < rs0.tr.nrows; i++) { 895 String r0[] = (String [])(rs0.tr.rows.elementAt(i)); 896 int col = ((Integer) h0.get("unique")).intValue(); 897 String uniq = r0[col]; 898 col = ((Integer) h0.get("name")).intValue(); 899 String iname = r0[col]; 900 if (uniq.charAt(0) == '0') { 901 continue; 902 } 903 JDBCStatement s1 = new JDBCStatement(conn); 904 JDBCResultSet rs1 = null; 905 try { 906 rs1 = (JDBCResultSet) 907 (s1.executeQuery("PRAGMA index_info(" + 908 SQLite.Shell.sql_quote(iname) + ")")); 909 } catch (SQLException e) { 910 } finally { 911 s1.close(); 912 } 913 if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { 914 continue; 915 } 916 Hashtable<String, Integer> h1 = 917 new Hashtable<String, Integer>(); 918 for (int k = 0; k < rs1.tr.ncolumns; k++) { 919 h1.put(rs1.tr.column[k], Integer.valueOf(k)); // android-changed 920 } 921 for (int k = 0; k < rs1.tr.nrows; k++) { 922 String r1[] = (String [])(rs1.tr.rows.elementAt(k)); 923 String row[] = new String[cols.length]; 924 row[0] = ""; 925 row[1] = ""; 926 row[2] = table; 927 col = ((Integer) h1.get("name")).intValue(); 928 row[3] = r1[col]; 929 col = ((Integer) h1.get("seqno")).intValue(); 930 row[4] = Integer.toString(Integer.parseInt(r1[col]) + 1); 931 row[5] = iname; 932 tr.newrow(row); 933 } 934 } 935 } 936 if (tr.nrows > 0) { 937 return rs; 938 } 939 JDBCStatement s1 = new JDBCStatement(conn); 940 try { 941 rs0 = (JDBCResultSet) 942 (s1.executeQuery("PRAGMA table_info(" + 943 SQLite.Shell.sql_quote(table) + ")")); 944 } catch (SQLException e) { 945 throw e; 946 } finally { 947 s1.close(); 948 } 949 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 950 Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); 951 for (int i = 0; i < rs0.tr.ncolumns; i++) { 952 h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed 953 } 954 for (int i = 0; i < rs0.tr.nrows; i++) { 955 String r0[] = (String [])(rs0.tr.rows.elementAt(i)); 956 int col = ((Integer) h0.get("type")).intValue(); 957 String type = r0[col]; 958 if (!type.equalsIgnoreCase("integer")) { 959 continue; 960 } 961 col = ((Integer) h0.get("pk")).intValue(); 962 String pk = r0[col]; 963 if (pk.charAt(0) == '0') { 964 continue; 965 } 966 String row[] = new String[cols.length]; 967 row[0] = ""; 968 row[1] = ""; 969 row[2] = table; 970 col = ((Integer) h0.get("name")).intValue(); 971 row[3] = r0[col]; 972 col = ((Integer) h0.get("cid")).intValue(); 973 row[4] = Integer.toString(Integer.parseInt(r0[col]) + 1); 974 row[5] = ""; 975 tr.newrow(row); 976 } 977 } 978 return rs; 979 } 980 internalImportedKeys(String table, String pktable, JDBCResultSet in, TableResultX out)981 private void internalImportedKeys(String table, String pktable, 982 JDBCResultSet in, TableResultX out) { 983 Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); 984 for (int i = 0; i < in.tr.ncolumns; i++) { 985 h0.put(in.tr.column[i], Integer.valueOf(i)); // android-changed 986 } 987 for (int i = 0; i < in.tr.nrows; i++) { 988 String r0[] = (String [])(in.tr.rows.elementAt(i)); 989 int col = ((Integer) h0.get("table")).intValue(); 990 String pktab = r0[col]; 991 if (pktable != null && !pktable.equalsIgnoreCase(pktab)) { 992 continue; 993 } 994 col = ((Integer) h0.get("from")).intValue(); 995 String fkcol = r0[col]; 996 col = ((Integer) h0.get("to")).intValue(); 997 String pkcol = r0[col]; 998 col = ((Integer) h0.get("seq")).intValue(); 999 String seq = r0[col]; 1000 String row[] = new String[out.ncolumns]; 1001 row[0] = ""; 1002 row[1] = ""; 1003 row[2] = pktab; 1004 row[3] = pkcol; 1005 row[4] = ""; 1006 row[5] = ""; 1007 row[6] = table; 1008 row[7] = fkcol == null ? pkcol : fkcol; 1009 row[8] = Integer.toString(Integer.parseInt(seq) + 1); 1010 row[9] = 1011 "" + java.sql.DatabaseMetaData.importedKeyNoAction; 1012 row[10] = 1013 "" + java.sql.DatabaseMetaData.importedKeyNoAction; 1014 row[11] = null; 1015 row[12] = null; 1016 row[13] = 1017 "" + java.sql.DatabaseMetaData.importedKeyNotDeferrable; 1018 out.newrow(row); 1019 } 1020 } 1021 getImportedKeys(String catalog, String schema, String table)1022 public ResultSet getImportedKeys(String catalog, String schema, 1023 String table) throws SQLException { 1024 JDBCStatement s0 = new JDBCStatement(conn); 1025 JDBCResultSet rs0 = null; 1026 try { 1027 try { 1028 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 1029 } catch (SQLite.Exception se) { 1030 throw new SQLException("schema reload failed"); 1031 } 1032 rs0 = (JDBCResultSet) 1033 (s0.executeQuery("PRAGMA foreign_key_list(" + 1034 SQLite.Shell.sql_quote(table) + ")")); 1035 } catch (SQLException e) { 1036 throw e; 1037 } finally { 1038 s0.close(); 1039 } 1040 String cols[] = { 1041 "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", 1042 "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", 1043 "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", 1044 "UPDATE_RULE", "DELETE_RULE", "FK_NAME", 1045 "PK_NAME", "DEFERRABILITY" 1046 }; 1047 int types[] = { 1048 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1049 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1050 Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, 1051 Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, 1052 Types.VARCHAR, Types.SMALLINT 1053 }; 1054 TableResultX tr = new TableResultX(); 1055 tr.columns(cols); 1056 tr.sql_types(types); 1057 JDBCResultSet rs = new JDBCResultSet((SQLite.TableResult) tr, null); 1058 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 1059 internalImportedKeys(table, null, rs0, tr); 1060 } 1061 return rs; 1062 } 1063 getExportedKeys(String catalog, String schema, String table)1064 public ResultSet getExportedKeys(String catalog, String schema, 1065 String table) throws SQLException { 1066 String cols[] = { 1067 "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", 1068 "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", 1069 "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", 1070 "UPDATE_RULE", "DELETE_RULE", "FK_NAME", 1071 "PK_NAME", "DEFERRABILITY" 1072 }; 1073 int types[] = { 1074 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1075 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1076 Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, 1077 Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, 1078 Types.VARCHAR, Types.SMALLINT 1079 }; 1080 TableResultX tr = new TableResultX(); 1081 tr.columns(cols); 1082 tr.sql_types(types); 1083 JDBCResultSet rs = new JDBCResultSet(tr, null); 1084 return rs; 1085 } 1086 getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable)1087 public ResultSet getCrossReference(String primaryCatalog, 1088 String primarySchema, 1089 String primaryTable, 1090 String foreignCatalog, 1091 String foreignSchema, 1092 String foreignTable) 1093 throws SQLException { 1094 JDBCResultSet rs0 = null; 1095 if (foreignTable != null && foreignTable.charAt(0) != '%') { 1096 JDBCStatement s0 = new JDBCStatement(conn); 1097 try { 1098 try { 1099 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 1100 } catch (SQLite.Exception se) { 1101 throw new SQLException("schema reload failed"); 1102 } 1103 rs0 = (JDBCResultSet) 1104 (s0.executeQuery("PRAGMA foreign_key_list(" + 1105 SQLite.Shell.sql_quote(foreignTable) + ")")); 1106 } catch (SQLException e) { 1107 throw e; 1108 } finally { 1109 s0.close(); 1110 } 1111 } 1112 String cols[] = { 1113 "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", 1114 "PKCOLUMN_NAME", "FKTABLE_CAT", "FKTABLE_SCHEM", 1115 "FKTABLE_NAME", "FKCOLUMN_NAME", "KEY_SEQ", 1116 "UPDATE_RULE", "DELETE_RULE", "FK_NAME", 1117 "PK_NAME", "DEFERRABILITY" 1118 }; 1119 int types[] = { 1120 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1121 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1122 Types.VARCHAR, Types.VARCHAR, Types.SMALLINT, 1123 Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, 1124 Types.VARCHAR, Types.SMALLINT 1125 }; 1126 TableResultX tr = new TableResultX(); 1127 tr.columns(cols); 1128 tr.sql_types(types); 1129 JDBCResultSet rs = new JDBCResultSet(tr, null); 1130 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 1131 String pktable = null; 1132 if (primaryTable != null && primaryTable.charAt(0) != '%') { 1133 pktable = primaryTable; 1134 } 1135 internalImportedKeys(foreignTable, pktable, rs0, tr); 1136 } 1137 return rs; 1138 } 1139 getTypeInfo()1140 public ResultSet getTypeInfo() throws SQLException { 1141 String cols[] = { 1142 "TYPE_NAME", "DATA_TYPE", "PRECISION", 1143 "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", 1144 "NULLABLE", "CASE_SENSITIVE", "SEARCHABLE", 1145 "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", 1146 "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", 1147 "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX" 1148 }; 1149 int types[] = { 1150 Types.VARCHAR, Types.SMALLINT, Types.INTEGER, 1151 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1152 Types.SMALLINT, Types.BIT, Types.SMALLINT, 1153 Types.BIT, Types.BIT, Types.BIT, 1154 Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, 1155 Types.INTEGER, Types.INTEGER, Types.INTEGER 1156 }; 1157 TableResultX tr = new TableResultX(); 1158 tr.columns(cols); 1159 tr.sql_types(types); 1160 JDBCResultSet rs = new JDBCResultSet(tr, null); 1161 String row1[] = { 1162 "VARCHAR", "" + Types.VARCHAR, "65536", 1163 "'", "'", null, 1164 "" + typeNullable, "1", "" + typeSearchable, 1165 "0", "0", "0", 1166 null, "0", "0", 1167 "0", "0", "0" 1168 }; 1169 tr.newrow(row1); 1170 String row2[] = { 1171 "INTEGER", "" + Types.INTEGER, "32", 1172 null, null, null, 1173 "" + typeNullable, "0", "" + typeSearchable, 1174 "0", "0", "1", 1175 null, "0", "0", 1176 "0", "0", "2" 1177 }; 1178 tr.newrow(row2); 1179 String row3[] = { 1180 "DOUBLE", "" + Types.DOUBLE, "16", 1181 null, null, null, 1182 "" + typeNullable, "0", "" + typeSearchable, 1183 "0", "0", "1", 1184 null, "0", "0", 1185 "0", "0", "10" 1186 }; 1187 tr.newrow(row3); 1188 String row4[] = { 1189 "FLOAT", "" + Types.FLOAT, "7", 1190 null, null, null, 1191 "" + typeNullable, "0", "" + typeSearchable, 1192 "0", "0", "1", 1193 null, "0", "0", 1194 "0", "0", "10" 1195 }; 1196 tr.newrow(row4); 1197 String row5[] = { 1198 "SMALLINT", "" + Types.SMALLINT, "16", 1199 null, null, null, 1200 "" + typeNullable, "0", "" + typeSearchable, 1201 "0", "0", "1", 1202 null, "0", "0", 1203 "0", "0", "2" 1204 }; 1205 tr.newrow(row5); 1206 String row6[] = { 1207 "BIT", "" + Types.BIT, "1", 1208 null, null, null, 1209 "" + typeNullable, "0", "" + typeSearchable, 1210 "0", "0", "1", 1211 null, "0", "0", 1212 "0", "0", "2" 1213 }; 1214 tr.newrow(row6); 1215 String row7[] = { 1216 "TIMESTAMP", "" + Types.TIMESTAMP, "30", 1217 null, null, null, 1218 "" + typeNullable, "0", "" + typeSearchable, 1219 "0", "0", "1", 1220 null, "0", "0", 1221 "0", "0", "0" 1222 }; 1223 tr.newrow(row7); 1224 String row8[] = { 1225 "DATE", "" + Types.DATE, "10", 1226 null, null, null, 1227 "" + typeNullable, "0", "" + typeSearchable, 1228 "0", "0", "1", 1229 null, "0", "0", 1230 "0", "0", "0" 1231 }; 1232 tr.newrow(row8); 1233 String row9[] = { 1234 "TIME", "" + Types.TIME, "8", 1235 null, null, null, 1236 "" + typeNullable, "0", "" + typeSearchable, 1237 "0", "0", "1", 1238 null, "0", "0", 1239 "0", "0", "0" 1240 }; 1241 tr.newrow(row9); 1242 String row10[] = { 1243 "BINARY", "" + Types.BINARY, "65536", 1244 null, null, null, 1245 "" + typeNullable, "0", "" + typeSearchable, 1246 "0", "0", "1", 1247 null, "0", "0", 1248 "0", "0", "0" 1249 }; 1250 tr.newrow(row10); 1251 String row11[] = { 1252 "VARBINARY", "" + Types.VARBINARY, "65536", 1253 null, null, null, 1254 "" + typeNullable, "0", "" + typeSearchable, 1255 "0", "0", "1", 1256 null, "0", "0", 1257 "0", "0", "0" 1258 }; 1259 tr.newrow(row11); 1260 String row12[] = { 1261 "REAL", "" + Types.REAL, "16", 1262 null, null, null, 1263 "" + typeNullable, "0", "" + typeSearchable, 1264 "0", "0", "1", 1265 null, "0", "0", 1266 "0", "0", "10" 1267 }; 1268 tr.newrow(row12); 1269 return rs; 1270 } 1271 getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)1272 public ResultSet getIndexInfo(String catalog, String schema, String table, 1273 boolean unique, boolean approximate) 1274 throws SQLException { 1275 JDBCStatement s0 = new JDBCStatement(conn); 1276 JDBCResultSet rs0 = null; 1277 try { 1278 try { 1279 conn.db.exec("SELECT 1 FROM sqlite_master LIMIT 1", null); 1280 } catch (SQLite.Exception se) { 1281 throw new SQLException("schema reload failed"); 1282 } 1283 rs0 = (JDBCResultSet) 1284 (s0.executeQuery("PRAGMA index_list(" + 1285 SQLite.Shell.sql_quote(table) + ")")); 1286 } catch (SQLException e) { 1287 throw e; 1288 } finally { 1289 s0.close(); 1290 } 1291 String cols[] = { 1292 "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", 1293 "NON_UNIQUE", "INDEX_QUALIFIER", "INDEX_NAME", 1294 "TYPE", "ORDINAL_POSITION", "COLUMN_NAME", 1295 "ASC_OR_DESC", "CARDINALITY", "PAGES", 1296 "FILTER_CONDITION" 1297 }; 1298 int types[] = { 1299 Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, 1300 Types.BIT, Types.VARCHAR, Types.VARCHAR, 1301 Types.SMALLINT, Types.SMALLINT, Types.VARCHAR, 1302 Types.VARCHAR, Types.INTEGER, Types.INTEGER, 1303 Types.VARCHAR 1304 }; 1305 TableResultX tr = new TableResultX(); 1306 tr.columns(cols); 1307 tr.sql_types(types); 1308 JDBCResultSet rs = new JDBCResultSet(tr, null); 1309 if (rs0 != null && rs0.tr != null && rs0.tr.nrows > 0) { 1310 Hashtable<String, Integer> h0 = new Hashtable<String, Integer>(); 1311 for (int i = 0; i < rs0.tr.ncolumns; i++) { 1312 h0.put(rs0.tr.column[i], Integer.valueOf(i)); // android-changed 1313 } 1314 for (int i = 0; i < rs0.tr.nrows; i++) { 1315 String r0[] = (String [])(rs0.tr.rows.elementAt(i)); 1316 int col = ((Integer) h0.get("unique")).intValue(); 1317 String uniq = r0[col]; 1318 col = ((Integer) h0.get("name")).intValue(); 1319 String iname = r0[col]; 1320 if (unique && uniq.charAt(0) == '0') { 1321 continue; 1322 } 1323 JDBCStatement s1 = new JDBCStatement(conn); 1324 JDBCResultSet rs1 = null; 1325 try { 1326 rs1 = (JDBCResultSet) 1327 (s1.executeQuery("PRAGMA index_info(" + 1328 SQLite.Shell.sql_quote(iname) + ")")); 1329 } catch (SQLException e) { 1330 } finally { 1331 s1.close(); 1332 } 1333 if (rs1 == null || rs1.tr == null || rs1.tr.nrows <= 0) { 1334 continue; 1335 } 1336 Hashtable<String, Integer> h1 = 1337 new Hashtable<String, Integer>(); 1338 for (int k = 0; k < rs1.tr.ncolumns; k++) { 1339 h1.put(rs1.tr.column[k], Integer.valueOf(k)); // android-changed 1340 } 1341 for (int k = 0; k < rs1.tr.nrows; k++) { 1342 String r1[] = (String [])(rs1.tr.rows.elementAt(k)); 1343 String row[] = new String[cols.length]; 1344 row[0] = ""; 1345 row[1] = ""; 1346 row[2] = table; 1347 row[3] = (uniq.charAt(0) != '0' || 1348 (iname.charAt(0) == '(' && 1349 iname.indexOf(" autoindex ") > 0)) ? "0" : "1"; 1350 row[4] = ""; 1351 row[5] = iname; 1352 row[6] = "" + tableIndexOther; 1353 col = ((Integer) h1.get("seqno")).intValue(); 1354 row[7] = Integer.toString(Integer.parseInt(r1[col]) + 1); 1355 col = ((Integer) h1.get("name")).intValue(); 1356 row[8] = r1[col]; 1357 row[9] = "A"; 1358 row[10] = "0"; 1359 row[11] = "0"; 1360 row[12] = null; 1361 tr.newrow(row); 1362 } 1363 } 1364 } 1365 return rs; 1366 } 1367 supportsResultSetType(int type)1368 public boolean supportsResultSetType(int type) throws SQLException { 1369 return type == ResultSet.TYPE_FORWARD_ONLY || 1370 type == ResultSet.TYPE_SCROLL_INSENSITIVE || 1371 type == ResultSet.TYPE_SCROLL_SENSITIVE; 1372 } 1373 supportsResultSetConcurrency(int type, int concurrency)1374 public boolean supportsResultSetConcurrency(int type, int concurrency) 1375 throws SQLException { 1376 if (type == ResultSet.TYPE_FORWARD_ONLY || 1377 type == ResultSet.TYPE_SCROLL_INSENSITIVE || 1378 type == ResultSet.TYPE_SCROLL_SENSITIVE) { 1379 return concurrency == ResultSet.CONCUR_READ_ONLY || 1380 concurrency == ResultSet.CONCUR_UPDATABLE; 1381 } 1382 return false; 1383 } 1384 ownUpdatesAreVisible(int type)1385 public boolean ownUpdatesAreVisible(int type) throws SQLException { 1386 if (type == ResultSet.TYPE_FORWARD_ONLY || 1387 type == ResultSet.TYPE_SCROLL_INSENSITIVE || 1388 type == ResultSet.TYPE_SCROLL_SENSITIVE) { 1389 return true; 1390 } 1391 return false; 1392 } 1393 ownDeletesAreVisible(int type)1394 public boolean ownDeletesAreVisible(int type) throws SQLException { 1395 if (type == ResultSet.TYPE_FORWARD_ONLY || 1396 type == ResultSet.TYPE_SCROLL_INSENSITIVE || 1397 type == ResultSet.TYPE_SCROLL_SENSITIVE) { 1398 return true; 1399 } 1400 return false; 1401 } 1402 ownInsertsAreVisible(int type)1403 public boolean ownInsertsAreVisible(int type) throws SQLException { 1404 if (type == ResultSet.TYPE_FORWARD_ONLY || 1405 type == ResultSet.TYPE_SCROLL_INSENSITIVE || 1406 type == ResultSet.TYPE_SCROLL_SENSITIVE) { 1407 return true; 1408 } 1409 return false; 1410 } 1411 othersUpdatesAreVisible(int type)1412 public boolean othersUpdatesAreVisible(int type) throws SQLException { 1413 return false; 1414 } 1415 othersDeletesAreVisible(int type)1416 public boolean othersDeletesAreVisible(int type) throws SQLException { 1417 return false; 1418 } 1419 othersInsertsAreVisible(int type)1420 public boolean othersInsertsAreVisible(int type) throws SQLException { 1421 return false; 1422 } 1423 updatesAreDetected(int type)1424 public boolean updatesAreDetected(int type) throws SQLException { 1425 return false; 1426 } 1427 deletesAreDetected(int type)1428 public boolean deletesAreDetected(int type) throws SQLException { 1429 return false; 1430 } 1431 insertsAreDetected(int type)1432 public boolean insertsAreDetected(int type) throws SQLException { 1433 return false; 1434 } 1435 supportsBatchUpdates()1436 public boolean supportsBatchUpdates() throws SQLException { 1437 return true; 1438 } 1439 getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)1440 public ResultSet getUDTs(String catalog, String schemaPattern, 1441 String typeNamePattern, int[] types) 1442 throws SQLException { 1443 return null; 1444 } 1445 getConnection()1446 public Connection getConnection() throws SQLException { 1447 return conn; 1448 } 1449 mapTypeName(int type)1450 static String mapTypeName(int type) { 1451 switch (type) { 1452 case Types.INTEGER: return "integer"; 1453 case Types.SMALLINT: return "smallint"; 1454 case Types.FLOAT: return "float"; 1455 case Types.DOUBLE: return "double"; 1456 case Types.TIMESTAMP: return "timestamp"; 1457 case Types.DATE: return "date"; 1458 case Types.TIME: return "time"; 1459 case Types.BINARY: return "binary"; 1460 case Types.VARBINARY: return "varbinary"; 1461 case Types.REAL: return "real"; 1462 } 1463 return "varchar"; 1464 } 1465 mapSqlType(String type)1466 static int mapSqlType(String type) { 1467 if (type == null) { 1468 return Types.VARCHAR; 1469 } 1470 type = type.toLowerCase(); 1471 if (type.startsWith("inter")) { 1472 return Types.VARCHAR; 1473 } 1474 if (type.startsWith("numeric") || 1475 type.startsWith("int")) { 1476 return Types.INTEGER; 1477 } 1478 if (type.startsWith("tinyint") || 1479 type.startsWith("smallint")) { 1480 return Types.SMALLINT; 1481 } 1482 if (type.startsWith("float")) { 1483 return Types.FLOAT; 1484 } 1485 if (type.startsWith("double")) { 1486 return Types.DOUBLE; 1487 } 1488 if (type.startsWith("datetime") || 1489 type.startsWith("timestamp")) { 1490 return Types.TIMESTAMP; 1491 } 1492 if (type.startsWith("date")) { 1493 return Types.DATE; 1494 } 1495 if (type.startsWith("time")) { 1496 return Types.TIME; 1497 } 1498 if (type.startsWith("blob")) { 1499 return Types.BINARY; 1500 } 1501 if (type.startsWith("binary")) { 1502 return Types.BINARY; 1503 } 1504 if (type.startsWith("varbinary")) { 1505 return Types.VARBINARY; 1506 } 1507 if (type.startsWith("real")) { 1508 return Types.REAL; 1509 } 1510 return Types.VARCHAR; 1511 } 1512 getM(String typeStr, int type)1513 static int getM(String typeStr, int type) { 1514 int m = 65536; 1515 switch (type) { 1516 case Types.INTEGER: m = 11; break; 1517 case Types.SMALLINT: m = 6; break; 1518 case Types.FLOAT: m = 25; break; 1519 case Types.REAL: 1520 case Types.DOUBLE: m = 54; break; 1521 case Types.TIMESTAMP: return 30; 1522 case Types.DATE: return 10; 1523 case Types.TIME: return 8; 1524 } 1525 typeStr = typeStr.toLowerCase(); 1526 int i1 = typeStr.indexOf('('); 1527 if (i1 > 0) { 1528 ++i1; 1529 int i2 = typeStr.indexOf(',', i1); 1530 if (i2 < 0) { 1531 i2 = typeStr.indexOf(')', i1); 1532 } 1533 if (i2 - i1 > 0) { 1534 String num = typeStr.substring(i1, i2); 1535 try { 1536 m = java.lang.Integer.parseInt(num, 10); 1537 } catch (NumberFormatException e) { 1538 } 1539 } 1540 } 1541 return m; 1542 } 1543 getD(String typeStr, int type)1544 static int getD(String typeStr, int type) { 1545 int d = 0; 1546 switch (type) { 1547 case Types.INTEGER: d = 10; break; 1548 case Types.SMALLINT: d = 5; break; 1549 case Types.FLOAT: d = 24; break; 1550 case Types.REAL: 1551 case Types.DOUBLE: d = 53; break; 1552 default: return getM(typeStr, type); 1553 } 1554 typeStr = typeStr.toLowerCase(); 1555 int i1 = typeStr.indexOf('('); 1556 if (i1 > 0) { 1557 ++i1; 1558 int i2 = typeStr.indexOf(',', i1); 1559 if (i2 < 0) { 1560 return getM(typeStr, type); 1561 } 1562 i1 = i2; 1563 i2 = typeStr.indexOf(')', i1); 1564 if (i2 - i1 > 0) { 1565 String num = typeStr.substring(i1, i2); 1566 try { 1567 d = java.lang.Integer.parseInt(num, 10); 1568 } catch (NumberFormatException e) { 1569 } 1570 } 1571 } 1572 return d; 1573 } 1574 supportsSavepoints()1575 public boolean supportsSavepoints() { 1576 return false; 1577 } 1578 supportsNamedParameters()1579 public boolean supportsNamedParameters() { 1580 return false; 1581 } 1582 supportsMultipleOpenResults()1583 public boolean supportsMultipleOpenResults() { 1584 return false; 1585 } 1586 supportsGetGeneratedKeys()1587 public boolean supportsGetGeneratedKeys() { 1588 return false; 1589 } 1590 supportsResultSetHoldability(int x)1591 public boolean supportsResultSetHoldability(int x) { 1592 return false; 1593 } 1594 supportsStatementPooling()1595 public boolean supportsStatementPooling() { 1596 return false; 1597 } 1598 locatorsUpdateCopy()1599 public boolean locatorsUpdateCopy() throws SQLException { 1600 throw new SQLException("not supported"); 1601 } 1602 getSuperTypes(String catalog, String schemaPattern, String typeNamePattern)1603 public ResultSet getSuperTypes(String catalog, String schemaPattern, 1604 String typeNamePattern) 1605 throws SQLException { 1606 throw new SQLException("not supported"); 1607 } 1608 getSuperTables(String catalog, String schemaPattern, String tableNamePattern)1609 public ResultSet getSuperTables(String catalog, String schemaPattern, 1610 String tableNamePattern) 1611 throws SQLException { 1612 throw new SQLException("not supported"); 1613 } 1614 getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern)1615 public ResultSet getAttributes(String catalog, String schemaPattern, 1616 String typeNamePattern, 1617 String attributeNamePattern) 1618 throws SQLException { 1619 throw new SQLException("not supported"); 1620 } 1621 getResultSetHoldability()1622 public int getResultSetHoldability() throws SQLException { 1623 return ResultSet.HOLD_CURSORS_OVER_COMMIT; 1624 } 1625 getDatabaseMajorVersion()1626 public int getDatabaseMajorVersion() { 1627 return SQLite.JDBCDriver.MAJORVERSION; 1628 } 1629 getDatabaseMinorVersion()1630 public int getDatabaseMinorVersion() { 1631 return SQLite.Constants.drv_minor; 1632 } 1633 getJDBCMajorVersion()1634 public int getJDBCMajorVersion() { 1635 return 1; 1636 } 1637 getJDBCMinorVersion()1638 public int getJDBCMinorVersion() { 1639 return 0; 1640 } 1641 getSQLStateType()1642 public int getSQLStateType() throws SQLException { 1643 return sqlStateXOpen; 1644 } 1645 getRowIdLifetime()1646 public RowIdLifetime getRowIdLifetime() throws SQLException { 1647 return RowIdLifetime.ROWID_UNSUPPORTED; 1648 } 1649 getSchemas(String cat, String schema)1650 public ResultSet getSchemas(String cat, String schema) 1651 throws SQLException { 1652 throw new SQLException("not supported"); 1653 } 1654 supportsStoredFunctionsUsingCallSyntax()1655 public boolean supportsStoredFunctionsUsingCallSyntax() 1656 throws SQLException { 1657 return false; 1658 } 1659 autoCommitFailureClosesAllResultSets()1660 public boolean autoCommitFailureClosesAllResultSets() 1661 throws SQLException { 1662 return false; 1663 } 1664 getClientInfoProperties()1665 public ResultSet getClientInfoProperties() throws SQLException { 1666 throw new SQLException("unsupported"); 1667 } 1668 getFunctions(String cat, String schema, String func)1669 public ResultSet getFunctions(String cat, String schema, String func) 1670 throws SQLException { 1671 throw new SQLException("unsupported"); 1672 } 1673 getFunctionColumns(String cat, String schema, String func, String colpat)1674 public ResultSet getFunctionColumns(String cat, String schema, 1675 String func, String colpat) 1676 throws SQLException { 1677 throw new SQLException("unsupported"); 1678 } 1679 unwrap(java.lang.Class<T> iface)1680 public <T> T unwrap(java.lang.Class<T> iface) throws SQLException { 1681 throw new SQLException("unsupported"); 1682 } 1683 isWrapperFor(java.lang.Class iface)1684 public boolean isWrapperFor(java.lang.Class iface) throws SQLException { 1685 return false; 1686 } 1687 1688 } 1689