001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) Copyright IBM Corporation, 2005-2007. All rights reserved.
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: */
017: package org.geotools.data.db2;
018:
019: import org.geotools.data.jdbc.JDBCUtils;
020: import org.geotools.data.jdbc.fidmapper.BasicFIDMapper;
021: import org.geotools.data.jdbc.fidmapper.DefaultFIDMapperFactory;
022: import org.geotools.data.jdbc.fidmapper.FIDMapper;
023: import org.geotools.data.jdbc.fidmapper.MaxIncFIDMapper;
024: import org.geotools.data.jdbc.fidmapper.TypedFIDMapper;
025: import java.io.IOException;
026: import java.sql.Connection;
027: import java.sql.ResultSet;
028: import java.sql.SQLException;
029: import java.sql.Statement;
030: import java.util.logging.Logger;
031:
032: /**
033: * Overrides DefaultFIDMapperFactory methods for DB2-specific handling.
034: *
035: * @author David Adler - IBM Corporation
036: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/db2/src/main/java/org/geotools/data/db2/DB2FIDMapperFactory.java $
037: */
038: public class DB2FIDMapperFactory extends DefaultFIDMapperFactory {
039: private static final Logger LOGGER = org.geotools.util.logging.Logging
040: .getLogger("org.geotools.data.db2");
041: private String databaseSchemaName = null;
042:
043: /**
044: * Default constructor will cause FID columns to be returned as business
045: * attributes.
046: */
047: public DB2FIDMapperFactory(String databaseSchemaName) {
048: super (true);
049: this .databaseSchemaName = databaseSchemaName;
050: }
051:
052: /**
053: * Constructs a DB2FIDMapperFactory with user specification of whether to
054: * return FID columns as business attributes.
055: *
056: * @param returnFIDColumnsAsAttributes true if FID columns should be
057: * returned as business attributes.
058: */
059: public DB2FIDMapperFactory(boolean returnFIDColumnsAsAttributes) {
060: super (returnFIDColumnsAsAttributes);
061: }
062:
063: /**
064: * Gets the appropriate FIDMapper for the specified table.
065: *
066: * @param catalog
067: * @param schema
068: * @param tableName
069: * @param connection the active database connection to get table key
070: * information
071: *
072: * @return the appropriate FIDMapper for the specified table.
073: *
074: * @throws IOException if any error occurs.
075: */
076: public FIDMapper getMapper(String catalog, String schema,
077: String tableName, Connection connection) throws IOException {
078: FIDMapper fm = super .getMapper(catalog, schema, tableName,
079: connection);
080: LOGGER.fine(toString(fm));
081:
082: return fm;
083: }
084:
085: /**
086: * Determine whether this column is autoincrement. An open connection to
087: * the database must be provided.
088: *
089: * @param catalog not used
090: * @param schema not used
091: * @param tableName the table name
092: * @param conn an open database connection
093: * @param tableInfo not used
094: * @param columnName the FID column name
095: * @param dataType not used
096: *
097: * @return true if this is an autoincrement column
098: *
099: * @throws SQLException
100: */
101: protected boolean isAutoIncrement(String catalog, String schema,
102: String tableName, Connection conn, ResultSet tableInfo,
103: String columnName, int dataType) throws SQLException {
104: // if it's not an integer type it can't be an auto increment type
105: if (!isIntegralType(dataType)) {
106: return false;
107: }
108:
109: // It seems like there should be a better way to get this directly from the catalog
110: boolean autoIncrement = false;
111: Statement statement = null;
112: ResultSet rs = null;
113:
114: try {
115: statement = conn.createStatement();
116:
117: String stmtString = "SELECT IDENTITY, GENERATED FROM SYSCAT.COLUMNS "
118: + "WHERE TABSCHEMA = '"
119: + tableInfo.getString("TABLE_SCHEM")
120: + "' "
121: + "AND TABNAME = '"
122: + tableName
123: + "' "
124: + "AND COLNAME = '" + columnName + "'";
125:
126: rs = statement.executeQuery(stmtString);
127:
128: if (rs.next()) {
129: if (rs.getString(1).equals("Y")
130: && rs.getString(2).equals("A")) {
131: autoIncrement = true;
132: }
133: }
134: } finally {
135: JDBCUtils.close(statement);
136: JDBCUtils.close(rs);
137: }
138:
139: return autoIncrement;
140: }
141:
142: /**
143: * Returns a DB2NullFIDMapper when there is no primary key.
144: *
145: * @param schema ignored.
146: * @param tableName ignored.
147: * @param connection ignored.
148: *
149: * @return a DB2NullFIDMapper.
150: */
151: protected FIDMapper buildNoPKMapper(String schema,
152: String tableName, Connection connection) {
153: FIDMapper mapper;
154: mapper = new DB2NullFIDMapper(schema, tableName);
155:
156: return mapper;
157: }
158:
159: /**
160: * Builds a FID mapper based on a single column primary key. Default
161: * version tries the auto-increment way, then a mapping on an {@link
162: * MaxIncFIDMapper} type for numeric columns, and a plain {@link
163: * BasicFIDMapper} of text based columns.
164: *
165: * @param schema
166: * @param tableName
167: * @param connection not used
168: * @param ci the column information
169: *
170: * @return a FIDMapper
171: */
172: protected FIDMapper buildSingleColumnFidMapper(String schema,
173: String tableName, Connection connection, ColumnInfo ci) {
174:
175: if (ci.isAutoIncrement()) {
176: return new DB2AutoIncrementFIDMapper(databaseSchemaName,
177: tableName, ci.getColName(), ci.getDataType());
178: } else if (isIntegralType(ci.getDataType())) {
179: return new MaxIncFIDMapper(databaseSchemaName, tableName,
180: ci.getColName(), ci.getDataType(), true);
181: } else {
182: return new BasicFIDMapper(databaseSchemaName, tableName, ci
183: .getColName(), ci.getSize(), true);
184: }
185: }
186:
187: /**
188: * Create a nice string representation of a FID Mapper
189: *
190: * @param fm the FID Mapper
191: *
192: * @return the String representation
193: */
194: String toString(FIDMapper fm) {
195: String mapperName = ((TypedFIDMapper) fm).getWrappedMapper()
196: .getClass().toString();
197: String colInfo = "";
198:
199: if (fm.getColumnCount() > 0) {
200: colInfo = fm.getColumnName(0) + ":" + fm.getColumnType(0)
201: + ":" + fm.getColumnSize(0) + ":"
202: + fm.getColumnDecimalDigits(0);
203: }
204:
205: String s = mapperName + ":" + fm.getColumnCount() + ":"
206: + colInfo + ":" + fm.returnFIDColumnsAsAttributes()
207: + ":" + fm.hasAutoIncrementColumns() + ":" + "";
208:
209: return s;
210: }
211: }
|