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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1412 public boolean othersUpdatesAreVisible(int type) throws SQLException { 1413 return false; 1414 } 1415 1416 public boolean othersDeletesAreVisible(int type) throws SQLException { 1417 return false; 1418 } 1419 1420 public boolean othersInsertsAreVisible(int type) throws SQLException { 1421 return false; 1422 } 1423 1424 public boolean updatesAreDetected(int type) throws SQLException { 1425 return false; 1426 } 1427 1428 public boolean deletesAreDetected(int type) throws SQLException { 1429 return false; 1430 } 1431 1432 public boolean insertsAreDetected(int type) throws SQLException { 1433 return false; 1434 } 1435 1436 public boolean supportsBatchUpdates() throws SQLException { 1437 return true; 1438 } 1439 1440 public ResultSet getUDTs(String catalog, String schemaPattern, 1441 String typeNamePattern, int[] types) 1442 throws SQLException { 1443 return null; 1444 } 1445 1446 public Connection getConnection() throws SQLException { 1447 return conn; 1448 } 1449 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 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 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 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 1575 public boolean supportsSavepoints() { 1576 return false; 1577 } 1578 1579 public boolean supportsNamedParameters() { 1580 return false; 1581 } 1582 1583 public boolean supportsMultipleOpenResults() { 1584 return false; 1585 } 1586 1587 public boolean supportsGetGeneratedKeys() { 1588 return false; 1589 } 1590 1591 public boolean supportsResultSetHoldability(int x) { 1592 return false; 1593 } 1594 1595 public boolean supportsStatementPooling() { 1596 return false; 1597 } 1598 1599 public boolean locatorsUpdateCopy() throws SQLException { 1600 throw new SQLException("not supported"); 1601 } 1602 1603 public ResultSet getSuperTypes(String catalog, String schemaPattern, 1604 String typeNamePattern) 1605 throws SQLException { 1606 throw new SQLException("not supported"); 1607 } 1608 1609 public ResultSet getSuperTables(String catalog, String schemaPattern, 1610 String tableNamePattern) 1611 throws SQLException { 1612 throw new SQLException("not supported"); 1613 } 1614 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 1622 public int getResultSetHoldability() throws SQLException { 1623 return ResultSet.HOLD_CURSORS_OVER_COMMIT; 1624 } 1625 1626 public int getDatabaseMajorVersion() { 1627 return SQLite.JDBCDriver.MAJORVERSION; 1628 } 1629 1630 public int getDatabaseMinorVersion() { 1631 return SQLite.Constants.drv_minor; 1632 } 1633 1634 public int getJDBCMajorVersion() { 1635 return 1; 1636 } 1637 1638 public int getJDBCMinorVersion() { 1639 return 0; 1640 } 1641 1642 public int getSQLStateType() throws SQLException { 1643 return sqlStateXOpen; 1644 } 1645 1646 public RowIdLifetime getRowIdLifetime() throws SQLException { 1647 return RowIdLifetime.ROWID_UNSUPPORTED; 1648 } 1649 1650 public ResultSet getSchemas(String cat, String schema) 1651 throws SQLException { 1652 throw new SQLException("not supported"); 1653 } 1654 1655 public boolean supportsStoredFunctionsUsingCallSyntax() 1656 throws SQLException { 1657 return false; 1658 } 1659 1660 public boolean autoCommitFailureClosesAllResultSets() 1661 throws SQLException { 1662 return false; 1663 } 1664 1665 public ResultSet getClientInfoProperties() throws SQLException { 1666 throw new SQLException("unsupported"); 1667 } 1668 1669 public ResultSet getFunctions(String cat, String schema, String func) 1670 throws SQLException { 1671 throw new SQLException("unsupported"); 1672 } 1673 1674 public ResultSet getFunctionColumns(String cat, String schema, 1675 String func, String colpat) 1676 throws SQLException { 1677 throw new SQLException("unsupported"); 1678 } 1679 1680 public <T> T unwrap(java.lang.Class<T> iface) throws SQLException { 1681 throw new SQLException("unsupported"); 1682 } 1683 1684 public boolean isWrapperFor(java.lang.Class iface) throws SQLException { 1685 return false; 1686 } 1687 1688 } 1689