Re: JDBC Driver - Schema Awareness - Mailing list pgsql-patches
From | Kris Jurka |
---|---|
Subject | Re: JDBC Driver - Schema Awareness |
Date | |
Msg-id | 3D8AAFF2.B20D088@ejurka.com Whole thread Raw |
In response to | JDBC Driver - Schema Awareness (Kris Jurka <jurka@ejurka.com>) |
List | pgsql-patches |
Barry Lind wrote: > > Kris, > > This all looks great. However I did notice that you didn't include > changes for LargeObjectManager.java and Serialize.java. Both of these > classes issue selects against pg_ tables and thus should be made schema > aware. Is that something you can include? If not I can do it. > > thanks, > --Barry The following patch adds schema awareness to the LargeObjectManager and parts of Serialize. The API for Serialize has no notion of schemas and did not change that. It also adds some missing escape characters on LIKE clauses missing from the original patch. This patch does not supercede the original, but adds to it. Two new files have been added to implement a Serialize regression test. Kris JurkaOnly in src/interfaces/jdbc/norg/postgresql/fastpath: .Fastpath.java.swp Only in src/interfaces/jdbc/norg/postgresql/jdbc1: .AbstractJdbc1DatabaseMetaData.java.swp diff -r -c src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java Thu Sep 19 15:13:06 2002 --- src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java Thu Sep 19 16:08:54 2002 *************** *** 1962,1968 **** if (connection.haveMinimumServerVersion("7.3")) { useSchemas = "SCHEMAS"; select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+ ! " CASE n.nspname LIKE 'pg\\_%' "+ " WHEN true THEN CASE n.nspname "+ " WHEN 'pg_catalog' THEN CASE c.relkind "+ " WHEN 'r' THEN 'SYSTEM TABLE' "+ --- 1962,1968 ---- if (connection.haveMinimumServerVersion("7.3")) { useSchemas = "SCHEMAS"; select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, "+ ! " CASE n.nspname LIKE 'pg\\\\_%' "+ " WHEN true THEN CASE n.nspname "+ " WHEN 'pg_catalog' THEN CASE c.relkind "+ " WHEN 'r' THEN 'SYSTEM TABLE' "+ *************** *** 2006,2019 **** } else { useSchemas = "NOSCHEMAS"; String tableType = ""+ ! " CASE c.relname LIKE 'pg\\_%' "+ ! " WHEN true THEN CASE c.relname LIKE 'pg\\_toast\\_%' "+ " WHEN true THEN CASE c.relkind "+ " WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+ " WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+ " ELSE NULL "+ " END "+ ! " WHEN false THEN CASE c.relname LIKE 'pg\\_temp\\_%' "+ " WHEN true THEN CASE c.relkind "+ " WHEN 'r' THEN 'TEMPORARY TABLE' "+ " WHEN 'i' THEN 'TEMPORARY INDEX' "+ --- 2006,2019 ---- } else { useSchemas = "NOSCHEMAS"; String tableType = ""+ ! " CASE c.relname LIKE 'pg\\\\_%' "+ ! " WHEN true THEN CASE c.relname LIKE 'pg\\\\_toast\\\\_%' "+ " WHEN true THEN CASE c.relkind "+ " WHEN 'r' THEN 'SYSTEM TOAST TABLE' "+ " WHEN 'i' THEN 'SYSTEM TOAST INDEX' "+ " ELSE NULL "+ " END "+ ! " WHEN false THEN CASE c.relname LIKE 'pg\\\\_temp\\\\_%' "+ " WHEN true THEN CASE c.relkind "+ " WHEN 'r' THEN 'TEMPORARY TABLE' "+ " WHEN 'i' THEN 'TEMPORARY INDEX' "+ *************** *** 2075,2090 **** tableTypeClauses = new Hashtable(); Hashtable ht = new Hashtable(); tableTypeClauses.put("TABLE",ht); ! ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\_%'"); ! ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname NOT LIKE 'pg\\_%'"); ht = new Hashtable(); tableTypeClauses.put("VIEW",ht); ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname <> 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname NOT LIKE 'pg\\_%'"); ht = new Hashtable(); tableTypeClauses.put("INDEX",ht); ! ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname NOT LIKE 'pg\\_%'"); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname NOT LIKE 'pg\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SEQUENCE",ht); ht.put("SCHEMAS","c.relkind = 'S'"); --- 2075,2090 ---- tableTypeClauses = new Hashtable(); Hashtable ht = new Hashtable(); tableTypeClauses.put("TABLE",ht); ! ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname NOT LIKE 'pg\\\\_%'"); ! ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname NOT LIKE 'pg\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("VIEW",ht); ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname <> 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname NOT LIKE 'pg\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("INDEX",ht); ! ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname NOT LIKE 'pg\\\\_%'"); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname NOT LIKE 'pg\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SEQUENCE",ht); ht.put("SCHEMAS","c.relkind = 'S'"); *************** *** 2092,2122 **** ht = new Hashtable(); tableTypeClauses.put("SYSTEM TABLE",ht); ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\_%' AND c.relname NOT LIKE 'pg\\_toast\\_%' AND c.relnameNOT LIKE 'pg\\_temp\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM TOAST TABLE",ht); ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_toast'"); ! ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\_toast\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM TOAST INDEX",ht); ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_toast'"); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\_toast\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM VIEW",ht); ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname = 'pg_catalog' "); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM INDEX",ht); ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\_%' AND c.relname NOT LIKE 'pg\\_toast\\_%' AND c.relnameNOT LIKE 'pg\\_temp\\_%'"); ht = new Hashtable(); tableTypeClauses.put("TEMPORARY TABLE",ht); ! ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname LIKE 'pg\\_temp\\_%' "); ! ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\_temp\\_%' "); ht = new Hashtable(); tableTypeClauses.put("TEMPORARY INDEX",ht); ! ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname LIKE 'pg\\_temp\\_%' "); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\_temp\\_%' "); } // These are the default tables, used when NULL is passed to getTables --- 2092,2122 ---- ht = new Hashtable(); tableTypeClauses.put("SYSTEM TABLE",ht); ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%' ANDc.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM TOAST TABLE",ht); ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname = 'pg_toast'"); ! ht.put("NOSCHEMAS","c.relkind = r' AND c.relname LIKE 'pg\\\\_toast\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM TOAST INDEX",ht); ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_toast'"); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_toast\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM VIEW",ht); ht.put("SCHEMAS","c.relkind = 'v' AND n.nspname = 'pg_catalog' "); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("SYSTEM INDEX",ht); ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname = 'pg_catalog'"); ! ht.put("NOSCHEMAS","c.relkind = 'v' AND c.relname LIKE 'pg\\\\_%' AND c.relname NOT LIKE 'pg\\\\_toast\\\\_%' ANDc.relname NOT LIKE 'pg\\\\_temp\\\\_%'"); ht = new Hashtable(); tableTypeClauses.put("TEMPORARY TABLE",ht); ! ht.put("SCHEMAS","c.relkind = 'r' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' "); ! ht.put("NOSCHEMAS","c.relkind = 'r' AND c.relname LIKE 'pg\\\\_temp\\\\_%' "); ht = new Hashtable(); tableTypeClauses.put("TEMPORARY INDEX",ht); ! ht.put("SCHEMAS","c.relkind = 'i' AND n.nspname LIKE 'pg\\\\_temp\\\\_%' "); ! ht.put("NOSCHEMAS","c.relkind = 'i' AND c.relname LIKE 'pg\\\\_temp\\\\_%' "); } // These are the default tables, used when NULL is passed to getTables *************** *** 2141,2147 **** { String sql; if (connection.haveMinimumServerVersion("7.3")) { ! sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname NOTLIKE 'pg\\_temp\\_%' ORDER BY TABLE_SCHEM"; } else { sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM"; } --- 2141,2147 ---- { String sql; if (connection.haveMinimumServerVersion("7.3")) { ! sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname NOTLIKE 'pg\\\\_temp\\\\_%' ORDER BY TABLE_SCHEM"; } else { sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM"; } *************** *** 3031,3037 **** + "AND t.tgisconstraint " + "AND t.tgconstrrelid=c2.oid " + "AND t.tgfoid=p1.oid " ! + "and p1.proname like 'RI\\_FKey\\_%\\_upd') " + "and " // isolate the delete rule --- 3031,3037 ---- + "AND t.tgisconstraint " + "AND t.tgconstrrelid=c2.oid " + "AND t.tgfoid=p1.oid " ! + "and p1.proname like 'RI\\\\_FKey\\\\_%\\\\_upd') " + "and " // isolate the delete rule *************** *** 3039,3045 **** + "and t1.tgisconstraint " + "and t1.tgconstrrelid=c2.oid " + "AND t1.tgfoid=p2.oid " ! + "and p2.proname like 'RI\\_FKey\\_%\\_del') " + "AND i.indrelid=c.oid " + "AND i.indexrelid=ic.oid " + "AND ic.oid=a.attrelid " --- 3039,3045 ---- + "and t1.tgisconstraint " + "and t1.tgconstrrelid=c2.oid " + "AND t1.tgfoid=p2.oid " ! + "and p2.proname like 'RI\\\\_FKey\\\\_%\\\\_del') " + "AND i.indrelid=c.oid " + "AND i.indexrelid=ic.oid " + "AND ic.oid=a.attrelid " Only in src/interfaces/jdbc/norg/postgresql/jdbc1: AbstractJdbc1DatabaseMetaData.java~ diff -r -c src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java Fri Sep 13 20:52:56 2002 --- src/interfaces/jdbc/norg/postgresql/jdbc1/AbstractJdbc1Statement.java Thu Sep 19 12:03:02 2002 *************** *** 1757,1764 **** */ private void setSerialize(int parameterIndex, long x, String classname) throws SQLException { ! // converts . to _, toLowerCase, and ensures length<32 ! String tablename = Serialize.toPostgreSQL( classname ); DriverManager.println("setSerialize: setting " + x + "::" + tablename ); // OID reference to tablerow-type must be cast like: <oid>::<tablename> --- 1757,1764 ---- */ private void setSerialize(int parameterIndex, long x, String classname) throws SQLException { ! // converts . to _, toLowerCase, and ensures length < max name length ! String tablename = Serialize.toPostgreSQL((java.sql.Connection)connection, classname ); DriverManager.println("setSerialize: setting " + x + "::" + tablename ); // OID reference to tablerow-type must be cast like: <oid>::<tablename> diff -r -c src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java src/interfaces/jdbc/norg/postgresql/largeobject/LargeObjectManager.java *** src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java Fri Sep 6 14:23:06 2002 --- src/interfaces/jdbc/norg/postgresql/largeobject/LargeObjectManager.java Thu Sep 19 11:58:04 2002 *************** *** 103,117 **** // // This is an example of Fastpath.addFunctions(); // ! ResultSet res = conn.createStatement().executeQuery("select proname, oid from pg_proc" + ! " where proname = 'lo_open'" + ! " or proname = 'lo_close'" + ! " or proname = 'lo_creat'" + ! " or proname = 'lo_unlink'" + ! " or proname = 'lo_lseek'" + ! " or proname = 'lo_tell'" + ! " or proname = 'loread'" + ! " or proname = 'lowrite'"); if (res == null) throw new PSQLException("postgresql.lo.init"); --- 103,126 ---- // // This is an example of Fastpath.addFunctions(); // ! String sql; ! if (conn.getMetaData().supportsSchemasInTableDefinitions()) { ! sql = "SELECT p.proname,p.oid "+ ! " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n "+ ! " WHERE p.pronamespace=n.oid AND n.nspname='pg_catalog' AND "; ! } else { ! sql = "SELECT proname,oid FROM pg_proc WHERE "; ! } ! sql += " proname = 'lo_open'" + ! " or proname = 'lo_close'" + ! " or proname = 'lo_creat'" + ! " or proname = 'lo_unlink'" + ! " or proname = 'lo_lseek'" + ! " or proname = 'lo_tell'" + ! " or proname = 'loread'" + ! " or proname = 'lowrite'"; ! ! ResultSet res = conn.createStatement().executeQuery(sql); if (res == null) throw new PSQLException("postgresql.lo.init"); Only in src/interfaces/jdbc/norg/postgresql/largeobject: LargeObjectManager.java~ diff -r -c src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java src/interfaces/jdbc/norg/postgresql/test/jdbc2/Jdbc2TestSuite.java *** src/interfaces/jdbc/org/postgresql/test/jdbc2/Jdbc2TestSuite.java Thu Sep 19 15:13:06 2002 --- src/interfaces/jdbc/norg/postgresql/test/jdbc2/Jdbc2TestSuite.java Thu Sep 19 13:23:22 2002 *************** *** 48,60 **** // PreparedStatement ! // ServerSide Prepared Statements ! suite.addTestSuite(ServerPreparedStmtTest.class); // BatchExecute suite.addTestSuite(BatchExecuteTest.class); - // MetaData // Other misc tests, based on previous problems users have had or specific // features some applications require. --- 48,59 ---- // PreparedStatement ! // ServerSide Prepared Statements ! suite.addTestSuite(ServerPreparedStmtTest.class); // BatchExecute suite.addTestSuite(BatchExecuteTest.class); // Other misc tests, based on previous problems users have had or specific // features some applications require. *************** *** 63,68 **** --- 62,69 ---- // Fastpath/LargeObject suite.addTestSuite(BlobTest.class); + + suite.addTestSuite(SerializeTest.class); suite.addTestSuite(UpdateableResultTest.class ); suite.addTestSuite(CallableStmtTest.class ); Only in src/interfaces/jdbc/norg/postgresql/test/jdbc2: SerializeObject.java Only in src/interfaces/jdbc/norg/postgresql/test/jdbc2: SerializeTest.java Only in src/interfaces/jdbc/norg/postgresql/util: .Serialize.java.swp diff -r -c src/interfaces/jdbc/org/postgresql/util/Serialize.java src/interfaces/jdbc/norg/postgresql/util/Serialize.java *** src/interfaces/jdbc/org/postgresql/util/Serialize.java Fri Sep 6 14:23:06 2002 --- src/interfaces/jdbc/norg/postgresql/util/Serialize.java Thu Sep 19 13:31:30 2002 *************** *** 124,137 **** * This creates an instance that can be used to serialize or deserialize * a Java object from a PostgreSQL table. */ ! public Serialize(Connection c, String type) throws SQLException { try { ! conn = c; if (Driver.logDebug) Driver.debug("Serialize: initializing instance for type: " + type); ! tableName = toPostgreSQL(type); className = type; ourClass = Class.forName(className); } --- 124,137 ---- * This creates an instance that can be used to serialize or deserialize * a Java object from a PostgreSQL table. */ ! public Serialize(Connection conn, String type) throws SQLException { try { ! this.conn = conn; if (Driver.logDebug) Driver.debug("Serialize: initializing instance for type: " + type); ! tableName = toPostgreSQL(conn,type); className = type; ourClass = Class.forName(className); } *************** *** 144,150 **** // Second check, the type must be a table boolean status = false; ! ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL("select typname from pg_type,pg_classwhere typname=relname and typname='" + tableName + "'"); if (rs != null) { if (rs.next()) --- 144,157 ---- // Second check, the type must be a table boolean status = false; ! String sql; ! if (conn.getMetaData().supportsSchemasInTableDefinitions()) { ! sql = "SELECT 1 FROM pg_catalog.pg_type t, pg_catalog.pg_class c WHERE t.typrelid=c.oid AND c.relkind='r' ANDt.typname='" + tableName + "' AND pg_table_is_visible(c.oid) "; ! } else { ! sql = "SELECT 1 FROM pg_type t, pg_class c WHERE t.typrelid=c.oid AND c.relkind='r' AND t.typname='"+tableName+"'"; ! } ! ! ResultSet rs = conn.createStatement().executeQuery(sql); if (rs != null) { if (rs.next()) *************** *** 187,193 **** * @return Object relating to oid * @exception SQLException on error */ ! public Object fetch(int oid) throws SQLException { try { --- 194,200 ---- * @return Object relating to oid * @exception SQLException on error */ ! public Object fetch(long oid) throws SQLException { try { *************** *** 228,234 **** if (Driver.logDebug) Driver.debug("Serialize.fetch: " + sb.toString()); ! ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)conn).ExecSQL(sb.toString()); if (rs != null) { --- 235,241 ---- if (Driver.logDebug) Driver.debug("Serialize.fetch: " + sb.toString()); ! ResultSet rs = conn.createStatement().executeQuery(sb.toString()); if (rs != null) { *************** *** 493,507 **** * @param o Class to base table on * @exception SQLException on error */ ! public static void create(Connection con, Class c) throws SQLException { if (c.isInterface()) throw new PSQLException("postgresql.serial.interface"); // See if the table exists ! String tableName = toPostgreSQL(c.getName()); ! ResultSet rs = ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL("select relname from pg_class whererelname = '" + tableName + "'"); if ( rs.next() ) { if (Driver.logDebug) --- 500,521 ---- * @param o Class to base table on * @exception SQLException on error */ ! public static void create(Connection conn, Class c) throws SQLException { if (c.isInterface()) throw new PSQLException("postgresql.serial.interface"); // See if the table exists ! String tableName = toPostgreSQL(conn,c.getName()); ! String sql; ! if (conn.getMetaData().supportsSchemasInTableDefinitions()) { ! sql = "SELECT 1 FROM pg_catalog.pg_class WHERE relkind='r' AND relname='" + tableName + "' AND pg_table_is_visible(oid)"; ! } else { ! sql = "SELECT 1 FROM pg_class WHERE relkind='r' AND relname='"+tableName+"'"; ! } ! ! ResultSet rs = conn.createStatement().executeQuery(sql); if ( rs.next() ) { if (Driver.logDebug) *************** *** 549,556 **** sb.append(tp[j][1]); else { ! create(con, type); ! sb.append(toPostgreSQL(n)); } } } --- 563,570 ---- sb.append(tp[j][1]); else { ! create(conn, type); ! sb.append(toPostgreSQL(conn,n)); } } } *************** *** 560,566 **** // Now create the table if (Driver.logDebug) Driver.debug("Serialize.create: " + sb ); ! ((org.postgresql.jdbc1.AbstractJdbc1Connection)con).ExecSQL(sb.toString()); } // This is used to translate between Java primitives and PostgreSQL types. --- 574,580 ---- // Now create the table if (Driver.logDebug) Driver.debug("Serialize.create: " + sb ); ! conn.createStatement().executeUpdate(sb.toString()); } // This is used to translate between Java primitives and PostgreSQL types. *************** *** 582,616 **** {"byte", "int2"} }; ! /* * This converts a Java Class name to a org.postgresql table, by replacing . with * _<p> * * Because of this, a Class name may not have _ in the name.<p> * Another limitation, is that the entire class name (including packages) ! * cannot be longer than 64 characters (a limit forced by PostgreSQL). * * @param name Class name * @return PostgreSQL table name * @exception SQLException on error */ ! public static String toPostgreSQL(String name) throws SQLException { name = name.toLowerCase(); if (name.indexOf("_") > -1) throw new PSQLException("postgresql.serial.underscore"); ! // Postgres table names can only be 64 character long. ! // Reserve 1 char, so allow only up to 63 chars. // If the full class name with package is too long // then just use the class name. If the class name is // too long throw an exception. // ! if ( name.length() > 63 ) { name = name.substring(name.lastIndexOf(".") + 1); ! if ( name.length() > 63 ) throw new PSQLException("postgresql.serial.namelength", name, new Integer(name.length())); } return name.replace('.', '_'); --- 596,648 ---- {"byte", "int2"} }; ! /** * This converts a Java Class name to a org.postgresql table, by replacing . with * _<p> * * Because of this, a Class name may not have _ in the name.<p> * Another limitation, is that the entire class name (including packages) ! * cannot be longer than the maximum table name length. * + * @param con The database connection * @param name Class name * @return PostgreSQL table name * @exception SQLException on error + * @since 7.3 */ ! public static String toPostgreSQL(Connection con, String name) throws SQLException { + DatabaseMetaData dbmd = con.getMetaData(); + int maxNameLength = dbmd.getMaxTableNameLength(); + return toPostgreSQL(maxNameLength,name); + } + + /** + * Convert a Java Class Name to an org.postgresql table name, by replacing . + * with _ <p> + * + * @deprecated Replaced by toPostgresql(connection, name) in 7.3 + */ + public static String toPostgreSQL(String name) throws SQLException { + return toPostgreSQL(31,name); + } + + private static String toPostgreSQL(int maxNameLength, String name) throws SQLException { + name = name.toLowerCase(); if (name.indexOf("_") > -1) throw new PSQLException("postgresql.serial.underscore"); ! // Postgres table names can only be so many characters long. // If the full class name with package is too long // then just use the class name. If the class name is // too long throw an exception. // ! if ( name.length() > maxNameLength ) { name = name.substring(name.lastIndexOf(".") + 1); ! if ( name.length() > maxNameLength ) throw new PSQLException("postgresql.serial.namelength", name, new Integer(name.length())); } return name.replace('.', '_'); Only in src/interfaces/jdbc/norg/postgresql/util: Serialize.java~ package org.postgresql.test.jdbc2; import org.postgresql.test.TestUtil; import junit.framework.TestCase; import java.sql.*; import org.postgresql.util.Serialize; public class SerializeTest extends TestCase { private Connection conn; private SerializeObject serobj; private Serialize ser; public SerializeTest(String name) { super(name); } protected void setUp() throws Exception { conn = TestUtil.openDB(); serobj = new SerializeObject(); serobj.intcol = 1; serobj.doublecol = 3.4; serobj.stringcol = "Hello"; TestUtil.dropTable(conn,Serialize.toPostgreSQL(conn,serobj.getClass().getName())); Serialize.create(conn, serobj); Serialize.create(conn, serobj); ser = new Serialize(conn,serobj); } protected void tearDown() throws Exception { TestUtil.dropTable(conn,Serialize.toPostgreSQL(conn,serobj.getClass().getName())); } public void testCreateSerialize() { try { long oid = ser.storeObject(serobj); SerializeObject serobj2 = (SerializeObject)ser.fetch(oid); assertNotNull(serobj2); assertEquals(serobj.intcol,serobj2.intcol); assertTrue(Math.abs(serobj.doublecol-serobj2.doublecol) < 0.0001); assertTrue(serobj.stringcol.equals(serobj2.stringcol)); } catch (SQLException sqle) { fail(sqle.getMessage()); } } } package org.postgresql.test.jdbc2; import java.io.Serializable; public class SerializeObject implements Serializable { public int intcol; public double doublecol; public String stringcol; }
pgsql-patches by date: