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 com.samskivert.depot.Exps;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.Key;
import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.annotation.Computed;
import com.samskivert.depot.clause.Distinct;
import com.samskivert.depot.clause.FieldDefinition;
import com.samskivert.depot.clause.FieldOverride;
import com.samskivert.depot.clause.ForUpdate;
@@ -39,53 +41,14 @@ import com.samskivert.depot.util.ByteEnum;
import com.samskivert.depot.util.Tuple2;
import static com.samskivert.depot.Log.log;
import com.samskivert.depot.clause.Distinct;
import com.samskivert.depot.impl.clause.CreateIndexClause;
import com.samskivert.depot.impl.clause.DeleteClause;
import com.samskivert.depot.impl.clause.DropIndexClause;
import com.samskivert.depot.impl.clause.UpdateClause;
import com.samskivert.depot.impl.expression.AggregateFun.Average;
import com.samskivert.depot.impl.expression.AggregateFun.Count;
import com.samskivert.depot.impl.expression.AggregateFun.Every;
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;
import com.samskivert.depot.impl.clause.*;
import com.samskivert.depot.impl.expression.*;
import com.samskivert.depot.impl.expression.AggregateFun.*;
import com.samskivert.depot.impl.expression.ConditionalFun.*;
import com.samskivert.depot.impl.expression.DateFun.*;
import com.samskivert.depot.impl.expression.NumericalFun.*;
import com.samskivert.depot.impl.expression.StringFun.*;
import com.samskivert.depot.impl.operator.*;
/**
* 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)
{
if (!_allowComplexIndices) {
for (Tuple2<SQLExpression<?>, Order> field : createIndexClause.getFields()) {
if (!(field.a instanceof ColumnExp<?>)) {
for (IndexDesc desc : createIndexClause.getDescs()) {
if (!(desc.expr instanceof ColumnExp<?>)) {
log.warning("This database can't handle complex indexes. Not creating.",
"ixName", createIndexClause.getName());
return null;
@@ -531,7 +494,7 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
// turn off table abbreviations here
_defaultType = createIndexClause.getPersistentClass();
boolean comma = false;
for (Tuple2<SQLExpression<?>, Order> field : createIndexClause.getFields()) {
for (IndexDesc desc : createIndexClause.getDescs()) {
if (comma) {
_builder.append(", ");
}
@@ -543,11 +506,11 @@ public abstract class BuildVisitor implements FragmentVisitor<Void>
if (_allowComplexIndices) {
_builder.append("(");
}
field.a.accept(this);
desc.expr.accept(this);
if (_allowComplexIndices) {
_builder.append(")");
}
if (field.b == Order.DESC) {
if (desc.order == Order.DESC) {
// ascending is default, print nothing unless explicitly descending
_builder.append(" desc");
}
@@ -27,6 +27,7 @@ import com.google.common.collect.Sets;
import static com.google.common.base.Preconditions.checkArgument;
import com.samskivert.depot.DatabaseException;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.Key;
import com.samskivert.depot.PersistenceContext;
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.jdbc.ColumnDefinition;
import com.samskivert.depot.impl.jdbc.DatabaseLiaison;
import com.samskivert.depot.util.Tuple2;
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
List<ColumnExp<?>> fields = Lists.newArrayList();
ListMultimap<String, Tuple2<SQLExpression<?>, Order>> namedFieldIndices =
ArrayListMultimap.create();
ListMultimap<String, Tuple2<SQLExpression<?>, Order>> uniqueNamedFieldIndices =
ArrayListMultimap.create();
ListMultimap<String, IndexDesc> namedFieldIndices = ArrayListMultimap.create();
ListMultimap<String, IndexDesc> uniqueNamedFieldIndices = ArrayListMultimap.create();
for (Field field : _pClass.getFields()) {
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.");
String name = index.name().equals("") ? field.getName() + "Index" : index.name();
Tuple2<SQLExpression<?>, Order> entry =
new Tuple2<SQLExpression<?>, Order>(fieldColumn, Order.ASC);
IndexDesc entry = new IndexDesc(fieldColumn, Order.ASC);
if (index.unique()) {
checkArgument(!namedFieldIndices.containsKey(index.name()),
"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)
{
List<Tuple2<SQLExpression<?>, Order>> definition = Lists.newArrayList();
List<IndexDesc> definition = Lists.newArrayList();
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<?>[]) {
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) {
definition.add(new Tuple2<SQLExpression<?>, Order>((SQLExpression<?>)config, Order.ASC));
} else if (config instanceof Tuple2<?,?>) {
@SuppressWarnings("unchecked") Tuple2<SQLExpression<?>, Order> tuple =
(Tuple2<SQLExpression<?>, Order>)config;
definition.add(tuple);
definition.add(new IndexDesc((SQLExpression<?>)config, Order.ASC));
} else if (config instanceof IndexDesc) {
definition.add((IndexDesc)config);
} else if (config instanceof List<?>) {
@SuppressWarnings("unchecked") List<Tuple2<SQLExpression<?>, Order>> defs =
(List<Tuple2<SQLExpression<?>, Order>>)config;
@SuppressWarnings("unchecked") List<IndexDesc> defs = (List<IndexDesc>)config;
definition.addAll(defs);
} else {
throw new IllegalArgumentException(
"Method '" + name + "' must return ColumnExp[], SQLExpression or " +
"List<Tuple2<SQLExpression, Order>>");
"List<IndexDesc>");
}
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.List;
import com.samskivert.depot.IndexDesc;
import com.samskivert.depot.PersistentRecord;
import com.samskivert.depot.clause.OrderBy.Order;
import com.samskivert.depot.clause.QueryClause;
import com.samskivert.depot.expression.SQLExpression;
import com.samskivert.depot.util.Tuple2;
import com.samskivert.depot.impl.FragmentVisitor;
import com.samskivert.depot.util.Tuple2;
/**
* Represents an CREATE INDEX instruction to the database.
@@ -26,12 +26,12 @@ public class CreateIndexClause
* database.
*/
public CreateIndexClause (Class<? extends PersistentRecord> pClass, String name, boolean unique,
List<Tuple2<SQLExpression<?>, Order>> fields)
List<IndexDesc> descs)
{
_pClass = pClass;
_name = name;
_unique = unique;
_fields = fields;
_descs = descs;
}
public Class<? extends PersistentRecord> getPersistentClass ()
@@ -49,9 +49,9 @@ public class CreateIndexClause
return _unique;
}
public List<Tuple2<SQLExpression<?>,Order>> getFields ()
public List<IndexDesc> getDescs ()
{
return _fields;
return _descs;
}
// from SQLFragment
@@ -71,5 +71,5 @@ public class CreateIndexClause
protected boolean _unique;
/** The components of the index, e.g. columns or functions of columns. */
protected List<Tuple2<SQLExpression<?>,Order>> _fields;
protected List<IndexDesc> _descs;
}