comparison src/main/java/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java @ 303:a91168efdf27

Small code and doc improvements. Moved helper functions to the bottom.
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Thu, 15 Aug 2019 20:17:56 +0200 (2019-08-15)
parents 1b6c514106ce
children cf372fae2adb
comparison
equal deleted inserted replaced
302:1b6c514106ce 303:a91168efdf27
72 MonetConnection.closeResultsetStatement(rs, st); 72 MonetConnection.closeResultsetStatement(rs, st);
73 } 73 }
74 // for debug: System.out.println("Read: env_current_user: " + env_current_user + " env_monet_version: " + env_monet_version + " env_max_clients: " + env_max_clients); 74 // for debug: System.out.println("Read: env_current_user: " + env_current_user + " env_monet_version: " + env_monet_version + " env_max_clients: " + env_max_clients);
75 } 75 }
76 76
77
78 /** 77 /**
79 * Internal utility method to create a Statement object, execute a query and return the ResulSet object which allows scrolling. 78 * Internal utility method to create a Statement object, execute a query and return the ResulSet object which allows scrolling.
80 * As the Statement object is created internally (the caller does not see it and thus can not close it), 79 * As the Statement object is created internally (the caller does not see it and thus can not close it),
81 * we set it to close (and free server resources) when the ResultSet object is closed by the caller. 80 * we set it to close (and free server resources) when the ResultSet object is closed by the caller.
82 */ 81 */
223 */ 222 */
224 @Override 223 @Override
225 public String getDatabaseProductVersion() throws SQLException { 224 public String getDatabaseProductVersion() throws SQLException {
226 if (env_monet_version == null) 225 if (env_monet_version == null)
227 getEnvValues(); 226 getEnvValues();
227 if (env_monet_version != null)
228 return env_monet_version;
228 // always return a valid String to prevent NPE in getTables() and getTableTypes() 229 // always return a valid String to prevent NPE in getTables() and getTableTypes()
229 return (env_monet_version != null) ? env_monet_version : ""; 230 return "";
230 } 231 }
231 232
232 /** 233 /**
233 * What is the name of this JDBC driver? 234 * What is the name of this JDBC driver?
234 * 235 *
1875 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\""); 1876 query.append(" ORDER BY \"PROCEDURE_SCHEM\", \"PROCEDURE_NAME\", \"SPECIFIC_NAME\", \"ORDINAL_POSITION\"");
1876 1877
1877 return executeMetaDataQuery(query.toString()); 1878 return executeMetaDataQuery(query.toString());
1878 } 1879 }
1879 1880
1880
1881 //== this is a helper method which does not belong to the interface
1882
1883 /**
1884 * Returns a SQL match part string where depending on the input value we
1885 * compose an exact match (use =) or match with wildcards (use LIKE) or IS NULL
1886 *
1887 * @param in the string to match
1888 * @return the SQL match part string
1889 */
1890 private static final String composeMatchPart(final String in) {
1891 if (in == null)
1892 return "IS NULL";
1893
1894 String sql = "= '";
1895 // check if SQL wildcards are used in the input, if so use LIKE
1896 if (in.contains("%") || in.contains("_"))
1897 sql = "LIKE '";
1898
1899 // all slashes and single quotes in input are escaped with a slash.
1900 final String escaped = in.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'");
1901
1902 return sql + escaped + "'";
1903 }
1904
1905 /**
1906 * Returns the given string between two double quotes for usage as
1907 * exact column or table name in SQL queries.
1908 *
1909 * @param in the string to quote
1910 * @return the quoted string
1911 */
1912 // @SuppressWarnings("unused")
1913 // private static final String dq(String in) {
1914 // return "\"" + in.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"") + "\"";
1915 // }
1916
1917 //== end helper methods
1918
1919
1920 /** 1881 /**
1921 * Retrieves a description of the tables available in the given catalog. 1882 * Retrieves a description of the tables available in the given catalog.
1922 * Only table descriptions matching the catalog, schema, table name and type criteria are returned. 1883 * Only table descriptions matching the catalog, schema, table name and type criteria are returned.
1923 * They are ordered by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME. 1884 * They are ordered by TABLE_TYPE, TABLE_CAT, TABLE_SCHEM and TABLE_NAME.
1924 * 1885 *
2102 // Return a resultset with no rows 2063 // Return a resultset with no rows
2103 return executeMetaDataQuery("SELECT cast(null as char(1)) AS \"TABLE_CAT\" WHERE 1 = 0"); 2064 return executeMetaDataQuery("SELECT cast(null as char(1)) AS \"TABLE_CAT\" WHERE 1 = 0");
2104 } 2065 }
2105 2066
2106 /** 2067 /**
2107 * Get the table types available in this database. The results 2068 * Get the table types available in this database.
2108 * are ordered by table type. 2069 * The results are ordered by table type.
2109 * 2070 *
2110 * <P>The table type is: 2071 * <P>The table type is:
2111 * <OL> 2072 * <OL>
2112 * <LI><B>TABLE_TYPE</B> String =&gt; table type. Typical types are "TABLE", 2073 * <LI><B>TABLE_TYPE</B> String =&gt; table type. Typical types are "TABLE",
2113 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", 2074 * "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
2114 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM". 2075 * "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
2115 * </OL> 2076 * </OL>
2116 * 2077 *
2117 * @return ResultSet each row has a single String column that is a 2078 * @return ResultSet each row has a single String column that is a table type
2118 * table type
2119 * @throws SQLException if a database error occurs 2079 * @throws SQLException if a database error occurs
2120 */ 2080 */
2121 @Override 2081 @Override
2122 public ResultSet getTableTypes() throws SQLException { 2082 public ResultSet getTableTypes() throws SQLException {
2123 // as of Jul2015 release we have a new table: sys.table_types with more table types 2083 // as of Jul2015 release we have a new table: sys.table_types with more table types
2084 String query = "SELECT \"table_type_name\" AS \"TABLE_TYPE\" FROM \"sys\".\"table_types\" ORDER BY 1";
2085
2124 // For old (pre jul2015) servers fall back to old behavior. 2086 // For old (pre jul2015) servers fall back to old behavior.
2125 final boolean preJul2015 = ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0); 2087 if ("11.19.15".compareTo(getDatabaseProductVersion()) >= 0)
2126 final String query = preJul2015 2088 query = "SELECT 'SESSION TABLE' AS \"TABLE_TYPE\" UNION ALL " +
2127 ? "SELECT 'SESSION TABLE' AS \"TABLE_TYPE\" UNION ALL " + 2089 "SELECT 'SESSION VIEW' UNION ALL " +
2128 "SELECT 'SESSION VIEW' UNION ALL " + 2090 "SELECT 'SYSTEM SESSION TABLE' UNION ALL " +
2129 "SELECT 'SYSTEM SESSION TABLE' UNION ALL " + 2091 "SELECT 'SYSTEM SESSION VIEW' UNION ALL " +
2130 "SELECT 'SYSTEM SESSION VIEW' UNION ALL " + 2092 "SELECT 'SYSTEM TABLE' UNION ALL " +
2131 "SELECT 'SYSTEM TABLE' UNION ALL " + 2093 "SELECT 'SYSTEM VIEW' UNION ALL " +
2132 "SELECT 'SYSTEM VIEW' UNION ALL " + 2094 "SELECT 'TABLE' UNION ALL " +
2133 "SELECT 'TABLE' UNION ALL " + 2095 "SELECT 'VIEW' ORDER BY 1";
2134 "SELECT 'VIEW' ORDER BY 1"
2135 : "SELECT \"table_type_name\" AS \"TABLE_TYPE\" FROM \"sys\".\"table_types\" ORDER BY 1";
2136 2096
2137 return executeMetaDataQuery(query); 2097 return executeMetaDataQuery(query);
2138 } 2098 }
2139 2099
2140 /** 2100 /**
2649 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\""); 2609 query.append(" ORDER BY \"TABLE_SCHEM\", \"TABLE_NAME\", \"COLUMN_NAME\"");
2650 2610
2651 return executeMetaDataQuery(query.toString()); 2611 return executeMetaDataQuery(query.toString());
2652 } 2612 }
2653 2613
2654 2614 // same SQL query used by getImportedKeys(), getExportedKeys() and getCrossReference()
2655 private static final String keyQuery = 2615 private static final String keyQuery =
2656 "SELECT cast(null AS char(1)) AS \"PKTABLE_CAT\", " + 2616 "SELECT cast(null AS char(1)) AS \"PKTABLE_CAT\", " +
2657 "pkschema.\"name\" AS \"PKTABLE_SCHEM\", " + 2617 "pkschema.\"name\" AS \"PKTABLE_SCHEM\", " +
2658 "pktable.\"name\" AS \"PKTABLE_NAME\", " + 2618 "pktable.\"name\" AS \"PKTABLE_NAME\", " +
2659 "pkkeycol.\"name\" AS \"PKCOLUMN_NAME\", " + 2619 "pkkeycol.\"name\" AS \"PKCOLUMN_NAME\", " +
3185 public boolean supportsResultSetType(final int type) throws SQLException { 3145 public boolean supportsResultSetType(final int type) throws SQLException {
3186 // The only type we don't support 3146 // The only type we don't support
3187 return type != ResultSet.TYPE_SCROLL_SENSITIVE; 3147 return type != ResultSet.TYPE_SCROLL_SENSITIVE;
3188 } 3148 }
3189 3149
3190
3191 /** 3150 /**
3192 * Does the database support the concurrency type in combination 3151 * Does the database support the concurrency type in combination
3193 * with the given result set type? 3152 * with the given result set type?
3194 * 3153 *
3195 * @param type - defined in java.sql.ResultSet 3154 * @param type - defined in java.sql.ResultSet
3210 return false; 3169 return false;
3211 3170
3212 // Everything else we do (well, what's left of it :) ) 3171 // Everything else we do (well, what's left of it :) )
3213 return true; 3172 return true;
3214 } 3173 }
3215
3216 3174
3217 /* lots of unsupported stuff... (no updatable ResultSet!) */ 3175 /* lots of unsupported stuff... (no updatable ResultSet!) */
3218 @Override 3176 @Override
3219 public boolean ownUpdatesAreVisible(final int type) { 3177 public boolean ownUpdatesAreVisible(final int type) {
3220 return false; 3178 return false;
3346 3304
3347 query.append(" ORDER BY \"DATA_TYPE\", \"TYPE_SCHEM\", \"TYPE_NAME\""); 3305 query.append(" ORDER BY \"DATA_TYPE\", \"TYPE_SCHEM\", \"TYPE_NAME\"");
3348 3306
3349 return executeMetaDataQuery(query.toString()); 3307 return executeMetaDataQuery(query.toString());
3350 } 3308 }
3351
3352 3309
3353 /** 3310 /**
3354 * Retrieves the connection that produced this metadata object. 3311 * Retrieves the connection that produced this metadata object.
3355 * 3312 *
3356 * @return the connection that produced this metadata object 3313 * @return the connection that produced this metadata object
4160 public boolean supportsRefCursors() { 4117 public boolean supportsRefCursors() {
4161 return false; 4118 return false;
4162 } 4119 }
4163 4120
4164 //== end methods interface DatabaseMetaData 4121 //== end methods interface DatabaseMetaData
4122
4123
4124 //== this is a helper method which does not belong to the interface
4125
4126 /**
4127 * Returns a SQL match part string where depending on the input value we
4128 * compose an exact match (use =) or match with wildcards (use LIKE) or IS NULL
4129 *
4130 * @param in the string to match
4131 * @return the SQL match part string
4132 */
4133 private static final String composeMatchPart(final String in) {
4134 if (in == null)
4135 return "IS NULL";
4136
4137 String cmp = "= '";
4138 // check if SQL wildcards are used in the input, if so use LIKE
4139 if (in.contains("%") || in.contains("_"))
4140 cmp = "LIKE '";
4141
4142 String val = in;
4143 if (in.contains("\\") || in.contains("'"))
4144 // all slashes and single quotes in input are escaped with a slash.
4145 val = in.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'");
4146
4147 return cmp + val + "'";
4148 }
4149
4150 /**
4151 * Returns the given string between two double quotes for usage as
4152 * exact column or table name in SQL queries.
4153 *
4154 * @param in the string to quote
4155 * @return the quoted string
4156 */
4157 // @SuppressWarnings("unused")
4158 // private static final String dq(String in) {
4159 // return "\"" + in.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\\\\"") + "\"";
4160 // }
4161
4162 //== end helper methods
4165 } 4163 }