Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java =================================================================== --- /home/ralf/workspace/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java (revision 7612) +++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/castor/cpa/CPAConfiguration.java (working copy) @@ -145,10 +145,10 @@ public static final String DEFAULT_TIMEZONE = "org.exolab.castor.jdo.defaultTimeZone"; - /** Property listing all the available key genence - * factories. (org.exolab.castor.jdo.keyGeneratorFactories). */ + /** Property listing all the available key genence factories. + * (org.castor.cpa.persistence.sql.keygen.factories). */ public static final String KEYGENERATOR_FACTORIES = - "org.exolab.castor.jdo.keyGeneratorFactories"; + "org.castor.cpa.persistence.sql.keygen.factories"; /** Property name of LOB buffer size in castor.properties. */ public static final String LOB_BUFFER_SIZE = Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenerator.java =================================================================== --- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenerator.java (revision 7612) +++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenerator.java (working copy) @@ -1,115 +0,0 @@ -package org.exolab.castor.jdo.keygen; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import org.castor.util.Messages; -import org.exolab.castor.mapping.MappingException; -import org.exolab.castor.persist.spi.KeyGenerator; -import org.exolab.castor.persist.spi.PersistenceFactory; - -/** - * @author Stein M. Hugubakken - */ -public abstract class AbstractKeyGenerator implements KeyGenerator { - private abstract class AbstractIdentityValue implements IdentityValue { - public AbstractIdentityValue() { } - } - - private class BigDecimalIdentityValue extends AbstractIdentityValue { - public Object getValue(final ResultSet rs) throws SQLException { - return rs.getBigDecimal(1); - } - } - - private class IntegerIdentityValue extends AbstractIdentityValue { - public Object getValue(final ResultSet rs) throws SQLException { - return new Integer(rs.getInt(1)); - } - } - - private class LongIdentityValue extends AbstractIdentityValue { - public Object getValue(final ResultSet rs) throws SQLException { - return new Long(rs.getLong(1)); - } - } - - private class StringIdentityValue extends AbstractIdentityValue { - public Object getValue(final ResultSet rs) throws SQLException { - return rs.getString(1); - } - } - - protected PersistenceFactory _factory; - - protected String _factoryName; - - protected byte _style = AFTER_INSERT; - - protected IdentityValue _identityValue = null; - - protected void checkSupportedFactory(final PersistenceFactory factory) - throws MappingException { - _factoryName = factory.getFactoryName(); - String supportedFactoryNames[] = getSupportedFactoryNames(); - boolean supported = false; - for (int i = 0; i < supportedFactoryNames.length; i++) { - if (_factoryName.equals(supportedFactoryNames[i])) { - supported = true; - } - } - - if (!supported) { - String msg = Messages.format("mapping.keyGenNotCompatible", getClass().getName(), _factoryName); - throw new MappingException(msg); - } - } - - public void supportsSqlType(final int sqlType) throws MappingException { - if (sqlType != Types.INTEGER - && sqlType != Types.NUMERIC - && sqlType != Types.DECIMAL - && sqlType != Types.BIGINT) { - String msg = Messages.format("mapping.keyGenSQLType", getClass().getName(), new Integer(sqlType)); - throw new MappingException(msg); - } - } - - /** - * Style of key generator: BEFORE_INSERT, DURING_INSERT or AFTER_INSERT ? - */ - public byte getStyle() { - return _style; - } - - public abstract String[] getSupportedFactoryNames(); - - protected void initIdentityValue(final int sqlType) { - if (sqlType == Types.INTEGER) { - _identityValue = new IntegerIdentityValue(); - } else if (sqlType == Types.BIGINT) { - _identityValue = new LongIdentityValue(); - } else if ((sqlType == Types.CHAR) || (sqlType == Types.VARCHAR)) { - _identityValue = new StringIdentityValue(); - } else { - _identityValue = new BigDecimalIdentityValue(); - } - } - - /** - * Is key generated in the same connection as INSERT? Default is true. - */ - public boolean isInSameConnection() { - return true; - } - - /** - * 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 { - return insert; - } -} Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenValueHandler.java =================================================================== --- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenValueHandler.java (revision 7612) +++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/AbstractKeyGenValueHandler.java (working copy) @@ -1,56 +0,0 @@ -package org.exolab.castor.jdo.keygen; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.castor.util.Messages; -import org.exolab.castor.jdo.PersistenceException; -import org.exolab.castor.persist.spi.KeyGenerator; - -public abstract class AbstractKeyGenValueHandler { - private KeyGenerator _keyGenerator; - private IdentityValue _identityValue; - - AbstractKeyGenValueHandler() { } - - public Object getValue(final PreparedStatement stmt) - throws PersistenceException, SQLException { - ResultSet rs = stmt.executeQuery(); - if (rs.next()) { return _identityValue.getValue(rs); } - String msg = Messages.format("persist.keyGenFailed", _keyGenerator.getClass().getName()); - throw new PersistenceException(msg); - } - - public Object getValue(final String sql, final Connection conn) - throws PersistenceException { - PreparedStatement stmt = null; - try { - stmt = conn.prepareStatement(sql); - return getValue(stmt); - } catch (SQLException e) { - String msg = Messages.format("persist.keyGenSQL", - _keyGenerator.getClass().getName(), e.toString()); - throw new PersistenceException(msg); - } finally { - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException ex) { - ex.printStackTrace(); - } - } - } - } - - public void setGenerator(final KeyGenerator generator) { - _keyGenerator = generator; - } - - public void setIdentityValue(final IdentityValue identityValue) { - _identityValue = identityValue; - } -} - - Index: /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGenerator.java =================================================================== --- /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGenerator.java (revision 7612) +++ /home/ralf/workspace/castor-1/cpa/src/main/java/org/exolab/castor/jdo/keygen/HighLowKeyGenerator.java (working copy) @@ -1,427 +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.Hashtable; -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.jdo.engine.JDBCSyntax; -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; - -/** - * The parent abstract class for HIGH-LOW key generators. - * - * @author Oleg Nitz - * @author Bruce Snyder - * @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $ - * @see HighLowKeyGeneratorFactory - */ -public class HighLowKeyGenerator implements KeyGenerator { - /** - * The Jakarta - * Commons Logging instance used for all logging. - */ - private static Log _log = LogFactory.getFactory().getInstance(HighLowKeyGenerator.class); - - private static final BigDecimal ONE = new BigDecimal(1); - - private static final String SEQ_TABLE = "table"; - - private static final String SEQ_KEY = "key-column"; - - private static final String SEQ_VALUE = "value-column"; - - private static final String GRAB_SIZE = "grab-size"; - - private static final String SAME_CONNECTION = "same-connection"; - - private static final String GLOBAL = "global"; - - private final PersistenceFactory _factory; - - private final int _sqlType; - - // Sequence table name - private final String _seqTable; - - // Sequence table key column name - private final String _seqKey; - - // Sequence table value column name - private final String _seqValue; - - // grab size as int - private int _grabSizeI; - - // flag of use of the same connection - // (less efficient, but in EJB envirinment we have no choice for now) - private boolean _sameConnection; - - // grab size as BigDecimal - private BigDecimal _grabSizeD; - - // last generated values - private Hashtable _lastValues = new Hashtable(); - - // maximum possible values after which database operation is needed - private Hashtable _maxValues = new Hashtable(); - - // to generate globally unique identities - private boolean _global; - - - /** - * Initialize the HIGH-LOW key generator. - */ - public HighLowKeyGenerator(final PersistenceFactory factory, final Properties params, - final int sqlType) throws MappingException { - String factorStr; - - _factory = factory; - _sqlType = sqlType; - supportsSqlType(sqlType); - - _seqTable = params.getProperty(SEQ_TABLE); - if (_seqTable == null) { - throw new MappingException(Messages.format( - "mapping.KeyGenParamNotSet", SEQ_TABLE, getClass().getName())); - } - - _seqKey = params.getProperty(SEQ_KEY); - if (_seqKey == null) { - throw new MappingException(Messages.format( - "mapping.KeyGenParamNotSet", SEQ_KEY, getClass().getName())); - } - - _seqValue = params.getProperty(SEQ_VALUE); - if (_seqValue == null) { - throw new MappingException(Messages.format( - "mapping.KeyGenParamNotSet", SEQ_VALUE, getClass().getName())); - } - - factorStr = params.getProperty(GRAB_SIZE, "10"); - try { - _grabSizeI = Integer.parseInt(factorStr); - } catch (NumberFormatException except) { - _grabSizeI = 0; - } - if (_grabSizeI <= 0) { - throw new MappingException(Messages.format( - "mapping.wrongKeyGenParam", factorStr, GRAB_SIZE, getClass().getName())); - } - _grabSizeD = new BigDecimal(_grabSizeI); - _sameConnection = "true".equals(params.getProperty(SAME_CONNECTION)); - _global = "true".equals(params.getProperty(GLOBAL)); - } - - /** - * 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))); - } - } - - /** - * @param conn An open connection within the given transaction - * @param internalTableName 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 synchronized Object generateKey(final Connection conn, final String tableName, - final String primKeyName, final Properties props) throws PersistenceException { - Object last; - Object max; - boolean inRange; - - String internalTableName = tableName; - if (_global) { - internalTableName = ""; - } - 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.