package org.hivedb.meta;
import org.hivedb.Hive;
import org.hivedb.HiveLockableException;
import org.hivedb.Lockable.Status;
import org.hivedb.Schema;
import org.hivedb.configuration.HiveConfigurationSchema;
import org.hivedb.management.HiveConfigurationSchemaInstaller;
import org.hivedb.meta.directory.DbDirectory;
import org.hivedb.meta.directory.Directory;
import org.hivedb.meta.directory.DirectoryWrapper;
import static org.hivedb.meta.directory.DirectoryWrapper.semaphoreToId;
import org.hivedb.meta.directory.KeySemaphore;
import org.hivedb.meta.persistence.CachingDataSourceProvider;
import org.hivedb.meta.persistence.IndexSchema;
import org.hivedb.util.AssertUtils;
import org.hivedb.util.Lists;
import org.hivedb.util.database.HiveDbDialect;
import org.hivedb.util.database.test.H2TestCase;
import org.hivedb.util.functional.Atom;
import org.hivedb.util.functional.Transform;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
import java.sql.Types;
import java.util.*;
public class DirectoryTest extends H2TestCase {
private PartitionDimension dimension;
private SecondaryIndex nameIndex, numIndex;
private String secondaryKeyString = "secondary key";
private Integer secondaryKeyNum = 1;
private Resource resource;
public Collection<Schema> getSchemas() {
return Arrays.asList(new Schema[]{
new HiveConfigurationSchema(getConnectString(H2TestCase.TEST_DB)),
new IndexSchema(createPopulatedPartitionDimension())});
}
private void prepare() {
try {
new HiveConfigurationSchemaInstaller(getConnectString(H2TestCase.TEST_DB)).run();
Hive hive = Hive.create(getConnectString(H2TestCase.TEST_DB), partitionDimensionName(), Types.INTEGER, CachingDataSourceProvider.getInstance(), null);
dimension = createPopulatedPartitionDimension();
dimension.setId(hive.getPartitionDimension().getId());
hive.setPartitionDimension(dimension);
resource = Atom.getFirstOrThrow(dimension.getResources());
hive.addResource(resource);
numIndex = resource.getSecondaryIndex("num");
nameIndex = resource.getSecondaryIndex("name");
for (SecondaryIndex secondaryIndex : resource.getSecondaryIndexes()) {
hive.addSecondaryIndex(resource, secondaryIndex);
}
hive.addNode(new Node("node", H2TestCase.TEST_DB, "", HiveDbDialect.H2));
SimpleJdbcDaoSupport dao = new SimpleJdbcDaoSupport();
dao.setDataSource(hive.getDataSourceProvider().getDataSource(getConnectString(H2TestCase.TEST_DB)));
// dao.getJdbcTemplate().update("SET TRACE_LEVEL_SYSTEM_OUT 3");
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@Before
@Override
public void beforeMethod() {
deleteDatabasesAfterEachTest = true;
super.afterMethod();
super.beforeMethod();
prepare();
}
protected PartitionDimension createPopulatedPartitionDimension() {
return new PartitionDimension(
Hive.NEW_OBJECT_ID,
partitionDimensionName(),
Types.INTEGER,
getConnectString(H2TestCase.TEST_DB),
createResources());
}
protected Collection<Resource> createResources() {
ArrayList<Resource> resources = new ArrayList<Resource>();
resources.add(createResource());
return resources;
}
protected Resource createResource() {
final Resource resource = new Resource("FOO", Types.INTEGER, false, createSecondaryIndexes());
return resource;
}
private Collection<SecondaryIndex> createSecondaryIndexes() {
return Arrays.asList(
new SecondaryIndex("name", Types.VARCHAR),
new SecondaryIndex("num", Types.INTEGER));
}
protected PartitionDimension createEmptyPartitionDimension() {
return new PartitionDimension(
Hive.NEW_OBJECT_ID,
partitionDimensionName(),
Types.INTEGER,
getConnectString(H2TestCase.TEST_DB),
new ArrayList<Resource>());
}
protected String partitionDimensionName() {
return "member";
}
private Hive getHive() {
return Hive.load(getConnectString(H2TestCase.TEST_DB), CachingDataSourceProvider.getInstance());
}
@Test
public void testInsertPrimaryIndexKey() throws Exception {
Directory d = getDirectory();
Integer key = new Integer(43);
Hive hive = getHive();
Node firstNode = Atom.getFirst(hive.getNodes());
d.insertPrimaryIndexKey(Atom.getFirst(hive.getNodes()), key);
for (Integer id : Transform.map(semaphoreToId(), d.getKeySemamphoresOfPrimaryIndexKey(key)))
assertEquals((Integer) firstNode.getId(), id);
}
@Test
public void testInsertPrimaryIndexKeyMultipleNodes() throws Exception {
Directory d = getDirectory();
Hive hive = getHive();
Integer key = new Integer(43);
for (Node node : hive.getNodes())
d.insertPrimaryIndexKey(node, key);
Collection<Integer> nodeIds = Transform.map(semaphoreToId(), d.getKeySemamphoresOfPrimaryIndexKey(key));
AssertUtils.assertUnique(nodeIds);
assertEquals(hive.getNodes().size(), nodeIds.size());
}
@Test
public void testDeletePrimaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys()) {
d.deletePrimaryIndexKey(key);
assertEquals(0, d.getKeySemamphoresOfPrimaryIndexKey(key).size());
}
}
@Test
public void testDeletePrimaryIndexKeyMultipleNodes() throws Exception {
Directory d = getDirectory();
Hive hive = getHive();
for (String key : getPrimaryIndexOrResourceKeys())
for (Node node : hive.getNodes())
d.insertPrimaryIndexKey(node, key);
for (String key : getPrimaryIndexOrResourceKeys()) {
d.deletePrimaryIndexKey(key);
assertEquals(0, d.getKeySemamphoresOfPrimaryIndexKey(key).size());
}
}
@Test
public void testGetNodeIdsOfPrimaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys())
assertEquals(1, d.getKeySemamphoresOfPrimaryIndexKey(key).size());
}
@Test
public void testGetNodeIdsOfSecondaryIndexKeys() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
assertTrue(d.getKeySemaphoresOfSecondaryIndexKey(nameIndex, secondaryKeyString).size() >= 1);
}
@Test
public void testGetKeySemaphoresOfSecondaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
assertEquals(1, d.getKeySemaphoresOfSecondaryIndexKey(nameIndex, secondaryKeyString).size());
}
@Test
public void testGetKeySemaphoresOfResourceIds() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys())
assertEquals(1, d.getKeySemaphoresOfResourceId(resource, key).size());
}
@Test
public void testGetKeySemaphoresOfPartitioningResourceIds() throws Exception {
Hive hive = Hive.load(getConnectString(H2TestCase.TEST_DB), CachingDataSourceProvider.getInstance());
hive.deleteResource(resource);
resource = Atom.getFirstOrNull(dimension.getResources());
resource.setIsPartitioningResource(true);
hive.addResource(resource);
resource = hive.getPartitionDimension().getResource(resource.getName());
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys())
assertEquals(1, d.getKeySemaphoresOfResourceId(resource, key).size());
}
@Test
public void testGetPrimaryIndexKeysOfResourceId() throws Exception {
Directory d = getDirectory();
Hive hive = getHive();
for (String key : getPrimaryIndexOrResourceKeys()) {
d.insertPrimaryIndexKey(Atom.getFirstOrThrow(hive.getNodes()), key);
d.insertResourceId(resource, key + 1, key);
assertEquals(key, d.getPrimaryIndexKeyOfResourceId(resource, key + 1).toString());
}
}
@SuppressWarnings("unchecked")
@Test
public void testInsertRelatedSecondaryIndexKeys() throws Exception {
//beforeMethod = false;
//afterMethod = false;
//System.out.println("insertRelated begin");
Hive hive = getHive();
//System.out.println(hive.toString());
//insertKeys(getHive());
Directory d = getDirectory();
for (String primaryIndexKey : getPrimaryIndexOrResourceKeys()) {
hive.directory().insertPrimaryIndexKey(primaryIndexKey);
d.insertResourceId(resource, primaryIndexKey, primaryIndexKey);
Map<SecondaryIndex, Collection<Object>> secondaryIndexKeyMap = new Hashtable<SecondaryIndex, Collection<Object>>();
secondaryIndexKeyMap.put(nameIndex, Arrays.asList(new Object[]{
secondaryKeyString
}));
secondaryIndexKeyMap.put(numIndex, Arrays.asList(new Object[]{
secondaryKeyNum
}));
// TODO: for some reason the BatchIndexWriter won't find the tables when running through maven
//d.batch().insertSecondaryIndexKeys(secondaryIndexKeyMap, primaryIndexKey);
for (SecondaryIndex secondaryIndex : secondaryIndexKeyMap.keySet()) {
for (Object secondaryIndexKeyNum : secondaryIndexKeyMap.get(secondaryIndex)) {
hive.directory().insertSecondaryIndexKey(secondaryIndex.getResource().getName(), secondaryIndex.getName(), secondaryIndexKeyNum, primaryIndexKey);
}
}
hive.directory().insertSecondaryIndexKey(numIndex.getResource().getName(), numIndex.getName(), secondaryKeyNum, primaryIndexKey);
assertEquals(1, d.getSecondaryIndexKeysOfResourceId(nameIndex, primaryIndexKey).size());
assertEquals(secondaryKeyString, Atom.getFirst(d.getSecondaryIndexKeysOfResourceId(nameIndex, primaryIndexKey)));
assertEquals(1,
d.getSecondaryIndexKeysOfResourceId(numIndex, primaryIndexKey).size());
assertEquals(secondaryKeyNum,
Atom.getFirst(d.getSecondaryIndexKeysOfResourceId(numIndex, primaryIndexKey)));
}
}
@Test
public void testUpdatePrimaryIndexKeyReadOnly() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys()) {
d.updatePrimaryIndexKeyReadOnly(key, true);
for (KeySemaphore s : d.getKeySemamphoresOfPrimaryIndexKey(key))
assertTrue(s.getStatus().equals(Status.readOnly));
}
}
@SuppressWarnings("unchecked")
@Test
public void testDeleteSecondaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
Collection secondaryKeys = d.getSecondaryIndexKeysOfResourceId(nameIndex, pkey);
assertTrue(secondaryKeys.size() > 0);
for (Object skey : secondaryKeys)
d.deleteSecondaryIndexKey(nameIndex, skey, pkey);
assertTrue(d.getSecondaryIndexKeysOfResourceId(nameIndex, pkey).size() == 0);
}
}
@Test
public void testDoesPrimaryIndexKeyExist() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
assertTrue(d.doesPrimaryIndexKeyExist(Atom.getFirst(getPrimaryIndexOrResourceKeys())));
assertTrue(!d.doesPrimaryIndexKeyExist(new Integer(378465784)));
}
@Test
public void testGetKeySemaphoresOfPrimaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys())
assertEquals(1, d.getKeySemamphoresOfPrimaryIndexKey(pkey).size());
}
@Test
public void testGetKeySemaphoresOfPrimaryIndexKeyMultiNode() throws Exception {
Directory d = getDirectory();
Hive hive = getHive();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
for (Node node : hive.getNodes())
d.insertPrimaryIndexKey(node, pkey);
assertEquals(hive.getNodes().size(), d.getKeySemamphoresOfPrimaryIndexKey(pkey).size());
}
}
@Test
public void testGetReadOnlyOfPrimaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
assertEquals(false, Lists.or(Transform.map(DirectoryWrapper.semaphoreToReadOnly(), d.getKeySemamphoresOfPrimaryIndexKey(pkey))));
d.updatePrimaryIndexKeyReadOnly(pkey, true);
assertTrue(Lists.or(Transform.map(DirectoryWrapper.semaphoreToReadOnly(), d.getKeySemamphoresOfPrimaryIndexKey(pkey))));
}
}
@Test
public void testGetReadOnlyOfResourceId() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
assertEquals(false, Lists.or(Transform.map(DirectoryWrapper.semaphoreToReadOnly(), d.getKeySemaphoresOfResourceId(resource, pkey))));
d.updatePrimaryIndexKeyReadOnly(pkey, true);
assertTrue(Lists.or(Transform.map(DirectoryWrapper.semaphoreToReadOnly(), d.getKeySemaphoresOfResourceId(resource, pkey))));
}
}
@SuppressWarnings("unchecked")
@Test
public void testGetNodeIdsOfSecondaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
Collection skeys = d.getSecondaryIndexKeysOfResourceId(nameIndex, pkey);
for (Object skey : skeys) {
assertTrue(d.getKeySemaphoresOfSecondaryIndexKey(nameIndex, skey).size() > 0);
}
}
}
@Test
public void testGetNodeSemphoresOfSecondaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
Collection<KeySemaphore> skeys = d.getKeySemaphoresOfSecondaryIndexKey(nameIndex, secondaryKeyString);
assertEquals(1, skeys.size());
}
@SuppressWarnings("unchecked")
@Test
public void testGetSecondaryIndexKeysOfPrimaryIndexKey() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String pkey : getPrimaryIndexOrResourceKeys()) {
Collection skeys = d.getSecondaryIndexKeysOfResourceId(nameIndex, pkey);
assertTrue(skeys.size() > 0);
assertEquals(secondaryKeyString, Atom.getFirst(skeys));
}
}
@Test
public void testDeleteAllSecondaryKeyForResourceId() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys()) {
assertTrue(d.getSecondaryIndexKeysOfResourceId(numIndex, key).size() > 0);
// TODO: for some reason the BatchIndexWriter won't find the tables when running through maven
//d.batch().deleteAllSecondaryIndexKeysOfResourceId(resource, key);
for (SecondaryIndex secondaryIndex : resource.getSecondaryIndexes()) {
for (Object secondaryIndexKey : d.getSecondaryIndexKeysOfResourceId(secondaryIndex, key)) {
d.deleteSecondaryIndexKey(secondaryIndex, secondaryIndexKey, key);
;
}
}
assertEquals(0, d.getSecondaryIndexKeysOfResourceId(numIndex, key).size());
}
}
@Test
public void testGetSecondaryKeyForResourceId() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys())
assertEquals(1, d.getSecondaryIndexKeysOfResourceId(nameIndex, key).size());
}
@Test
public void testDeleteResourceId() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
for (String key : getPrimaryIndexOrResourceKeys()) {
// TODO: for some reason the BatchIndexWriter won't find the tables when running through maven
//d.batch().deleteAllSecondaryIndexKeysOfResourceId(resource, key);
for (SecondaryIndex secondaryIndex : resource.getSecondaryIndexes()) {
for (Object secondaryIndexKey : d.getSecondaryIndexKeysOfResourceId(secondaryIndex, key)) {
d.deleteSecondaryIndexKey(secondaryIndex, secondaryIndexKey, key);
;
}
}
assertEquals(0, d.getSecondaryIndexKeysOfResourceId(numIndex, key).size());
d.deleteResourceId(resource, key);
assertFalse(d.doesResourceIdExist(resource, key));
assertEquals(0, d.getSecondaryIndexKeysOfResourceId(nameIndex, key).size());
assertEquals(0, d.getSecondaryIndexKeysOfResourceId(numIndex, key).size());
}
}
@Test
public void testUpdatePrimaryIndexKeyOfResourceId() throws Exception {
insertKeys(getHive());
Directory d = getDirectory();
String firstKey = Atom.getFirst(getPrimaryIndexOrResourceKeys());
for (String key : getPrimaryIndexOrResourceKeys()) {
d.updatePrimaryIndexKeyOfResourceId(resource, key, firstKey);
assertEquals(firstKey, d.getPrimaryIndexKeyOfResourceId(resource, key).toString());
}
}
private Directory getDirectory() {
return new DbDirectory(dimension, CachingDataSourceProvider.getInstance().getDataSource(dimension.getIndexUri()));
}
@Override
public Collection<String> getDatabaseNames() {
return Arrays.asList(new String[]{H2TestCase.TEST_DB, "data1", "data2"});
}
private Collection<String> getPrimaryIndexOrResourceKeys() {
return Arrays.asList(new String[]{"1", "2", "3", "4"});
}
private void insertKeys(Hive hive) throws HiveLockableException {
Directory d = getDirectory();
Resource resource = dimension.getResource(createResource().getName());
for (String key : getPrimaryIndexOrResourceKeys()) {
hive.directory().insertPrimaryIndexKey(key);
d.insertResourceId(resource, key, key);
hive.directory().insertSecondaryIndexKey(nameIndex.getResource().getName(), nameIndex.getName(), secondaryKeyString, key);
hive.directory().insertSecondaryIndexKey(numIndex.getResource().getName(), numIndex.getName(), secondaryKeyNum, key);
}
}
}