Tuple2<blah blah> -> IndexDesc.

If you have persistent classes with complex (or ordered) indices, you need to
return IndexDesc now instead of Tuple2<blah blah>.
This commit is contained in:
Michael Bayne
2015-02-10 12:52:48 -08:00
parent 66952dc472
commit 40e6ccc833
4 changed files with 68 additions and 77 deletions
@@ -0,0 +1,34 @@
//
// Depot library - a Java relational persistence library
// https://github.com/threerings/depot/blob/master/LICENSE
package com.samskivert.depot;
import com.samskivert.depot.clause.OrderBy;
import com.samskivert.depot.expression.SQLExpression;
/**
* Describes an index on a persistent class's table.
*/
public class IndexDesc {
/** The expression that defines this index. */
public final SQLExpression<?> expr;
/** The order of the index. */
public final OrderBy.Order order;
public IndexDesc (SQLExpression<?> expr, OrderBy.Order order) {
this.expr = expr;
this.order = order;
}
@Override public int hashCode () {
return expr.hashCode() ^ order.hashCode();
}
@Override public boolean equals (Object other) {
return (other instanceof IndexDesc) && expr.equals(((IndexDesc)other).expr) &&
order == ((IndexDesc)other).order;
}
}
@@ -17,9 +17,11 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.samskivert.depot.Exps; import com.samskivert.depot.Exps;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.Key; import com.samskivert.depot.Key;
import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.annotation.Computed; import com.samskivert.depot.annotation.Computed;
import com.samskivert.depot.clause.Distinct;
import com.samskivert.depot.clause.FieldDefinition; import com.samskivert.depot.clause.FieldDefinition;
import com.samskivert.depot.clause.FieldOverride; import com.samskivert.depot.clause.FieldOverride;
import com.samskivert.depot.clause.ForUpdate; import com.samskivert.depot.clause.ForUpdate;
@@ -39,53 +41,14 @@ import com.samskivert.depot.util.ByteEnum;
import com.samskivert.depot.util.Tuple2; import com.samskivert.depot.util.Tuple2;
import static com.samskivert.depot.Log.log; import static com.samskivert.depot.Log.log;
import com.samskivert.depot.clause.Distinct; import com.samskivert.depot.impl.clause.*;
import com.samskivert.depot.impl.clause.CreateIndexClause; import com.samskivert.depot.impl.expression.*;
import com.samskivert.depot.impl.clause.DeleteClause; import com.samskivert.depot.impl.expression.AggregateFun.*;
import com.samskivert.depot.impl.clause.DropIndexClause; import com.samskivert.depot.impl.expression.ConditionalFun.*;
import com.samskivert.depot.impl.clause.UpdateClause; import com.samskivert.depot.impl.expression.DateFun.*;
import com.samskivert.depot.impl.expression.AggregateFun.Average; import com.samskivert.depot.impl.expression.NumericalFun.*;
import com.samskivert.depot.impl.expression.AggregateFun.Count; import com.samskivert.depot.impl.expression.StringFun.*;
import com.samskivert.depot.impl.expression.AggregateFun.Every; import com.samskivert.depot.impl.operator.*;
import com.samskivert.depot.impl.expression.AggregateFun.Max;
import com.samskivert.depot.impl.expression.AggregateFun.Min;
import com.samskivert.depot.impl.expression.AggregateFun.Sum;
import com.samskivert.depot.impl.expression.AggregateFun;
import com.samskivert.depot.impl.expression.ConditionalFun.Coalesce;
import com.samskivert.depot.impl.expression.ConditionalFun.Greatest;
import com.samskivert.depot.impl.expression.ConditionalFun.Least;
import com.samskivert.depot.impl.expression.DateFun.DatePart;
import com.samskivert.depot.impl.expression.DateFun.DateTruncate;
import com.samskivert.depot.impl.expression.DateFun.Now;
import com.samskivert.depot.impl.expression.IntervalExp;
import com.samskivert.depot.impl.expression.LiteralExp;
import com.samskivert.depot.impl.expression.NumericalFun.Abs;
import com.samskivert.depot.impl.expression.NumericalFun.Ceil;
import com.samskivert.depot.impl.expression.NumericalFun.Exp;
import com.samskivert.depot.impl.expression.NumericalFun.Floor;
import com.samskivert.depot.impl.expression.NumericalFun.Ln;
import com.samskivert.depot.impl.expression.NumericalFun.Log10;
import com.samskivert.depot.impl.expression.NumericalFun.Pi;
import com.samskivert.depot.impl.expression.NumericalFun.Power;
import com.samskivert.depot.impl.expression.NumericalFun.Random;
import com.samskivert.depot.impl.expression.NumericalFun.Round;
import com.samskivert.depot.impl.expression.NumericalFun.Sign;
import com.samskivert.depot.impl.expression.NumericalFun.Sqrt;
import com.samskivert.depot.impl.expression.NumericalFun.Trunc;
import com.samskivert.depot.impl.expression.RandomExp;
import com.samskivert.depot.impl.expression.StringFun.Length;
import com.samskivert.depot.impl.expression.StringFun.Lower;
import com.samskivert.depot.impl.expression.StringFun.Position;
import com.samskivert.depot.impl.expression.StringFun.Substring;
import com.samskivert.depot.impl.expression.StringFun.Trim;
import com.samskivert.depot.impl.expression.StringFun.Upper;
import com.samskivert.depot.impl.expression.ValueExp;
import com.samskivert.depot.impl.operator.BinaryOperator;
import com.samskivert.depot.impl.operator.Exists;
import com.samskivert.depot.impl.operator.In;
import com.samskivert.depot.impl.operator.IsNull;
import com.samskivert.depot.impl.operator.MultiOperator;
import com.samskivert.depot.impl.operator.Not;
/** /**
* Implements the base functionality of the SQL-building pass of {@link SQLBuilder}. Dialectal * Implements the base functionality of the SQL-building pass of {@link SQLBuilder}. Dialectal
@@ -510,8 +473,8 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
public Void visit (CreateIndexClause createIndexClause) public Void visit (CreateIndexClause createIndexClause)
{ {
if (!_allowComplexIndices) { if (!_allowComplexIndices) {
for (Tuple2<SQLExpression<?>, Order> field : createIndexClause.getFields()) { for (IndexDesc desc : createIndexClause.getDescs()) {
if (!(field.a instanceof ColumnExp<?>)) { if (!(desc.expr instanceof ColumnExp<?>)) {
log.warning("This database can't handle complex indexes. Not creating.", log.warning("This database can't handle complex indexes. Not creating.",
"ixName", createIndexClause.getName()); "ixName", createIndexClause.getName());
return null; return null;
@@ -531,7 +494,7 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
// turn off table abbreviations here // turn off table abbreviations here
_defaultType = createIndexClause.getPersistentClass(); _defaultType = createIndexClause.getPersistentClass();
boolean comma = false; boolean comma = false;
for (Tuple2<SQLExpression<?>, Order> field : createIndexClause.getFields()) { for (IndexDesc desc : createIndexClause.getDescs()) {
if (comma) { if (comma) {
_builder.append(", "); _builder.append(", ");
} }
@@ -543,11 +506,11 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
if (_allowComplexIndices) { if (_allowComplexIndices) {
_builder.append("("); _builder.append("(");
} }
field.a.accept(this); desc.expr.accept(this);
if (_allowComplexIndices) { if (_allowComplexIndices) {
_builder.append(")"); _builder.append(")");
} }
if (field.b == Order.DESC) { if (desc.order == Order.DESC) {
// ascending is default, print nothing unless explicitly descending // ascending is default, print nothing unless explicitly descending
_builder.append(" desc"); _builder.append(" desc");
} }
@@ -27,6 +27,7 @@ import com.google.common.collect.Sets;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import com.samskivert.depot.DatabaseException; import com.samskivert.depot.DatabaseException;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.Key; import com.samskivert.depot.Key;
import com.samskivert.depot.PersistenceContext; import com.samskivert.depot.PersistenceContext;
import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.PersistentRecord;
@@ -48,7 +49,6 @@ import com.samskivert.depot.expression.SQLExpression;
import com.samskivert.depot.impl.clause.CreateIndexClause; import com.samskivert.depot.impl.clause.CreateIndexClause;
import com.samskivert.depot.impl.jdbc.ColumnDefinition; import com.samskivert.depot.impl.jdbc.ColumnDefinition;
import com.samskivert.depot.impl.jdbc.DatabaseLiaison; import com.samskivert.depot.impl.jdbc.DatabaseLiaison;
import com.samskivert.depot.util.Tuple2;
import static com.samskivert.depot.Log.log; import static com.samskivert.depot.Log.log;
/** /**
@@ -99,10 +99,8 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
// introspect on the class and create marshallers and indices for persistent fields // introspect on the class and create marshallers and indices for persistent fields
List<ColumnExp<?>> fields = Lists.newArrayList(); List<ColumnExp<?>> fields = Lists.newArrayList();
ListMultimap<String, Tuple2<SQLExpression<?>, Order>> namedFieldIndices = ListMultimap<String, IndexDesc> namedFieldIndices = ArrayListMultimap.create();
ArrayListMultimap.create(); ListMultimap<String, IndexDesc> uniqueNamedFieldIndices = ArrayListMultimap.create();
ListMultimap<String, Tuple2<SQLExpression<?>, Order>> uniqueNamedFieldIndices =
ArrayListMultimap.create();
for (Field field : _pClass.getFields()) { for (Field field : _pClass.getFields()) {
int mods = field.getModifiers(); int mods = field.getModifiers();
@@ -182,8 +180,7 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
"Unique columns are implicitly indexed and should not be @Index'd."); "Unique columns are implicitly indexed and should not be @Index'd.");
String name = index.name().equals("") ? field.getName() + "Index" : index.name(); String name = index.name().equals("") ? field.getName() + "Index" : index.name();
Tuple2<SQLExpression<?>, Order> entry = IndexDesc entry = new IndexDesc(fieldColumn, Order.ASC);
new Tuple2<SQLExpression<?>, Order>(fieldColumn, Order.ASC);
if (index.unique()) { if (index.unique()) {
checkArgument(!namedFieldIndices.containsKey(index.name()), checkArgument(!namedFieldIndices.containsKey(index.name()),
"All @Index for a particular name must be unique or non-unique"); "All @Index for a particular name must be unique or non-unique");
@@ -930,27 +927,24 @@ public class DepotMarshaller<T extends PersistentRecord> implements QueryMarshal
protected CreateIndexClause buildIndex (String name, boolean unique, Object config) protected CreateIndexClause buildIndex (String name, boolean unique, Object config)
{ {
List<Tuple2<SQLExpression<?>, Order>> definition = Lists.newArrayList(); List<IndexDesc> definition = Lists.newArrayList();
if (config instanceof ColumnExp<?>) { if (config instanceof ColumnExp<?>) {
definition.add(new Tuple2<SQLExpression<?>, Order>((ColumnExp<?>)config, Order.ASC)); definition.add(new IndexDesc((ColumnExp<?>)config, Order.ASC));
} else if (config instanceof ColumnExp<?>[]) { } else if (config instanceof ColumnExp<?>[]) {
for (ColumnExp<?> column : (ColumnExp<?>[])config) { for (ColumnExp<?> column : (ColumnExp<?>[])config) {
definition.add(new Tuple2<SQLExpression<?>, Order>(column, Order.ASC)); definition.add(new IndexDesc(column, Order.ASC));
} }
} else if (config instanceof SQLExpression) { } else if (config instanceof SQLExpression) {
definition.add(new Tuple2<SQLExpression<?>, Order>((SQLExpression<?>)config, Order.ASC)); definition.add(new IndexDesc((SQLExpression<?>)config, Order.ASC));
} else if (config instanceof Tuple2<?,?>) { } else if (config instanceof IndexDesc) {
@SuppressWarnings("unchecked") Tuple2<SQLExpression<?>, Order> tuple = definition.add((IndexDesc)config);
(Tuple2<SQLExpression<?>, Order>)config;
definition.add(tuple);
} else if (config instanceof List<?>) { } else if (config instanceof List<?>) {
@SuppressWarnings("unchecked") List<Tuple2<SQLExpression<?>, Order>> defs = @SuppressWarnings("unchecked") List<IndexDesc> defs = (List<IndexDesc>)config;
(List<Tuple2<SQLExpression<?>, Order>>)config;
definition.addAll(defs); definition.addAll(defs);
} else { } else {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Method '" + name + "' must return ColumnExp[], SQLExpression or " + "Method '" + name + "' must return ColumnExp[], SQLExpression or " +
"List<Tuple2<SQLExpression, Order>>"); "List<IndexDesc>");
} }
return new CreateIndexClause(_pClass, getTableName() + "_" + name, unique, definition); return new CreateIndexClause(_pClass, getTableName() + "_" + name, unique, definition);
} }
@@ -7,13 +7,13 @@ package com.samskivert.depot.impl.clause;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.PersistentRecord; import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.clause.OrderBy.Order; import com.samskivert.depot.clause.OrderBy.Order;
import com.samskivert.depot.clause.QueryClause; import com.samskivert.depot.clause.QueryClause;
import com.samskivert.depot.expression.SQLExpression; import com.samskivert.depot.expression.SQLExpression;
import com.samskivert.depot.util.Tuple2;
import com.samskivert.depot.impl.FragmentVisitor; import com.samskivert.depot.impl.FragmentVisitor;
import com.samskivert.depot.util.Tuple2;
/** /**
* Represents an CREATE INDEX instruction to the database. * Represents an CREATE INDEX instruction to the database.
@@ -26,12 +26,12 @@ public class CreateIndexClause
* database. * database.
*/ */
public CreateIndexClause (Class<? extends PersistentRecord> pClass, String name, boolean unique, public CreateIndexClause (Class<? extends PersistentRecord> pClass, String name, boolean unique,
List<Tuple2<SQLExpression<?>, Order>> fields) List<IndexDesc> descs)
{ {
_pClass = pClass; _pClass = pClass;
_name = name; _name = name;
_unique = unique; _unique = unique;
_fields = fields; _descs = descs;
} }
public Class<? extends PersistentRecord> getPersistentClass () public Class<? extends PersistentRecord> getPersistentClass ()
@@ -49,9 +49,9 @@ public class CreateIndexClause
return _unique; return _unique;
} }
public List<Tuple2<SQLExpression<?>,Order>> getFields () public List<IndexDesc> getDescs ()
{ {
return _fields; return _descs;
} }
// from SQLFragment // from SQLFragment
@@ -71,5 +71,5 @@ public class CreateIndexClause
protected boolean _unique; protected boolean _unique;
/** The components of the index, e.g. columns or functions of columns. */ /** The components of the index, e.g. columns or functions of columns. */
protected List<Tuple2<SQLExpression<?>,Order>> _fields; protected List<IndexDesc> _descs;
} }