/* * Copyright 2013 Gordon Burgett and individual contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xflatdb.xflat.engine; import java.io.File; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import org.xflatdb.xflat.ShardsetConfig; import org.xflatdb.xflat.Table; import org.xflatdb.xflat.TableConfig; import org.xflatdb.xflat.db.BigIntIdGenerator; import org.xflatdb.xflat.db.XFlatDatabase; import org.xflatdb.xflat.query.NumericIntervalProvider; import org.xflatdb.xflat.query.XPathQuery; import org.jdom2.Element; import org.junit.BeforeClass; import org.junit.Test; import test.Foo; import test.Utils; import static org.junit.Assert.*; import org.xflatdb.xflat.Id; import org.xflatdb.xflat.db.TimestampIdGenerator; /** * * @author Gordon */ public class IdShardedEngineIntegrationTests { static File workspace = new File(new File("DbIntegrationTests"), "IdShardedEngineIntegrationTests"); static String tbl = "table"; @BeforeClass public static void setUpClass(){ if(workspace.exists()){ Utils.deleteDir(workspace); } } private XFlatDatabase getDatabase(String testName){ return getDatabase(testName, TableConfig.DEFAULT .withIdGenerator(BigIntIdGenerator.class) .sharded(ShardsetConfig.by(XPathQuery.Id, Integer.class, NumericIntervalProvider.forInteger(2, 100)))); } private XFlatDatabase getDatabase(String testName, TableConfig config){ File dbDir = new File(workspace, testName); XFlatDatabase ret = (XFlatDatabase)XFlatDatabase.Build(dbDir) .withTableConfig(tbl, config) .create(); ret.getConversionService().addConverter(Foo.class, Element.class, new Foo.ToElementConverter()); ret.getConversionService().addConverter(Element.class, Foo.class, new Foo.FromElementConverter()); return ret; } @Test public void testInsertRetrieve_SingleShard_OneFileCreated() throws Exception { String testName = "testInsertRetrieve_SingleShard_OneFileCreated"; System.out.println(testName); XFlatDatabase db = getDatabase(testName); Table<Foo> table = db.getTable(Foo.class, tbl); Foo foo = new Foo(); foo.fooInt = 1; table.insert(foo); Foo foo2 = table.find(foo.getId()); assertEquals("should retrieve same data", foo, foo2); db.shutdown(); File shardDir = new File(new File(workspace, testName), tbl + ".xml"); assertTrue("shard directory should exist", shardDir.exists()); assertTrue("shard directory should be a directory", shardDir.isDirectory()); File[] shards = shardDir.listFiles(); assertEquals("should be one shard", 1, shards.length); assertTrue("Should be named after the range of data", new File(shardDir, "-98.xml").exists()); } @Test public void testInsertRetrieve_MultipleShards_MultipleFilesCreated() throws Exception { String testName = "testInsertRetrieve_MultipleShards_MultipleFilesCreated"; System.out.println(testName); XFlatDatabase db = getDatabase(testName); Table<Foo> table = db.getTable(Foo.class, tbl); Foo foo = new Foo(); foo.fooInt = 1; table.insert(foo); foo = new Foo(); foo.fooInt = 2; table.insert(foo); foo = new Foo(); foo.fooInt = 3; table.insert(foo); List<Foo> fooList = table.findAll(XPathQuery.gt(XPathQuery.Id, 1)); //can't trust ordering of a query Collections.sort(fooList, new Comparator<Foo>(){ @Override public int compare(Foo o1, Foo o2) { return o1.getId().compareTo(o2.getId()); } }); assertEquals("Should get 2 foos", 2, fooList.size()); assertEquals("should retrieve same data", 2, fooList.get(0).fooInt); assertEquals("should retrieve same data", 3, fooList.get(1).fooInt); db.shutdown(); File shardDir = new File(new File(workspace, testName), this.tbl + ".xml"); assertTrue("shard directory should exist", shardDir.exists()); assertTrue("shard directory should be a directory", shardDir.isDirectory()); File[] shards = shardDir.listFiles(); assertEquals("should be two shards", 2, shards.length); assertTrue("Should be named after the range of data", new File(shardDir, "-98.xml").exists()); assertTrue("Should be named after the range of data", new File(shardDir, "2.xml").exists()); } @Test public void testInsertRetrieve_DifferentIdRepresentation_UsesIdGeneratorForConversion() throws Exception { String testName = "testInsertRetrieve_DifferentIdRepresentation_UsesIdGeneratorForConversion"; System.out.println(testName); XFlatDatabase db = getDatabase(testName, new TableConfig() .withIdGenerator(TimestampIdGenerator.class) .sharded(ShardsetConfig.by(XPathQuery.Id, Long.class, NumericIntervalProvider.forLong(2, 100)))); Table<FooLongId> table = db.getTable(FooLongId.class, tbl); FooLongId foo = new FooLongId(); foo.setFooString("junk"); table.insert(foo); FooLongId foo2 = table.find(foo.getId()); assertEquals("should retrieve same data", foo, foo2); db.shutdown(); } } @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) class FooLongId { @Id private Long id; public Long getId(){ return id; } @XmlElement private String fooString; /** * Gets the fooString. */ public String getFooString(){ return this.fooString; } /** * Sets the fooString. */ public void setFooString(String fooString){ this.fooString = fooString; } @Override public int hashCode() { int hash = 5; hash = 97 * hash + Objects.hashCode(this.id); hash = 97 * hash + Objects.hashCode(this.fooString); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final FooLongId other = (FooLongId) obj; if (!Objects.equals(this.id, other.id)) { return false; } if (!Objects.equals(this.fooString, other.fooString)) { return false; } return true; } @Override public String toString() { return "FooLongId{" + "id=" + id + ", fooString=" + fooString + '}'; } }