package com.google.sitebricks.persist.sql;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.sitebricks.persist.EntityStore;
import com.google.sitebricks.persist.PersistAopModule;
import com.google.sitebricks.persist.Persister;
import com.google.sitebricks.persist.Transactional;
import com.google.sitebricks.persist.Work;
import com.jolbox.bonecp.BoneCPConfig;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.inject.Inject;
import javax.inject.Provider;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
/**
* @author dhanji@gmail.com (Dhanji R. Prasanna)
*/
public class SqlStoreIntegrationTest {
public static final String A_NAME = "Jason Van Zyl";
private static final String TEST_DB_FILE = "target/test_sql_db";
private static final String ANOTHER_NAME = "Jason";
public static class SqlSaver {
@Inject
Provider<Sql> sql;
@Work
public void make() {
sql.get().execute("insert into my_table (id, name) values (1, @name)",
ImmutableMap.<String, Object>of("name", A_NAME));
}
@Work
public String find() {
List<Map<String,Object>> list = sql.get().list("select * from my_table");
assertFalse(list.isEmpty());
return list.iterator().next().get("name").toString();
}
}
public static class SqlTransactionalSaver {
@Inject
Provider<Sql> sql;
@Work @Transactional
public void make() {
sql.get().execute("insert into my_table (id, name) values (1, @name)",
ImmutableMap.<String, Object>of("name", ANOTHER_NAME));
}
@Work @Transactional
public String find() {
return sql.get().list("select * from my_table").iterator().next().get("name").toString();
}
}
private static final AtomicInteger dbCount = new AtomicInteger(1);
private BoneCPConfig config;
@BeforeMethod
public final void pre() {
String database = "db" + dbCount.incrementAndGet();
config = new BoneCPConfig();
config.setJdbcUrl("jdbc:hsqldb:mem:" + database + ";sql.syntax_mys=true");
config.setUsername("sa");
config.setPassword("");
}
private static void createTable(Injector injector) {
Persister persister = injector.getInstance(Persister.class);
persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
((Sql) es.delegate()).execute("create table my_table (id integer, name text not null)");
return null;
}
});
final AtomicBoolean tableExists = new AtomicBoolean();
persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
tableExists.set(((Sql) es.delegate()).tableExists("my_table"));
return null;
}
});
assertTrue(tableExists.get());
}
@Test
public final void storeAndRetrieve() throws InterruptedException {
SqlModule redisModule = new SqlModule(config);
Injector injector = Guice.createInjector(redisModule, new PersistAopModule(redisModule));
createTable(injector);
SqlSaver saver = injector.getInstance(SqlSaver.class);
saver.make();
assertEquals(A_NAME, saver.find());
}
@Test
public final void storeAndRetrieveTransactional() {
SqlModule redisModule = new SqlModule(config);
Injector injector = Guice.createInjector(redisModule, new PersistAopModule(redisModule));
createTable(injector);
SqlTransactionalSaver saver = injector
.getInstance(SqlTransactionalSaver.class);
saver.make();
assertEquals(ANOTHER_NAME, saver.find());
}
@Test
public final void storeAndRetrieveWithoutAop() {
Injector injector = Guice.createInjector(new SqlModule(config));
createTable(injector);
Persister persister = injector
.getInstance(Persister.class);
persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
((Sql)es.delegate()).execute("insert into my_table (id, name) values (1, @name)",
ImmutableMap.<String, Object>of("name", A_NAME));
return null;
}
});
Object param = persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
return ((Sql)es.delegate()).list("select * from my_table").iterator().next().get("name").toString();
}
});
assertEquals(A_NAME, param);
}
@Test
public final void storeAndRemoveWithoutAop() {
Injector injector = Guice.createInjector(new SqlModule(config));
createTable(injector);
Persister persister = injector.getInstance(Persister.class);
persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
((Sql)es.delegate()).execute("insert into my_table (id, name) values (1, @name)",
ImmutableMap.<String, Object>of("name", A_NAME));
return null;
}
});
persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
((Sql)es.delegate()).execute("delete from my_table where name = @name and id = @id",
ImmutableMap.<String, Object>of(
"id", 1,
"name", A_NAME
));
return null;
}
});
Object param = persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
return ((Sql)es.delegate()).list("select * from my_table");
}
});
assertTrue(param instanceof List);
assertTrue(((List)param).isEmpty());
}
@Test // No different in Redis to @Work
public final void storeAndRetrieveInTransaction() {
Injector injector = Guice.createInjector(new SqlModule(config));
createTable(injector);
final Persister persister = injector
.getInstance(Persister.class);
Object param = persister.call(new Persister.InWork() {
@Override
public Object perform(EntityStore es) throws Throwable {
persister.call(new Persister.InTransaction() {
@Override
public Object perform(EntityStore es) throws Throwable {
((Sql)es.delegate()).execute("insert into my_table (id, name) values (1, @name)",
ImmutableMap.<String, Object>of("name", ANOTHER_NAME));
return null;
}
});
return persister.call(new Persister.InTransaction() {
@Override
public Object perform(EntityStore es) throws Throwable {
return ((Sql)es.delegate()).list("select * from my_table").iterator().next().get("name").toString();
}
});
}
});
assertEquals(ANOTHER_NAME, param);
}
}