/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002, 2015 Oracle and/or its affiliates. All rights reserved.
*
*/
package com.sleepycat.collections.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.sleepycat.bind.EntityBinding;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.ClassCatalog;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.serial.TupleSerialBinding;
import com.sleepycat.bind.tuple.IntegerBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;
import com.sleepycat.collections.StoredMap;
import com.sleepycat.collections.TransactionRunner;
import com.sleepycat.collections.TransactionWorker;
import com.sleepycat.compat.DbCompat;
import com.sleepycat.db.Database;
import com.sleepycat.db.DatabaseConfig;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.util.test.SharedTestUtils;
import com.sleepycat.util.test.TestBase;
import com.sleepycat.util.test.TestEnv;
/**
* Unit test for [#19085]. The collections API supports storing and retrieving
* null values, as long as the value binding supports null values.
*/
public class NullValueTest extends TestBase
implements TransactionWorker {
private Environment env;
private ClassCatalog catalog;
private Database db;
private TransactionRunner runner;
public NullValueTest() {
customName = "NullValueTest";
}
@Before
public void setUp()
throws Exception {
SharedTestUtils.printTestName(customName);
env = TestEnv.TXN.open(customName);
runner = new TransactionRunner(env);
open();
}
@After
public void tearDown() {
if (catalog != null) {
try {
catalog.close();
} catch (DatabaseException e) {
System.out.println("During tearDown: " + e);
}
}
if (db != null) {
try {
db.close();
} catch (DatabaseException e) {
System.out.println("During tearDown: " + e);
}
}
if (env != null) {
try {
env.close();
} catch (DatabaseException e) {
System.out.println("During tearDown: " + e);
}
}
catalog = null;
db = null;
env = null;
}
private void open()
throws Exception {
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
DbCompat.setTypeBtree(dbConfig);
Database catalogDb = DbCompat.testOpenDatabase(env, null, "catalog",
null, dbConfig);
catalog = new StoredClassCatalog(catalogDb);
db = DbCompat.testOpenDatabase(env, null, "test", null, dbConfig);
}
@Test
public void runTest()
throws Exception {
runner.run(this);
}
public void doWork() {
expectSuccessWithBindingThatDoesSupportNull();
expectExceptionWithBindingThatDoesNotSupportNull();
expectExceptionWithWithEntityBinding();
}
private void expectSuccessWithBindingThatDoesSupportNull() {
/* Pass null for baseClass to support null values. */
final EntryBinding<String> dataBinding =
new SerialBinding<String>(catalog, null /*baseClass*/);
final StoredMap<Integer, String> map = new StoredMap<Integer, String>
(db, new IntegerBinding(), dataBinding, true);
/* Store a null value.*/
map.put(1, null);
/* Get the null value. */
assertNull(map.get(1));
for (String value : map.values()) {
assertNull(value);
}
for (Map.Entry<Integer, String> entry : map.entrySet()) {
assertEquals(Integer.valueOf(1), entry.getKey());
assertNull(entry.getValue());
}
map.remove(1);
}
private void expectExceptionWithBindingThatDoesNotSupportNull() {
/* Pass non-null for baseClass, null values will not be allowed. */
final EntryBinding<String> dataBinding =
new SerialBinding<String>(catalog, String.class /*baseClass*/);
final StoredMap<Integer, String> map = new StoredMap<Integer, String>
(db, new IntegerBinding(), dataBinding, true);
try {
map.put(1, null);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void expectExceptionWithWithEntityBinding() {
final EntityBinding<MyEntity> entityBinding =
new MyEntityBinding(catalog);
final StoredMap<Integer, MyEntity> map =
new StoredMap<Integer, MyEntity>
(db, new IntegerBinding(), entityBinding, true);
try {
map.put(1, null);
fail();
} catch (IllegalArgumentException expected) {
}
}
static class MyEntity {
int key;
String data;
}
static class MyEntityBinding extends TupleSerialBinding<String, MyEntity> {
MyEntityBinding(ClassCatalog catalog) {
super(catalog, String.class);
}
public MyEntity entryToObject(TupleInput keyInput, String data) {
final MyEntity entity = new MyEntity();
entity.key = keyInput.readInt();
entity.data = data;
return entity;
}
public void objectToKey(MyEntity entity, TupleOutput keyOutput) {
keyOutput.writeInt(entity.key);
}
public String objectToData(MyEntity entity) {
return entity.data;
}
}
}