001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.data.postgis.fidmapper;
017:
018: import org.geotools.data.jdbc.JDBCDataStoreConfig;
019: import org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory;
020: import org.geotools.data.jdbc.fidmapper.FIDMapper;
021: import org.geotools.data.postgis.PostgisSQLBuilder;
022: import org.geotools.filter.SQLEncoderPostgis;
023: import java.sql.Connection;
024: import java.sql.ResultSet;
025: import java.sql.SQLException;
026: import java.sql.Statement;
027: import java.util.logging.Level;
028:
029: /**
030: * Postgis specific FIDMapperFactory that uses the {@link org.geotools.data.postgis.fidmapper.OIDFidMapper OIDFidMapper}
031: * to map tables with no primary keys or tables that have weird primary keys that cannot be mapped
032: * in other ways.
033: *
034: * @author Andrea Aime
035: *
036: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/postgis/src/main/java/org/geotools/data/postgis/fidmapper/PostgisFIDMapperFactory.java $
037: */
038: public class PostgisFIDMapperFactory extends DefaultFIDMapperFactory {
039: JDBCDataStoreConfig config;
040:
041: public PostgisFIDMapperFactory(JDBCDataStoreConfig config) {
042: this .config = config;
043: //setReturningTypedFIDMapper( false );
044: }
045:
046: protected FIDMapper buildNoPKMapper(String schema,
047: String tableName, Connection connection) {
048: //oid's supported before version 7
049: if (getDatabaseMajorVersion(connection) <= 7) {
050: return new OIDFidMapper();
051: }
052:
053: //table could also have been created with OID flag on
054: PostgisSQLBuilder sqlb = new PostgisSQLBuilder(
055: new SQLEncoderPostgis(), config);
056: String sql = "SELECT " + sqlb.encodeColumnName("oid")
057: + " FROM " + sqlb.encodeTableName(tableName)
058: + " LIMIT 1";
059: Statement st = null;
060:
061: try {
062: st = connection.createStatement();
063: st.execute(sql);
064:
065: //if we get here oid is supported
066: return new OIDFidMapper();
067: } catch (SQLException e) {
068: //ignore, fall back to parent
069: } finally {
070: try {
071: st.close();
072: } catch (SQLException ignore) {
073: }
074: }
075:
076: return super .buildNoPKMapper(schema, tableName, connection);
077: }
078:
079: /**
080: * Retrieves Postgresql database major version number. This is used to see
081: * if OID are there or not.
082: *
083: * @param connection
084: */
085: private int getDatabaseMajorVersion(Connection connection) {
086: int major;
087:
088: try {
089: major = connection.getMetaData().getDatabaseMajorVersion();
090: } catch (SQLException e) {
091: LOGGER.log(Level.WARNING, "Failed to retrieve Postgres "
092: + "database version number, assuming 7. Error is: "
093: + e.getMessage(), e);
094: major = 7;
095: }
096:
097: return major;
098: }
099:
100: protected FIDMapper buildLastResortFidMapper(String schema,
101: String tableName, Connection connection,
102: ColumnInfo[] colInfos) {
103: if (getDatabaseMajorVersion(connection) > 7) {
104: throw new IllegalArgumentException(
105: "Tables for postgis 8+ must have a primary key defined");
106: }
107:
108: return new OIDFidMapper();
109: }
110:
111: protected FIDMapper buildSingleColumnFidMapper(String schema,
112: String tableName, Connection connection, ColumnInfo ci) {
113: if (ci.isAutoIncrement()) {
114: return new PostGISAutoIncrementFIDMapper(schema, tableName,
115: ci.getColName(), ci.getDataType());
116: }
117:
118: return super .buildSingleColumnFidMapper(schema, tableName,
119: connection, ci);
120: }
121:
122: /**
123: * see@DefaultFIDMapperFactory in main module (jdbc)
124: * This version pre-double quotes the column name and table name and passes it to the superclass's version.
125: */
126: protected boolean isAutoIncrement(String catalog, String schema,
127: String tableName, Connection conn, ResultSet tableInfo,
128: String columnName, int dataType) throws SQLException {
129: String schemaName = null;
130:
131: if (schema != null) {
132: schemaName = "\"" + schema + "\"";
133: }
134:
135: return super .isAutoIncrement(catalog, schemaName, "\""
136: + tableName + "\"", conn, tableInfo, "\"" + columnName
137: + "\"", dataType);
138: }
139:
140: //
141: // /**
142: // * @see org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory#getMapper(org.geotools.feature.FeatureType)
143: // */
144: // public FIDMapper getMapper( FeatureType featureType ) {
145: // return new TypedFIDMapper(new OIDFidMapper(), featureType.getTypeName());
146: // }
147: //
148: // /**
149: // * @see org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory#getMapper(java.lang.String, java.lang.String, java.lang.String, java.sql.Connection)
150: // */
151: // public FIDMapper getMapper( String catalog, String schema, String tableName,
152: // Connection connection ) throws IOException {
153: // return new TypedFIDMapper(new OIDFidMapper(), tableName);
154: // }
155: }
|