";
- }
- last = _lastValues.get(internalTableName);
- max = _maxValues.get(internalTableName);
- if (last != null) {
- if (_sqlType == Types.INTEGER) {
- last = new Integer(((Integer) last).intValue() + 1);
- } else if (_sqlType == Types.BIGINT) {
- last = new Long(((Long) last).longValue() + 1);
- } else {
- last = ((BigDecimal) last).add(ONE);
- }
- } else {
- QueryExpression query;
- String sql;
- String sql2;
- PreparedStatement stmt = null;
- PreparedStatement stmt2 = null;
- ResultSet rs;
- boolean success;
-
- try {
- // the separate connection should be committed/rolled back at this point
- if (!_sameConnection) {
- conn.rollback();
- }
-
- // Create SQL sentence of the form
- // "SELECT seq_val FROM seq_table WHERE seq_key='table'"
- // with database-dependent keyword for lock
- // [george stewart] Note, that some databases (InstantDB,
- // HypersonicSQL) don't support such locks.
- query = _factory.getQueryExpression();
- query.addColumn(_seqTable, _seqValue);
- query.addCondition(_seqTable, _seqKey, QueryExpression.OP_EQUALS,
- JDBCSyntax.PARAMETER);
-
- // SELECT and put lock on the last record
- sql = query.getStatement(true);
- // For the case if the "SELECT FOR UPDATE" is not supported
- // we perform dirty checking
- sql2 = "UPDATE " + _seqTable
- + " SET " + _seqValue + "=" + JDBCSyntax.PARAMETER
- + JDBCSyntax.WHERE + _seqKey + QueryExpression.OP_EQUALS + JDBCSyntax.PARAMETER
- + JDBCSyntax.AND + _seqValue + QueryExpression.OP_EQUALS + JDBCSyntax.PARAMETER;
-
- stmt = conn.prepareStatement(sql);
- stmt.setString(1, internalTableName);
- stmt2 = conn.prepareStatement(sql2);
- stmt2.setString(2, internalTableName);
-
- // Retry 7 times (lucky number)
- success = false;
- for (int i = 0; !success && (i < 7); i++) {
- rs = stmt.executeQuery();
-
- if (rs.next()) {
- if (_sqlType == Types.INTEGER) {
- int value;
- int maxVal;
-
- value = rs.getInt(1);
- stmt2.setInt(3, value);
- last = new Integer(value + 1);
- maxVal = value + _grabSizeI;
- max = new Integer(maxVal);
- stmt2.setInt(1, maxVal);
- } else if (_sqlType == Types.BIGINT) {
- long value;
- long maxVal;
-
- value = rs.getLong(1);
- stmt2.setLong(3, value);
- last = new Long(value + 1);
- maxVal = value + _grabSizeI;
- max = new Long(maxVal);
- stmt2.setLong(1, maxVal);
- } else {
- BigDecimal value;
- BigDecimal maxVal;
-
- value = rs.getBigDecimal(1);
- stmt2.setBigDecimal(3, value);
- last = value.add(ONE);
- maxVal = value.add(_grabSizeD);
- max = maxVal;
- stmt2.setBigDecimal(1, maxVal);
- }
- // For the case if the "SELECT FOR UPDATE" is not supported
- // we perform dirty checking
- success = (stmt2.executeUpdate() == 1);
- } else {
- // [Terry Child] Initialize the counter with MAX(pk) + 1
- // for the case of switching from some other key generator
- // to HIGH-LOW
- stmt.close();
- if (!_global) {
- String sqlStatement = JDBCSyntax.SELECT + "MAX(" + primKeyName + ") "
- + "FROM " + internalTableName;
- stmt = conn.prepareStatement(sqlStatement);
- rs = stmt.executeQuery();
- }
- if (_sqlType == Types.INTEGER) {
- int maxPK = 0;
-
- if (!_global && rs.next()) {
- maxPK = rs.getInt(1);
- }
- last = new Integer(maxPK + 1);
- max = new Integer(maxPK + _grabSizeI);
- } else if (_sqlType == Types.BIGINT) {
- long maxPK = 0;
-
- if (!_global && rs.next()) {
- maxPK = rs.getLong(1);
- }
- last = new Long(maxPK + 1);
- max = new Long(maxPK + _grabSizeI);
- } else {
- BigDecimal maxPK = null;
-
- if (!_global && rs.next()) {
- maxPK = rs.getBigDecimal(1);
- }
- if (maxPK == null) {
- maxPK = new BigDecimal(0);
- }
- last = maxPK.add(ONE);
- max = maxPK.add(_grabSizeD);
- }
- stmt2.close();
-
- String sqlStatement = "INSERT INTO " + _seqTable
- + " (" + _seqKey + "," + _seqValue + ") VALUES (?, ?)";
- stmt2 = conn.prepareStatement(sqlStatement);
- stmt2.setString(1, internalTableName);
- stmt2.setObject(2, max);
- stmt2.executeUpdate();
- success = true;
- }
- }
- if (!_sameConnection) {
- if (success) {
- conn.commit();
- } else {
- conn.rollback();
- }
- }
- if (!success) {
- throw new PersistenceException(Messages.format(
- "persist.keyGenFailed", getClass().getName()));
- }
- } catch (SQLException ex) {
- if (!_sameConnection) {
- try {
- conn.rollback();
- } catch (SQLException ex2) {
- _log.warn ("Problem rolling back JDBC transaction.", ex2);
- }
- }
- throw new PersistenceException(Messages.format(
- "persist.keyGenSQL", getClass().getName(), ex.toString()), ex);
- } finally {
- if (stmt != null) {
- try {
- stmt.close();
- } catch (SQLException ex) {
- _log.warn (Messages.message("persist.stClosingFailed"), ex);
- }
- }
- if (stmt2 != null) {
- try {
- stmt2.close();
- } catch (SQLException ex) {
- _log.warn (Messages.message("persist.stClosingFailed"), ex);
- }
- }
- }
- }
-
- if (_sqlType == Types.INTEGER) {
- inRange = (((Integer) last).intValue() < ((Integer) max).intValue());
- } else if (_sqlType == Types.BIGINT) {
- inRange = (((Long) last).longValue() < ((Long) max).longValue());
- } else {
- inRange = (((BigDecimal) last).compareTo((BigDecimal) max) < 0);
- }
-
- if (inRange) {
- _lastValues.put(internalTableName, last);
- _maxValues.put(internalTableName, max);
- } else {
- _lastValues.remove(internalTableName);
- _maxValues.remove(internalTableName);
- }
- return last;
- }
-
-
- /**
- * Style of key generator: BEFORE_INSERT, DURING_INSERT or AFTER_INSERT ?
- */
- public final byte getStyle() {
- return BEFORE_INSERT;
- }
-
-
- /**
- * Gives a possibility to patch the Castor-generated SQL statement
- * for INSERT (makes sense for DURING_INSERT key generators).
- */
- public final String patchSQL(final String insert, final String primKeyName) {
- return insert;
- }
-
-
- /**
- * Is key generated in the same connection as INSERT?
- */
- public final boolean isInSameConnection() {
- return _sameConnection;
- }
-
-}
-
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGeneratorFactory.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGeneratorFactory.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGeneratorFactory.java (working copy)
@@ -1,103 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.util.Properties;
-
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.KeyGeneratorFactory;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-
-/**
- * HIGH-LOW key generator factory.
- * The short name of this key generator is "HIGH-LOW".
- * It uses the following alrorithm: a special sequence table must be in
- * the database with keeps the maximum key values. The name of the
- * sequence table is a mandatory parameter of the key generator,
- * the parameter name is "table".
- * The name of the primary key column of the sequence table and
- * the name of the column in which maximum values are stored are
- * mandatory parameters with the names "key-column" and "value-column",
- * respectively. The key column contains table names, so it must be of
- * a character type (char or varchar). The value column contains primary key
- * values, it must be of a numeric type (numeric or int).
- * Key generator reads the maximum value X for the given table,
- * writes the new value (X + N) to the sequence table and during next N
- * calls returns values X + 1, ..., X + N without database access.
- * Number N (which sometimes is called "grab size") is an optional
- * parameter of the key generator, the parameter name is "grab-size",
- * default value is "1".
- * For example, if you want to obtain HIGH-LOW key generator with
- * 3 digits in the LOW part of the key, you should set "grab-size" to "1000".
- *
- * @author Oleg Nitz
- * @version $Revision$ $Date: 2005-06-01 06:08:22 -0600 (Wed, 01 Jun 2005) $
- * @see HighLowKeyGenerator
- */
-public final class HighLowKeyGeneratorFactory implements KeyGeneratorFactory {
- /**
- * Produce the key generator.
- * @param factory Helper object for obtaining database-specific QuerySyntax.
- * @param params Parameters for key generator.
- */
- public KeyGenerator getKeyGenerator(final PersistenceFactory factory,
- final Properties params, final int sqlType) throws MappingException {
-
- return new HighLowKeyGenerator(factory, params, sqlType);
- }
-
- /**
- * The short name of this key generator is "HIGH-LOW".
- */
- public String getName() {
- return "HIGH-LOW";
- }
-}
-
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGenerator.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGenerator.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGenerator.java (working copy)
@@ -1,248 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-package org.exolab.castor.jdo.keygen;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.castor.util.Messages;
-import org.exolab.castor.jdo.PersistenceException;
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-/**
- * IDENTITY key generator.
- * @author Oleg Nitz
- * @author Stein M. Hugubakken
- * @author Bruce Snyder
- * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
- * @see IdentityKeyGeneratorFactory
- */
-public final class IdentityKeyGenerator extends AbstractKeyGenerator {
- private abstract class IdentityKeyGenValueHandler extends AbstractKeyGenValueHandler {
- protected abstract Object getValue(Connection conn, String tableName) throws PersistenceException;
- }
-
- private class DefaultType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("SELECT @@identity", conn);
- }
- }
-
- private class DB2Type extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- // Statement worked with IBM UDB v7 and v8 but not with IBM DB2 v6.
- // StringBuffer buf = new StringBuffer("SELECT IDENTITY_VAL_LOCAL() FROM ");
- // buf.append(tableName).append(" FETCH FIRST ROW ONLY");
-
- // Statement works with IBM UDB and IBM DB2.
- StringBuffer buf = new StringBuffer();
- buf.append("SELECT IDENTITY_VAL_LOCAL() FROM sysibm.sysdummy1");
- return getValue(buf.toString(), conn);
- }
- }
-
- private class HsqlType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- PreparedStatement stmt = null;
- Object v = null;
- try {
- stmt = conn.prepareCall("{call IDENTITY()}");
- v = getValue(stmt);
- } catch (SQLException e) {
- String msg = Messages.format("persist.keyGenSQL", getClass().getName(), e.toString());
- throw new PersistenceException(msg);
- } finally {
- if (stmt != null) {
- try {
- stmt.close();
- } catch (SQLException ex) {
- _log.warn("Problem closing JDBCstatement", ex);
- }
- }
- }
- return v;
- }
- }
-
- private class InformixType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("select dbinfo('sqlca.sqlerrd1') from systables where tabid = 1", conn);
- }
- }
-
- private class MySqlType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("SELECT LAST_INSERT_ID()", conn);
- }
- }
-
- private class SapDbType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("SELECT " + tableName + ".currval" + " FROM " + tableName, conn);
- }
- }
-
- private class DerbyType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("SELECT IDENTITY_VAL_LOCAL() FROM " + tableName, conn);
- }
- }
-
- private class PostgresqlType extends IdentityKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName)
- throws PersistenceException {
- return getValue("SELECT currval ('" + tableName + "_id_seq')", conn);
- }
- }
-
- /**
- * The Jakarta
- * Commons Logging instance used for all logging.
- */
- private static Log _log = LogFactory.getFactory().getInstance(IdentityKeyGenerator.class);
-
- private IdentityKeyGenValueHandler _type = null;
-
- private String _fName = null;
-
- /**
- * Initialize the IDENTITY key generator.
- * @param factory A PersistenceFactory instance.
- * @param sqlType A SQLTypidentifier.
- * @throws MappingException if this key generator is not compatible with the
- * persistance factory.
- */
- public IdentityKeyGenerator(final PersistenceFactory factory, final int sqlType)
- throws MappingException {
- _fName = factory.getFactoryName();
-
- checkSupportedFactory(factory);
- supportsSqlType(sqlType);
- initIdentityValue(sqlType);
- initType(_fName);
- }
-
- public String[] getSupportedFactoryNames() {
- return new String[] {"sybase", "sql-server", "hsql", "mysql", "informix", "sapdb",
- "db2", "derby", "postgresql", "pointbase" };
- }
-
- /**
- * Determine if the key generator supports a given sql type.
- *
- * @param sqlType
- * @throws MappingException
- */
- public void supportsSqlType(final int sqlType) throws MappingException {
- if (sqlType != Types.INTEGER && sqlType != Types.NUMERIC
- && sqlType != Types.DECIMAL && sqlType != Types.BIGINT) {
- throw new MappingException(Messages.format(
- "mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)));
- }
-
- if (sqlType != Types.INTEGER && _fName.equals("hsql")) {
- throw new MappingException(Messages.format(
- "mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)));
- }
-
- if (sqlType != Types.NUMERIC && _fName.equals("derby")) {
- throw new MappingException(Messages.format(
- "mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)));
- }
- }
-
- private void initType(final String fName) {
- if (fName.equals("hsql")) {
- _type = new HsqlType();
- } else if (fName.equals("mysql")) {
- _type = new MySqlType();
- } else if (fName.equals("informix")) {
- _type = new InformixType();
- } else if (fName.equals("db2")) {
- _type = new DB2Type();
- } else if (fName.equals("sapdb")) {
- _type = new SapDbType();
- } else if (fName.equals("derby")) {
- _type = new DerbyType();
- } else if (fName.equals("postgresql")) {
- _type = new PostgresqlType();
- } else {
- _type = new DefaultType();
- }
- _type.setGenerator(this);
- _type.setIdentityValue(_identityValue);
- }
-
- /**
- * @param conn An open connection within the given transaction.
- * @param tableName The table name.
- * @param primKeyName The primary key name.
- * @param props A temporary replacement for Principal object.
- * @return A new key.
- * @throws PersistenceException An error occured talking to persistent storage.
- */
- public Object generateKey(final Connection conn, final String tableName,
- final String primKeyName, final Properties props) throws PersistenceException {
- try {
- return _type.getValue(conn, tableName);
- } catch (Exception e) {
- _log.error("Problem generating new key", e);
- return null;
- }
- }
-}
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGeneratorFactory.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGeneratorFactory.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityKeyGeneratorFactory.java (working copy)
@@ -1,87 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.util.Properties;
-
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.KeyGeneratorFactory;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-
-/**
- * IDENTITY key generator factory.
- * The short name of this key generator is "IDENTITY".
- * It works for Sybase and SQL Server identity (autoincrement) fields and
- * fetched @@identity after insert.
- *
- * @author Oleg Nitz
- * @version $Revision$ $Date: 2005-06-01 06:08:22 -0600 (Wed, 01 Jun 2005) $
- * @see IdentityKeyGenerator
- */
-public final class IdentityKeyGeneratorFactory implements KeyGeneratorFactory {
- /**
- * Produce the key generator.
- *
- * @param factory Helper object for obtaining database-specific QuerySyntax.
- * @param params Parameters for key generator.
- */
- public KeyGenerator getKeyGenerator(final PersistenceFactory factory,
- final Properties params, final int sqlType) throws MappingException {
-
- return new IdentityKeyGenerator(factory, sqlType);
- }
-
- /**
- * The short name of this key generator is "IDENTITY".
- */
- public String getName() {
- return "IDENTITY";
- }
-}
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityValue.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityValue.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/IdentityValue.java (working copy)
@@ -1,8 +0,0 @@
-package org.exolab.castor.jdo.keygen;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-public interface IdentityValue {
- Object getValue(ResultSet rs) throws SQLException;
-}
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGenerator.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGenerator.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGenerator.java (working copy)
@@ -1,225 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.math.BigDecimal;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Properties;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.castor.util.Messages;
-import org.exolab.castor.jdo.PersistenceException;
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-import org.exolab.castor.persist.spi.QueryExpression;
-
-/**
- * MAX key generator.
- * @author Oleg Nitz
- * @author Leonardo Souza Mario Bueno
- * @author Bruce Snyder
- * @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
- * @see MaxKeyGeneratorFactory
- */
-public final class MaxKeyGenerator implements KeyGenerator {
- /** The Jakarta
- * Commons Logging instance used for all logging. */
- private static Log _log = LogFactory.getFactory().getInstance(MaxKeyGenerator.class);
-
- private static final BigDecimal ONE = new BigDecimal(1);
-
- private final int _sqlType;
-
- private final PersistenceFactory _factory;
-
- /**
- * Initialize the MAX key generator.
- */
- public MaxKeyGenerator(final PersistenceFactory factory, final int sqlType)
- throws MappingException {
- _factory = factory;
- _sqlType = sqlType;
- supportsSqlType(sqlType);
- }
-
- /**
- * Determine if the key generator supports a given sql type.
- *
- * @param sqlType
- * @throws MappingException
- */
- public void supportsSqlType(final int sqlType) throws MappingException {
- if ((sqlType != Types.INTEGER) && (sqlType != Types.NUMERIC)
- && (sqlType != Types.DECIMAL) && (sqlType != Types.BIGINT)) {
- throw new MappingException(Messages.format(
- "mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)));
- }
- }
-
- /**
- * Generate a new key for the specified table as "MAX(primary_key) + 1".
- *
- * If there is no records in the table, then the value 1 is returned.
- *
- * @param conn An open connection within the given transaction
- * @param tableName The table name
- * @param primKeyName The primary key name
- * @param props A temporary replacement for Principal object
- * @return A new key
- * @throws PersistenceException An error occured talking to persistent
- * storage
- */
- public Object generateKey(final Connection conn, final String tableName,
- final String primKeyName, final Properties props) throws PersistenceException {
-
- String sql;
- PreparedStatement stmt = null;
- ResultSet rs;
- QueryExpression query;
- Object identity = null;
-
- try {
- query = _factory.getQueryExpression();
- if (_factory.getFactoryName().equals("mysql")) {
- // Create SQL sentence of the form
- // "SELECT MAX(pk) FROM table"
- query.addSelect("MAX(" + _factory.quoteName(primKeyName) + ")");
- query.addTable(tableName);
-
- // SELECT without lock
- sql = query.getStatement(false);
- } else {
- // Create SQL sentence of the form
- // "SELECT pk FROM table WHERE pk=(SELECT MAX(t1.pk) FROM table t1)"
- // with database-dependent keyword for lock
- query.addColumn(tableName, primKeyName);
- query.addCondition(tableName, primKeyName, QueryExpression.OP_EQUALS,
- "(SELECT MAX(t1." + _factory.quoteName(primKeyName) + ") FROM "
- + _factory.quoteName(tableName) + " t1)");
-
- // SELECT and put lock on the last record
- sql = query.getStatement(true);
- }
-
- stmt = conn.prepareStatement(sql);
- rs = stmt.executeQuery();
-
- if (rs.next()) {
- if (_sqlType == Types.INTEGER) {
- identity = new Integer(rs.getInt(1) + 1);
- } else if (_sqlType == Types.BIGINT) {
- identity = new Long(rs.getLong(1) + 1);
- } else {
- BigDecimal max = rs.getBigDecimal(1);
- if (max == null) {
- identity = ONE;
- } else {
- identity = max.add(ONE);
- }
- }
- } else {
- if (_sqlType == Types.INTEGER) {
- identity = new Integer(1);
- } else if (_sqlType == Types.BIGINT) {
- identity = new Long(1);
- } else {
- identity = ONE;
- }
- }
- } catch (SQLException ex) {
- throw new PersistenceException(Messages.format(
- "persist.keyGenSQL", getClass().getName(), ex.toString()), ex);
- } finally {
- if (stmt != null) {
- try {
- stmt.close();
- } catch (SQLException ex) {
- _log.warn (Messages.message ("persist.stClosingFailed"), ex);
- }
- }
- }
- if (identity == null) {
- throw new PersistenceException(Messages.format(
- "persist.keyGenOverflow", getClass().getName()));
- }
- return identity;
- }
-
-
- /**
- * Style of key generator: BEFORE_INSERT, DURING_INSERT or AFTER_INSERT ?
- */
- public byte getStyle() {
- return BEFORE_INSERT;
- }
-
-
- /**
- * Gives a possibility to patch the Castor-generated SQL statement
- * for INSERT (makes sense for DURING_INSERT key generators).
- */
- public String patchSQL(final String insert, final String primKeyName) {
- return insert;
- }
-
-
- /**
- * Is key generated in the same connection as INSERT?
- */
- public boolean isInSameConnection() {
- return true;
- }
-}
-
-
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGeneratorFactory.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGeneratorFactory.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/MaxKeyGeneratorFactory.java (working copy)
@@ -1,93 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.util.Properties;
-
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.KeyGeneratorFactory;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-
-/**
- * MAX key generator factory.
- * The short name of this key generator is "MAX".
- * It uses the following alrorithm: the maximum value of the primary
- * key is fetched and the correspondent record is locked until the end
- * of transaction, generator returns (max + 1).
- * The lock guarantees that key generators of concurrent transactions
- * will not use this key value, so DuplicateKeyException is impossible.
- * If the table is empty, generator returns 1, no lock is put,
- * DuplicateKeyException is possible.
- *
- * @author Oleg Nitz
- * @version $Revision$ $Date: 2005-06-01 06:08:22 -0600 (Wed, 01 Jun 2005) $
- * @see MaxKeyGenerator
- */
-public final class MaxKeyGeneratorFactory implements KeyGeneratorFactory {
- /**
- * Produce the key generator.
- *
- * @param factory Helper object for obtaining database-specific QuerySyntax.
- * @param params Parameters for key generator.
- */
- public KeyGenerator getKeyGenerator(final PersistenceFactory factory,
- final Properties params, final int sqlType) throws MappingException {
-
- return new MaxKeyGenerator(factory, sqlType);
- }
-
- /**
- * The short name of this key generator is "MAX".
- */
- public String getName() {
- return "MAX";
- }
-}
-
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGenerator.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGenerator.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGenerator.java (working copy)
@@ -1,312 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-package org.exolab.castor.jdo.keygen;
-
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.Types;
-import java.text.MessageFormat;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.castor.util.Messages;
-import org.exolab.castor.jdo.PersistenceException;
-import org.castor.cpa.persistence.sql.driver.DB2Factory;
-import org.castor.cpa.persistence.sql.driver.InterbaseFactory;
-import org.castor.cpa.persistence.sql.driver.OracleFactory;
-import org.castor.cpa.persistence.sql.driver.PostgreSQLFactory;
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-/**
- * SEQUENCE key generator.
- * @author Oleg Nitz
- * @author Bruce Snyder
- * @version $Revision$ $Date: 2006-04-13 06:47:36 -0600 (Thu, 13 Apr 2006) $
- * @see SequenceKeyGeneratorFactory
- */
-public final class SequenceKeyGenerator extends AbstractKeyGenerator {
- private abstract class SequenceKeyGenValueHandler extends AbstractKeyGenValueHandler {
- protected abstract Object getValue(Connection conn, String tableName,
- String primKeyName, Properties props) throws Exception;
- }
-
- private class DefaultType extends SequenceKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName,
- final String primKeyName, final Properties props) throws Exception {
- if (_style == BEFORE_INSERT) {
- return getValue("SELECT nextval('" + getSeqName(tableName, primKeyName) + "')", conn);
- } else if (_triggerPresent && _factoryName.equals("postgresql")) {
- Object insStmt = props.get("insertStatement");
- Class psqlStmtClass = Class.forName("org.postgresql.Statement");
- Method getInsertedOID = psqlStmtClass.getMethod("getInsertedOID", (Class[]) null);
- int insertedOID = ((Integer) getInsertedOID.invoke(insStmt, (Object[]) null)).intValue();
- PreparedStatement stmt = conn.prepareStatement(
- "SELECT " + _factory.quoteName(primKeyName)
- + " FROM " + _factory.quoteName(tableName) + " WHERE OID=?");
- stmt.setInt(1, insertedOID);
- return getValue(stmt);
- } else {
- return getValue(
- "SELECT " + _factory.quoteName(getSeqName(tableName, primKeyName) + ".currval")
- + " FROM " + _factory.quoteName(tableName), conn);
- }
- }
- }
-
- private class DB2Type extends SequenceKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName,
- final String primKeyName, final Properties props)
- throws PersistenceException {
- return getValue("SELECT nextval FOR " + getSeqName(tableName, primKeyName) + " FROM SYSIBM.SYSDUMMY1", conn);
- }
- }
-
- private class InterbaseType extends SequenceKeyGenValueHandler {
- protected Object getValue(final Connection conn, final String tableName,
- final String primKeyName, final Properties props)
- throws PersistenceException {
- // interbase only does before_insert, and does it its own way
- return getValue("SELECT gen_id(" + getSeqName(tableName, primKeyName) + "," + _increment + ") FROM rdb$database", conn);
- }
- }
-
- /** The Jakarta
- * Commons Logging instance used for all logging. */
- private static final Log LOG = LogFactory.getFactory().getInstance(SequenceKeyGenerator.class);
-
- private int _increment;
-
- private String _seqName;
-
- private boolean _triggerPresent;
-
- private SequenceKeyGenValueHandler _type = null;
-
- /**
- * Initialize the SEQUENCE key generator.
- */
- public SequenceKeyGenerator(final PersistenceFactory factory, final Properties params,
- final int sqlType) throws MappingException {
- checkSupportedFactory(factory);
- supportsSqlType(sqlType);
- initIdentityValue(sqlType);
- initType();
-
- boolean returning = "true".equals(params.getProperty("returning"));
- _triggerPresent = "true".equals(params.getProperty("trigger", "false"));
-
- if (!_factoryName.equals(OracleFactory.FACTORY_NAME) && returning) {
- throw new MappingException(Messages.format("mapping.keyGenParamNotCompat",
- "returning=\"true\"", getClass().getName(), _factoryName));
- }
-
- _factory = factory;
-
- _seqName = params.getProperty("sequence", "{0}_seq");
-
- _style = (_factoryName.equals(PostgreSQLFactory.FACTORY_NAME)
- || _factoryName.equals(InterbaseFactory.FACTORY_NAME)
- || _factoryName.equals(DB2Factory.FACTORY_NAME)
- ? BEFORE_INSERT : (returning ? DURING_INSERT : AFTER_INSERT));
- if (_triggerPresent && !returning) {
- _style = AFTER_INSERT;
- }
- if (_triggerPresent && _style == BEFORE_INSERT) {
- throw new MappingException(Messages.format("mapping.keyGenParamNotCompat",
- "trigger=\"true\"", getClass().getName(), _factoryName));
- }
-
- try {
- _increment = Integer.parseInt(params.getProperty("increment", "1"));
- } catch (NumberFormatException nfe) {
- _increment = 1;
- }
- }
-
- /**
- * Determine if the key generator supports a given sql type.
- *
- * @param sqlType
- * @throws MappingException
- */
- public void supportsSqlType(final int sqlType) throws MappingException {
- if (sqlType != Types.INTEGER
- && sqlType != Types.NUMERIC
- && sqlType != Types.DECIMAL
- && sqlType != Types.BIGINT
- && sqlType != Types.CHAR
- && sqlType != Types.VARCHAR) {
- throw new MappingException(Messages.format("mapping.keyGenSQLType",
- getClass().getName(), new Integer(sqlType)));
- }
- }
-
- private String getSeqName(final String tableName, final String primKeyName) {
- return MessageFormat.format(_seqName, new String[] {tableName, primKeyName});
- }
-
- public String[] getSupportedFactoryNames() {
- return new String[] {OracleFactory.FACTORY_NAME, PostgreSQLFactory.FACTORY_NAME,
- InterbaseFactory.FACTORY_NAME, "sapdb", DB2Factory.FACTORY_NAME};
- }
-
- private void initType() {
- if (_factoryName.equals("interbase")) {
- _type = new InterbaseType();
- } else if (_factoryName.equals("db2")) {
- _type = new DB2Type();
- } else {
- _type = new DefaultType();
- }
- _type.setGenerator(this);
- _type.setIdentityValue(_identityValue);
- }
-
- /**
- * @param conn An open connection within the given transaction.
- * @param tableName The table name.
- * @param primKeyName The primary key name.
- * @param props A temporary replacement for Principal object.
- * @return A new key.
- * @throws PersistenceException An error occured talking to persistent storage.
- */
- public Object generateKey(final Connection conn, final String tableName,
- final String primKeyName, final Properties props) throws PersistenceException {
- try {
- return _type.getValue(conn, tableName, primKeyName, props);
- } catch (Exception e) {
- LOG.error("Problem generating new key", e);
- throw new PersistenceException(Messages.format("persist.keyGenSQL", e));
- }
- }
-
- /**
- * Gives a possibility to patch the Castor-generated SQL statement
- * for INSERT (makes sense for DURING_INSERT key generators).
- */
- public String patchSQL(final String insert, final String primKeyName)
- throws MappingException {
- StringTokenizer st;
- String tableName;
- String seqName;
- String nextval;
- StringBuffer sb;
- int lp1; // the first left parenthesis, which starts fields list
- int lp2; // the second left parenthesis, which starts values list
-
- if (_style == BEFORE_INSERT) {
- return insert;
- }
-
- // First find the table name
- st = new StringTokenizer(insert);
- if (!st.hasMoreTokens() || !st.nextToken().equalsIgnoreCase("INSERT")) {
- throw new MappingException(Messages.format("mapping.keyGenCannotParse", insert));
- }
- if (!st.hasMoreTokens() || !st.nextToken().equalsIgnoreCase("INTO")) {
- throw new MappingException(Messages.format("mapping.keyGenCannotParse", insert));
- }
- if (!st.hasMoreTokens()) {
- throw new MappingException(Messages.format("mapping.keyGenCannotParse", insert));
- }
- tableName = st.nextToken();
-
- // remove every double quote in the tablename
- int idxQuote = tableName.indexOf('"');
- if (idxQuote >= 0) {
- StringBuffer buffer2 = new StringBuffer();
- int pos = 0;
-
- do {
- buffer2.append(tableName.substring(pos, idxQuote));
- pos = idxQuote + 1;
- idxQuote = tableName.indexOf('"', pos);
- } while (idxQuote != -1);
-
- buffer2.append(tableName.substring(pos));
-
- tableName = buffer2.toString();
- }
-
- // due to varargs in 1.5, see CASTOR-1097
- seqName = MessageFormat.format(_seqName, new Object[] {tableName, primKeyName});
- nextval = _factory.quoteName(seqName + ".nextval");
- lp1 = insert.indexOf('(');
- lp2 = insert.indexOf('(', lp1 + 1);
- if (lp1 < 0) {
- throw new MappingException(Messages.format("mapping.keyGenCannotParse", insert));
- }
- sb = new StringBuffer(insert);
- // if no onInsert triggers in the DB, we have to supply the Key values manually
- if (!_triggerPresent) {
- if (lp2 < 0) {
- // Only one pk field in the table, the INSERT statement would be
- // INSERT INTO table VALUES ()
- lp2 = lp1;
- lp1 = insert.indexOf(" VALUES ");
- // don't change the order of lines below,
- // otherwise index becomes invalid
- sb.insert(lp2 + 1, nextval);
- sb.insert(lp1 + 1, "(" + _factory.quoteName(primKeyName) + ") ");
- } else {
- // don't change the order of lines below,
- // otherwise index becomes invalid
- sb.insert(lp2 + 1, nextval + ",");
- sb.insert(lp1 + 1, _factory.quoteName(primKeyName) + ",");
- }
- }
- if (_style == DURING_INSERT) {
- // append 'RETURNING primKeyName INTO ?'
- sb.append(" RETURNING ");
- sb.append(_factory.quoteName(primKeyName));
- sb.append(" INTO ?");
- }
- return sb.toString();
- }
-}
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGeneratorFactory.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGeneratorFactory.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/SequenceKeyGeneratorFactory.java (working copy)
@@ -1,93 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- * $Id$
- */
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.util.Properties;
-
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.KeyGeneratorFactory;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-
-/**
- * SEQUENCE key generator factory.
- * The short name of this key generator is "SEQUENCE".
- * It uses Oracle/PostrgeSQL SEQUENCEs
- * There are two optional parameters for this key generator:
- * 1) name is "sequence" and the default value is "{0}_seq";
- * 2) name is "returning", values: "true"/"false", default is "false".
- * The latter parameter should be used only with Oracle8i, "true" value
- * turns on more efficient RETURNING syntax.
- * It is possible to use naming patterns like this for obtaining
- * SEQUENCE name by table name. This gives the possibility to use
- * one global key generator declaration rather than one per table.
- *
- * @author Oleg Nitz
- * @version $Revision$ $Date: 2005-06-01 06:08:22 -0600 (Wed, 01 Jun 2005) $
- * @see SequenceKeyGenerator
- */
-public final class SequenceKeyGeneratorFactory implements KeyGeneratorFactory {
- /**
- * Produce the key generator.
- *
- * @param factory Helper object for obtaining database-specific QuerySyntax.
- * @param params Parameters for key generator.
- */
- public KeyGenerator getKeyGenerator(final PersistenceFactory factory, final Properties params,
- final int sqlType) throws MappingException {
- return new SequenceKeyGenerator(factory, params, sqlType);
- }
-
- /**
- * The short name of this key generator is "SEQUENCE".
- */
- public String getName() {
- return "SEQUENCE";
- }
-}
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGenerator.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGenerator.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGenerator.java (working copy)
@@ -1,201 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- */
-
-/**
- * ----------------------------------------------
- * UUIDKeyGenerator
- * ----------------------------------------------
- * Developed by Publica Data-Service GmbH
- *
- * Team "New Projects" are:
- * Joerg Sailer, Martin Goettler, Andreas Grimme,
- * Thorsten Prix, Norbert Fuss, Thomas Fach
- *
- * Address:
- * Publica Data-Service GmbH
- * Steinerne Furt 72
- * 86167 Augsburg
- * Germany
- *
- * Internet: http://www.publica.de
- *
- * "live long and in prosper"
- * ----------------------------------------------
-**/
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.net.InetAddress;
-import java.sql.Connection;
-import java.sql.Types;
-import java.text.DecimalFormat;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.castor.util.Messages;
-import org.exolab.castor.jdo.PersistenceException;
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-/**
- * UUID key generator.
- * @author Thomas Fach
- * @author Bruce Snyder
- * @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
- * @see UUIDKeyGeneratorFactory
- */
-public final class UUIDKeyGenerator implements KeyGenerator {
- private DecimalFormat _df = new DecimalFormat();
-
- private String _sHost = null;
-
- private static long _staticCounter = 0;
-
- /**
- * Initialize the UUID key generator.
- */
- public UUIDKeyGenerator(final PersistenceFactory factory, final int sqlType)
- throws MappingException {
- supportsSqlType(sqlType);
- }
-
- /**
- * Determine if the key generator supports a given sql type.
- *
- * @param sqlType
- * @throws MappingException
- */
- public void supportsSqlType(final int sqlType) throws MappingException {
- if (sqlType != Types.CHAR && sqlType != Types.VARCHAR && sqlType != Types.LONGVARCHAR) {
- throw new MappingException(Messages.format("mapping.keyGenSQLType",
- getClass().getName(), new Integer(sqlType)));
- }
- }
-
- /**
- * Generate a new unique key for the specified table.
- *
- * @param conn An open connection within the given transaction
- * @param tableName The table name
- * @param primKeyName The primary key name
- * @param props A temporary replacement for Principal object
- * @return A new key
- * @throws PersistenceException An error occured talking to persistent
- * storage
- */
- public Object generateKey(final Connection conn, final String tableName,
- final String primKeyName, final Properties props) throws PersistenceException {
- String sUUID = null;
-
- try {
- // getting IP (fixed length: 12 character)
- if (_sHost == null) {
- _sHost = InetAddress.getLocalHost().getHostAddress();
- }
-
- StringTokenizer st = new StringTokenizer(_sHost, ".");
- _df.applyPattern("000");
- while (st.hasMoreTokens()) {
- if (sUUID == null) {
- sUUID = _df.format(new Integer(st.nextToken()));
- } else {
- sUUID += _df.format(new Integer(st.nextToken()));
- }
- }
-
- // getting currentTimeMillis (fixed length: 13 character)
- _df.applyPattern("0000000000000");
- sUUID += _df.format(System.currentTimeMillis());
-
- // getting static counter (fixed length: 15 character)
- if (_staticCounter >= 99999) {
- // 99999 generated keys in one timer interval? no...
- _staticCounter = 0;
- }
-
- _staticCounter++;
- _df.applyPattern("00000");
- sUUID += _df.format(_staticCounter);
- } catch (Exception ex) {
- throw new PersistenceException(Messages.format(
- "persist.keyGenSQL", getClass().getName(), ex.toString()), ex);
- }
-
- if (sUUID == null) {
- throw new PersistenceException(Messages.format(
- "persist.keyGenOverflow", getClass().getName()));
- }
-
- return sUUID;
- }
-
-
- /**
- * Style of key generator: BEFORE_INSERT, DURING_INSERT or AFTER_INSERT ?
- */
- public byte getStyle() {
- return BEFORE_INSERT;
- }
-
-
- /**
- * Gives a possibility to patch the Castor-generated SQL statement
- * for INSERT (makes sense for DURING_INSERT key generators).
- */
- public String patchSQL(final String insert, final String primKeyName) {
- return insert;
- }
-
-
- /**
- * Is key generated in the same connection as INSERT?
- */
- public boolean isInSameConnection() {
- return true;
- }
-
-}
\ No newline at end of file
Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGeneratorFactory.java
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGeneratorFactory.java (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/UUIDKeyGeneratorFactory.java (working copy)
@@ -1,115 +0,0 @@
-/**
- * Redistribution and use of this software and associated documentation
- * ("Software"), with or without modification, are permitted provided
- * that the following conditions are met:
- *
- * 1. Redistributions of source code must retain copyright
- * statements and notices. Redistributions must also contain a
- * copy of this document.
- *
- * 2. Redistributions in binary form must reproduce the
- * above copyright notice, this list of conditions and the
- * following disclaimer in the documentation and/or other
- * materials provided with the distribution.
- *
- * 3. The name "Exolab" must not be used to endorse or promote
- * products derived from this Software without prior written
- * permission of Intalio, Inc. For written permission,
- * please contact info@exolab.org.
- *
- * 4. Products derived from this Software may not be called "Exolab"
- * nor may "Exolab" appear in their names without prior written
- * permission of Intalio, Inc. Exolab is a registered
- * trademark of Intalio, Inc.
- *
- * 5. Due credit should be given to the Exolab Project
- * (http://www.exolab.org/).
- *
- * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
- * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
- *
- */
-
-/**
- * ----------------------------------------------
- * UUIDKeyGenerator
- * ----------------------------------------------
- * Developed by Publica Data-Service GmbH
- *
- * Team "New Projects" are:
- * Joerg Sailer, Martin Goettler, Andreas Grimme,
- * Thorsten Prix, Norbert Fuss, Thomas Fach
- *
- * Address:
- * Publica Data-Service GmbH
- * Steinerne Furt 72
- * 86167 Augsburg
- * Germany
- *
- * Internet: http://www.publica.de
- *
- * "live long and in prosper"
- * ----------------------------------------------
-**/
-
-
-package org.exolab.castor.jdo.keygen;
-
-
-import java.util.Properties;
-
-import org.exolab.castor.mapping.MappingException;
-import org.exolab.castor.persist.spi.KeyGenerator;
-import org.exolab.castor.persist.spi.KeyGeneratorFactory;
-import org.exolab.castor.persist.spi.PersistenceFactory;
-
-
-/**
- * UUID key generator factory.
- * The short name of this key generator is "UUID".
- * It uses the following alrorithm:
- * The uuid is a combination of the IP address, the current
- * time in milliseconds since 1970 and a static counter.
- * The complete key consists of a 30 character fixed length string.
- * Brief statement:
- * The ip only exists once during runtime of castor, the
- * current time in milliseconds (updated every 55 mills) is
- * in combination to the ip pretty unique. considering a static
- * counter will be used a database-wide unique key will be created.
- *
- * @author Thomas Fach
- * @version $Revision$ $Date: 2005-06-01 06:08:22 -0600 (Wed, 01 Jun 2005) $
- * @see UUIDKeyGenerator
- */
-public final class UUIDKeyGeneratorFactory implements KeyGeneratorFactory {
- /**
- * Produce the key generator.
- *
- * @param factory Helper object for obtaining database-specific QuerySyntax.
- * @param params Parameters for key generator.
- */
- public KeyGenerator getKeyGenerator(final PersistenceFactory factory,
- final Properties params, final int sqlType) throws MappingException {
- return new UUIDKeyGenerator(factory, sqlType);
- }
-
- /**
- * The short name of this key generator is "UUID".
- */
- public String getName() {
- return "UUID";
- }
-}
-
Index: /home/ralf/workspace/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties
===================================================================
--- /home/ralf/workspace/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties (revision 7612)
+++ /home/ralf/workspace/castor-1/cpa/src/main/resources/org/castor/cpa/castor.cpa.properties (working copy)
@@ -27,12 +27,12 @@
# List of key generator factories:
#
-org.exolab.castor.jdo.keyGeneratorFactories=\
- org.exolab.castor.jdo.keygen.MaxKeyGeneratorFactory,\
- org.exolab.castor.jdo.keygen.HighLowKeyGeneratorFactory,\
- org.exolab.castor.jdo.keygen.IdentityKeyGeneratorFactory,\
- org.exolab.castor.jdo.keygen.SequenceKeyGeneratorFactory,\
- org.exolab.castor.jdo.keygen.UUIDKeyGeneratorFactory
+org.castor.cpa.persistence.sql.keygen.factories=\
+ org.castor.cpa.persistence.sql.keygen.MaxKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.HighLowKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.IdentityKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.SequenceKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.UUIDKeyGeneratorFactory
# Configures the default time zone to apply to dates/times fetched from database
# fields (if not already part of the data). Specify same format as in
Index: /home/ralf/workspace/castor-1/src/doc/release-notes.xml
===================================================================
--- /home/ralf/workspace/castor-1/src/doc/release-notes.xml (revision 7612)
+++ /home/ralf/workspace/castor-1/src/doc/release-notes.xml (working copy)
@@ -76,8 +76,50 @@
org.castor.cpa.persistence.sql.driver.DerbyFactory,\
org.castor.cpa.persistence.sql.driver.PointbaseFactory,\
org.castor.cpa.persistence.sql.driver.ProgressFactory
+
+ Moved SQL keygenerators into new org.castor.cpa.persistence.sql.keygen package
+
+
+ As we had to change the package of the drivers in castor.properties anyway,
+ we also renamed the property that configures the classnames of the available
+ drivers from org.exolab.castor.jdo.keyGeneratorFactories to
+ org.castor.cpa.persistence.sql.keygen.factories.
+
+
+
+ The entry in properties file should now be:
+
+
+# List of key generator factories:
+#
+org.castor.cpa.persistence.sql.keygen.factories=\
+ org.castor.cpa.persistence.sql.keygen.MaxKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.HighLowKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.IdentityKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.SequenceKeyGeneratorFactory,\
+ org.castor.cpa.persistence.sql.keygen.UUIDKeyGeneratorFactory
+
+
+ Moved SQL keygenerators into new org.castor.cpa.persistence.sql.keygen package.
+
+
+ Ralf Joachim
+ ralf.joachim@syscon.eu
+
+
+ Ralf Joachim
+ ralf.joachim@syscon.eu
+
+
+ Ralf Joachim
+ ralf.joachim@syscon.eu
+
+ Enh.
+ JDO
+ 20080518
+
Created how to's for setting up Castor with eclipse and execution of JDO test suites.