Generalize the automatic key value generation code so that it works on any column, and on any number of columns within a record.
This commit is contained in:
@@ -22,6 +22,7 @@ package com.samskivert.jdbc.depot;
|
|||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.samskivert.jdbc.depot.Key.WhereCondition;
|
import com.samskivert.jdbc.depot.Key.WhereCondition;
|
||||||
import com.samskivert.jdbc.depot.clause.DeleteClause;
|
import com.samskivert.jdbc.depot.clause.DeleteClause;
|
||||||
@@ -240,9 +241,9 @@ public class BindVisitor implements ExpressionVisitor
|
|||||||
DepotMarshaller marsh = _types.getMarshaller(insertClause.getPersistentClass());
|
DepotMarshaller marsh = _types.getMarshaller(insertClause.getPersistentClass());
|
||||||
|
|
||||||
Object pojo = insertClause.getPojo();
|
Object pojo = insertClause.getPojo();
|
||||||
String ixField = insertClause.getIndexField();
|
Set<String> generatedFields = insertClause.getIdentityFields();
|
||||||
for (String field : marsh.getColumnFieldNames()) {
|
for (String field : marsh.getColumnFieldNames()) {
|
||||||
if (ixField == null || !ixField.equals(field)) {
|
if (!generatedFields.contains(field)) {
|
||||||
marsh.getFieldMarshaller(field).readFromObject(pojo, _stmt, _argIdx ++);
|
marsh.getFieldMarshaller(field).readFromObject(pojo, _stmt, _argIdx ++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.sql.SQLException;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.samskivert.jdbc.depot.Key.WhereCondition;
|
import com.samskivert.jdbc.depot.Key.WhereCondition;
|
||||||
import com.samskivert.jdbc.depot.annotation.Computed;
|
import com.samskivert.jdbc.depot.annotation.Computed;
|
||||||
@@ -450,12 +451,12 @@ public abstract class BuildVisitor implements ExpressionVisitor
|
|||||||
}
|
}
|
||||||
_builder.append(") values(");
|
_builder.append(") values(");
|
||||||
|
|
||||||
String ixField = insertClause.getIndexField();
|
Set<String> generatedFields = insertClause.getIdentityFields();
|
||||||
for (int ii = 0; ii < fields.length; ii++) {
|
for (int ii = 0; ii < fields.length; ii++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
_builder.append(", ");
|
_builder.append(", ");
|
||||||
}
|
}
|
||||||
if (ixField != null && ixField.equals(fields[ii])) {
|
if (generatedFields.contains(fields[ii])) {
|
||||||
_builder.append("DEFAULT");
|
_builder.append("DEFAULT");
|
||||||
} else {
|
} else {
|
||||||
_builder.append("?");
|
_builder.append("?");
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean seenIdentityGenerator = false;
|
||||||
|
|
||||||
// introspect on the class and create marshallers for persistent fields
|
// introspect on the class and create marshallers for persistent fields
|
||||||
ArrayList<String> fields = new ArrayList<String>();
|
ArrayList<String> fields = new ArrayList<String>();
|
||||||
for (Field field : _pclass.getFields()) {
|
for (Field field : _pclass.getFields()) {
|
||||||
@@ -136,38 +138,19 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
_pkColumns = new ArrayList<FieldMarshaller>();
|
_pkColumns = new ArrayList<FieldMarshaller>();
|
||||||
}
|
}
|
||||||
_pkColumns.add(fm);
|
_pkColumns.add(fm);
|
||||||
|
|
||||||
// check if this field defines a new TableGenerator
|
|
||||||
generator = field.getAnnotation(TableGenerator.class);
|
|
||||||
if (generator != null) {
|
|
||||||
context.tableGenerators.put(generator.name(), generator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the entity defines a single-columnar primary key, figure out if we will be generating
|
|
||||||
// values for it
|
|
||||||
if (_pkColumns != null) {
|
|
||||||
GeneratedValue gv = null;
|
|
||||||
FieldMarshaller keyField = null;
|
|
||||||
// loop over fields to see if there's a @GeneratedValue at all
|
|
||||||
for (FieldMarshaller field : _pkColumns) {
|
|
||||||
gv = field.getGeneratedValue();
|
|
||||||
if (gv != null) {
|
|
||||||
keyField = field;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyField != null) {
|
// check if this field defines a new TableGenerator
|
||||||
// and if there is, make sure we've a single-column id
|
generator = field.getAnnotation(TableGenerator.class);
|
||||||
if (_pkColumns.size() > 1) {
|
if (generator != null) {
|
||||||
throw new IllegalArgumentException(
|
context.tableGenerators.put(generator.name(), generator);
|
||||||
"Cannot use @GeneratedValue on multiple-column @Id's");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// the primary key must be numeric if we are to auto-assign it
|
// check if this field is auto-generated
|
||||||
Class<?> ftype = keyField.getField().getType();
|
GeneratedValue gv = fm.getGeneratedValue();
|
||||||
|
if (gv != null) {
|
||||||
|
// we can only do this on numeric fields
|
||||||
|
Class<?> ftype = field.getType();
|
||||||
boolean isNumeric = (
|
boolean isNumeric = (
|
||||||
ftype.equals(Byte.TYPE) || ftype.equals(Byte.class) ||
|
ftype.equals(Byte.TYPE) || ftype.equals(Byte.class) ||
|
||||||
ftype.equals(Short.TYPE) || ftype.equals(Short.class) ||
|
ftype.equals(Short.TYPE) || ftype.equals(Short.class) ||
|
||||||
@@ -175,14 +158,17 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
ftype.equals(Long.TYPE) || ftype.equals(Long.class));
|
ftype.equals(Long.TYPE) || ftype.equals(Long.class));
|
||||||
if (!isNumeric) {
|
if (!isNumeric) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Cannot use @GeneratedValue on non-numeric column");
|
"Cannot use @GeneratedValue on non-numeric column: " + field.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(gv.strategy()) {
|
switch(gv.strategy()) {
|
||||||
case AUTO:
|
case AUTO:
|
||||||
case IDENTITY:
|
case IDENTITY:
|
||||||
_keyGenerator = new IdentityKeyGenerator(
|
if (seenIdentityGenerator) {
|
||||||
gv, getTableName(), keyField.getColumnName());
|
throw new IllegalArgumentException(
|
||||||
|
"Persistent records can have at most one AUTO/IDENTITY generator.");
|
||||||
|
}
|
||||||
|
_valueGenerators.put(field.getName(), new IdentityValueGenerator(gv, this, fm));
|
||||||
|
seenIdentityGenerator = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TABLE:
|
case TABLE:
|
||||||
@@ -192,11 +178,12 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unknown generator [generator=" + name + "]");
|
"Unknown generator [generator=" + name + "]");
|
||||||
}
|
}
|
||||||
_keyGenerator = new TableKeyGenerator(
|
_valueGenerators.put(
|
||||||
generator, gv, getTableName(), keyField.getColumnName());
|
field.getName(), new TableValueGenerator(generator, gv, this, fm));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate our full list of fields/columns for use in queries
|
// generate our full list of fields/columns for use in queries
|
||||||
@@ -270,12 +257,12 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link KeyGenerator} used to generate primary keys for this persistent object,
|
* Returns the {@link ValueGenerator} used to generate primary keys for this persistent object,
|
||||||
* or null if it does not use a key generator.
|
* or null if it does not use a key generator.
|
||||||
*/
|
*/
|
||||||
public KeyGenerator getKeyGenerator ()
|
public Iterable<ValueGenerator> getValueGenerators ()
|
||||||
{
|
{
|
||||||
return _keyGenerator;
|
return _valueGenerators.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -435,37 +422,40 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills in the primary key just assigned to the supplied persistence object by the execution
|
* Go through the registered {@link ValueGenerator}s for our persistent object and run the
|
||||||
* of the results of {@link #createInsert}.
|
* ones that match the current postFactum phase, filling in the fields on the supplied object
|
||||||
|
* while we go. This method used to generate a key; that is now a separate step.
|
||||||
*
|
*
|
||||||
* @return the newly assigned primary key or null if the object does not use primary keys or
|
* The return value is only non-empty for the !postFactum phase, in which case it is a set
|
||||||
* this is not the right time to assign the key.
|
* of field names that are associated with {@link IdentityValueGenerator}, because these need
|
||||||
|
* special handling in the INSERT (specifically, 'DEFAULT' must be supplied as a value in
|
||||||
|
* the eventual SQL).
|
||||||
*/
|
*/
|
||||||
public Key assignPrimaryKey (
|
public Set<String> generateFieldValues (
|
||||||
Connection conn, DatabaseLiaison liaison, Object po, boolean postFactum)
|
Connection conn, DatabaseLiaison liaison, Object po, boolean postFactum)
|
||||||
throws SQLException
|
|
||||||
{
|
{
|
||||||
// if we have no primary key or no generator, then we're done
|
Set<String> idFields = new HashSet<String>();
|
||||||
if (!hasPrimaryKey() || _keyGenerator == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// run this generator either before or after the actual insertion
|
for (ValueGenerator vg : _valueGenerators.values()) {
|
||||||
if (_keyGenerator.isPostFactum() != postFactum) {
|
if (!postFactum && vg instanceof IdentityValueGenerator) {
|
||||||
return null;
|
idFields.add(vg.getFieldMarshaller().getField().getName());
|
||||||
}
|
}
|
||||||
|
if (vg.isPostFactum() != postFactum) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int nextValue = _keyGenerator.nextGeneratedValue(conn, liaison);
|
int nextValue = vg.nextGeneratedValue(conn, liaison);
|
||||||
_pkColumns.get(0).getField().set(po, nextValue);
|
vg.getFieldMarshaller().getField().set(po, nextValue);
|
||||||
return makePrimaryKey(nextValue);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String errmsg = "Failed to assign primary key [type=" + _pclass + "]";
|
throw new IllegalStateException(
|
||||||
throw (SQLException) new SQLException(errmsg).initCause(e);
|
"Failed to assign primary key [type=" + _pclass + "]", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return idFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called by the persistence context to register a migration for the entity managed by
|
* This is called by the persistence context to register a migration for the entity managed by
|
||||||
* this marshaller.
|
* this marshaller.
|
||||||
@@ -575,9 +565,9 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
getTableName() + "_" + idx.name(), idx.unique());
|
getTableName() + "_" + idx.name(), idx.unique());
|
||||||
}
|
}
|
||||||
|
|
||||||
// its key generator
|
// its value generators
|
||||||
if (_keyGenerator != null) {
|
for (ValueGenerator vg : _valueGenerators.values()) {
|
||||||
_keyGenerator.init(conn, liaison);
|
vg.init(conn, liaison);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and its full text search indexes
|
// and its full text search indexes
|
||||||
@@ -969,6 +959,9 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
/** The @Computed annotation of this entity, or null. */
|
/** The @Computed annotation of this entity, or null. */
|
||||||
protected Computed _computed;
|
protected Computed _computed;
|
||||||
|
|
||||||
|
/** A mapping of field names to value generators for that field. */
|
||||||
|
protected Map<String, ValueGenerator> _valueGenerators = new HashMap<String, ValueGenerator>();
|
||||||
|
|
||||||
/** A field marshaller for each persistent field in our object. */
|
/** A field marshaller for each persistent field in our object. */
|
||||||
protected Map<String, FieldMarshaller> _fields = new HashMap<String, FieldMarshaller>();
|
protected Map<String, FieldMarshaller> _fields = new HashMap<String, FieldMarshaller>();
|
||||||
|
|
||||||
@@ -976,9 +969,6 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
* define a primary key. */
|
* define a primary key. */
|
||||||
protected ArrayList<FieldMarshaller> _pkColumns;
|
protected ArrayList<FieldMarshaller> _pkColumns;
|
||||||
|
|
||||||
/** The generator to use for auto-generating primary key values, or null. */
|
|
||||||
protected KeyGenerator _keyGenerator;
|
|
||||||
|
|
||||||
/** The persisent fields of our object, in definition order. */
|
/** The persisent fields of our object, in definition order. */
|
||||||
protected String[] _allFields;
|
protected String[] _allFields;
|
||||||
|
|
||||||
@@ -999,4 +989,5 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
|
|
||||||
/** The name of the table we use to track schema versions. */
|
/** The name of the table we use to track schema versions. */
|
||||||
protected static final String SCHEMA_VERSION_TABLE = "DepotSchemaVersion";
|
protected static final String SCHEMA_VERSION_TABLE = "DepotSchemaVersion";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,10 +37,7 @@ import com.samskivert.jdbc.JDBCUtil;
|
|||||||
|
|
||||||
import com.samskivert.jdbc.depot.Modifier.*;
|
import com.samskivert.jdbc.depot.Modifier.*;
|
||||||
import com.samskivert.jdbc.depot.clause.DeleteClause;
|
import com.samskivert.jdbc.depot.clause.DeleteClause;
|
||||||
import com.samskivert.jdbc.depot.clause.FieldOverride;
|
|
||||||
import com.samskivert.jdbc.depot.clause.FromOverride;
|
|
||||||
import com.samskivert.jdbc.depot.clause.InsertClause;
|
import com.samskivert.jdbc.depot.clause.InsertClause;
|
||||||
import com.samskivert.jdbc.depot.clause.Join;
|
|
||||||
import com.samskivert.jdbc.depot.clause.QueryClause;
|
import com.samskivert.jdbc.depot.clause.QueryClause;
|
||||||
import com.samskivert.jdbc.depot.clause.UpdateClause;
|
import com.samskivert.jdbc.depot.clause.UpdateClause;
|
||||||
import com.samskivert.jdbc.depot.expression.SQLExpression;
|
import com.samskivert.jdbc.depot.expression.SQLExpression;
|
||||||
@@ -175,24 +172,26 @@ public abstract class DepotRepository
|
|||||||
// key will be null if record was supplied without a primary key
|
// key will be null if record was supplied without a primary key
|
||||||
return _ctx.invoke(new CachingModifier<T>(record, key, key) {
|
return _ctx.invoke(new CachingModifier<T>(record, key, key) {
|
||||||
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
public int invoke (Connection conn, DatabaseLiaison liaison) throws SQLException {
|
||||||
// update our modifier's key so that it can cache our results
|
// set any auto-generated column values
|
||||||
|
Set<String> identityFields = marsh.generateFieldValues(conn, liaison, _result, false);
|
||||||
|
|
||||||
|
// if needed, update our modifier's key so that it can cache our results
|
||||||
if (_key == null) {
|
if (_key == null) {
|
||||||
updateKey(marsh.assignPrimaryKey(conn, liaison, _result, false));
|
updateKey(marsh.getPrimaryKey(_result, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
String ixField = null;
|
builder.newQuery(new InsertClause<T>(pClass, _result, identityFields));
|
||||||
if (_key == null && marsh.hasPrimaryKey() && marsh.getKeyGenerator() != null &&
|
|
||||||
marsh.getKeyGenerator() instanceof IdentityKeyGenerator) {
|
|
||||||
ixField = ((IdentityKeyGenerator) marsh.getKeyGenerator()).getColumn();
|
|
||||||
}
|
|
||||||
builder.newQuery(new InsertClause<T>(pClass, _result, ixField));
|
|
||||||
|
|
||||||
PreparedStatement stmt = builder.prepare(conn);
|
PreparedStatement stmt = builder.prepare(conn);
|
||||||
try {
|
try {
|
||||||
int mods = stmt.executeUpdate();
|
int mods = stmt.executeUpdate();
|
||||||
// check again in case we have a post-factum key generator
|
|
||||||
|
// run any post-factum value generators
|
||||||
|
marsh.generateFieldValues(conn, liaison, _result, true);
|
||||||
|
|
||||||
|
// and check once more if a key now exists
|
||||||
if (_key == null) {
|
if (_key == null) {
|
||||||
updateKey(marsh.assignPrimaryKey(conn, liaison, _result, true));
|
updateKey(marsh.getPrimaryKey(_result, false));
|
||||||
}
|
}
|
||||||
return mods;
|
return mods;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -575,22 +574,25 @@ public abstract class DepotRepository
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the update modified zero rows or the primary key was obviously unset, do
|
// if the update modified zero rows or the primary key was obviously unset, do
|
||||||
// an insertion
|
// an insertion: first, set any auto-generated column values
|
||||||
|
Set<String> identityFields = marsh.generateFieldValues(conn, liaison, _result, false);
|
||||||
|
|
||||||
|
// update our modifier's key so that it can cache our results
|
||||||
if (_key == null) {
|
if (_key == null) {
|
||||||
updateKey(marsh.assignPrimaryKey(conn, liaison, _result, false));
|
updateKey(marsh.getPrimaryKey(_result, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
String ixField = null;
|
builder.newQuery(new InsertClause<T>(pClass, _result, identityFields));
|
||||||
if (_key == null && marsh.hasPrimaryKey() && marsh.getKeyGenerator() != null &&
|
|
||||||
marsh.getKeyGenerator() instanceof IdentityKeyGenerator) {
|
|
||||||
ixField = ((IdentityKeyGenerator) marsh.getKeyGenerator()).getColumn();
|
|
||||||
}
|
|
||||||
builder.newQuery(new InsertClause<T>(pClass, _result, ixField));
|
|
||||||
|
|
||||||
stmt = builder.prepare(conn);
|
stmt = builder.prepare(conn);
|
||||||
int mods = stmt.executeUpdate();
|
int mods = stmt.executeUpdate();
|
||||||
|
|
||||||
|
// run any post-factum value generators
|
||||||
|
marsh.generateFieldValues(conn, liaison, _result, true);
|
||||||
|
|
||||||
|
// and check once more if a key now exists
|
||||||
if (_key == null) {
|
if (_key == null) {
|
||||||
updateKey(marsh.assignPrimaryKey(conn, liaison, _result, true));
|
updateKey(marsh.getPrimaryKey(_result, false));
|
||||||
}
|
}
|
||||||
created[0] = true;
|
created[0] = true;
|
||||||
return mods;
|
return mods;
|
||||||
|
|||||||
@@ -222,10 +222,8 @@ public abstract class FieldMarshaller<T>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.getAnnotation(Id.class) != null) {
|
// figure out how we're going to generate our primary key values
|
||||||
// figure out how we're going to generate our primary key values
|
_generatedValue = field.getAnnotation(GeneratedValue.class);
|
||||||
_generatedValue = field.getAnnotation(GeneratedValue.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class BooleanMarshaller extends FieldMarshaller<Boolean> {
|
protected static class BooleanMarshaller extends FieldMarshaller<Boolean> {
|
||||||
|
|||||||
+7
-7
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// samskivert library - useful routines for java programs
|
// samskivert library - useful routines for java programs
|
||||||
// Copyright (C) 2006-2007 Michael Bayne, Pär Winzell
|
// Copyright (C) 2006-2007 Michael Bayne, Pär Winzell
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or modify it
|
// This library is free software; you can redistribute it and/or modify it
|
||||||
// under the terms of the GNU Lesser General Public License as published
|
// under the terms of the GNU Lesser General Public License as published
|
||||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||||
@@ -24,17 +24,16 @@ import java.sql.Connection;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
import com.samskivert.jdbc.DatabaseLiaison;
|
import com.samskivert.jdbc.DatabaseLiaison;
|
||||||
import com.samskivert.jdbc.LiaisonRegistry;
|
|
||||||
import com.samskivert.jdbc.depot.annotation.GeneratedValue;
|
import com.samskivert.jdbc.depot.annotation.GeneratedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates primary keys using an identity column.
|
* Generates primary keys using an identity column.
|
||||||
*/
|
*/
|
||||||
public class IdentityKeyGenerator extends KeyGenerator
|
public class IdentityValueGenerator extends ValueGenerator
|
||||||
{
|
{
|
||||||
public IdentityKeyGenerator (GeneratedValue gv, String table, String column)
|
public IdentityValueGenerator (GeneratedValue gv, DepotMarshaller dm, FieldMarshaller fm)
|
||||||
{
|
{
|
||||||
super(gv, table, column);
|
super(gv, dm, fm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from interface KeyGenerator
|
// from interface KeyGenerator
|
||||||
@@ -47,13 +46,14 @@ public class IdentityKeyGenerator extends KeyGenerator
|
|||||||
public void init (Connection conn, DatabaseLiaison liaison)
|
public void init (Connection conn, DatabaseLiaison liaison)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
liaison.initializeGenerator(conn, _table, _column, _initialValue, _allocationSize);
|
liaison.initializeGenerator(
|
||||||
|
conn, _dm.getTableName(), _fm.getColumnName(), _initialValue, _allocationSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// from interface KeyGenerator
|
// from interface KeyGenerator
|
||||||
public int nextGeneratedValue (Connection conn, DatabaseLiaison liaison)
|
public int nextGeneratedValue (Connection conn, DatabaseLiaison liaison)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
return liaison.lastInsertedId(conn, _table, _column);
|
return liaison.lastInsertedId(conn, _dm.getTableName(), _fm.getColumnName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-4
@@ -30,16 +30,15 @@ import com.samskivert.jdbc.depot.annotation.TableGenerator;
|
|||||||
|
|
||||||
import com.samskivert.jdbc.DatabaseLiaison;
|
import com.samskivert.jdbc.DatabaseLiaison;
|
||||||
import com.samskivert.jdbc.JDBCUtil;
|
import com.samskivert.jdbc.JDBCUtil;
|
||||||
import com.samskivert.jdbc.LiaisonRegistry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates primary keys using an external table .
|
* Generates primary keys using an external table .
|
||||||
*/
|
*/
|
||||||
public class TableKeyGenerator extends KeyGenerator
|
public class TableValueGenerator extends ValueGenerator
|
||||||
{
|
{
|
||||||
public TableKeyGenerator (TableGenerator tg, GeneratedValue gv, String table, String column)
|
public TableValueGenerator (TableGenerator tg, GeneratedValue gv, DepotMarshaller dm, FieldMarshaller fm)
|
||||||
{
|
{
|
||||||
super(gv, table, column);
|
super(gv, dm, fm);
|
||||||
_valueTable = defStr(tg.table(), "IdSequences");
|
_valueTable = defStr(tg.table(), "IdSequences");
|
||||||
_pkColumnName = defStr(tg.pkColumnName(), "sequence");
|
_pkColumnName = defStr(tg.pkColumnName(), "sequence");
|
||||||
_pkColumnValue = defStr(tg.pkColumnValue(), "default");
|
_pkColumnValue = defStr(tg.pkColumnValue(), "default");
|
||||||
+12
-17
@@ -27,16 +27,16 @@ import com.samskivert.jdbc.DatabaseLiaison;
|
|||||||
import com.samskivert.jdbc.depot.annotation.GeneratedValue;
|
import com.samskivert.jdbc.depot.annotation.GeneratedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the interface to our primary key generators.
|
* Defines the interface to our value generators.
|
||||||
*/
|
*/
|
||||||
public abstract class KeyGenerator
|
public abstract class ValueGenerator
|
||||||
{
|
{
|
||||||
public KeyGenerator (GeneratedValue gv, String table, String column)
|
public ValueGenerator (GeneratedValue gv, DepotMarshaller dm, FieldMarshaller fm)
|
||||||
{
|
{
|
||||||
_allocationSize = gv.allocationSize();
|
_allocationSize = gv.allocationSize();
|
||||||
_initialValue = gv.initialValue();
|
_initialValue = gv.initialValue();
|
||||||
_table = table;
|
_dm = dm;
|
||||||
_column = column;
|
_fm = fm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,24 +57,19 @@ public abstract class KeyGenerator
|
|||||||
public abstract int nextGeneratedValue (Connection conn, DatabaseLiaison liaison)
|
public abstract int nextGeneratedValue (Connection conn, DatabaseLiaison liaison)
|
||||||
throws SQLException;
|
throws SQLException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the table for which we're generating a key value.
|
public DepotMarshaller getDepotMarshaller ()
|
||||||
*/
|
|
||||||
public String getTable ()
|
|
||||||
{
|
{
|
||||||
return _table;
|
return _dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public FieldMarshaller getFieldMarshaller ()
|
||||||
* Returns the name of the column for which we're generating a key value.
|
|
||||||
*/
|
|
||||||
public String getColumn ()
|
|
||||||
{
|
{
|
||||||
return _column;
|
return _fm;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int _initialValue;
|
protected int _initialValue;
|
||||||
protected int _allocationSize;
|
protected int _allocationSize;
|
||||||
protected String _table;
|
protected DepotMarshaller _dm;
|
||||||
protected String _column;
|
protected FieldMarshaller _fm;
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
package com.samskivert.jdbc.depot.clause;
|
package com.samskivert.jdbc.depot.clause;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import com.samskivert.jdbc.depot.PersistentRecord;
|
import com.samskivert.jdbc.depot.PersistentRecord;
|
||||||
import com.samskivert.jdbc.depot.expression.ExpressionVisitor;
|
import com.samskivert.jdbc.depot.expression.ExpressionVisitor;
|
||||||
@@ -30,11 +31,12 @@ import com.samskivert.jdbc.depot.expression.ExpressionVisitor;
|
|||||||
*/
|
*/
|
||||||
public class InsertClause<T extends PersistentRecord> extends QueryClause
|
public class InsertClause<T extends PersistentRecord> extends QueryClause
|
||||||
{
|
{
|
||||||
public InsertClause (Class<? extends PersistentRecord> pClass, Object pojo, String ixField)
|
public InsertClause (
|
||||||
|
Class<? extends PersistentRecord> pClass, Object pojo, Set<String> identityFields)
|
||||||
{
|
{
|
||||||
_pClass = pClass;
|
_pClass = pClass;
|
||||||
_pojo = pojo;
|
_pojo = pojo;
|
||||||
_ixField = ixField;
|
_idFields = identityFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<? extends PersistentRecord> getPersistentClass ()
|
public Class<? extends PersistentRecord> getPersistentClass ()
|
||||||
@@ -47,9 +49,9 @@ public class InsertClause<T extends PersistentRecord> extends QueryClause
|
|||||||
return _pojo;
|
return _pojo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIndexField ()
|
public Set<String> getIdentityFields ()
|
||||||
{
|
{
|
||||||
return _ixField;
|
return _idFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from SQLExpression
|
// from SQLExpression
|
||||||
@@ -70,5 +72,5 @@ public class InsertClause<T extends PersistentRecord> extends QueryClause
|
|||||||
/** The object from which to fetch values, or null. */
|
/** The object from which to fetch values, or null. */
|
||||||
protected Object _pojo;
|
protected Object _pojo;
|
||||||
|
|
||||||
protected String _ixField;
|
protected Set<String> _idFields;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user