/* HeliDB -- A simple database for Java, http://www.helidb.org
* Copyright (C) 2008, 2009 Karl Gustafsson
*
* This file is a part of HeliDB.
*
* HeliDB 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 3 of the License, or
* (at your option) any later version.
*
* HeliDB 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.helidb.doc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.entityfs.Directory;
import org.entityfs.EFile;
import org.entityfs.support.log.LogAdapterHolder;
import org.entityfs.support.log.StdOutLogAdapter;
import org.entityfs.support.util.TwoObjects;
import org.entityfs.util.Directories;
import org.entityfs.util.FileReadableFile;
import org.entityfs.util.FileSystems;
import org.entityfs.util.Files;
import org.entityfs.util.IteratorDeleter;
import org.entityfs.util.io.ReadWritableFileAdapter;
import org.helidb.Database;
import org.helidb.backend.DatabaseBackend;
import org.helidb.backend.heap.HeapBackend;
import org.helidb.backend.heap.HeapBackendBuilder;
import org.helidb.backend.index.bplus.BPlusTreeIndexBackendBuilder;
import org.helidb.impl.simple.SimpleDatabase;
import org.helidb.impl.txn.log.LoggingTransactionalDatabase;
import org.helidb.lang.hasher.IntegerToIntegerHasher;
import org.helidb.lang.serializer.IntegerNullSerializer;
import org.helidb.lang.serializer.IntegerSerializer;
import org.helidb.lang.serializer.LongSerializer;
import org.helidb.lang.serializer.StringSerializer;
import org.helidb.test.support.FileSupport;
import org.helidb.txn.Transaction;
import org.helidb.util.bplus.BPlusTree;
import org.helidb.util.bplus.FileBackedNodeRepositoryBuilder;
import org.helidb.util.bplus.FixedSizeNodeSizeStrategy;
import org.helidb.util.bplus.NodeRepository;
import org.junit.Test;
public class ProgrammersGuideExamplesTest extends AbstractExamplesTest
{
@Test
@SuppressWarnings("unchecked")
public void testExDatabase() throws IOException
{
Database<String, String> db = null;
File f = FileSupport.createTempFile();
try
{
Object o = runExampleMethodTest("pg/ex/ex_database.javaa", "java.io.File f = (java.io.File) args[0];\r\n", "return db;", null, new Object[] { f }, null);
db = (Database<String, String>) o;
assertEquals(2, db.size());
assertEquals("value 1", db.get("key 1"));
assertEquals("value 2", db.get("key 2"));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete());
}
}
@Test
public void testExTransaction() throws IOException
{
String codePrefix = "org.helidb.txn.TransactionalDatabase<String, String> db1 = (org.helidb.txn.TransactionalDatabase<String, String>) args[0];\r\norg.helidb.txn.TransactionalDatabase<String, String> db2 = (org.helidb.txn.TransactionalDatabase<String, String>) args[1];\r\n";
LogAdapterHolder lah = new LogAdapterHolder(new StdOutLogAdapter());
File f1 = FileSupport.createTempFile();
File f1l = FileSupport.createTempFile();
File f2 = FileSupport.createTempFile();
File f2l = FileSupport.createTempFile();
try
{
LoggingTransactionalDatabase<String, String, Long> db1 = new LoggingTransactionalDatabase<String, String, Long>(new HeapBackend<String, String>(new ReadWritableFileAdapter(f1), false, StringSerializer.INSTANCE, StringSerializer.INSTANCE, lah), new ReadWritableFileAdapter(f1l), StringSerializer.INSTANCE, StringSerializer.INSTANCE, lah);
try
{
LoggingTransactionalDatabase<String, String, Long> db2 = new LoggingTransactionalDatabase<String, String, Long>(new HeapBackend<String, String>(new ReadWritableFileAdapter(f2), false, StringSerializer.INSTANCE, StringSerializer.INSTANCE, lah), new ReadWritableFileAdapter(f2l), StringSerializer.INSTANCE, StringSerializer.INSTANCE, lah);
try
{
Transaction txn = Transaction.startTransaction(false);
db2.insert("years", "2007");
txn.commit();
runExampleMethodTest("pg/ex/ex_transaction.javaa", codePrefix, "return null;\r\n", null, new Object[] { db1, db2 }, null);
txn = Transaction.startTransaction(true);
try
{
assertEquals(1, db1.size());
assertTrue(db1.containsKey("lastUpdate"));
assertEquals(1, db2.size());
assertEquals("2007, 2008", db2.get("years"));
}
finally
{
txn.rollback();
}
}
finally
{
db2.close();
}
}
finally
{
db1.close();
}
}
finally
{
assertTrue(f1.delete() & f1l.delete() & f2.delete() & f2l.delete());
}
}
@Test
public void testExLoggingTransactionalDb() throws IOException
{
String codePrefix = "java.io.File f = (java.io.File) args[0]; java.io.File lf = (java.io.File) args[1];";
File f = FileSupport.createTempFile();
File lf = FileSupport.createTempFile();
try
{
runExampleMethodTest("pg/ex/ex_logging_transactional_db.javaa", codePrefix, "db.close(); return null;", null, new Object[] { f, lf }, null);
}
finally
{
assertTrue(f.delete() & lf.delete());
}
}
@Test
public void testExScTransactionalDb() throws IOException
{
String codePrefix = "org.entityfs.EFile f = (org.entityfs.EFile) args[0]; org.entityfs.Directory tmpDir = (org.entityfs.Directory) args[1];";
File d = FileSupport.createTempDirectory();
Directory root = FileSystems.getEntityForDirectory(d, false);
try
{
EFile f = Directories.newFile(root, "f");
runExampleMethodTest("pg/ex/ex_sc_transactional_db.javaa", codePrefix, "return null;", null, new Object[] { f, root }, null);
}
finally
{
new IteratorDeleter(root).delete();
assertTrue(d.delete());
}
}
@Test
@SuppressWarnings("unchecked")
public void testExCrsHeapBackend() throws IOException
{
Database<Integer, Long> db = null;
File f = FileSupport.createTempFile();
try
{
Object o = runExampleMethodTest("pg/ex/ex_crs_heap_backend.javaa", "java.io.File f = (java.io.File) args[0];\r\n", "return db;", null, new Object[] { f }, null);
db = (Database<Integer, Long>) o;
assertEquals(7, db.size());
assertEquals(Long.valueOf(1), db.get(1));
assertEquals(Long.valueOf(1), db.get(2));
assertEquals(Long.valueOf(2), db.get(3));
assertEquals(Long.valueOf(3), db.get(4));
assertEquals(Long.valueOf(5), db.get(5));
assertEquals(Long.valueOf(8), db.get(6));
assertEquals(Long.valueOf(13), db.get(7));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete());
}
}
@Test
@SuppressWarnings("unchecked")
public void testExCrsBplusTreeBackend() throws IOException
{
Database<Integer, String> db = null;
File f = FileSupport.createTempFile();
try
{
Object o = runExampleMethodTest("pg/ex/ex_crs_bplus_tree_backend.javaa", "java.io.File f = (java.io.File) args[0];\r\n", "return db;", null, new Object[] { f }, null);
db = (Database<Integer, String>) o;
assertEquals(6, db.size());
assertEquals("apple", db.get(1));
assertEquals("banana", db.get(2));
assertEquals("grapefruit", db.get(3));
assertEquals("orange", db.get(4));
assertEquals("tangerine", db.get(5));
assertEquals("pear", db.get(6));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete());
}
}
@Test
@SuppressWarnings("unchecked")
public void testExBplusIndexAndHeapBackend() throws IOException
{
Database<String, String> db = null;
File f = FileSupport.createTempFile();
File indf = FileSupport.createTempFile();
try
{
Object o = runExampleMethodTest("pg/ex/ex_bplus_index_and_heap_backend.javaa", "java.io.File f = (java.io.File) args[0]; java.io.File indf = (java.io.File) args[1];\r\n", "return db;", null, new Object[] { f, indf }, null);
db = (Database<String, String>) o;
assertEquals(1, db.size());
assertEquals("oranges", db.get("apples"));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete() & indf.delete());
}
}
@Test
@SuppressWarnings("unchecked")
public void testExLruCacheBplusIndexAndHeapBackend() throws IOException
{
Database<String, String> db = null;
File f = FileSupport.createTempFile();
File indf = FileSupport.createTempFile();
try
{
Object o = runExampleMethodTest("pg/ex/ex_lru_cache_bplus_index_and_heap_backend.javaa", "java.io.File f = (java.io.File) args[0]; java.io.File indf = (java.io.File) args[1];\r\n", "return db;", null, new Object[] { f, indf }, null);
db = (Database<String, String>) o;
assertEquals(1, db.size());
assertEquals("Ritmo", db.get("Fiat"));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete() & indf.delete());
}
}
@Test
public void testUsingCursor() throws IOException
{
LogAdapterHolder lah = new LogAdapterHolder(new StdOutLogAdapter());
Database<Integer, String> db = null;
File f = FileSupport.createTempFile();
File indf = FileSupport.createTempFile();
try
{
NodeRepository<Integer> nr = new FileBackedNodeRepositoryBuilder<Integer, Long>().setNodeSizeStrategy(new FixedSizeNodeSizeStrategy(4096)).setKeySerializer(IntegerNullSerializer.INSTANCE).setValueSerializer(LongSerializer.INSTANCE).setInternalPointerSize(1).setLogAdapterHolder(lah).create(new ReadWritableFileAdapter(indf), false);
BPlusTree<Integer, Long> bt = new BPlusTree<Integer, Long>(nr, lah);
DatabaseBackend<Integer, String, Long> hb = new HeapBackendBuilder<Integer, String>().setKeySerializer(IntegerSerializer.INSTANCE).setLogAdapterHolder(lah).setValueSerializer(StringSerializer.INSTANCE).create(new ReadWritableFileAdapter(f));
DatabaseBackend<Integer, String, Long> b = new BPlusTreeIndexBackendBuilder<Integer, Integer>().setKeyHasher(IntegerToIntegerHasher.INSTANCE).setLogAdapterHolder(lah).create(hb, bt);
db = new SimpleDatabase<Integer, String, Long>(b, lah);
db.insert(10, "Roger");
db.insert(42, "Phil");
db.insert(33, "Monica");
db.insert(65, "Bill");
db.insert(48, "Peter");
List<TwoObjects<String, String>> replaces = new ArrayList<TwoObjects<String, String>>();
replaces.add(new TwoObjects<String, String>("System.out.println", "l.add"));
replaces.add(new TwoObjects<String, String>("return", "return null"));
List<String> l = new ArrayList<String>();
runExampleMethodTest("pg/ex/ex_using_cursor_to_find_records_to_process.javaa", "org.helidb.Database<Integer, String> db = (org.helidb.Database<Integer, String>) args[0]; java.util.List<String> l = (java.util.List<String>) args[1];", "return null;", null, new Object[] { db, l }, replaces);
assertEquals(2, l.size());
assertEquals("42: Phil", l.get(0));
assertEquals("48: Peter", l.get(1));
}
finally
{
if (db != null)
{
db.close();
}
assertTrue(f.delete() & indf.delete());
}
}
@Test
public void testUsingTheMoneySerializer() throws IOException
{
File targetD = FileSupport.createTempDirectory();
File f = File.createTempFile("tmp", "tmp", targetD);
Directory targetDir = FileSystems.getEntityForDirectory(targetD, false);
try
{
compileClass("Currency", runReplaces(Files.readTextFile(new FileReadableFile(getDocFile("pg/ex/serializer/ex_Currency.javaa"))), null), targetDir);
compileClass("Money", runReplaces(Files.readTextFile(new FileReadableFile(getDocFile("pg/ex/serializer/ex_Money.javaa"))), null), targetDir);
compileClass("MoneySerializer", runReplaces(Files.readTextFile(new FileReadableFile(getDocFile("pg/ex/serializer/ex_MoneySerializer.javaa"))), null), targetDir);
List<TwoObjects<String, String>> replaces = new ArrayList<TwoObjects<String, String>>();
replaces.add(new TwoObjects<String, String>("MoneySerializer", "MoooneySerializer"));
replaces.add(new TwoObjects<String, String>("Money", "org.helidb.javabank.Money"));
replaces.add(new TwoObjects<String, String>("MoooneySerializer", "org.helidb.javabank.MoneySerializer"));
replaces.add(new TwoObjects<String, String>("Currency", "org.helidb.javabank.Currency"));
runExampleMethodTest("pg/ex/serializer/ex_using_the_money_serializer.javaa", "java.io.File f = (java.io.File) args[0];\r\n", "db.close(); return null;", null, new Object[] { f }, replaces, targetDir);
}
finally
{
new IteratorDeleter(targetDir).delete();
targetDir.getFileSystem().close();
assertTrue(targetD.delete());
}
}
}