package edu.washington.escience.myria.accessmethod;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FilenameUtils;
import org.junit.Test;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableList;
import edu.washington.escience.myria.MyriaConstants;
import edu.washington.escience.myria.RelationKey;
import edu.washington.escience.myria.Schema;
import edu.washington.escience.myria.Type;
import edu.washington.escience.myria.operator.DbQueryScan;
import edu.washington.escience.myria.operator.Operator;
import edu.washington.escience.myria.storage.TupleBatch;
import edu.washington.escience.myria.storage.TupleBatchBuffer;
import edu.washington.escience.myria.util.FSUtils;
import edu.washington.escience.myria.util.SQLiteUtils;
import edu.washington.escience.myria.util.TestUtils;
import edu.washington.escience.myria.util.Tuple;
public class SQLiteTest {
/** The logger for this class. */
private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SQLiteTest.class);
@Test
public void sqliteTest() throws Exception {
Logger.getLogger("com.almworks.sqlite4java").setLevel(Level.SEVERE);
Logger.getLogger("com.almworks.sqlite4java.Internal").setLevel(Level.SEVERE);
final RelationKey testtableKey = RelationKey.of("test", "test", "testtable");
final Schema outputSchema =
new Schema(
ImmutableList.of(Type.LONG_TYPE, Type.STRING_TYPE), ImmutableList.of("id", "name"));
final String tempDirPath =
Files.createTempDirectory(MyriaConstants.SYSTEM_NAME + "_SQLiteTest")
.toFile()
.getAbsolutePath();
final String dbAbsolutePath = FilenameUtils.concat(tempDirPath, "sqlite_testtable.db");
SQLiteUtils.createTable(dbAbsolutePath, testtableKey, "id long,name varchar(20)", true, true);
final String[] names = TestUtils.randomFixedLengthNumericString(1000, 1005, 200, 20);
final long[] ids = TestUtils.randomLong(1000, 1005, names.length);
final TupleBatchBuffer tbb = new TupleBatchBuffer(outputSchema);
for (int i = 0; i < names.length; i++) {
tbb.putLong(0, ids[i]);
tbb.putString(1, names[i]);
}
for (final TupleBatch tb : tbb.getAll()) {
SQLiteAccessMethod.tupleBatchInsert(SQLiteInfo.of(dbAbsolutePath), testtableKey, tb);
}
final HashMap<Tuple, Integer> expectedResult = TestUtils.tupleBatchToTupleBag(tbb);
/* Scan the testtable in database */
final DbQueryScan scan =
new DbQueryScan(
SQLiteInfo.of(dbAbsolutePath),
testtableKey,
outputSchema,
new int[] {0, 1},
new boolean[] {true, false});
final Operator root = scan;
root.open(null);
/* For debugging purposes, print Schema */
final Schema schema = root.getSchema();
if (schema != null) {
LOGGER.debug("Schema of result is: " + schema);
} else {
LOGGER.error("Result has no Schema, exiting");
root.close();
return;
}
TupleBatch tb = null;
final TupleBatchBuffer result = new TupleBatchBuffer(outputSchema);
while (!root.eos()) {
tb = root.nextReady();
if (tb != null) {
tb.compactInto(result);
}
}
/* Cleanup */
root.close();
final HashMap<Tuple, Integer> resultBag = TestUtils.tupleBatchToTupleBag(result);
List<TupleBatch> batches = result.getAll();
Long previousId = null;
String previousName = null;
for (TupleBatch tb1 : batches) {
for (int i = 0; i < tb1.numTuples(); i++) {
long currentId = tb1.getLong(0, i);
String currentName = tb1.getString(1, i);
if (previousId != null) {
assertNotNull(previousId);
assertNotNull(previousName);
assertTrue(previousId <= currentId);
if (previousId == currentId) {
assertTrue(previousName.compareTo(currentName) >= 0);
}
}
previousId = currentId;
previousName = currentName;
}
}
TestUtils.assertTupleBagEqual(expectedResult, resultBag);
FSUtils.blockingDeleteDirectory(tempDirPath);
}
}