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