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; either
009: * version 2.1 of the License, or (at your option) any later version.
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.oracle;
017:
018: import java.sql.Connection;
019: import java.sql.ResultSet;
020: import java.sql.SQLException;
021: import java.sql.Statement;
022:
023: import org.geotools.data.DataSourceException;
024:
025: /**
026: * Provides a sequence for generating unique FID keys. Selects the max value of the fid column
027: * then increments it with each successive call to getNext().
028: *
029: * <p>
030: * This may break if other tools are modifying the database at the same time. But this is a wider
031: * issue that should be dealt with in a Geotools standard way. When that way is determined this
032: * class can probably disappear. This is also part of the reason why this class is only package
033: * visible, since this method of generating fids should not be used by other data sources.
034: * </p>
035: *
036: * @author Sean Geoghegan, Defence Science and Technology Organisation
037: * @author $Author: seangeo $
038: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/oracle-spatial/src/main/java/org/geotools/data/oracle/FIDSequence.java $
039: * @version $Id: FIDSequence.java 20886 2006-08-07 15:30:17Z jgarnett $
040: *
041: * @task REVISIT: This assumes that the DB does not manage the PK itself. I need to work out a way
042: * to check that is does and then defer to the DB in that case.
043: */
044: class FIDSequence {
045: /** Holds the current FID. THis is incremented for each getNext() call */
046: private int current;
047:
048: /**
049: * Creates a FID sequence that generates unique FID keys for adding features to the table.
050: *
051: * @param conn The Database Connection
052: * @param tablename The table
053: * @param fidColumn The FID column
054: *
055: * @throws DataSourceException If an error occurs determining the max fid.
056: */
057: FIDSequence(Connection conn, String tablename, String fidColumn)
058: throws DataSourceException {
059: ResultSet resultSet = null;
060:
061: try {
062: String query = "SELECT max(" + fidColumn + ") FROM "
063: + tablename;
064:
065: Statement statement = conn.createStatement();
066:
067: resultSet = statement.executeQuery(query);
068:
069: if (resultSet.next()) {
070: Number number = (Number) resultSet.getObject(1);
071:
072: current = number.intValue();
073: } else {
074: throw new DataSourceException("Could not get max for "
075: + fidColumn);
076: }
077: } catch (SQLException e) {
078: throw new DataSourceException("SQL Error occured when "
079: + "generating unique key", e);
080: } catch (ClassCastException e) {
081: throw new DataSourceException("Error casting fid column "
082: + "to a number", e);
083: } finally {
084: try {
085: if (resultSet != null) {
086: resultSet.close();
087: }
088: } catch (SQLException e1) {
089: // dont need to do anything here - just closing the result set
090: }
091: }
092: }
093:
094: /**
095: * Gets the next unique FID key.
096: *
097: * @return The next key in the sequence.
098: */
099: int getNext() {
100: current += 1;
101:
102: return current;
103: }
104: }
|