diff --git a/etc/libs-incl.xml b/etc/libs-incl.xml index cab29fe..6d983e7 100644 --- a/etc/libs-incl.xml +++ b/etc/libs-incl.xml @@ -2,10 +2,14 @@ - - - + + + + + + + diff --git a/src/java/com/samskivert/depot/tests/CrudTest.java b/src/java/com/samskivert/depot/tests/CrudTest.java new file mode 100644 index 0000000..469faaf --- /dev/null +++ b/src/java/com/samskivert/depot/tests/CrudTest.java @@ -0,0 +1,82 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2009 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.tests; + +import java.util.Arrays; + +import com.google.common.collect.ImmutableMap; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Tests simple create/read/update/delete behaviors. + */ +public class CrudTest extends TestBase +{ + @Test public void testCreateReadDelete () + { + TestRecord in = createTestRecord(1); + _repo.insert(in); + + TestRecord out = _repo.loadNoCache(in.recordId); + assertNotNull(out != null); // we got a result + assertTrue(in != out); // it didn't come from the cache + + // make sure all of the fields were marshalled and unmarshalled correctly + assertTestRecordEquals(in, out); + + // finally clean up after ourselves + _repo.delete(TestRecord.getKey(in.recordId)); + assertNull(_repo.loadNoCache(in.recordId)); + } + + @Test public void testUpdateDelete () + { + TestRecord in = createTestRecord(1); + _repo.insert(in); + + // first try updating using the whole-record update mechanism + in.homeTown = "Funky Town"; + _repo.update(in); + assertTestRecordEquals(in, _repo.loadNoCache(in.recordId)); + + // then try update partial + String name = "Bob"; + int age = 25; + int[] numbers = { 1, 2, 3, 4, 5 }; + _repo.updatePartial(TestRecord.getKey(in.recordId), + ImmutableMap.of(TestRecord.NAME, name, TestRecord.AGE, age, + TestRecord.NUMBERS, numbers)); + TestRecord up = _repo.loadNoCache(in.recordId); + assertEquals(name, up.name); + assertEquals(age, up.age); + assertTrue(Arrays.equals(numbers, up.numbers)); + + // finally clean up after ourselves + _repo.delete(TestRecord.getKey(in.recordId)); + assertNull(_repo.loadNoCache(in.recordId)); + } + + // 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(); +} diff --git a/src/java/com/samskivert/depot/tests/QueryTest.java b/src/java/com/samskivert/depot/tests/QueryTest.java new file mode 100644 index 0000000..8473544 --- /dev/null +++ b/src/java/com/samskivert/depot/tests/QueryTest.java @@ -0,0 +1,104 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2009 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.tests; + +import java.util.Collections; + +import com.google.common.collect.Sets; +import com.samskivert.util.RandomUtil; + +import com.samskivert.depot.Exps; +import com.samskivert.depot.Key; +import com.samskivert.depot.KeySet; +import com.samskivert.depot.PersistentRecord; +import com.samskivert.depot.annotation.Computed; +import com.samskivert.depot.clause.Where; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * Tests queries. + */ +public class QueryTest extends TestBase +{ + @Computed(shadowOf=TestRecord.class) + public static class TestNameRecord extends PersistentRecord + { + public int recordId; + public String name; + + @Override public String toString () { + return recordId + ":" + name; + } + } + + @Test public void testQueries () + { + for (int ii = 1; ii <= CREATE_RECORDS; ii++) { + TestRecord record = createTestRecord(ii); + record.name = "Spam! " + ii; + record.age = RandomUtil.getInt(100); + record.homeTown = "Over there"; + _repo.insert(record); + } + + // test the empty key set + KeySet none = KeySet.newKeySet( + TestRecord.class, Collections.>emptySet()); + assertEquals(0, _repo.deleteAll(TestRecord.class, none)); + + // test collection caching (TODO: check that the records are ==) + Where where = new Where(TestRecord.RECORD_ID.greaterThan(CREATE_RECORDS-50)); + assertEquals(50, _repo.findAll(TestRecord.class, where).size()); + assertEquals(50, _repo.findAll(TestRecord.class, where).size()); + + // test a partial key set + KeySet some = KeySet.newSimpleKeySet( + TestRecord.class, Sets.newHashSet(1, 3, 5, 7, 9)); + assertEquals(5, _repo.loadAll(some.toCollection()).size()); + + // make sure our computed records work + for (TestNameRecord tnr : _repo.findAll(TestNameRecord.class)) { + assertEquals("Spam! " + tnr.recordId, tnr.name); + } + + assertEquals(CREATE_RECORDS, _repo.findAll(TestRecord.class).size()); + _repo.deleteAll(TestRecord.class, new Where(TestRecord.RECORD_ID.lessEq(CREATE_RECORDS/2))); + assertEquals(CREATE_RECORDS/2, _repo.findAll(TestRecord.class).size()); + + _repo.deleteAll(TestRecord.class, new Where(Exps.literal("true"))); + assertEquals(0, _repo.findAll(TestRecord.class).size()); + +// // TODO: try to break our In() clause +// Set ids = Sets.newHashSet(); +// for (int ii = 1; ii <= In.MAX_KEYS*2+3; ii++) { +// ids.add(ii); +// } +// _repo.deleteAll(TestRecord.class, KeySet.newSimpleKeySet(TestRecord.class, ids)); + } + + // 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(); + + protected static final int CREATE_RECORDS = 150; +} diff --git a/src/java/com/samskivert/depot/tests/TestBase.java b/src/java/com/samskivert/depot/tests/TestBase.java new file mode 100644 index 0000000..dd48aaa --- /dev/null +++ b/src/java/com/samskivert/depot/tests/TestBase.java @@ -0,0 +1,98 @@ +// +// $Id$ +// +// Depot library - a Java relational persistence library +// Copyright (C) 2006-2009 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.tests; + +import java.sql.Date; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Properties; + +import com.samskivert.jdbc.StaticConnectionProvider; +import com.samskivert.util.Calendars; + +import com.samskivert.depot.PersistenceContext; + +import static org.junit.Assert.*; + +/** + * Contains shared code to set up in-memory databases for unit testing. + */ +public abstract class TestBase +{ + /** + * Creates a persistence context configured to run against an (empty) in-memory HSQLDB. + * Note: the in-memory HSQL database is shared for the duration of the VM, so tests have + * to clean up after themselves to avoid conflicting with one another. + */ + protected PersistenceContext createPersistenceContext () + { + Properties props = new Properties(); + props.put("default.driver", "org.hsqldb.jdbcDriver"); + props.put("default.url", "jdbc:hsqldb:mem:test"); + props.put("default.username", "sa"); + props.put("default.password", ""); + + PersistenceContext perCtx = new PersistenceContext(); + perCtx.init("test", new StaticConnectionProvider(props), new TestCacheAdapter()); + return perCtx; + } + + /** + * If a test doesn't need any special repository setup, it can use this method to create a + * fresh persistence context and test repository in one fell swoop. + */ + protected TestRepository createTestRepository () + { + return new TestRepository(createPersistenceContext()); + } + + /** + * Creates a test record with all fields initialized to valid values. + */ + protected TestRecord createTestRecord (int recordId) + { + Date now = Calendars.now().zeroTime().toSQLDate(); + Timestamp tnow = new Timestamp(System.currentTimeMillis()); + TestRecord rec = new TestRecord(); + rec.recordId = recordId; + rec.name = "Elvis"; + rec.age = 99; + rec.created = now; + rec.homeTown = "Right here"; + rec.lastModified = tnow; + rec.numbers = new int[] { 9, 0, 2, 1, 0 }; + return rec; + } + + /** + * Confirms that the supplied test records are field-by-field equal. + */ + protected void assertTestRecordEquals (TestRecord expect, TestRecord got) + { + assertEquals(expect.recordId, got.recordId); + assertEquals(expect.name, got.name); + assertEquals(expect.age, got.age); + assertEquals(expect.created, got.created); + assertEquals(expect.homeTown, got.homeTown); + assertEquals(expect.lastModified, got.lastModified); + assertTrue(Arrays.equals(expect.numbers, got.numbers)); + } +} diff --git a/src/java/com/samskivert/depot/tests/TestRecord.java b/src/java/com/samskivert/depot/tests/TestRecord.java index 5bf6853..bf8374b 100644 --- a/src/java/com/samskivert/depot/tests/TestRecord.java +++ b/src/java/com/samskivert/depot/tests/TestRecord.java @@ -60,7 +60,7 @@ public class TestRecord extends PersistentRecord public String homeTown; - @Index + // @Index // TODO: this horks HSQLDB public Date created; public Timestamp lastModified; diff --git a/src/java/com/samskivert/depot/tests/TestRepository.java b/src/java/com/samskivert/depot/tests/TestRepository.java index 96d1cc6..3bc9266 100644 --- a/src/java/com/samskivert/depot/tests/TestRepository.java +++ b/src/java/com/samskivert/depot/tests/TestRepository.java @@ -20,130 +20,25 @@ package com.samskivert.depot.tests; -import java.sql.Date; -import java.sql.Timestamp; -import java.util.Collections; import java.util.Set; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; - -import com.samskivert.jdbc.StaticConnectionProvider; -import com.samskivert.util.RandomUtil; - import com.samskivert.depot.DepotRepository; -import com.samskivert.depot.Key; -import com.samskivert.depot.KeySet; import com.samskivert.depot.PersistenceContext; import com.samskivert.depot.PersistentRecord; -import com.samskivert.depot.SchemaMigration; -import com.samskivert.depot.annotation.Computed; -import com.samskivert.depot.clause.Where; -import com.samskivert.depot.impl.expression.LiteralExp; -import com.samskivert.depot.impl.operator.GreaterThan; -import com.samskivert.depot.impl.operator.LessThan; /** * A test tool for the Depot repository services. */ public class TestRepository extends DepotRepository { - @Computed(shadowOf=TestRecord.class) - public static class TestNameRecord extends PersistentRecord + public TestRecord loadNoCache (int recordId) { - public int recordId; - public String name; - - @Override public String toString () { - return recordId + ":" + name; - } + return load(TestRecord.getKey(recordId), CacheStrategy.NONE); } - public static void main (String[] args) - throws Exception + public TestRecord loadWithCache (int recordId) { - PersistenceContext perCtx = new PersistenceContext(); - perCtx.init("test", new StaticConnectionProvider("depot.properties"), - new TestCacheAdapter()); - - // tests a bogus rename migration - // perCtx.registerMigration(TestRecord.class, new SchemaMigration.Rename(1, "foo", "bar")); - - // tests a custom add column migration - perCtx.registerMigration(TestRecord.class, - new SchemaMigration.Add(2, TestRecord.HOME_TOWN, "'Anytown USA'")); - - TestRepository repo = new TestRepository(perCtx); - - System.out.println("Deleting old record."); - repo.delete(TestRecord.getKey(1)); - - Date now = new Date(System.currentTimeMillis()); - Timestamp tnow = new Timestamp(System.currentTimeMillis()); - - TestRecord record = new TestRecord(); - record.recordId = 1; - record.name = "Elvis"; - record.age = 99; - record.created = now; - record.homeTown = "Right here"; - record.lastModified = tnow; - record.numbers = new int[] { 9, 0, 2, 1, 0 }; - - repo.insert(record); - System.out.println("Record: " + repo.load(TestRecord.getKey(record.recordId))); - -// record.age = 25; -// record.name = "Bob"; -// record.numbers = new int[] { 1, 2, 3, 4, 5 }; -// repo.update(record, TestRecord.AGE, TestRecord.NAME, TestRecord.NUMBERS); - - repo.updatePartial(TestRecord.getKey(record.recordId), - ImmutableMap.of(TestRecord.AGE, 25, TestRecord.NAME, "Bob", - TestRecord.NUMBERS, new int[] { 1, 2, 3, 4, 5 })); - System.out.println("Updated " + repo.load(TestRecord.getKey(record.recordId))); - - for (int ii = 2; ii < CREATE_RECORDS; ii++) { - record = new TestRecord(); - record.recordId = ii; - record.name = "Spam!"; - record.age = RandomUtil.getInt(150); - record.homeTown = "Over there"; - record.numbers = new int[] { 5, 4, 3, 2, 1 }; - record.created = now; - record.lastModified = tnow; - repo.insert(record); - } - - // test the empty ky set - KeySet none = KeySet.newKeySet( - TestRecord.class, Collections.>emptySet()); - System.out.println("Load none " + repo.loadAll(none.toCollection()) + "."); - System.out.println("Delete none " + repo.deleteAll(TestRecord.class, none) + "."); - - // test collection caching - Where where = new Where(new GreaterThan(TestRecord.RECORD_ID, 100)); - System.out.println("100 and up: " + repo.findAll(TestRecord.class, where).size()); - System.out.println("100 and up again: " + repo.findAll(TestRecord.class, where).size()); - - // test a partial key set - KeySet some = KeySet.newSimpleKeySet( - TestRecord.class, Sets.newHashSet(1, 3, 5, 7, 9)); - System.out.println("Load some " + repo.loadAll(some.toCollection()) + "."); - - System.out.println("Names " + repo.findAll(TestNameRecord.class) + "."); - System.out.println("Have " + repo.findAll(TestRecord.class).size() + " records."); - repo.deleteAll(TestRecord.class, new Where(new LessThan( - TestRecord.RECORD_ID, CREATE_RECORDS/2))); - System.out.println("Now have " + repo.findAll(TestRecord.class).size() + " records."); - repo.deleteAll(TestRecord.class, new Where(new LiteralExp("true"))); -// // TODO: try to break our In() clause -// Set ids = Sets.newHashSet(); -// for (int ii = 1; ii <= In.MAX_KEYS*2+3; ii++) { -// ids.add(ii); -// } -// repo.deleteAll(TestRecord.class, KeySet.newSimpleKeySet(TestRecord.class, ids)); - System.out.println("Now have " + repo.findAll(TestRecord.class).size() + " records."); + return load(TestRecord.getKey(recordId)); } public TestRepository (PersistenceContext perCtx) @@ -156,6 +51,4 @@ public class TestRepository extends DepotRepository { classes.add(TestRecord.class); } - - protected static final int CREATE_RECORDS = 150; }