Re: Avoiding explicit addDataType calls for PostGIS - Mailing list pgsql-jdbc
From | Oliver Jowett |
---|---|
Subject | Re: Avoiding explicit addDataType calls for PostGIS |
Date | |
Msg-id | 416B63BF.4090304@opencloud.com Whole thread Raw |
In response to | Re: Avoiding explicit addDataType calls for PostGIS (Markus Schaber <schabios@logi-track.com>) |
Responses |
Re: Avoiding explicit addDataType calls for PostGIS
Re: Avoiding explicit addDataType calls for PostGIS |
List | pgsql-jdbc |
Markus Schaber wrote: > Hi, Oliver, > > On Thu, 07 Oct 2004 10:11:22 +1300 > Oliver Jowett <oliver@opencloud.com> wrote: > >>If your objective is to produce a driver that automatically supports >>the extra datatypes, how about a provider-properties-file approach? > > That is a nice idea that allows to control default configuration without > recompiling, and without explicit code in the app. Here is a first cut at implementing this. The driver looks for resources named "postgresql.properties" in its classloader, loads them as property files in the order the classloader returns them, and uses the result as default properties. These defaults are overridden in turn by user-provided properties and properties extracted from the connection URL. Properties of the form datatype.<typename>=<classname> cause the given class to be loaded and registered via addDataType. The default set of datatypes (interval, money, line, etc) are registered in this way by a default postgresql.properties included in the driver jar. I haven't looked at preventing user properties from causing classloading yet.. don't know if it is worth it. Also I have not investigated the exact order of resources that ClassLoader.getResources() returns; it might need some tuning. -O Index: org/postgresql/Driver.java.in =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/Driver.java.in,v retrieving revision 1.48 diff -u -c -r1.48 Driver.java.in *** org/postgresql/Driver.java.in 10 Oct 2004 15:39:30 -0000 1.48 --- org/postgresql/Driver.java.in 12 Oct 2004 04:35:56 -0000 *************** *** 15,20 **** --- 15,21 ---- import java.io.*; import java.sql.*; import java.util.*; + import java.net.URL; import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLState; *************** *** 66,71 **** --- 67,95 ---- } } + // + // Helper to retrieve default properties from classloader resource + // properties files. + // + private Properties defaultProperties; + synchronized Properties getDefaultProperties() throws IOException { + if (defaultProperties != null) + return defaultProperties; + + Properties merged = new Properties(); + + Enumeration urls = getClass().getClassLoader().getResources("postgresql.properties"); + while (urls.hasMoreElements()) { + URL url = (URL)urls.nextElement(); + InputStream is = url.openStream(); + merged.load(is); + is.close(); + } + + defaultProperties = merged; + return defaultProperties; + } + /* * Try to make a database connection to the given URL. The driver * should return "null" if it realizes it is the wrong kind of *************** *** 125,132 **** */ public java.sql.Connection connect(String url, Properties info) throws SQLException { ! Properties props; ! if ((props = parseURL(url, info)) == null) { if (Driver.logDebug) Driver.debug("Error in url" + url); --- 149,172 ---- */ public java.sql.Connection connect(String url, Properties info) throws SQLException { ! // get defaults ! Properties defaults; ! try { ! defaults = getDefaultProperties(); ! } catch (IOException ioe) { ! throw new PSQLException(GT.tr("Error loading default settings from postgresql.properties"), ! PSQLState.UNEXPECTED_ERROR, ioe); ! } ! ! // override defaults with provided properties ! Properties props = new Properties(defaults); ! for (Enumeration e = info.propertyNames(); e.hasMoreElements(); ) { ! String propName = (String)e.nextElement(); ! props.put(propName, info.getProperty(propName)); ! } ! ! // parse URL and add more properties ! if ((props = parseURL(url, props)) == null) { if (Driver.logDebug) Driver.debug("Error in url" + url); Index: org/postgresql/jdbc2/AbstractJdbc2Connection.java =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v retrieving revision 1.18 diff -u -c -r1.18 AbstractJdbc2Connection.java *** org/postgresql/jdbc2/AbstractJdbc2Connection.java 10 Oct 2004 15:39:40 -0000 1.18 --- org/postgresql/jdbc2/AbstractJdbc2Connection.java 12 Oct 2004 04:35:57 -0000 *************** *** 93,103 **** prepareThreshold = 0; try { prepareThreshold = Integer.parseInt(info.getProperty("prepareThreshold", "0")); } catch (Exception e) {} ! ! if (prepareThreshold < 0) ! prepareThreshold = 0; ! //Print out the driver version number if (Driver.logInfo) Driver.info(Driver.getVersion()); --- 93,102 ---- prepareThreshold = 0; try { prepareThreshold = Integer.parseInt(info.getProperty("prepareThreshold", "0")); + if (prepareThreshold < 0) + prepareThreshold = 0; } catch (Exception e) {} ! //Print out the driver version number if (Driver.logInfo) Driver.info(Driver.getVersion()); *************** *** 118,124 **** rollbackQuery = getQueryExecutor().createSimpleQuery("ROLLBACK"); // Initialize object handling ! initObjectTypes(); } /* --- 117,123 ---- rollbackQuery = getQueryExecutor().createSimpleQuery("ROLLBACK"); // Initialize object handling ! initObjectTypes(info); } /* *************** *** 417,444 **** // This holds the available types, a String to Class mapping. private final HashMap objectTypes = new HashMap(); - // This array contains the types that are supported as standard. - // - // The first entry is the types name on the database, the second - // the full class name of the handling class. - // - private static final Object[][] defaultObjectTypes = { - { "box", org.postgresql.geometric.PGbox.class }, - { "circle", org.postgresql.geometric.PGcircle.class }, - { "line", org.postgresql.geometric.PGline.class }, - { "lseg", org.postgresql.geometric.PGlseg.class }, - { "path", org.postgresql.geometric.PGpath.class }, - { "point", org.postgresql.geometric.PGpoint.class }, - { "polygon", org.postgresql.geometric.PGpolygon.class }, - { "money", org.postgresql.util.PGmoney.class }, - { "interval", org.postgresql.util.PGInterval.class } - }; - // This initialises the objectTypes hashtable ! private void initObjectTypes() throws SQLException { ! for (int i = 0; i < defaultObjectTypes.length; ++i) ! addDataType((String) defaultObjectTypes[i][0], (Class) defaultObjectTypes[i][1]); } /** --- 416,441 ---- // This holds the available types, a String to Class mapping. private final HashMap objectTypes = new HashMap(); // This initialises the objectTypes hashtable ! private void initObjectTypes(Properties info) throws SQLException { ! for (Enumeration e = info.propertyNames(); e.hasMoreElements(); ) { ! String propertyName = (String)e.nextElement(); ! if (propertyName.startsWith("datatype.")) { ! String typeName = propertyName.substring(9); ! String className = info.getProperty(propertyName); ! Class klass; ! ! try { ! klass = Class.forName(className); ! } catch (ClassNotFoundException cnfe) { ! throw new PSQLException(GT.tr("Unable to load the class {0} responsible for the datatype {1}", newObject[] { className, typeName }), ! PSQLState.SYSTEM_ERROR, cnfe); ! } ! ! addDataType(typeName, klass); ! } ! } } /** Index: build.xml =================================================================== RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/build.xml,v retrieving revision 1.52 diff -u -c -r1.52 build.xml *** build.xml 10 Oct 2004 15:39:29 -0000 1.52 --- build.xml 12 Oct 2004 04:35:57 -0000 *************** *** 105,110 **** --- 105,111 ---- </fileset> <fileset dir="${srcdir}"> + <include name="postgresql.properties"/> <include name="${package}/translation/*.class" /> </fileset> </jar> *** /dev/null Mon Feb 2 17:15:26 2004 --- postgresql.properties Tue Oct 12 17:08:52 2004 *************** *** 0 **** --- 1,16 ---- + # + # This property file is included in the driver jar and controls the default + # driver settings. These values may be overridden or added to by placing + # additional property files (also named 'postgresql.properties') in the + # driver's classpath. + # + prepareThreshold=5 + datatype.box=org.postgresql.geometric.PGbox + datatype.circle=org.postgresql.geometric.PGcircle + datatype.line=org.postgresql.geometric.PGline + datatype.lseg=org.postgresql.geometric.PGlseg + datatype.path=org.postgresql.geometric.PGpath + datatype.point=org.postgresql.geometric.PGpoint + datatype.polygon=org.postgresql.geometric.PGpolygon + datatype.money=org.postgresql.util.PGmoney + datatype.interval=org.postgresql.util.PGInterval
pgsql-jdbc by date: