No String[]. Use ColumnExp[] all the way down. Now that things are getting
tidier, it's a shame that ColumnExp is named as it is because really it's a FieldExp as it represents the name of the Java object field, not the actual name of the column which may be something different (if you use @Column(name="foo")). Maybe next time.
This commit is contained in:
@@ -513,8 +513,7 @@ public abstract class DepotRepository
|
|||||||
if (key == null) {
|
if (key == null) {
|
||||||
throw new IllegalArgumentException("Can't update record with null primary key.");
|
throw new IllegalArgumentException("Can't update record with null primary key.");
|
||||||
}
|
}
|
||||||
String[] fields = ColumnExp.toNames(modifiedFields);
|
return doUpdate(key, new UpdateClause(pClass, key, modifiedFields, record));
|
||||||
return doUpdate(key, new UpdateClause(pClass, key, fields, record));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -566,12 +565,12 @@ public abstract class DepotRepository
|
|||||||
key.validateQueryType(type); // and another
|
key.validateQueryType(type); // and another
|
||||||
|
|
||||||
// separate the arguments into keys and values
|
// separate the arguments into keys and values
|
||||||
final String[] fields = new String[fieldsValues.length/2];
|
final ColumnExp[] fields = new ColumnExp[fieldsValues.length/2];
|
||||||
final SQLExpression[] values = new SQLExpression[fields.length];
|
final SQLExpression[] values = new SQLExpression[fields.length];
|
||||||
for (int ii = 0, idx = 0; ii < fields.length; ii++) {
|
for (int ii = 0, idx = 0; ii < fields.length; ii++) {
|
||||||
fields[ii] = ((ColumnExp) fieldsValues[idx++]).name;
|
fields[ii] = (ColumnExp)fieldsValues[idx++];
|
||||||
if (fieldsValues[idx] instanceof SQLExpression) {
|
if (fieldsValues[idx] instanceof SQLExpression) {
|
||||||
values[ii] = (SQLExpression) fieldsValues[idx++];
|
values[ii] = (SQLExpression)fieldsValues[idx++];
|
||||||
} else {
|
} else {
|
||||||
values[ii] = new ValueExp(fieldsValues[idx++]);
|
values[ii] = new ValueExp(fieldsValues[idx++]);
|
||||||
}
|
}
|
||||||
@@ -639,11 +638,11 @@ public abstract class DepotRepository
|
|||||||
key.validateQueryType(type); // and another
|
key.validateQueryType(type); // and another
|
||||||
|
|
||||||
// separate the arguments into keys and values
|
// separate the arguments into keys and values
|
||||||
final String[] fields = new String[fieldsValues.size()];
|
final ColumnExp[] fields = new ColumnExp[fieldsValues.size()];
|
||||||
final SQLExpression[] values = new SQLExpression[fields.length];
|
final SQLExpression[] values = new SQLExpression[fields.length];
|
||||||
int ii = 0;
|
int ii = 0;
|
||||||
for (Map.Entry<ColumnExp, ? extends SQLExpression> entry : fieldsValues.entrySet()) {
|
for (Map.Entry<ColumnExp, ? extends SQLExpression> entry : fieldsValues.entrySet()) {
|
||||||
fields[ii] = entry.getKey().name;
|
fields[ii] = entry.getKey();
|
||||||
values[ii] = entry.getValue();
|
values[ii] = entry.getValue();
|
||||||
ii ++;
|
ii ++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,13 +111,13 @@ public class Key<T extends PersistentRecord> extends WhereClause
|
|||||||
_pClass = pClass;
|
_pClass = pClass;
|
||||||
|
|
||||||
// build a local map of field name -> field value
|
// build a local map of field name -> field value
|
||||||
Map<String, Comparable<?>> map = Maps.newHashMap();
|
Map<ColumnExp, Comparable<?>> map = Maps.newHashMap();
|
||||||
for (int i = 0; i < fields.length; i ++) {
|
for (int i = 0; i < fields.length; i ++) {
|
||||||
map.put(fields[i].name, values[i]);
|
map.put(fields[i], values[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// look up the cached primary key fields for this object
|
// look up the cached primary key fields for this object
|
||||||
String[] keyFields = DepotUtil.getKeyFields(pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
|
|
||||||
// now extract the values in field order and ensure none are extra or missing
|
// now extract the values in field order and ensure none are extra or missing
|
||||||
_values = new Comparable<?>[values.length];
|
_values = new Comparable<?>[values.length];
|
||||||
@@ -219,12 +219,12 @@ public class Key<T extends PersistentRecord> extends WhereClause
|
|||||||
*/
|
*/
|
||||||
public void toShortString (StringBuilder builder)
|
public void toShortString (StringBuilder builder)
|
||||||
{
|
{
|
||||||
String[] keyFields = DepotUtil.getKeyFields(_pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(_pClass);
|
||||||
for (int ii = 0; ii < keyFields.length; ii ++) {
|
for (int ii = 0; ii < keyFields.length; ii ++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
builder.append(":");
|
builder.append(":");
|
||||||
}
|
}
|
||||||
builder.append(keyFields[ii]).append("=").append(_values[ii]);
|
builder.append(keyFields[ii].name).append("=").append(_values[ii]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public abstract class KeySet<T extends PersistentRecord> extends WhereClause
|
|||||||
return new EmptyKeySet<T>(pClass);
|
return new EmptyKeySet<T>(pClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] keyFields = DepotUtil.getKeyFields(pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
if (keyFields.length == 1) {
|
if (keyFields.length == 1) {
|
||||||
Comparable<?> first = keys.iterator().next().getValues()[0];
|
Comparable<?> first = keys.iterator().next().getValues()[0];
|
||||||
Comparable<?>[] keyArray;
|
Comparable<?>[] keyArray;
|
||||||
@@ -100,7 +100,7 @@ public abstract class KeySet<T extends PersistentRecord> extends WhereClause
|
|||||||
public static <T extends PersistentRecord> KeySet<T> newSimpleKeySet (
|
public static <T extends PersistentRecord> KeySet<T> newSimpleKeySet (
|
||||||
Class<T> pClass, Collection<? extends Comparable<?>> keys)
|
Class<T> pClass, Collection<? extends Comparable<?>> keys)
|
||||||
{
|
{
|
||||||
String[] keyFields = DepotUtil.getKeyFields(pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
if (keyFields.length != 1) {
|
if (keyFields.length != 1) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Cannot create KeySet using simple keys for record with non-simple primary key " +
|
"Cannot create KeySet using simple keys for record with non-simple primary key " +
|
||||||
@@ -171,8 +171,7 @@ public abstract class KeySet<T extends PersistentRecord> extends WhereClause
|
|||||||
|
|
||||||
@Override public SQLExpression getWhereExpression () {
|
@Override public SQLExpression getWhereExpression () {
|
||||||
// Single-column keys result in the compact IN(keyVal1, keyVal2, ...)
|
// Single-column keys result in the compact IN(keyVal1, keyVal2, ...)
|
||||||
ColumnExp column = new ColumnExp(_pClass, DepotUtil.getKeyFields(_pClass)[0]);
|
return new In(DepotUtil.getKeyFields(_pClass)[0], _keys);
|
||||||
return new In(column, _keys);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// from Iterable<Key<T>>
|
// from Iterable<Key<T>>
|
||||||
|
|||||||
@@ -29,23 +29,34 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import com.samskivert.depot.PersistentRecord;
|
import com.samskivert.depot.PersistentRecord;
|
||||||
|
import com.samskivert.depot.expression.ColumnExp;
|
||||||
import com.samskivert.depot.impl.ExpressionVisitor;
|
import com.samskivert.depot.impl.ExpressionVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds actual SQL given a main persistent type and some {@link QueryClause} objects.
|
* Represents a complete select clause.
|
||||||
*/
|
*/
|
||||||
public class SelectClause implements QueryClause
|
public class SelectClause
|
||||||
|
implements QueryClause
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Creates a new Query object to generate one or more instances of the specified persistent
|
* Creates a new select clause, selecting the supplied columns from the specified persistent
|
||||||
* class, as dictated by the key and query clauses. A persistence context is supplied for
|
* class for rows that match the supplied clauses.
|
||||||
* instantiation of marshallers, which may trigger table creations and schema migrations.
|
|
||||||
*/
|
*/
|
||||||
public SelectClause (Class<? extends PersistentRecord> pClass, String[] fields,
|
public SelectClause (Class<? extends PersistentRecord> pClass,
|
||||||
|
ColumnExp[] columns, QueryClause... clauses)
|
||||||
|
{
|
||||||
|
this(pClass, columns, Arrays.asList(clauses));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new select clause, selecting the supplied columns from the specified persistent
|
||||||
|
* class for rows that match the supplied clauses.
|
||||||
|
*/
|
||||||
|
public SelectClause (Class<? extends PersistentRecord> pClass, ColumnExp[] columns,
|
||||||
Collection<? extends QueryClause> clauses)
|
Collection<? extends QueryClause> clauses)
|
||||||
{
|
{
|
||||||
_pClass = pClass;
|
_pClass = pClass;
|
||||||
_fields = fields;
|
_fields = columns;
|
||||||
|
|
||||||
// iterate over the clauses and sort them into the different types we understand
|
// iterate over the clauses and sort them into the different types we understand
|
||||||
for (QueryClause clause : clauses) {
|
for (QueryClause clause : clauses) {
|
||||||
@@ -107,15 +118,6 @@ public class SelectClause implements QueryClause
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A varargs version of the constructor.
|
|
||||||
*/
|
|
||||||
public SelectClause (Class<? extends PersistentRecord> pClass,
|
|
||||||
String[] fields, QueryClause... clauses)
|
|
||||||
{
|
|
||||||
this(pClass, fields, Arrays.asList(clauses));
|
|
||||||
}
|
|
||||||
|
|
||||||
public FieldDefinition lookupDefinition (String field)
|
public FieldDefinition lookupDefinition (String field)
|
||||||
{
|
{
|
||||||
return _disMap.get(field);
|
return _disMap.get(field);
|
||||||
@@ -131,7 +133,7 @@ public class SelectClause implements QueryClause
|
|||||||
return _pClass;
|
return _pClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getFields ()
|
public ColumnExp[] getFields ()
|
||||||
{
|
{
|
||||||
return _fields;
|
return _fields;
|
||||||
}
|
}
|
||||||
@@ -229,7 +231,7 @@ public class SelectClause implements QueryClause
|
|||||||
protected Class<? extends PersistentRecord> _pClass;
|
protected Class<? extends PersistentRecord> _pClass;
|
||||||
|
|
||||||
/** The persistent fields to select. */
|
/** The persistent fields to select. */
|
||||||
protected String[] _fields;
|
protected ColumnExp[] _fields;
|
||||||
|
|
||||||
/** The from override clause, if any. */
|
/** The from override clause, if any. */
|
||||||
protected FromOverride _fromOverride;
|
protected FromOverride _fromOverride;
|
||||||
|
|||||||
@@ -34,16 +34,6 @@ public class ColumnExp
|
|||||||
/** The name of the column we reference. */
|
/** The name of the column we reference. */
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
/** Converts an array of column expressions to an array of just the bare names. */
|
|
||||||
public static String[] toNames (ColumnExp[] columns)
|
|
||||||
{
|
|
||||||
String[] names = new String[columns.length];
|
|
||||||
for (int ii = 0; ii < names.length; ii++) {
|
|
||||||
names[ii] = columns[ii].name;
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ColumnExp (Class<? extends PersistentRecord> pClass, String field)
|
public ColumnExp (Class<? extends PersistentRecord> pClass, String field)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
@@ -78,9 +68,18 @@ public class ColumnExp
|
|||||||
return _pClass;
|
return _pClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getField ()
|
@Override // from Object
|
||||||
|
public int hashCode ()
|
||||||
{
|
{
|
||||||
return name;
|
return _pClass.hashCode() ^ this.name.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override // from Object
|
||||||
|
public boolean equals (Object other)
|
||||||
|
{
|
||||||
|
return (other instanceof ColumnExp) &&
|
||||||
|
((ColumnExp)other)._pClass.equals(_pClass) &&
|
||||||
|
((ColumnExp)other).name.equals(this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // from Object
|
@Override // from Object
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
public Void visit (Key.Expression key)
|
public Void visit (Key.Expression key)
|
||||||
{
|
{
|
||||||
Class<? extends PersistentRecord> pClass = key.getPersistentClass();
|
Class<? extends PersistentRecord> pClass = key.getPersistentClass();
|
||||||
String[] keyFields = DepotUtil.getKeyFields(pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
Comparable<?>[] values = key.getValues();
|
Comparable<?>[] values = key.getValues();
|
||||||
for (int ii = 0; ii < keyFields.length; ii ++) {
|
for (int ii = 0; ii < keyFields.length; ii ++) {
|
||||||
if (ii > 0) {
|
if (ii > 0) {
|
||||||
@@ -233,7 +233,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
|
|
||||||
public Void visit (ColumnExp columnExp)
|
public Void visit (ColumnExp columnExp)
|
||||||
{
|
{
|
||||||
appendRhsColumn(columnExp.getPersistentClass(), columnExp.getField());
|
appendRhsColumn(columnExp.getPersistentClass(), columnExp);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
// while expanding column names in the SELECT query, do aliasing and expansion
|
// while expanding column names in the SELECT query, do aliasing and expansion
|
||||||
_enableAliasing = _enableOverrides = true;
|
_enableAliasing = _enableOverrides = true;
|
||||||
|
|
||||||
for (String field : selectClause.getFields()) {
|
for (ColumnExp field : selectClause.getFields()) {
|
||||||
// write column to a temporary buffer
|
// write column to a temporary buffer
|
||||||
StringBuilder saved = _builder;
|
StringBuilder saved = _builder;
|
||||||
_builder = new StringBuilder();
|
_builder = new StringBuilder();
|
||||||
@@ -447,7 +447,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
appendTableAbbreviation(pClass);
|
appendTableAbbreviation(pClass);
|
||||||
_builder.append(" set ");
|
_builder.append(" set ");
|
||||||
|
|
||||||
String[] fields = updateClause.getFields();
|
ColumnExp[] fields = updateClause.getFields();
|
||||||
Object pojo = updateClause.getPojo();
|
Object pojo = updateClause.getPojo();
|
||||||
SQLExpression[] values = updateClause.getValues();
|
SQLExpression[] values = updateClause.getValues();
|
||||||
for (int ii = 0; ii < fields.length; ii ++) {
|
for (int ii = 0; ii < fields.length; ii ++) {
|
||||||
@@ -487,15 +487,15 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
_innerClause = true;
|
_innerClause = true;
|
||||||
|
|
||||||
Set<String> idFields = insertClause.getIdentityFields();
|
Set<String> idFields = insertClause.getIdentityFields();
|
||||||
String[] fields = marsh.getColumnFieldNames();
|
ColumnExp[] fields = marsh.getColumnFieldNames();
|
||||||
|
|
||||||
_builder.append("insert into ");
|
_builder.append("insert into ");
|
||||||
appendTableName(insertClause.getPersistentClass());
|
appendTableName(insertClause.getPersistentClass());
|
||||||
_builder.append(" (");
|
_builder.append(" (");
|
||||||
|
|
||||||
boolean comma = false;
|
boolean comma = false;
|
||||||
for (String field : fields) {
|
for (ColumnExp field : fields) {
|
||||||
if (idFields.contains(field)) {
|
if (idFields.contains(field.name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (comma) {
|
if (comma) {
|
||||||
@@ -507,8 +507,8 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
_builder.append(") values (");
|
_builder.append(") values (");
|
||||||
|
|
||||||
comma = false;
|
comma = false;
|
||||||
for (String field : fields) {
|
for (ColumnExp field : fields) {
|
||||||
if (idFields.contains(field)) {
|
if (idFields.contains(field.name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (comma) {
|
if (comma) {
|
||||||
@@ -568,10 +568,10 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
_builder.append("?");
|
_builder.append("?");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bindField (Class<? extends PersistentRecord> pClass, String field, Object pojo)
|
protected void bindField (
|
||||||
|
Class<? extends PersistentRecord> pClass, ColumnExp field, Object pojo)
|
||||||
{
|
{
|
||||||
final DepotMarshaller<?> marshaller = _types.getMarshaller(pClass);
|
final DepotMarshaller<?> marshaller = _types.getMarshaller(pClass);
|
||||||
|
|
||||||
_bindables.add(newBindable(marshaller, field, pojo));
|
_bindables.add(newBindable(marshaller, field, pojo));
|
||||||
_builder.append("?");
|
_builder.append("?");
|
||||||
}
|
}
|
||||||
@@ -592,21 +592,22 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
// equivalent of an lvalue; something that can appear to the left of an equals sign.
|
// equivalent of an lvalue; something that can appear to the left of an equals sign.
|
||||||
// We do not prepend this identifier with a table abbreviation, nor do we expand
|
// We do not prepend this identifier with a table abbreviation, nor do we expand
|
||||||
// field overrides, shadowOf declarations, or the like: it is just a column name.
|
// field overrides, shadowOf declarations, or the like: it is just a column name.
|
||||||
protected void appendLhsColumn (Class<? extends PersistentRecord> type, String field)
|
protected void appendLhsColumn (Class<? extends PersistentRecord> type, ColumnExp field)
|
||||||
{
|
{
|
||||||
|
// TODO: nix type and use the class from the supplied ColumnExp
|
||||||
DepotMarshaller<?> dm = _types.getMarshaller(type);
|
DepotMarshaller<?> dm = _types.getMarshaller(type);
|
||||||
if (dm == null) {
|
if (dm == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unknown field on persistent record [record=" + type + ", field=" + field + "]");
|
"Unknown field on persistent record [record=" + type + ", field=" + field + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldMarshaller<?> fm = dm.getFieldMarshaller(field);
|
FieldMarshaller<?> fm = dm.getFieldMarshaller(field.name);
|
||||||
appendIdentifier(fm.getColumnName());
|
appendIdentifier(fm.getColumnName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appends an expression for the given field on the given persistent record; this can
|
// Appends an expression for the given field on the given persistent record; this can
|
||||||
// appear in a SELECT list, in WHERE clauses, etc, etc.
|
// appear in a SELECT list, in WHERE clauses, etc, etc.
|
||||||
protected void appendRhsColumn (Class<? extends PersistentRecord> type, String field)
|
protected void appendRhsColumn (Class<? extends PersistentRecord> type, ColumnExp field)
|
||||||
{
|
{
|
||||||
DepotMarshaller<?> dm = _types.getMarshaller(type);
|
DepotMarshaller<?> dm = _types.getMarshaller(type);
|
||||||
if (dm == null) {
|
if (dm == null) {
|
||||||
@@ -615,7 +616,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// first, see if there's a field definition
|
// first, see if there's a field definition
|
||||||
FieldMarshaller<?> fm = dm.getFieldMarshaller(field);
|
FieldMarshaller<?> fm = dm.getFieldMarshaller(field.name);
|
||||||
Map<String, FieldDefinition> fieldDefs = _definitions.get(type);
|
Map<String, FieldDefinition> fieldDefs = _definitions.get(type);
|
||||||
if (fieldDefs != null) {
|
if (fieldDefs != null) {
|
||||||
FieldDefinition fieldDef = fieldDefs.get(field);
|
FieldDefinition fieldDef = fieldDefs.get(field);
|
||||||
@@ -670,7 +671,7 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
_builder.append(fieldComputed.fieldDefinition());
|
_builder.append(fieldComputed.fieldDefinition());
|
||||||
if (_enableAliasing) {
|
if (_enableAliasing) {
|
||||||
_builder.append(" as ");
|
_builder.append(" as ");
|
||||||
appendIdentifier(field);
|
appendIdentifier(field.name);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -715,40 +716,18 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
_types = types;
|
_types = types;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DepotTypes _types;
|
|
||||||
|
|
||||||
/** For each SQL parameter ? we add an {@link Comparable} to bind to this list. */
|
|
||||||
protected List<Bindable> _bindables = Lists.newLinkedList();
|
|
||||||
|
|
||||||
/** A StringBuilder to hold the constructed SQL. */
|
|
||||||
protected StringBuilder _builder = new StringBuilder();
|
|
||||||
|
|
||||||
/** A mapping of field overrides per persistent record. */
|
|
||||||
protected Map<Class<? extends PersistentRecord>, Map<String, FieldDefinition>> _definitions=
|
|
||||||
Maps.newHashMap();
|
|
||||||
|
|
||||||
/** Set this to non-null to suppress table abbreviations from being prepended for a class. */
|
|
||||||
protected Class<? extends PersistentRecord> _defaultType;
|
|
||||||
|
|
||||||
/** A flag that's set to true for inner SELECT's */
|
|
||||||
protected boolean _innerClause = false;
|
|
||||||
|
|
||||||
protected boolean _enableOverrides = false;
|
|
||||||
|
|
||||||
protected boolean _enableAliasing = false;
|
|
||||||
|
|
||||||
protected static interface Bindable
|
protected static interface Bindable
|
||||||
{
|
{
|
||||||
void doBind (Connection conn, PreparedStatement stmt, int argIx) throws Exception;
|
void doBind (Connection conn, PreparedStatement stmt, int argIx) throws Exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Bindable newBindable (
|
protected static Bindable newBindable (
|
||||||
final DepotMarshaller<?> marshaller, final String field, final Object pojo)
|
final DepotMarshaller<?> marshaller, final ColumnExp field, final Object pojo)
|
||||||
{
|
{
|
||||||
return new Bindable() {
|
return new Bindable() {
|
||||||
public void doBind (Connection conn, PreparedStatement stmt, int argIx)
|
public void doBind (Connection conn, PreparedStatement stmt, int argIx)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
marshaller.getFieldMarshaller(field).getAndWriteToStatement(stmt, argIx, pojo);
|
marshaller.getFieldMarshaller(field.name).getAndWriteToStatement(stmt, argIx, pojo);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -774,4 +753,24 @@ public abstract class BuildVisitor implements ExpressionVisitor<Void>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected DepotTypes _types;
|
||||||
|
|
||||||
|
/** For each SQL parameter ? we add an {@link Comparable} to bind to this list. */
|
||||||
|
protected List<Bindable> _bindables = Lists.newLinkedList();
|
||||||
|
|
||||||
|
/** A StringBuilder to hold the constructed SQL. */
|
||||||
|
protected StringBuilder _builder = new StringBuilder();
|
||||||
|
|
||||||
|
/** A mapping of field overrides per persistent record. */
|
||||||
|
protected Map<Class<? extends PersistentRecord>, Map<String, FieldDefinition>> _definitions=
|
||||||
|
Maps.newHashMap();
|
||||||
|
|
||||||
|
/** Set this to non-null to suppress table abbreviations from being prepended for a class. */
|
||||||
|
protected Class<? extends PersistentRecord> _defaultType;
|
||||||
|
|
||||||
|
/** A flag that's set to true for inner SELECT's */
|
||||||
|
protected boolean _innerClause = false;
|
||||||
|
protected boolean _enableOverrides = false;
|
||||||
|
protected boolean _enableAliasing = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
boolean seenIdentityGenerator = false;
|
boolean seenIdentityGenerator = false;
|
||||||
|
|
||||||
// introspect on the class and create marshallers for persistent fields
|
// introspect on the class and create marshallers for persistent fields
|
||||||
List<String> fields = Lists.newArrayList();
|
List<ColumnExp> fields = Lists.newArrayList();
|
||||||
for (Field field : _pClass.getFields()) {
|
for (Field field : _pClass.getFields()) {
|
||||||
int mods = field.getModifiers();
|
int mods = field.getModifiers();
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
|
|
||||||
FieldMarshaller<?> fm = FieldMarshaller.createMarshaller(field);
|
FieldMarshaller<?> fm = FieldMarshaller.createMarshaller(field);
|
||||||
_fields.put(field.getName(), fm);
|
_fields.put(field.getName(), fm);
|
||||||
fields.add(field.getName());
|
fields.add(new ColumnExp(_pClass, field.getName()));
|
||||||
|
|
||||||
// check to see if this is our primary key
|
// check to see if this is our primary key
|
||||||
if (field.getAnnotation(Id.class) != null) {
|
if (field.getAnnotation(Id.class) != null) {
|
||||||
@@ -220,7 +220,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generate our full list of fields/columns for use in queries
|
// generate our full list of fields/columns for use in queries
|
||||||
_allFields = fields.toArray(new String[fields.size()]);
|
_allFields = fields.toArray(new ColumnExp[fields.size()]);
|
||||||
|
|
||||||
// now check for @Entity annotations on the entire superclass chain
|
// now check for @Entity annotations on the entire superclass chain
|
||||||
Class<? extends PersistentRecord> iterClass = pClass.asSubclass(PersistentRecord.class);
|
Class<? extends PersistentRecord> iterClass = pClass.asSubclass(PersistentRecord.class);
|
||||||
@@ -291,7 +291,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
/**
|
/**
|
||||||
* Returns all the persistent fields of our class, in definition order.
|
* Returns all the persistent fields of our class, in definition order.
|
||||||
*/
|
*/
|
||||||
public String[] getFieldNames ()
|
public ColumnExp[] getFieldNames ()
|
||||||
{
|
{
|
||||||
return _allFields;
|
return _allFields;
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
/**
|
/**
|
||||||
* Returns all the persistent fields that correspond to concrete table columns.
|
* Returns all the persistent fields that correspond to concrete table columns.
|
||||||
*/
|
*/
|
||||||
public String[] getColumnFieldNames ()
|
public ColumnExp[] getColumnFieldNames ()
|
||||||
{
|
{
|
||||||
return _columnFields;
|
return _columnFields;
|
||||||
}
|
}
|
||||||
@@ -349,11 +349,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
* Return the names of the columns that constitute the primary key of our associated persistent
|
* Return the names of the columns that constitute the primary key of our associated persistent
|
||||||
* record.
|
* record.
|
||||||
*/
|
*/
|
||||||
public String[] getPrimaryKeyFields ()
|
public ColumnExp[] getPrimaryKeyFields ()
|
||||||
{
|
{
|
||||||
String[] pkcols = new String[_pkColumns.size()];
|
ColumnExp[] pkcols = new ColumnExp[_pkColumns.size()];
|
||||||
for (int ii = 0; ii < pkcols.length; ii ++) {
|
for (int ii = 0; ii < pkcols.length; ii ++) {
|
||||||
pkcols[ii] = _pkColumns.get(ii).getField().getName();
|
pkcols[ii] = new ColumnExp(_pClass, _pkColumns.get(ii).getField().getName());
|
||||||
}
|
}
|
||||||
return pkcols;
|
return pkcols;
|
||||||
}
|
}
|
||||||
@@ -500,11 +500,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
|
|
||||||
// figure out the list of fields that correspond to actual table columns and generate the
|
// figure out the list of fields that correspond to actual table columns and generate the
|
||||||
// SQL used to create and migrate our table (unless we're a computed entity)
|
// SQL used to create and migrate our table (unless we're a computed entity)
|
||||||
_columnFields = new String[_allFields.length];
|
_columnFields = new ColumnExp[_allFields.length];
|
||||||
ColumnDefinition[] declarations = new ColumnDefinition[_allFields.length];
|
ColumnDefinition[] declarations = new ColumnDefinition[_allFields.length];
|
||||||
int jj = 0;
|
int jj = 0;
|
||||||
for (String field : _allFields) {
|
for (ColumnExp field : _allFields) {
|
||||||
FieldMarshaller<?> fm = _fields.get(field);
|
FieldMarshaller<?> fm = _fields.get(field.name);
|
||||||
// include all persistent non-computed fields
|
// include all persistent non-computed fields
|
||||||
ColumnDefinition colDef = fm.getColumnDefinition();
|
ColumnDefinition colDef = fm.getColumnDefinition();
|
||||||
if (colDef != null) {
|
if (colDef != null) {
|
||||||
@@ -683,9 +683,8 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
primaryKeyColumns[ii] = _pkColumns.get(ii).getColumnName();
|
primaryKeyColumns[ii] = _pkColumns.get(ii).getColumnName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
liaison.createTableIfMissing(
|
liaison.createTableIfMissing(conn, getTableName(), fieldsToColumns(_columnFields),
|
||||||
conn, getTableName(), fieldsToColumns(_columnFields),
|
declarations, null, primaryKeyColumns);
|
||||||
declarations, null, primaryKeyColumns);
|
|
||||||
|
|
||||||
// add its indexen
|
// add its indexen
|
||||||
for (CreateIndexClause iclause : _indexes) {
|
for (CreateIndexClause iclause : _indexes) {
|
||||||
@@ -750,8 +749,8 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
Set<String> preMigrateColumns = Sets.newHashSet(metaData.tableColumns);
|
Set<String> preMigrateColumns = Sets.newHashSet(metaData.tableColumns);
|
||||||
|
|
||||||
// add any missing columns
|
// add any missing columns
|
||||||
for (String fname : _columnFields) {
|
for (ColumnExp field : _columnFields) {
|
||||||
final FieldMarshaller<?> fmarsh = _fields.get(fname);
|
final FieldMarshaller<?> fmarsh = _fields.get(field.name);
|
||||||
if (metaData.tableColumns.remove(fmarsh.getColumnName())) {
|
if (metaData.tableColumns.remove(fmarsh.getColumnName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -942,11 +941,11 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// translate an array of field names to an array of column names
|
// translate an array of field names to an array of column names
|
||||||
protected String[] fieldsToColumns (String[] fields)
|
protected String[] fieldsToColumns (ColumnExp[] fields)
|
||||||
{
|
{
|
||||||
String[] columns = new String[fields.length];
|
String[] columns = new String[fields.length];
|
||||||
for (int ii = 0; ii < columns.length; ii ++) {
|
for (int ii = 0; ii < columns.length; ii ++) {
|
||||||
FieldMarshaller<?> fm = _fields.get(fields[ii]);
|
FieldMarshaller<?> fm = _fields.get(fields[ii].name);
|
||||||
if (fm == null) {
|
if (fm == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unknown field on record [field=" + fields[ii] + ", class=" + _pClass + "]");
|
"Unknown field on record [field=" + fields[ii] + ", class=" + _pClass + "]");
|
||||||
@@ -963,8 +962,8 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
TableMetaData meta, PersistenceContext ctx, SQLBuilder builder)
|
TableMetaData meta, PersistenceContext ctx, SQLBuilder builder)
|
||||||
throws DatabaseException
|
throws DatabaseException
|
||||||
{
|
{
|
||||||
for (String fname : _columnFields) {
|
for (ColumnExp field : _columnFields) {
|
||||||
FieldMarshaller<?> fmarsh = _fields.get(fname);
|
FieldMarshaller<?> fmarsh = _fields.get(field.name);
|
||||||
meta.tableColumns.remove(fmarsh.getColumnName());
|
meta.tableColumns.remove(fmarsh.getColumnName());
|
||||||
}
|
}
|
||||||
for (String column : meta.tableColumns) {
|
for (String column : meta.tableColumns) {
|
||||||
@@ -1067,10 +1066,10 @@ public class DepotMarshaller<T extends PersistentRecord>
|
|||||||
protected List<FieldMarshaller<?>> _pkColumns;
|
protected List<FieldMarshaller<?>> _pkColumns;
|
||||||
|
|
||||||
/** The persisent fields of our object, in definition order. */
|
/** The persisent fields of our object, in definition order. */
|
||||||
protected String[] _allFields;
|
protected ColumnExp[] _allFields;
|
||||||
|
|
||||||
/** The fields of our object with directly corresponding table columns. */
|
/** The fields of our object with directly corresponding table columns. */
|
||||||
protected String[] _columnFields;
|
protected ColumnExp[] _columnFields;
|
||||||
|
|
||||||
/** The indexes defined for this record. */
|
/** The indexes defined for this record. */
|
||||||
protected List<CreateIndexClause> _indexes = Lists.newArrayList();
|
protected List<CreateIndexClause> _indexes = Lists.newArrayList();
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ import java.util.Map;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import com.samskivert.depot.PersistentRecord;
|
||||||
import com.samskivert.depot.annotation.Id;
|
import com.samskivert.depot.annotation.Id;
|
||||||
|
import com.samskivert.depot.expression.ColumnExp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple utility methods used by various things.
|
* Simple utility methods used by various things.
|
||||||
@@ -38,18 +40,18 @@ public class DepotUtil
|
|||||||
* Returns an array containing the names of the primary key fields for the supplied persistent
|
* Returns an array containing the names of the primary key fields for the supplied persistent
|
||||||
* class. The values are introspected and cached for the lifetime of the VM.
|
* class. The values are introspected and cached for the lifetime of the VM.
|
||||||
*/
|
*/
|
||||||
public static String[] getKeyFields (Class<?> pClass)
|
public static ColumnExp[] getKeyFields (Class<? extends PersistentRecord> pClass)
|
||||||
{
|
{
|
||||||
String[] fields = _keyFields.get(pClass);
|
ColumnExp[] fields = _keyFields.get(pClass);
|
||||||
if (fields == null) {
|
if (fields == null) {
|
||||||
List<String> kflist = Lists.newArrayList();
|
List<ColumnExp> kflist = Lists.newArrayList();
|
||||||
for (Field field : pClass.getFields()) {
|
for (Field field : pClass.getFields()) {
|
||||||
// look for @Id fields
|
// look for @Id fields
|
||||||
if (field.getAnnotation(Id.class) != null) {
|
if (field.getAnnotation(Id.class) != null) {
|
||||||
kflist.add(field.getName());
|
kflist.add(new ColumnExp(pClass, field.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_keyFields.put(pClass, fields = kflist.toArray(new String[kflist.size()]));
|
_keyFields.put(pClass, fields = kflist.toArray(new ColumnExp[kflist.size()]));
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
@@ -64,5 +66,5 @@ public class DepotUtil
|
|||||||
|
|
||||||
/** A (never expiring) cache of primary key field names for all persistent classes (of which
|
/** A (never expiring) cache of primary key field names for all persistent classes (of which
|
||||||
* there are merely dozens, so we don't need to worry about expiring). */
|
* there are merely dozens, so we don't need to worry about expiring). */
|
||||||
protected static Map<Class<?>,String[]> _keyFields = Maps.newHashMap();
|
protected static Map<Class<?>, ColumnExp[]> _keyFields = Maps.newHashMap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,15 +179,15 @@ public class ExpressionEvaluator
|
|||||||
return new NoValue("Column lookup on unknown persistent class: " + pClass);
|
return new NoValue("Column lookup on unknown persistent class: " + pClass);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Field field = pClass.getField(columnExp.getField());
|
Field field = pClass.getField(columnExp.name);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
log.warning("Couldn't locate field on class", "field", columnExp.getField(),
|
log.warning("Couldn't locate field on class", "field", columnExp.name,
|
||||||
"class", pClass);
|
"class", pClass);
|
||||||
return new NoValue("Internal Error");
|
return new NoValue("Internal Error");
|
||||||
}
|
}
|
||||||
return field.get(_pRec);
|
return field.get(_pRec);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warning("Failed to retrieve field value", "field", columnExp.getField(), e);
|
log.warning("Failed to retrieve field value", "field", columnExp.name, e);
|
||||||
return new NoValue("Internal Error");
|
return new NoValue("Internal Error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,13 +237,13 @@ public class ExpressionEvaluator
|
|||||||
return new NoValue("Column lookup on unknown persistent class: " + pClass);
|
return new NoValue("Column lookup on unknown persistent class: " + pClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] keyFields = DepotUtil.getKeyFields(pClass);
|
ColumnExp[] keyFields = DepotUtil.getKeyFields(pClass);
|
||||||
Comparable<?>[] values = key.getValues();
|
Comparable<?>[] values = key.getValues();
|
||||||
|
|
||||||
for (int ii = 0; ii < keyFields.length; ii ++) {
|
for (int ii = 0; ii < keyFields.length; ii ++) {
|
||||||
Object value;
|
Object value;
|
||||||
try {
|
try {
|
||||||
value = pClass.getDeclaredField(keyFields[ii]).get(_pRec);
|
value = pClass.getDeclaredField(keyFields[ii].name).get(_pRec);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warning("Failed to retrieve field value", "field", keyFields[ii], e);
|
log.warning("Failed to retrieve field value", "field", keyFields[ii], e);
|
||||||
return new NoValue("Internal Error");
|
return new NoValue("Internal Error");
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.Collection;
|
|||||||
import com.samskivert.depot.PersistentRecord;
|
import com.samskivert.depot.PersistentRecord;
|
||||||
import com.samskivert.depot.clause.QueryClause;
|
import com.samskivert.depot.clause.QueryClause;
|
||||||
import com.samskivert.depot.clause.WhereClause;
|
import com.samskivert.depot.clause.WhereClause;
|
||||||
|
import com.samskivert.depot.expression.ColumnExp;
|
||||||
import com.samskivert.depot.expression.SQLExpression;
|
import com.samskivert.depot.expression.SQLExpression;
|
||||||
|
|
||||||
import com.samskivert.depot.impl.ExpressionVisitor;
|
import com.samskivert.depot.impl.ExpressionVisitor;
|
||||||
@@ -36,7 +37,7 @@ public class UpdateClause
|
|||||||
implements QueryClause
|
implements QueryClause
|
||||||
{
|
{
|
||||||
public UpdateClause (Class<? extends PersistentRecord> pClass, WhereClause where,
|
public UpdateClause (Class<? extends PersistentRecord> pClass, WhereClause where,
|
||||||
String[] fields, PersistentRecord pojo)
|
ColumnExp[] fields, PersistentRecord pojo)
|
||||||
{
|
{
|
||||||
_pClass = pClass;
|
_pClass = pClass;
|
||||||
_where = where;
|
_where = where;
|
||||||
@@ -46,7 +47,7 @@ public class UpdateClause
|
|||||||
}
|
}
|
||||||
|
|
||||||
public UpdateClause (Class<? extends PersistentRecord> pClass, WhereClause where,
|
public UpdateClause (Class<? extends PersistentRecord> pClass, WhereClause where,
|
||||||
String[] fields, SQLExpression[] values)
|
ColumnExp[] fields, SQLExpression[] values)
|
||||||
{
|
{
|
||||||
_pClass = pClass;
|
_pClass = pClass;
|
||||||
_fields = fields;
|
_fields = fields;
|
||||||
@@ -60,7 +61,7 @@ public class UpdateClause
|
|||||||
return _where;
|
return _where;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getFields ()
|
public ColumnExp[] getFields ()
|
||||||
{
|
{
|
||||||
return _fields;
|
return _fields;
|
||||||
}
|
}
|
||||||
@@ -107,7 +108,7 @@ public class UpdateClause
|
|||||||
protected WhereClause _where;
|
protected WhereClause _where;
|
||||||
|
|
||||||
/** The persistent fields to update. */
|
/** The persistent fields to update. */
|
||||||
protected String[] _fields;
|
protected ColumnExp[] _fields;
|
||||||
|
|
||||||
/** The field values, or null. */
|
/** The field values, or null. */
|
||||||
protected SQLExpression[] _values;
|
protected SQLExpression[] _values;
|
||||||
|
|||||||
Reference in New Issue
Block a user