From 84758df7251342470c4a592291286426b0fcd371 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Wed, 8 Dec 2010 20:03:27 +0000 Subject: [PATCH] Added support for joins when doing field selections: List> jdata = _repo.from(TestRecord.class). join(TestRecord.NAME, EnumKeyRecord.NAME). select(TestRecord.RECORD_ID, EnumKeyRecord.TYPE); This should eliminate the need for pesky one-off computed records when doing ad-hoc joins. --- .../samskivert/depot/impl/FindAllQuery.java | 13 +++- .../samskivert/depot/SelectFieldsTest.java | 72 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/samskivert/depot/SelectFieldsTest.java diff --git a/src/main/java/com/samskivert/depot/impl/FindAllQuery.java b/src/main/java/com/samskivert/depot/impl/FindAllQuery.java index 8d5ca5c..0a37441 100644 --- a/src/main/java/com/samskivert/depot/impl/FindAllQuery.java +++ b/src/main/java/com/samskivert/depot/impl/FindAllQuery.java @@ -308,6 +308,14 @@ public abstract class FindAllQuery public ColumnSetQueryMarshaller (PersistenceContext ctx, ColumnSet cset) { _cset = cset; _cmarsh = ctx.getMarshaller(cset.ptype); + _marshes = Maps.newHashMap(); + _marshes.put(cset.ptype, _cmarsh); + for (ColumnExp cexp : cset.columns) { + Class cclass = cexp.getPersistentClass(); + if (!_marshes.containsKey(cclass)) { + _marshes.put(cclass, ctx.getMarshaller(cexp.getPersistentClass())); + } + } } public String getTableName () { @@ -325,13 +333,16 @@ public abstract class FindAllQuery public R createObject (ResultSet rs) throws SQLException { Object[] data = new Object[_cset.columns.length]; for (int ii = 0; ii < data.length; ii++) { - data[ii] = _cmarsh.getFieldMarshaller(_cset.columns[ii].name).getFromSet(rs); + ColumnExp col = _cset.columns[ii]; + data[ii] = _marshes.get(col.getPersistentClass()). + getFieldMarshaller(col.name).getFromSet(rs, ii+1); } return _cset.createObject(data); } protected ColumnSet _cset; protected DepotMarshaller _cmarsh; + protected Map, DepotMarshaller> _marshes; } // from Query diff --git a/src/test/java/com/samskivert/depot/SelectFieldsTest.java b/src/test/java/com/samskivert/depot/SelectFieldsTest.java new file mode 100644 index 0000000..f314bcf --- /dev/null +++ b/src/test/java/com/samskivert/depot/SelectFieldsTest.java @@ -0,0 +1,72 @@ +// +// $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; + +import java.util.List; + +import com.google.common.collect.Lists; +import com.samskivert.depot.Tuple2; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Tests individual field selection. + */ +public class SelectFieldsTest extends TestBase +{ + @Test public void testCreateReadDelete () + { + for (int ii = 0; ii < 10; ii++) { + _repo.insert(createTestRecord(ii)); + } + _repo.insert(new EnumKeyRecord(EnumKeyRecord.Type.A, "Elvis")); + _repo.insert(new EnumKeyRecord(EnumKeyRecord.Type.B, "Moses")); + _repo.insert(new EnumKeyRecord(EnumKeyRecord.Type.C, "Abraham")); + _repo.insert(new EnumKeyRecord(EnumKeyRecord.Type.D, "Elvis")); + + // test some basic one and two column selects + List allKeys = _repo.from(TestRecord.class).select(TestRecord.RECORD_ID); + assertEquals(allKeys, Lists.newArrayList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + + List someKeys = _repo.from(TestRecord.class).where( + TestRecord.RECORD_ID.greaterThan(5)).select(TestRecord.RECORD_ID); + assertEquals(someKeys, Lists.newArrayList(6, 7, 8, 9)); + + List> data = _repo.from(TestRecord.class).where( + TestRecord.RECORD_ID.greaterThan(7)).select(TestRecord.RECORD_ID, TestRecord.NAME); + assertEquals(data, Lists.newArrayList(Tuple2.newTuple(8, "Elvis"), + Tuple2.newTuple(9, "Elvis"))); + + // test a basic join + List> jdata = _repo.from(TestRecord.class).join( + TestRecord.NAME, EnumKeyRecord.NAME).select(TestRecord.RECORD_ID, EnumKeyRecord.TYPE); + System.out.println(jdata); + + // finally clean up after ourselves + _repo.from(TestRecord.class).where(Exps.trueLiteral()).delete(); + _repo.from(EnumKeyRecord.class).where(Exps.trueLiteral()).delete(); + } + + // the HSQL in-memory database persists for the lifetime of the VM, which means we have to + // clean up after ourselves in every test; thus we go ahead and share a repository + protected TestRepository _repo = createTestRepository(); +}