Roll everything on up to Tuple5. We boil the plates so that you don't have to!
This commit is contained in:
@@ -29,8 +29,9 @@ import com.google.common.collect.Lists;
|
||||
import com.samskivert.depot.clause.*;
|
||||
import com.samskivert.depot.expression.ColumnExp;
|
||||
import com.samskivert.depot.expression.SQLExpression;
|
||||
import com.samskivert.depot.impl.Projector;
|
||||
import com.samskivert.depot.impl.FindAllQuery;
|
||||
import com.samskivert.depot.impl.Projector;
|
||||
import com.samskivert.depot.util.*; // TupleN
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
@@ -378,6 +379,35 @@ public class QueryBuilder<T extends PersistentRecord>
|
||||
return select(exp1, exp2).get(0); // TODO: revamp FindOneQuery and use that
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value from the first row that matches the configured query clauses.
|
||||
*/
|
||||
public <V1, V2, V3> Tuple3<V1, V2, V3> load (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2, SQLExpression<V3> exp3)
|
||||
{
|
||||
return select(exp1, exp2, exp3).get(0); // TODO: revamp FindOneQuery and use that
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value from the first row that matches the configured query clauses.
|
||||
*/
|
||||
public <V1, V2, V3, V4> Tuple4<V1, V2, V3, V4> load (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2,
|
||||
SQLExpression<V3> exp3, SQLExpression<V4> exp4)
|
||||
{
|
||||
return select(exp1, exp2, exp3, exp4).get(0); // TODO: revamp FindOneQuery and use that
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value from the first row that matches the configured query clauses.
|
||||
*/
|
||||
public <V1, V2, V3, V4, V5> Tuple5<V1, V2, V3, V4, V5> load (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2, SQLExpression<V3> exp3,
|
||||
SQLExpression<V4> exp4, SQLExpression<V5> exp5)
|
||||
{
|
||||
return select(exp1, exp2, exp3, exp4, exp5).get(0); // TODO: use revamped FindOneQuery
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the supplied expression from the rows matching the query.
|
||||
*/
|
||||
@@ -396,6 +426,40 @@ public class QueryBuilder<T extends PersistentRecord>
|
||||
_ctx, Projector.create(_pclass, exp1, exp2), getClauses()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the supplied expressions from the rows matching the query.
|
||||
*/
|
||||
public <V1, V2, V3> List<Tuple3<V1,V2,V3>> select (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2, SQLExpression<V3> exp3)
|
||||
{
|
||||
return _ctx.invoke(new FindAllQuery.Projection<T,Tuple3<V1,V2,V3>>(
|
||||
_ctx, Projector.create(_pclass, exp1, exp2, exp3), getClauses()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the supplied expressions from the rows matching the query.
|
||||
*/
|
||||
public <V1, V2, V3, V4> List<Tuple4<V1,V2,V3,V4>> select (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2,
|
||||
SQLExpression<V3> exp3, SQLExpression<V4> exp4)
|
||||
{
|
||||
return _ctx.invoke(new FindAllQuery.Projection<T,Tuple4<V1,V2,V3,V4>>(
|
||||
_ctx, Projector.create(_pclass, exp1, exp2, exp3, exp4),
|
||||
getClauses()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns just the supplied expressions from the rows matching the query.
|
||||
*/
|
||||
public <V1, V2, V3, V4, V5> List<Tuple5<V1,V2,V3,V4,V5>> select (
|
||||
SQLExpression<V1> exp1, SQLExpression<V2> exp2, SQLExpression<V3> exp3,
|
||||
SQLExpression<V4> exp4, SQLExpression<V5> exp5)
|
||||
{
|
||||
return _ctx.invoke(new FindAllQuery.Projection<T,Tuple5<V1,V2,V3,V4,V5>>(
|
||||
_ctx, Projector.create(_pclass, exp1, exp2, exp3, exp4, exp5),
|
||||
getClauses()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the records that match the configured query clauses. Note that only the where
|
||||
* clauses are used to evaluate a deletion. Attempts to use other clauses will result in
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
package com.samskivert.depot.impl;
|
||||
|
||||
import com.samskivert.depot.PersistentRecord;
|
||||
import com.samskivert.depot.Tuple2;
|
||||
import com.samskivert.depot.expression.SQLExpression;
|
||||
import com.samskivert.depot.util.*; // TupleN
|
||||
|
||||
/**
|
||||
* Contains a set of selection expressions which are to be projected (selected) from a set of
|
||||
@@ -53,6 +53,54 @@ public abstract class Projector<T extends PersistentRecord,R>
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends PersistentRecord, V1, V2, V3> Projector<T,Tuple3<V1,V2,V3>> create (
|
||||
Class<T> ptype, SQLExpression<V1> col1, SQLExpression<V2> col2, SQLExpression<V3> col3)
|
||||
{
|
||||
return new Projector<T, Tuple3<V1,V2,V3>>(ptype, new SQLExpression[] { col1, col2, col3 }) {
|
||||
public Tuple3<V1,V2,V3> createObject (Object[] results) {
|
||||
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
|
||||
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
|
||||
@SuppressWarnings("unchecked") V3 r3 = (V3)results[2];
|
||||
return new Tuple3<V1,V2,V3>(r1, r2, r3);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends PersistentRecord, V1, V2, V3, V4>
|
||||
Projector<T,Tuple4<V1,V2,V3,V4>> create (
|
||||
Class<T> ptype, SQLExpression<V1> col1, SQLExpression<V2> col2, SQLExpression<V3> col3,
|
||||
SQLExpression<V4> col4)
|
||||
{
|
||||
return new Projector<T, Tuple4<V1,V2,V3,V4>>(
|
||||
ptype, new SQLExpression[] { col1, col2, col3, col4 }) {
|
||||
public Tuple4<V1,V2,V3,V4> createObject (Object[] results) {
|
||||
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
|
||||
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
|
||||
@SuppressWarnings("unchecked") V3 r3 = (V3)results[2];
|
||||
@SuppressWarnings("unchecked") V4 r4 = (V4)results[3];
|
||||
return new Tuple4<V1,V2,V3,V4>(r1, r2, r3, r4);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T extends PersistentRecord, V1, V2, V3, V4, V5>
|
||||
Projector<T,Tuple5<V1,V2,V3,V4,V5>> create (
|
||||
Class<T> ptype, SQLExpression<V1> col1, SQLExpression<V2> col2, SQLExpression<V3> col3,
|
||||
SQLExpression<V4> col4, SQLExpression<V5> col5)
|
||||
{
|
||||
return new Projector<T, Tuple5<V1,V2,V3,V4,V5>>(
|
||||
ptype, new SQLExpression[] { col1, col2, col3, col4, col5 }) {
|
||||
public Tuple5<V1,V2,V3,V4,V5> createObject (Object[] results) {
|
||||
@SuppressWarnings("unchecked") V1 r1 = (V1)results[0];
|
||||
@SuppressWarnings("unchecked") V2 r2 = (V2)results[1];
|
||||
@SuppressWarnings("unchecked") V3 r3 = (V3)results[2];
|
||||
@SuppressWarnings("unchecked") V4 r4 = (V4)results[3];
|
||||
@SuppressWarnings("unchecked") V5 r5 = (V5)results[4];
|
||||
return new Tuple5<V1,V2,V3,V4,V5>(r1, r2, r3, r4, r5);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public final Class<T> ptype;
|
||||
public final SQLExpression<?>[] selexps;
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.depot;
|
||||
package com.samskivert.depot.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Depot library - a Java relational persistence library
|
||||
// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell
|
||||
//
|
||||
// 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
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.depot.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Contains a three column result. This class is immutable and the objects it references are also
|
||||
* meant to be immutable. They will generally contain only Depot primitive types (Java primitives,
|
||||
* SQL primitives and some array types), which should be treated as immutable.
|
||||
*/
|
||||
public class Tuple3<A,B,C> implements Serializable
|
||||
{
|
||||
/** The first column of the result. */
|
||||
public final A a;
|
||||
|
||||
/** The second column of the result. */
|
||||
public final B b;
|
||||
|
||||
/** The third column of the result. */
|
||||
public final C c;
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public static <A, B, C> Tuple3<A, B, C> create (A a, B b, C c)
|
||||
{
|
||||
return new Tuple3<A, B, C>(a, b, c);
|
||||
}
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public Tuple3 (A a, B b, C c)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return "[" + a + "," + b + "," + c + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode ()
|
||||
{
|
||||
return Objects.hashCode(a, b, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof Tuple3<?,?,?>) {
|
||||
Tuple3<?,?,?> otup = (Tuple3<?,?,?>)other;
|
||||
return Objects.equal(a, otup.a) && Objects.equal(b, otup.b) && Objects.equal(c, otup.c);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Depot library - a Java relational persistence library
|
||||
// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell
|
||||
//
|
||||
// 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
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.depot.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Contains a four column result. This class is immutable and the objects it references are also
|
||||
* meant to be immutable. They will generally contain only Depot primitive types (Java primitives,
|
||||
* SQL primitives and some array types), which should be treated as immutable.
|
||||
*/
|
||||
public class Tuple4<A,B,C,D> implements Serializable
|
||||
{
|
||||
/** The first column of the result. */
|
||||
public final A a;
|
||||
|
||||
/** The second column of the result. */
|
||||
public final B b;
|
||||
|
||||
/** The third column of the result. */
|
||||
public final C c;
|
||||
|
||||
/** The fourth column of the result. */
|
||||
public final D d;
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public static <A, B, C, D> Tuple4<A, B, C, D> create (A a, B b, C c, D d)
|
||||
{
|
||||
return new Tuple4<A, B, C, D>(a, b, c, d);
|
||||
}
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public Tuple4 (A a, B b, C c, D d)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return "[" + a + "," + b + "," + c + "," + d + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode ()
|
||||
{
|
||||
return Objects.hashCode(a, b, c, d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof Tuple4<?,?,?,?>) {
|
||||
Tuple4<?,?,?,?> otup = (Tuple4<?,?,?,?>)other;
|
||||
return Objects.equal(a, otup.a) && Objects.equal(b, otup.b) &&
|
||||
Objects.equal(c, otup.c) && Objects.equal(d, otup.d);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
// Depot library - a Java relational persistence library
|
||||
// Copyright (C) 2006-2010 Michael Bayne and Pär Winzell
|
||||
//
|
||||
// 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
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.depot.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Contains a five column result. This class is immutable and the objects it references are also
|
||||
* meant to be immutable. They will generally contain only Depot primitive types (Java primitives,
|
||||
* SQL primitives and some array types), which should be treated as immutable.
|
||||
*/
|
||||
public class Tuple5<A,B,C,D,E> implements Serializable
|
||||
{
|
||||
/** The first column of the result. */
|
||||
public final A a;
|
||||
|
||||
/** The second column of the result. */
|
||||
public final B b;
|
||||
|
||||
/** The third column of the result. */
|
||||
public final C c;
|
||||
|
||||
/** The fourth column of the result. */
|
||||
public final D d;
|
||||
|
||||
/** The fifth column of the result. */
|
||||
public final E e;
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public static <A, B, C, D, E> Tuple5<A, B, C, D, E> create (A a, B b, C c, D d, E e)
|
||||
{
|
||||
return new Tuple5<A, B, C, D, E>(a, b, c, d, e);
|
||||
}
|
||||
|
||||
/** Constructs an initialized tuple. */
|
||||
public Tuple5 (A a, B b, C c, D d, E e)
|
||||
{
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return "[" + a + "," + b + "," + c + "," + d + "," + e + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode ()
|
||||
{
|
||||
return Objects.hashCode(a, b, c, d, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof Tuple5<?,?,?,?,?>) {
|
||||
Tuple5<?,?,?,?,?> otup = (Tuple5<?,?,?,?,?>)other;
|
||||
return Objects.equal(a, otup.a) && Objects.equal(b, otup.b) &&
|
||||
Objects.equal(c, otup.c) && Objects.equal(d, otup.d) && Objects.equal(e, otup.e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-3
@@ -23,7 +23,7 @@ package com.samskivert.depot;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.samskivert.depot.Tuple2;
|
||||
import com.samskivert.depot.util.*; // TupleN
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -31,9 +31,9 @@ import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests individual field selection.
|
||||
* Tests projection selections, aggregates, etc.
|
||||
*/
|
||||
public class SelectFieldsTest extends TestBase
|
||||
public class ProjectionTest extends TestBase
|
||||
{
|
||||
@Before public void createRecords ()
|
||||
{
|
||||
@@ -70,6 +70,24 @@ public class SelectFieldsTest extends TestBase
|
||||
assertEquals(data, want);
|
||||
}
|
||||
|
||||
@Test public void testTupleN ()
|
||||
{
|
||||
assertEquals(Tuple2.create(1, "Elvis"),
|
||||
_repo.from(TestRecord.class).where(TestRecord.RECORD_ID.eq(1)).
|
||||
load(TestRecord.RECORD_ID, TestRecord.NAME));
|
||||
assertEquals(Tuple3.create(1, "Elvis", 99),
|
||||
_repo.from(TestRecord.class).where(TestRecord.RECORD_ID.eq(1)).
|
||||
load(TestRecord.RECORD_ID, TestRecord.NAME, TestRecord.AGE));
|
||||
assertEquals(Tuple4.create(1, "Elvis", 99, "Right here"),
|
||||
_repo.from(TestRecord.class).where(TestRecord.RECORD_ID.eq(1)).
|
||||
load(TestRecord.RECORD_ID, TestRecord.NAME, TestRecord.AGE,
|
||||
TestRecord.HOME_TOWN));
|
||||
assertEquals(Tuple5.create(1, "Elvis", 99, "Right here", EnumKeyRecord.Type.A),
|
||||
_repo.from(TestRecord.class).where(TestRecord.RECORD_ID.eq(1)).
|
||||
load(TestRecord.RECORD_ID, TestRecord.NAME, TestRecord.AGE,
|
||||
TestRecord.HOME_TOWN, TestRecord.TYPE));
|
||||
}
|
||||
|
||||
@Test public void testProjectedJoin ()
|
||||
{
|
||||
// test a basic join
|
||||
@@ -75,6 +75,7 @@ public abstract class TestBase
|
||||
rec.age = 99;
|
||||
rec.created = now;
|
||||
rec.homeTown = "Right here";
|
||||
rec.type = EnumKeyRecord.Type.A;
|
||||
rec.lastModified = tnow;
|
||||
rec.numbers = new int[] { 9, 0, 2, 1, 0 };
|
||||
return rec;
|
||||
@@ -90,6 +91,7 @@ public abstract class TestBase
|
||||
assertEquals(expect.age, got.age);
|
||||
assertEquals(expect.created, got.created);
|
||||
assertEquals(expect.homeTown, got.homeTown);
|
||||
assertEquals(expect.type, got.type);
|
||||
assertEquals(expect.lastModified, got.lastModified);
|
||||
assertTrue(Arrays.equals(expect.numbers, got.numbers));
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ public class TestRecord extends PersistentRecord
|
||||
public static final ColumnExp<String> NAME = colexp(_R, "name");
|
||||
public static final ColumnExp<Integer> AGE = colexp(_R, "age");
|
||||
public static final ColumnExp<String> HOME_TOWN = colexp(_R, "homeTown");
|
||||
public static final ColumnExp<EnumKeyRecord.Type> TYPE = colexp(_R, "type");
|
||||
public static final ColumnExp<Date> CREATED = colexp(_R, "created");
|
||||
public static final ColumnExp<Timestamp> LAST_MODIFIED = colexp(_R, "lastModified");
|
||||
public static final ColumnExp<int[]> NUMBERS = colexp(_R, "numbers");
|
||||
@@ -58,6 +59,8 @@ public class TestRecord extends PersistentRecord
|
||||
|
||||
public String homeTown;
|
||||
|
||||
public EnumKeyRecord.Type type;
|
||||
|
||||
@Index
|
||||
public Date created;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user