Fixed some bugs in DBBean and added a Junit TC for it
This commit is contained in:
parent
70189fddfe
commit
1aedfb52b7
4 changed files with 299 additions and 80 deletions
|
|
@ -144,51 +144,56 @@ public abstract class DBBean {
|
|||
Class<? extends DBBean> c = this.getClass();
|
||||
DBBeanConfig config = DBBeanConfig.getBeanConfig( c );
|
||||
try {
|
||||
Long id = this.getId();
|
||||
// Generate the SQL
|
||||
StringBuilder query = new StringBuilder();
|
||||
if( id == null ) {
|
||||
query.append("INSERT INTO ").append( config.tableName );
|
||||
query.append( " (" );
|
||||
if (this.id == null) {
|
||||
query.append("INSERT INTO ").append(config.tableName).append(' ');
|
||||
StringBuilder sqlCols = new StringBuilder();
|
||||
StringBuilder sqlValues = new StringBuilder();
|
||||
for (Field field : config.fields) {
|
||||
if (!List.class.isAssignableFrom(field.getType())) {
|
||||
query.append(" ");
|
||||
query.append(DBBeanConfig.getFieldName(field));
|
||||
query.append(",");
|
||||
if (sqlCols.length() == 0)
|
||||
sqlCols.append("(");
|
||||
else sqlCols.append(", ");
|
||||
sqlCols.append(DBBeanConfig.getFieldName(field));
|
||||
|
||||
if (sqlValues.length() == 0)
|
||||
sqlValues.append("VALUES(");
|
||||
else sqlValues.append(", ");
|
||||
sqlValues.append("?");
|
||||
}
|
||||
}
|
||||
if(query.charAt(query.length()-1) == ',')
|
||||
query.deleteCharAt(query.length()-1);
|
||||
query.append( ") VALUES(" );
|
||||
for( Field field : config.fields ){
|
||||
query.append( "?," );
|
||||
}
|
||||
if(query.charAt(query.length()-1) == ',')
|
||||
query.deleteCharAt(query.length()-1);
|
||||
query.append( ")" );
|
||||
}
|
||||
else{
|
||||
query.append("UPDATE ").append( config.tableName );
|
||||
query.append( " SET" );
|
||||
if (sqlCols.length() > 0) {
|
||||
query.append(sqlCols).append(") ");
|
||||
query.append(sqlValues).append(") ");
|
||||
} else
|
||||
query.append("DEFAULT VALUES");
|
||||
} else {
|
||||
query.append("UPDATE ").append(config.tableName).append(' ');
|
||||
StringBuilder sqlSets = new StringBuilder();
|
||||
for (Field field : config.fields) {
|
||||
if (!List.class.isAssignableFrom(field.getType())) {
|
||||
query.append(" ");
|
||||
query.append(DBBeanConfig.getFieldName(field));
|
||||
query.append("=?,");
|
||||
if (sqlSets.length() > 0)
|
||||
sqlSets.append(", ");
|
||||
sqlSets.append(DBBeanConfig.getFieldName(field));
|
||||
sqlSets.append("=?");
|
||||
}
|
||||
}
|
||||
if(query.charAt(query.length()-1) == ',')
|
||||
query.deleteCharAt(query.length()-1);
|
||||
if (sqlSets.length() > 0) {
|
||||
query.append("SET ").append(sqlSets);
|
||||
query.append("WHERE ").append(config.idColumn).append("=?");
|
||||
} else
|
||||
query = null; // Class has no fields that needs updating
|
||||
}
|
||||
|
||||
// Check if we have a valid query to run, skip otherwise
|
||||
if (query != null) {
|
||||
String sql = query.toString();
|
||||
logger.finest("Save Bean(" + c.getName() + ", id: " + this.getId() + ") query: " + sql);
|
||||
PreparedStatement stmt = db.getPreparedStatement(sql);
|
||||
// Put in the variables in the SQL
|
||||
int index = 1;
|
||||
for (Field field : config.fields) {
|
||||
|
||||
// Another DBBean class
|
||||
if (DBBean.class.isAssignableFrom(field.getType())) {
|
||||
DBBean subObj = (DBBean) getFieldValue(field);
|
||||
|
|
@ -196,8 +201,7 @@ public abstract class DBBean {
|
|||
if (recursive || subObj.getId() == null)
|
||||
subObj.save(db);
|
||||
stmt.setObject(index, subObj.getId());
|
||||
}
|
||||
else
|
||||
} else
|
||||
stmt.setObject(index, null);
|
||||
index++;
|
||||
}
|
||||
|
|
@ -213,21 +217,25 @@ public abstract class DBBean {
|
|||
index++;
|
||||
}
|
||||
}
|
||||
if( id != null )
|
||||
stmt.setObject(index, id);
|
||||
if (this.id != null)
|
||||
stmt.setObject(index, this.id);
|
||||
|
||||
// Execute the SQL
|
||||
DBConnection.exec(stmt);
|
||||
if( id == null ) {
|
||||
if (this.id == null) {
|
||||
this.id = db.getLastInsertID(stmt);
|
||||
// as this is a new object so add it to the cache
|
||||
DBBeanSQLResultHandler.cacheDBBean(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the list, after we get the object id
|
||||
// Save sub beans, after we get the parent object id
|
||||
for(Field field : config.fields){
|
||||
if( List.class.isAssignableFrom( field.getType() ) &&
|
||||
field.getAnnotation( DBLinkTable.class ) != null){
|
||||
if (this.id == null)
|
||||
throw new SQLException("Unknown parent object id");
|
||||
|
||||
List<DBBean> list = (List<DBBean>)getFieldValue(field);
|
||||
if( list != null ){
|
||||
DBLinkTable linkTable = field.getAnnotation( DBLinkTable.class );
|
||||
|
|
@ -250,14 +258,14 @@ public abstract class DBBean {
|
|||
subIdCol = subConfig.idColumn;
|
||||
}
|
||||
// Save links in link table
|
||||
sql = "";
|
||||
String sql;
|
||||
if( subTable.equals(subConfig.tableName) )
|
||||
sql = "UPDATE "+subTable+" SET "+idCol+"=? WHERE "+subIdCol+"=?";
|
||||
else
|
||||
sql = "REPLACE INTO "+subTable+" SET "+idCol+"=?, "+subIdCol+"=?";
|
||||
logger.finest("Save Bean("+c.getName()+", id: "+subObj.getId()+") query: "+sql);
|
||||
PreparedStatement subStmt = db.getPreparedStatement( sql );
|
||||
subStmt.setLong(1, this.getId() );
|
||||
subStmt.setLong(1, this.id );
|
||||
subStmt.setLong(2, subObj.getId() );
|
||||
DBConnection.exec(subStmt);
|
||||
}
|
||||
|
|
@ -348,13 +356,13 @@ public abstract class DBBean {
|
|||
|
||||
// ID
|
||||
query.append(" ").append(config.idColumn).append(" ");
|
||||
query.append( classToDBName( Long.class ) );
|
||||
query.append( classToColType( Long.class ) );
|
||||
query.append(" PRIMARY KEY AUTO_INCREMENT, ");
|
||||
|
||||
for( Field field : config.fields ){
|
||||
query.append(" ");
|
||||
query.append( DBBeanConfig.getFieldName(field) );
|
||||
query.append( classToDBName(c) );
|
||||
query.append( classToColType(c) );
|
||||
query.append(", ");
|
||||
}
|
||||
query.delete( query.length()-2, query.length());
|
||||
|
|
@ -367,7 +375,7 @@ public abstract class DBBean {
|
|||
DBConnection.exec(stmt);
|
||||
}
|
||||
|
||||
private static String classToDBName(Class<?> c){
|
||||
private static String classToColType(Class<?> c){
|
||||
if( c == String.class) return "CLOB"; // TEXT
|
||||
else if(c == Short.class) return "SMALLINT";
|
||||
else if(c == short.class) return "SMALLINT";
|
||||
|
|
@ -387,7 +395,7 @@ public abstract class DBBean {
|
|||
else if(c == byte.class) return "BINARY(1)";
|
||||
else if(c == Timestamp.class) return "DATETIME";
|
||||
else if(DBBean.class.isAssignableFrom(c))
|
||||
return classToDBName(Long.class);
|
||||
return classToColType(Long.class);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class DBBeanConfig{
|
|||
* Caches the fields
|
||||
*/
|
||||
private static void initBeanConfig(Class<? extends DBBean> c){
|
||||
logger.fine("Initiating new BeanConfig( "+c.getName()+" )");
|
||||
//logger.fine("Initiating new BeanConfig( "+c.getName()+" )");
|
||||
DBBeanConfig config = new DBBeanConfig();
|
||||
// Find the table name
|
||||
DBBean.DBTable tableAnn = c.getAnnotation(DBBean.DBTable.class);
|
||||
|
|
|
|||
|
|
@ -107,4 +107,12 @@ public abstract class DBBeanObjectDSO<T> extends DBBean{
|
|||
public Configurator<T> getObjectConfigurator(){
|
||||
return new Configurator<>(cachedObj);
|
||||
}
|
||||
|
||||
|
||||
public String toString(){
|
||||
Object obj = getObject();
|
||||
if (obj != null)
|
||||
return obj.toString();
|
||||
return "null (DSO: "+ super.toString() +")";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
203
test/zutil/db/bean/DBBeanSaveTest.java
Executable file
203
test/zutil/db/bean/DBBeanSaveTest.java
Executable file
|
|
@ -0,0 +1,203 @@
|
|||
package zutil.db.bean;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.db.handler.SimpleSQLResult;
|
||||
import zutil.log.CompactLogFormatter;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class DBBeanSaveTest {
|
||||
|
||||
private DBConnection db = new DBConnection(DBConnection.DBMS.SQLite, ":memory:");
|
||||
public DBBeanSaveTest() throws Exception {}
|
||||
|
||||
@BeforeClass
|
||||
public static void init(){
|
||||
LogUtil.setGlobalFormatter(new CompactLogFormatter());
|
||||
LogUtil.setGlobalLevel(Level.ALL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static class SimpleTestClass extends DBBean{
|
||||
int intField;
|
||||
String strField;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleClassCreate() throws SQLException {
|
||||
db.exec("CREATE TABLE SimpleTestClass (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"intField INTEGER, " +
|
||||
"strField TEXT);");
|
||||
|
||||
SimpleTestClass obj = new SimpleTestClass();
|
||||
obj.intField = 1234;
|
||||
obj.strField = "helloworld";
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1234,
|
||||
getColumnValue(db, "SimpleTestClass", "intField"));
|
||||
assertEquals("helloworld",
|
||||
getColumnValue(db, "SimpleTestClass", "strField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleClassUpdate() throws SQLException {
|
||||
db.exec("CREATE TABLE SimpleTestClass (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"intField INTEGER, " +
|
||||
"strField TEXT);");
|
||||
|
||||
SimpleTestClass obj = new SimpleTestClass();
|
||||
obj.intField = 1234;
|
||||
obj.strField = "helloworld";
|
||||
obj.save(db);
|
||||
obj.intField = 1337;
|
||||
obj.strField = "monkey";
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1337,
|
||||
getColumnValue(db, "SimpleTestClass", "intField"));
|
||||
assertEquals("monkey",
|
||||
getColumnValue(db, "SimpleTestClass", "strField"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@DBBean.DBTable("aliasTable")
|
||||
private static class AliasFieldsTestClass extends DBBean{
|
||||
@DBColumn("aliasIntField")
|
||||
int intField;
|
||||
@DBColumn("aliasStrField")
|
||||
String strField;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasFieldsCreate() throws SQLException {
|
||||
db.exec("CREATE TABLE aliasTable (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"aliasIntField INTEGER, " +
|
||||
"aliasStrField TEXT);");
|
||||
|
||||
AliasFieldsTestClass obj = new AliasFieldsTestClass();
|
||||
obj.intField = 1234;
|
||||
obj.strField = "helloworld";
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1234,
|
||||
getColumnValue(db, "aliasTable", "aliasIntField"));
|
||||
assertEquals("helloworld",
|
||||
getColumnValue(db, "aliasTable", "aliasStrField"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasFieldsUpdate() throws SQLException {
|
||||
db.exec("CREATE TABLE aliasTable (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"aliasIntField INTEGER, " +
|
||||
"aliasStrField TEXT);");
|
||||
|
||||
AliasFieldsTestClass obj = new AliasFieldsTestClass();
|
||||
obj.intField = 1234;
|
||||
obj.strField = "helloworld";
|
||||
obj.save(db);
|
||||
obj.intField = 1337;
|
||||
obj.strField = "monkey";
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1337,
|
||||
getColumnValue(db, "aliasTable", "aliasIntField"));
|
||||
assertEquals("monkey",
|
||||
getColumnValue(db, "aliasTable", "aliasStrField"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@DBBean.DBTable("parent")
|
||||
private static class ParentTestClass extends DBBean{
|
||||
@DBLinkTable(table = "subobject", idColumn = "parent_id",beanClass = SubObjectTestClass.class)
|
||||
List<SubObjectTestClass> subobjs = new ArrayList<>();
|
||||
}
|
||||
@DBBean.DBTable("subobject")
|
||||
private static class SubObjectTestClass extends DBBean{
|
||||
int intField;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subObjectCreate() throws SQLException {
|
||||
db.exec("CREATE TABLE parent (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
|
||||
db.exec("CREATE TABLE subobject (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"parent_id INTEGER, " +
|
||||
"intField INTEGER);");
|
||||
|
||||
ParentTestClass obj = new ParentTestClass();
|
||||
SubObjectTestClass subObj = new SubObjectTestClass();
|
||||
subObj.intField = 1337;
|
||||
obj.subobjs.add(subObj);
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1337,
|
||||
getColumnValue(db, "subobject", "intField"));
|
||||
assertEquals(1,
|
||||
getColumnValue(db, "subobject", "parent_id"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@DBBean.DBTable("parent")
|
||||
private static class ParentLinkTestClass extends DBBean{
|
||||
@DBLinkTable(table = "link", idColumn = "parent_id",beanClass = SubObjectTestClass.class)
|
||||
List<SubObjectTestClass> subobjs = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subLinkObjectCreate() throws SQLException {
|
||||
db.exec("CREATE TABLE parent (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);");
|
||||
db.exec("CREATE TABLE link (" +
|
||||
"parent_id INTEGER, " +
|
||||
"id INTEGER);");
|
||||
db.exec("CREATE TABLE subobject (" +
|
||||
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"parent_id INTEGER, " +
|
||||
"intField INTEGER);");
|
||||
|
||||
ParentTestClass obj = new ParentTestClass();
|
||||
SubObjectTestClass subObj = new SubObjectTestClass();
|
||||
subObj.intField = 1337;
|
||||
obj.subobjs.add(subObj);
|
||||
obj.save(db);
|
||||
|
||||
assertEquals(1,
|
||||
getColumnValue(db, "link", "parent_id"));
|
||||
assertEquals(1,
|
||||
getColumnValue(db, "link", "id"));
|
||||
assertEquals(1337,
|
||||
getColumnValue(db, "subobject", "intField"));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static Object getColumnValue(DBConnection db, String table, String column) throws SQLException {
|
||||
return db.exec("SELECT "+column+" FROM "+table, new SimpleSQLResult<>());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue