@@ -447,63 +447,18 @@ private ResultSet executeMetadataQuery(
447447 }
448448 }
449449
450- private static String escapeLiteral (String value ) {
451- return value .replace ("'" , "''" );
452- }
453-
454- @ Override
455- public ResultSet getTables (String catalog , String schemaPattern , String tableNamePattern , String [] types ) throws SQLException {
456- String pattern = tableNamePattern == null || tableNamePattern .isEmpty ()
457- ? "%"
458- : escapeLiteral (tableNamePattern );
459- StringBuilder sql = new StringBuilder ();
460- sql .append ("SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, NAME AS TABLE_NAME, TYPE AS TABLE_TYPE, " )
461- .append ("NULL AS REMARKS, NULL AS TYPE_CAT, NULL AS TYPE_SCHEM, NULL AS TYPE_NAME, " )
462- .append ("NULL AS SELF_REFERENCING_COL_NAME, NULL AS REF_GENERATION FROM (" )
463- .append ("SELECT 'sqlite_schema' AS NAME, 'SYSTEM TABLE' AS TYPE" )
464- .append (" UNION ALL SELECT NAME, UPPER(TYPE) AS TYPE FROM sqlite_schema" )
465- .append (" WHERE NAME NOT LIKE 'sqlite\\ _%' ESCAPE '\\ ' AND UPPER(TYPE) IN ('TABLE', 'VIEW')" )
466- .append (" UNION ALL SELECT NAME, 'GLOBAL TEMPORARY' AS TYPE FROM sqlite_temp_master" )
467- .append (" UNION ALL SELECT NAME, 'SYSTEM TABLE' AS TYPE FROM sqlite_schema" )
468- .append (" WHERE NAME LIKE 'sqlite\\ _%' ESCAPE '\\ '" )
469- .append (") WHERE TABLE_NAME LIKE '" ).append (pattern ).append ("' ESCAPE '\\ '" );
470- if (types != null && types .length != 0 ) {
471- sql .append (" AND TABLE_TYPE IN (" );
472- for (int i = 0 ; i < types .length ; i ++) {
473- if (i > 0 ) {
474- sql .append ("," );
475- }
476- sql .append ("'" ).append (escapeLiteral (types [i ].toUpperCase ())).append ("'" );
477- }
478- sql .append (")" );
479- }
480- sql .append (" ORDER BY TABLE_TYPE, TABLE_NAME" );
481- return executeMetadataQuery (sql .toString ());
450+ @ Override public ResultSet getTables (String catalog , String schemaPattern , String tableNamePattern , String [] types ) throws SQLException {
451+ String pattern = tableNamePattern == null || tableNamePattern .isEmpty () ? "%" : tableNamePattern ;
452+ return executeMetadataQuery (MetadataSql .tables (pattern , types ));
482453 }
483454
484455 @ Override
485456 public ResultSet getColumns (String catalog , String schemaPattern , String tableNamePattern , String columnNamePattern ) throws SQLException {
486457 String tablePattern = tableNamePattern == null || tableNamePattern .isEmpty () ? "%" : tableNamePattern ;
487458 String columnPattern = columnNamePattern == null || columnNamePattern .isEmpty () ? "%" : columnNamePattern ;
488- String sql = "WITH t(TABLE_NAME, CREATE_SQL, TABLE_RANK) AS ("
489- + " SELECT 'sqlite_schema' AS TABLE_NAME, NULL AS CREATE_SQL, 1 AS TABLE_RANK"
490- + " UNION ALL SELECT NAME, SQL, 1 FROM sqlite_schema"
491- + " WHERE NAME LIKE 'sqlite\\ _%' ESCAPE '\\ '"
492- + " UNION ALL SELECT NAME, SQL, 2 FROM sqlite_schema"
493- + " WHERE NAME NOT LIKE 'sqlite\\ _%' ESCAPE '\\ ' AND UPPER(TYPE) = 'TABLE'"
494- + " UNION ALL SELECT NAME, SQL, 3 FROM sqlite_schema"
495- + " WHERE NAME NOT LIKE 'sqlite\\ _%' ESCAPE '\\ ' AND UPPER(TYPE) = 'VIEW'"
496- + " UNION ALL SELECT NAME, NULL, 0 FROM sqlite_temp_master"
497- + ") SELECT t.TABLE_NAME AS TABLE_NAME, t.CREATE_SQL AS CREATE_SQL, p.cid AS CID, "
498- + "p.name AS COLUMN_NAME, p.type AS DECLARED_TYPE, p.\" notnull\" AS NOT_NULL, "
499- + "p.dflt_value AS COLUMN_DEF, p.pk AS PK, p.hidden AS HIDDEN "
500- + "FROM t JOIN pragma_table_xinfo(t.TABLE_NAME) p "
501- + "WHERE t.TABLE_NAME LIKE '" + escapeLiteral (tablePattern ) + "' ESCAPE '\\ '"
502- + " AND p.name LIKE '" + escapeLiteral (columnPattern ) + "' ESCAPE '\\ '"
503- + " ORDER BY t.TABLE_RANK, t.TABLE_NAME, p.cid" ;
504459 // getColumns synthesizes its column labels, so the raw SQL must not drive column-origin
505460 // resolution for the result set.
506- return executeMetadataQuery (sql , null , LibsqlDatabaseMetaData ::columnsResult );
461+ return executeMetadataQuery (MetadataSql . columns ( tablePattern , columnPattern ) , null , LibsqlDatabaseMetaData ::columnsResult );
507462 }
508463
509464 private static StmtResult columnsResult (StmtResult raw ) {
@@ -668,39 +623,6 @@ private static StmtResult primaryKeysResult(StmtResult raw, String table) {
668623 return new StmtResult (PRIMARY_KEY_COLUMNS , rows , 0 , null );
669624 }
670625
671- private static String importedKeysSql (String table ) {
672- String escapedTable = escapeLiteral (table == null ? "" : table );
673- return "SELECT f.id AS FK_ID, f.seq AS KEY_SEQ, f.\" table\" AS PKTABLE_NAME, "
674- + "f.\" from\" AS FKCOLUMN_NAME, f.\" to\" AS PKCOLUMN_NAME, "
675- + "f.on_update AS UPDATE_RULE, f.on_delete AS DELETE_RULE, "
676- + "c.sql AS FK_CREATE_SQL, p.sql AS PK_CREATE_SQL, "
677- + "(SELECT pi.name FROM pragma_table_info(f.\" table\" ) pi WHERE pi.pk = 1) AS PK_FIRST_COLUMN "
678- + "FROM pragma_foreign_key_list('" + escapedTable + "') f "
679- + "LEFT JOIN sqlite_schema c ON lower(c.name) = lower('" + escapedTable + "') "
680- + "LEFT JOIN sqlite_schema p ON lower(p.name) = lower(f.\" table\" ) "
681- + "ORDER BY f.id, f.seq" ;
682- }
683-
684- private static String exportedKeysSql (String parentTable , String childTable ) {
685- String escapedParent = escapeLiteral (parentTable == null ? "" : parentTable );
686- StringBuilder sql = new StringBuilder ()
687- .append ("SELECT f.id AS FK_ID, f.seq AS KEY_SEQ, " )
688- .append ("COALESCE(p.name, f.\" table\" ) AS PKTABLE_NAME, f.\" from\" AS FKCOLUMN_NAME, " )
689- .append ("COALESCE(f.\" to\" , (SELECT pi.name FROM pragma_table_info(f.\" table\" ) pi WHERE pi.pk = 1)) AS PKCOLUMN_NAME, " )
690- .append ("f.on_update AS UPDATE_RULE, f.on_delete AS DELETE_RULE, " )
691- .append ("m.name AS FKTABLE_NAME, m.sql AS FK_CREATE_SQL, p.sql AS PK_CREATE_SQL, " )
692- .append ("(SELECT group_concat(pi.name, ',') FROM pragma_table_info(f.\" table\" ) pi WHERE pi.pk > 0) AS PK_COLUMNS " )
693- .append ("FROM sqlite_schema m JOIN pragma_foreign_key_list(m.name) f " )
694- .append ("LEFT JOIN sqlite_schema p ON lower(p.name) = lower(f.\" table\" ) " )
695- .append ("WHERE m.type = 'table' AND lower(f.\" table\" ) = lower('" )
696- .append (escapedParent )
697- .append ("')" );
698- if (childTable != null ) {
699- sql .append (" AND lower(m.name) = lower('" ).append (escapeLiteral (childTable )).append ("')" );
700- }
701- return sql .append (" ORDER BY m.name, f.id, f.seq" ).toString ();
702- }
703-
704626 private static StmtResult importedKeysResult (
705627 StmtResult raw , String catalog , String schema , String table ) {
706628 List <ForeignKeyRow > rows = new ArrayList <>();
@@ -905,24 +827,11 @@ private Row toRow() {
905827
906828 private record ColumnShape (int jdbcType , String typeName , int columnSize , int decimalDigits ) {}
907829
908- @ Override
909- public ResultSet getPrimaryKeys (String catalog , String schema , String table ) throws SQLException {
910- String escapedTable = escapeLiteral (table == null ? "" : table );
911- String sql = "SELECT p.name AS COLUMN_NAME, p.pk AS KEY_SEQ, s.sql AS CREATE_SQL "
912- + "FROM pragma_table_info('" + escapedTable + "') p "
913- + "LEFT JOIN sqlite_schema s ON lower(s.name) = lower('" + escapedTable + "') "
914- + "WHERE p.pk > 0" ;
915- return executeMetadataQuery (sql , null , raw -> primaryKeysResult (raw , table ));
830+ @ Override public ResultSet getPrimaryKeys (String catalog , String schema , String table ) throws SQLException {
831+ return executeMetadataQuery (MetadataSql .primaryKeys (table ), null , raw -> primaryKeysResult (raw , table ));
916832 }
917833
918- @ Override
919- public ResultSet getTableTypes () throws SQLException {
920- return executeMetadataQuery (
921- "SELECT 'TABLE' AS TABLE_TYPE "
922- + "UNION SELECT 'VIEW' AS TABLE_TYPE "
923- + "UNION SELECT 'SYSTEM TABLE' AS TABLE_TYPE "
924- + "UNION SELECT 'GLOBAL TEMPORARY' AS TABLE_TYPE" );
925- }
834+ @ Override public ResultSet getTableTypes () throws SQLException { return executeMetadataQuery (MetadataSql .tableTypes ()); }
926835
927836 @ Override
928837 public Connection getConnection () throws SQLException {
@@ -931,22 +840,20 @@ public Connection getConnection() throws SQLException {
931840
932841 @ Override public ResultSet getProcedures (String catalog , String schemaPattern , String procedureNamePattern ) throws SQLException { return metadataResult (PROCEDURES_RESULT ); }
933842 @ Override public ResultSet getProcedureColumns (String catalog , String schemaPattern , String procedureNamePattern , String columnNamePattern ) throws SQLException { return metadataResult (PROCEDURE_COLUMNS_RESULT ); }
934- @ Override public ResultSet getSchemas () throws SQLException { return executeMetadataQuery ("SELECT NULL AS TABLE_SCHEM, NULL AS TABLE_CATALOG WHERE 0" ); }
935- @ Override public ResultSet getCatalogs () throws SQLException { return executeMetadataQuery ("SELECT NULL AS TABLE_CAT WHERE 0" ); }
843+ @ Override public ResultSet getSchemas () throws SQLException { return executeMetadataQuery (MetadataSql . schemas () ); }
844+ @ Override public ResultSet getCatalogs () throws SQLException { return executeMetadataQuery (MetadataSql . catalogs () ); }
936845 @ Override public ResultSet getColumnPrivileges (String catalog , String schema , String table , String columnNamePattern ) throws SQLException { return metadataResult (COLUMN_PRIVILEGES_RESULT ); }
937846 @ Override public ResultSet getTablePrivileges (String catalog , String schemaPattern , String tableNamePattern ) throws SQLException { return metadataResult (TABLE_PRIVILEGES_RESULT ); }
938847 @ Override public ResultSet getBestRowIdentifier (String catalog , String schema , String table , int scope , boolean nullable ) throws SQLException { return metadataResult (BEST_ROW_IDENTIFIER_RESULT ); }
939848 @ Override public ResultSet getVersionColumns (String catalog , String schema , String table ) throws SQLException { return metadataResult (VERSION_COLUMNS_RESULT ); }
940- @ Override
941- public ResultSet getImportedKeys (String catalog , String schema , String table ) throws SQLException {
942- return executeMetadataQuery (
943- importedKeysSql (table ), null , raw -> importedKeysResult (raw , catalog , schema , table ));
849+ @ Override public ResultSet getImportedKeys (String catalog , String schema , String table ) throws SQLException {
850+ return executeMetadataQuery (MetadataSql .importedKeys (table ), null ,
851+ raw -> importedKeysResult (raw , catalog , schema , table ));
944852 }
945853
946- @ Override
947- public ResultSet getExportedKeys (String catalog , String schema , String table ) throws SQLException {
948- return executeMetadataQuery (
949- exportedKeysSql (table , null ), null , raw -> exportedKeysResult (raw , catalog , schema , catalog , schema ));
854+ @ Override public ResultSet getExportedKeys (String catalog , String schema , String table ) throws SQLException {
855+ return executeMetadataQuery (MetadataSql .exportedKeys (table , null ), null ,
856+ raw -> exportedKeysResult (raw , catalog , schema , catalog , schema ));
950857 }
951858
952859 @ Override
@@ -971,9 +878,7 @@ public ResultSet getCrossReference(
971878 if (foreignTable == null ) {
972879 return getImportedKeys (parentCatalog , parentSchema , parentTable );
973880 }
974- return executeMetadataQuery (
975- exportedKeysSql (parentTable , foreignTable ),
976- null ,
881+ return executeMetadataQuery (MetadataSql .exportedKeys (parentTable , foreignTable ), null ,
977882 raw -> exportedKeysResult (raw , parentCatalog , parentSchema , foreignCatalog , foreignSchema ));
978883 }
979884
@@ -985,20 +890,7 @@ private static boolean requestsNamespace(String name) {
985890 public ResultSet getTypeInfo () throws SQLException {
986891 return metadataResult (TYPE_INFO_RESULT );
987892 }
988- @ Override public ResultSet getIndexInfo (String catalog , String schema , String table , boolean unique , boolean approximate ) throws SQLException {
989- String escapedTable = escapeLiteral (table == null ? "" : table );
990- String sql = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, '" + escapedTable + "' AS TABLE_NAME, " +
991- "CASE il.\" unique\" WHEN 1 THEN 0 ELSE 1 END AS NON_UNIQUE, " +
992- "NULL AS INDEX_QUALIFIER, il.name AS INDEX_NAME, 3 AS TYPE, " +
993- "ii.seqno + 1 AS ORDINAL_POSITION, ii.name AS COLUMN_NAME, " +
994- "'A' AS ASC_OR_DESC, 0 AS CARDINALITY, 0 AS PAGES, NULL AS FILTER_CONDITION " +
995- "FROM pragma_index_list('" + escapedTable + "') il, pragma_index_info(il.name) ii" ;
996- if (unique ) {
997- sql += " WHERE il.\" unique\" = 1" ;
998- }
999- sql += " ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION" ;
1000- return executeMetadataQuery (sql );
1001- }
893+ @ Override public ResultSet getIndexInfo (String catalog , String schema , String table , boolean unique , boolean approximate ) throws SQLException { return executeMetadataQuery (MetadataSql .indexInfo (table , unique )); }
1002894 @ Override public boolean supportsResultSetType (int type ) throws SQLException { return type == ResultSet .TYPE_FORWARD_ONLY ; }
1003895 @ Override public boolean supportsResultSetConcurrency (int type , int concurrency ) throws SQLException { return type == ResultSet .TYPE_FORWARD_ONLY && concurrency == ResultSet .CONCUR_READ_ONLY ; }
1004896 @ Override public boolean ownUpdatesAreVisible (int type ) throws SQLException { return false ; }
0 commit comments