/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.postgis.fidmapper;
import org.geotools.data.jdbc.JDBCDataStoreConfig;
import org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory;
import org.geotools.data.jdbc.fidmapper.FIDMapper;
import org.geotools.data.postgis.PostgisSQLBuilder;
import org.geotools.filter.SQLEncoderPostgis;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
/**
* Postgis specific FIDMapperFactory that uses the {@link org.geotools.data.postgis.fidmapper.OIDFidMapper OIDFidMapper}
* to map tables with no primary keys or tables that have weird primary keys that cannot be mapped
* in other ways.
*
* @author Andrea Aime
*
* @source $URL$
*/
public class PostgisFIDMapperFactory extends DefaultFIDMapperFactory {
JDBCDataStoreConfig config;
public PostgisFIDMapperFactory(JDBCDataStoreConfig config) {
this.config = config;
//setReturningTypedFIDMapper( false );
}
protected FIDMapper buildNoPKMapper(String schema, String tableName,
Connection connection) {
//oid's supported before version 7
if (getDatabaseMajorVersion(connection) <= 7) {
return new OIDFidMapper();
}
//table could also have been created with OID flag on
PostgisSQLBuilder sqlb = new PostgisSQLBuilder(new SQLEncoderPostgis(),
config);
String sql = "SELECT " + sqlb.encodeColumnName("oid") + " FROM "
+ sqlb.encodeTableName(tableName) + " LIMIT 1";
Statement st = null;
try {
st = connection.createStatement();
st.execute(sql);
//if we get here oid is supported
return new OIDFidMapper();
} catch (SQLException e) {
//ignore, fall back to parent
} finally {
try {
st.close();
} catch (SQLException ignore) {
}
}
return super.buildNoPKMapper(schema, tableName, connection);
}
/**
* Retrieves Postgresql database major version number. This is used to see
* if OID are there or not.
*
* @param connection
*/
private int getDatabaseMajorVersion(Connection connection) {
int major;
try {
major = connection.getMetaData().getDatabaseMajorVersion();
} catch (SQLException e) {
LOGGER.log(Level.WARNING,
"Failed to retrieve Postgres "
+ "database version number, assuming 7. Error is: "
+ e.getMessage(), e);
major = 7;
}
return major;
}
protected FIDMapper buildLastResortFidMapper(String schema,
String tableName, Connection connection, ColumnInfo[] colInfos) {
if (getDatabaseMajorVersion(connection) > 7) {
throw new IllegalArgumentException(
"Tables for postgis 8+ must have a primary key defined");
}
return new OIDFidMapper();
}
protected FIDMapper buildSingleColumnFidMapper(String schema,
String tableName, Connection connection, ColumnInfo ci) {
if (ci.isAutoIncrement()) {
return new PostGISAutoIncrementFIDMapper(schema, tableName,
ci.getColName(), ci.getDataType());
} else if("uuid".equals(ci.getTypeName())) {
return new UUIDFIDMapper(ci.getColName(), ci.dataType);
}
return super.buildSingleColumnFidMapper(schema, tableName, connection, ci);
}
/**
* see@DefaultFIDMapperFactory in main module (jdbc)
* This version pre-double quotes the column name and table name and passes it to the superclass's version.
*/
protected boolean isAutoIncrement(String catalog, String schema,
String tableName, Connection conn, ResultSet tableInfo,
String columnName, int dataType) throws SQLException {
String schemaName = null;
if (schema != null) {
schemaName = "\"" + schema + "\"";
}
return super.isAutoIncrement(catalog, schemaName,
"\"" + tableName + "\"", conn, tableInfo, "\"" + columnName + "\"",
dataType);
}
//
// /**
// * @see org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory#getMapper(org.geotools.feature.FeatureType)
// */
// public FIDMapper getMapper( FeatureType featureType ) {
// return new TypedFIDMapper(new OIDFidMapper(), featureType.getTypeName());
// }
//
// /**
// * @see org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory#getMapper(java.lang.String, java.lang.String, java.lang.String, java.sql.Connection)
// */
// public FIDMapper getMapper( String catalog, String schema, String tableName,
// Connection connection ) throws IOException {
// return new TypedFIDMapper(new OIDFidMapper(), tableName);
// }
}