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,90 +144,98 @@ public abstract class DBBean {
|
||||||
Class<? extends DBBean> c = this.getClass();
|
Class<? extends DBBean> c = this.getClass();
|
||||||
DBBeanConfig config = DBBeanConfig.getBeanConfig( c );
|
DBBeanConfig config = DBBeanConfig.getBeanConfig( c );
|
||||||
try {
|
try {
|
||||||
Long id = this.getId();
|
// Generate the SQL
|
||||||
// Generate the SQL
|
StringBuilder query = new StringBuilder();
|
||||||
StringBuilder query = new StringBuilder();
|
if (this.id == null) {
|
||||||
if( id == null ) {
|
query.append("INSERT INTO ").append(config.tableName).append(' ');
|
||||||
query.append("INSERT INTO ").append( config.tableName );
|
StringBuilder sqlCols = new StringBuilder();
|
||||||
query.append( " (" );
|
StringBuilder sqlValues = new StringBuilder();
|
||||||
for( Field field : config.fields ){
|
for (Field field : config.fields) {
|
||||||
if( !List.class.isAssignableFrom(field.getType()) ){
|
if (!List.class.isAssignableFrom(field.getType())) {
|
||||||
query.append(" ");
|
if (sqlCols.length() == 0)
|
||||||
query.append(DBBeanConfig.getFieldName(field));
|
sqlCols.append("(");
|
||||||
query.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) == ',')
|
if (sqlCols.length() > 0) {
|
||||||
query.deleteCharAt(query.length()-1);
|
query.append(sqlCols).append(") ");
|
||||||
query.append( ") VALUES(" );
|
query.append(sqlValues).append(") ");
|
||||||
for( Field field : config.fields ){
|
} else
|
||||||
query.append( "?," );
|
query.append("DEFAULT VALUES");
|
||||||
}
|
} else {
|
||||||
if(query.charAt(query.length()-1) == ',')
|
query.append("UPDATE ").append(config.tableName).append(' ');
|
||||||
query.deleteCharAt(query.length()-1);
|
StringBuilder sqlSets = new StringBuilder();
|
||||||
query.append( ")" );
|
for (Field field : config.fields) {
|
||||||
}
|
if (!List.class.isAssignableFrom(field.getType())) {
|
||||||
else{
|
if (sqlSets.length() > 0)
|
||||||
query.append("UPDATE ").append( config.tableName );
|
sqlSets.append(", ");
|
||||||
query.append( " SET" );
|
sqlSets.append(DBBeanConfig.getFieldName(field));
|
||||||
for( Field field : config.fields ){
|
sqlSets.append("=?");
|
||||||
if( !List.class.isAssignableFrom(field.getType()) ){
|
|
||||||
query.append(" ");
|
|
||||||
query.append(DBBeanConfig.getFieldName(field));
|
|
||||||
query.append("=?,");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(query.charAt(query.length()-1) == ',')
|
if (sqlSets.length() > 0) {
|
||||||
query.deleteCharAt(query.length()-1);
|
query.append("SET ").append(sqlSets);
|
||||||
query.append(" WHERE ").append(config.idColumn).append("=?");
|
query.append("WHERE ").append(config.idColumn).append("=?");
|
||||||
|
} else
|
||||||
|
query = null; // Class has no fields that needs updating
|
||||||
}
|
}
|
||||||
|
|
||||||
String sql = query.toString();
|
// Check if we have a valid query to run, skip otherwise
|
||||||
logger.finest("Save Bean("+c.getName()+", id: "+this.getId()+") query: "+ sql);
|
if (query != null) {
|
||||||
PreparedStatement stmt = db.getPreparedStatement( sql );
|
String sql = query.toString();
|
||||||
// Put in the variables in the SQL
|
logger.finest("Save Bean(" + c.getName() + ", id: " + this.getId() + ") query: " + sql);
|
||||||
int index = 1;
|
PreparedStatement stmt = db.getPreparedStatement(sql);
|
||||||
for(Field field : config.fields){
|
// 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);
|
||||||
|
if (subObj != null) {
|
||||||
|
if (recursive || subObj.getId() == null)
|
||||||
|
subObj.save(db);
|
||||||
|
stmt.setObject(index, subObj.getId());
|
||||||
|
} else
|
||||||
|
stmt.setObject(index, null);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
// A list of DBBeans
|
||||||
|
else if (List.class.isAssignableFrom(field.getType()) &&
|
||||||
|
field.getAnnotation(DBLinkTable.class) != null) {
|
||||||
|
// Do stuff later
|
||||||
|
}
|
||||||
|
// Normal field
|
||||||
|
else {
|
||||||
|
Object value = getFieldValue(field);
|
||||||
|
stmt.setObject(index, value);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.id != null)
|
||||||
|
stmt.setObject(index, this.id);
|
||||||
|
|
||||||
// Another DBBean class
|
// Execute the SQL
|
||||||
if( DBBean.class.isAssignableFrom( field.getType() )){
|
DBConnection.exec(stmt);
|
||||||
DBBean subObj = (DBBean)getFieldValue(field);
|
if (this.id == null) {
|
||||||
if(subObj != null){
|
this.id = db.getLastInsertID(stmt);
|
||||||
if( recursive || subObj.getId() == null )
|
// as this is a new object so add it to the cache
|
||||||
subObj.save(db);
|
DBBeanSQLResultHandler.cacheDBBean(this);
|
||||||
stmt.setObject(index, subObj.getId() );
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
stmt.setObject(index, null);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
// A list of DBBeans
|
|
||||||
else if( List.class.isAssignableFrom( field.getType() ) &&
|
|
||||||
field.getAnnotation( DBLinkTable.class ) != null){
|
|
||||||
// Do stuff later
|
|
||||||
}
|
|
||||||
// Normal field
|
|
||||||
else{
|
|
||||||
Object value = getFieldValue(field);
|
|
||||||
stmt.setObject(index, value);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( id != null )
|
|
||||||
stmt.setObject(index, id);
|
|
||||||
|
|
||||||
// Execute the SQL
|
|
||||||
DBConnection.exec(stmt);
|
|
||||||
if( 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){
|
for(Field field : config.fields){
|
||||||
if( List.class.isAssignableFrom( field.getType() ) &&
|
if( List.class.isAssignableFrom( field.getType() ) &&
|
||||||
field.getAnnotation( DBLinkTable.class ) != null){
|
field.getAnnotation( DBLinkTable.class ) != null){
|
||||||
|
if (this.id == null)
|
||||||
|
throw new SQLException("Unknown parent object id");
|
||||||
|
|
||||||
List<DBBean> list = (List<DBBean>)getFieldValue(field);
|
List<DBBean> list = (List<DBBean>)getFieldValue(field);
|
||||||
if( list != null ){
|
if( list != null ){
|
||||||
DBLinkTable linkTable = field.getAnnotation( DBLinkTable.class );
|
DBLinkTable linkTable = field.getAnnotation( DBLinkTable.class );
|
||||||
|
|
@ -250,14 +258,14 @@ public abstract class DBBean {
|
||||||
subIdCol = subConfig.idColumn;
|
subIdCol = subConfig.idColumn;
|
||||||
}
|
}
|
||||||
// Save links in link table
|
// Save links in link table
|
||||||
sql = "";
|
String sql;
|
||||||
if( subTable.equals(subConfig.tableName) )
|
if( subTable.equals(subConfig.tableName) )
|
||||||
sql = "UPDATE "+subTable+" SET "+idCol+"=? WHERE "+subIdCol+"=?";
|
sql = "UPDATE "+subTable+" SET "+idCol+"=? WHERE "+subIdCol+"=?";
|
||||||
else
|
else
|
||||||
sql = "REPLACE INTO "+subTable+" SET "+idCol+"=?, "+subIdCol+"=?";
|
sql = "REPLACE INTO "+subTable+" SET "+idCol+"=?, "+subIdCol+"=?";
|
||||||
logger.finest("Save Bean("+c.getName()+", id: "+subObj.getId()+") query: "+sql);
|
logger.finest("Save Bean("+c.getName()+", id: "+subObj.getId()+") query: "+sql);
|
||||||
PreparedStatement subStmt = db.getPreparedStatement( sql );
|
PreparedStatement subStmt = db.getPreparedStatement( sql );
|
||||||
subStmt.setLong(1, this.getId() );
|
subStmt.setLong(1, this.id );
|
||||||
subStmt.setLong(2, subObj.getId() );
|
subStmt.setLong(2, subObj.getId() );
|
||||||
DBConnection.exec(subStmt);
|
DBConnection.exec(subStmt);
|
||||||
}
|
}
|
||||||
|
|
@ -348,13 +356,13 @@ public abstract class DBBean {
|
||||||
|
|
||||||
// ID
|
// ID
|
||||||
query.append(" ").append(config.idColumn).append(" ");
|
query.append(" ").append(config.idColumn).append(" ");
|
||||||
query.append( classToDBName( Long.class ) );
|
query.append( classToColType( Long.class ) );
|
||||||
query.append(" PRIMARY KEY AUTO_INCREMENT, ");
|
query.append(" PRIMARY KEY AUTO_INCREMENT, ");
|
||||||
|
|
||||||
for( Field field : config.fields ){
|
for( Field field : config.fields ){
|
||||||
query.append(" ");
|
query.append(" ");
|
||||||
query.append( DBBeanConfig.getFieldName(field) );
|
query.append( DBBeanConfig.getFieldName(field) );
|
||||||
query.append( classToDBName(c) );
|
query.append( classToColType(c) );
|
||||||
query.append(", ");
|
query.append(", ");
|
||||||
}
|
}
|
||||||
query.delete( query.length()-2, query.length());
|
query.delete( query.length()-2, query.length());
|
||||||
|
|
@ -367,7 +375,7 @@ public abstract class DBBean {
|
||||||
DBConnection.exec(stmt);
|
DBConnection.exec(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String classToDBName(Class<?> c){
|
private static String classToColType(Class<?> c){
|
||||||
if( c == String.class) return "CLOB"; // TEXT
|
if( c == String.class) return "CLOB"; // TEXT
|
||||||
else if(c == Short.class) return "SMALLINT";
|
else if(c == Short.class) return "SMALLINT";
|
||||||
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 == byte.class) return "BINARY(1)";
|
||||||
else if(c == Timestamp.class) return "DATETIME";
|
else if(c == Timestamp.class) return "DATETIME";
|
||||||
else if(DBBean.class.isAssignableFrom(c))
|
else if(DBBean.class.isAssignableFrom(c))
|
||||||
return classToDBName(Long.class);
|
return classToColType(Long.class);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ class DBBeanConfig{
|
||||||
* Caches the fields
|
* Caches the fields
|
||||||
*/
|
*/
|
||||||
private static void initBeanConfig(Class<? extends DBBean> c){
|
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();
|
DBBeanConfig config = new DBBeanConfig();
|
||||||
// Find the table name
|
// Find the table name
|
||||||
DBBean.DBTable tableAnn = c.getAnnotation(DBBean.DBTable.class);
|
DBBean.DBTable tableAnn = c.getAnnotation(DBBean.DBTable.class);
|
||||||
|
|
|
||||||
|
|
@ -107,4 +107,12 @@ public abstract class DBBeanObjectDSO<T> extends DBBean{
|
||||||
public Configurator<T> getObjectConfigurator(){
|
public Configurator<T> getObjectConfigurator(){
|
||||||
return new Configurator<>(cachedObj);
|
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