This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch version3
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/version3 by this push:
new b5917ac EMPIREDB-362 checkDatabase exists and Enum improvements
b5917ac is described below
commit b5917ac811bbf81e16cf42d342bbf7f75f47e876
Author: Rainer Döbele <[email protected]>
AuthorDate: Sun Feb 13 14:22:45 2022 +0100
EMPIREDB-362 checkDatabase exists and Enum improvements
---
.../empire/samples/db/advanced/CarSalesDB.java | 71 +++-
.../empire/samples/db/advanced/SampleAdvApp.java | 365 +++++++++------------
.../empire/samples/db/advanced/SampleAdvDB.java | 74 +++++
.../org/apache/empire/samples/db/SampleApp.java | 203 ++++--------
.../org/apache/empire/samples/db/SampleDB.java | 73 +++++
.../apache/empire/samples/db/beans/Employee.java | 24 +-
.../empire/samples/db/beans/EmployeeQuery.java | 55 ++--
.../main/java/org/apache/empire/data/Column.java | 7 -
.../java/org/apache/empire/data/ColumnExpr.java | 7 +
.../main/java/org/apache/empire/db/DBColumn.java | 12 +-
.../main/java/org/apache/empire/db/DBCommand.java | 40 ++-
.../java/org/apache/empire/db/DBCommandExpr.java | 7 +-
.../main/java/org/apache/empire/db/DBDatabase.java | 10 +
.../main/java/org/apache/empire/db/DBRecord.java | 91 +----
.../java/org/apache/empire/db/DBRecordBase.java | 145 ++++++--
.../java/org/apache/empire/db/DBRecordBean.java | 2 +
.../java/org/apache/empire/db/DBRecordData.java | 16 +-
.../main/java/org/apache/empire/db/DBRowSet.java | 24 ++
.../empire/db/expr/column/DBAbstractFuncExpr.java | 9 +
.../apache/empire/db/expr/column/DBAliasExpr.java | 10 +
.../apache/empire/db/expr/column/DBCalcExpr.java | 9 +
.../apache/empire/db/expr/column/DBCaseExpr.java | 6 +
.../empire/db/expr/column/DBCaseWhenExpr.java | 7 +
.../apache/empire/db/expr/column/DBConcatExpr.java | 9 +
.../apache/empire/db/expr/column/DBCountExpr.java | 9 +
.../apache/empire/db/expr/column/DBScalarExpr.java | 9 +
.../apache/empire/db/expr/column/DBValueExpr.java | 14 +
.../empire/db/expr/column/DBVarArgsFuncExpr.java | 6 +
.../empire/db/list/DBBeanListFactoryImpl.java | 26 +-
.../java/org/apache/empire/dbms/DBMSHandler.java | 4 +
.../org/apache/empire/dbms/DBMSHandlerBase.java | 61 +++-
.../empire/dbms/oracle/OracleRowNumExpr.java | 9 +
.../empire/dbms/sqlserver/DBMSHandlerMSSQL.java | 21 ++
33 files changed, 864 insertions(+), 571 deletions(-)
diff --git
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/CarSalesDB.java
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/CarSalesDB.java
index 4dc0f9c..628f350 100644
---
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/CarSalesDB.java
+++
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/CarSalesDB.java
@@ -20,6 +20,7 @@ package org.apache.empire.samples.db.advanced;
import java.math.BigDecimal;
import java.math.RoundingMode;
+import java.sql.SQLException;
import java.time.LocalDate;
import java.util.List;
@@ -33,6 +34,9 @@ import org.apache.empire.db.DBSQLScript;
import org.apache.empire.db.DBTableColumn;
import org.apache.empire.db.generic.TDatabase;
import org.apache.empire.db.generic.TTable;
+import org.apache.empire.db.validation.DBModelChecker;
+import org.apache.empire.db.validation.DBModelErrorLogger;
+import org.apache.empire.dbms.postgresql.DBMSHandlerPostgreSQL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -179,18 +183,38 @@ public class CarSalesDB extends TDatabase<CarSalesDB>
addRelation( MODEL.BRAND_ID.referenceOn( BRAND.ID ));
addRelation( SALES.MODEL_ID.referenceOn( MODEL.ID ));
}
-
- public boolean checkExists(DBContext context)
+
+ @Override
+ public void open(DBContext context)
{
- // Check whether DB exists
- DBCommand cmd = createCommand();
- cmd.select(BRAND.count());
- // Check using "select count(*) from DEPARTMENTS"
- log.info("Checking whether table DEPARTMENTS exists (SQLException will
be logged if not - please ignore) ...");
- return (context.getUtils().querySingleInt(cmd, -1) >= 0);
+ // Enable prepared statements
+ setPreparedStatementsEnabled(true);
+ // Check exists
+ if (checkExists(context))
+ { // attach to driver
+ super.open(context);
+ // yes, it exists, then check the model
+ checkDataModel(context);
+ }
+ else
+ { // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, true);
+ // create the database
+ createDatabase(context);
+ // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, false);
+ // attach to driver
+ super.open(context);
+ // populate
+ populate(context);
+ // Commit
+ context.commit();
+ }
}
- public void createDatabase(DBContext context)
+ private void createDatabase(DBContext context)
{
// create DDL for Database Definition
DBSQLScript script = new DBSQLScript(context);
@@ -199,10 +223,29 @@ public class CarSalesDB extends TDatabase<CarSalesDB>
log.info(script.toString());
// Execute Script
script.executeAll(false);
- // populate
- populate(context);
- // Commit
- context.commit();
+ }
+
+ private void checkDataModel(DBContext context)
+ { try {
+ DBModelChecker modelChecker =
context.getDbms().createModelChecker(this);
+ // Check data model
+ log.info("Checking DataModel for {} using {}",
getClass().getSimpleName(), modelChecker.getClass().getSimpleName());
+ // dbo schema
+ DBModelErrorLogger logger = new DBModelErrorLogger();
+ modelChecker.checkModel(this, context.getConnection(), logger);
+ // show result
+ log.info("Data model check done. Found {} errors and {}
warnings.", logger.getErrorCount(), logger.getWarnCount());
+ } catch(Exception e) {
+ log.error("FATAL error when checking data model. Probably not
properly implemented by DBMSHandler!");
+ }
+ }
+
+ private void setAutoCommit(DBContext context, boolean enable)
+ { try {
+ context.getConnection().setAutoCommit(enable);
+ } catch (SQLException e) {
+ log.error("Unable to set AutoCommit on Connection", e);
+ }
}
private void populate(DBContext context)
@@ -271,7 +314,7 @@ public class CarSalesDB extends TDatabase<CarSalesDB>
.orderBy(BRAND.NAME.desc(), MODEL.NAME.asc());
*/
DBCommand cmd = createCommand()
- .select (BRAND.NAME.as("BRAND"), MODEL.CONFIG_NAME.as("MODEL"),
MODEL.BASE_PRICE)
+ .selectQualified(BRAND.NAME, MODEL.CONFIG_NAME, MODEL.BASE_PRICE)
.select (SALES.MODEL_ID.count().as("SALES_COUNT"),
SALES.PRICE.avg().as("AVG_SALES_PRICE"))
.select
(SALES.PRICE.avg().minus(MODEL.BASE_PRICE.avg()).round(2).as("DIFFERENCE"))
.join (MODEL.BRAND_ID, BRAND.ID)
diff --git
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvApp.java
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvApp.java
index 6dda2d2..f1a3fe0 100644
---
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvApp.java
+++
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvApp.java
@@ -40,11 +40,8 @@ import org.apache.empire.db.DBTableColumn;
import org.apache.empire.db.context.DBContextStatic;
import org.apache.empire.db.exceptions.ConstraintViolationException;
import org.apache.empire.db.exceptions.StatementFailedException;
-import org.apache.empire.db.validation.DBModelChecker;
-import org.apache.empire.db.validation.DBModelErrorLogger;
import org.apache.empire.dbms.DBMSHandler;
import org.apache.empire.dbms.h2.DBMSHandlerH2;
-import org.apache.empire.dbms.postgresql.DBMSHandlerPostgreSQL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,176 +50,163 @@ public class SampleAdvApp
{
// Logger
private static final Logger log =
LoggerFactory.getLogger(SampleAdvApp.class);
+
+ private static SampleAdvConfig config = new SampleAdvConfig();
- private static final SampleAdvDB db = new SampleAdvDB();
+ private final SampleAdvDB db = new SampleAdvDB();
- private static SampleAdvConfig config = new SampleAdvConfig();
+ private final CarSalesDB carSales = new CarSalesDB();
- private static DBContext context;
+ private DBContext context;
// Shortcuts
- private static SampleAdvDB.Employees T_EMP = db.T_EMPLOYEES;
- private static SampleAdvDB.Departments T_DEP = db.T_DEPARTMENTS;
- private static SampleAdvDB.EmployeeDepartmentHistory T_EDH =
db.T_EMP_DEP_HIST;
+ private SampleAdvDB.Employees T_EMP = db.T_EMPLOYEES;
+ private SampleAdvDB.Departments T_DEP = db.T_DEPARTMENTS;
+ private SampleAdvDB.EmployeeDepartmentHistory T_EDH = db.T_EMP_DEP_HIST;
/**
* <PRE>
* This is the entry point of the Empire-DB Sample Application
* Please check the config.xml configuration file for Database and
Connection settings.
* </PRE>
- * @param args command line arguments
+ * @param args arguments
*/
public static void main(String[] args)
{
+ // Init Configuration
+ config.init((args.length > 0 ? args[0] : "config.xml" ));
+ // create the app
+ SampleAdvApp app = new SampleAdvApp();
try
- {
-
- // Init Configuration
- config.init((args.length > 0 ? args[0] : "config.xml" ));
-
- System.out.println("Running DB Sample Advanced...");
-
- // STEP 1: Get a JDBC Connection
- System.out.println("*** Step 1: getJDBCConnection() ***");
- Connection conn = getJDBCConnection();
+ { // Run
+ log.info("Running DB Sample...");
+ app.run();
+ // Done
+ log.info("DB Sample finished successfully.");
+ } catch (Exception e) {
+ // Error
+ log.error("Running SampleApp failed with Exception" +
e.toString(), e);
+ if (app.context!=null)
+ app.context.rollback();
+ } finally {
+ if (app.context!=null)
+ app.context.discard();
+ }
+ }
- // STEP 2: Choose a dbms
- System.out.println("*** Step 2: getDatabaseProvider() ***");
- DBMSHandler dbms = getDBMSHandler(config.getDatabaseProvider());
-
- // STEP 2.2: Create a Context
- context = new DBContextStatic(dbms, conn);
-
- // STEP 3: Open Database (and create if not existing)
- System.out.println("*** Step 3: openDatabase() ***");
- try {
- // Enable the use of prepared statements for update and insert
commands as well as for read operations on a DBRecord.
- // Note: For custom SQL commands parameters must be explicitly
declared using cmd.addCmdParam();
- db.setPreparedStatementsEnabled(true);
- // Open the database
- db.open(context);
- // Check whether database exists
- databaseExists();
- System.out.println("*** Database already exists. Checking data
model... ***");
- checkDataModel();
-
- } catch(Exception e) {
- // STEP 4: Create Database
- System.out.println("*** Step 4: createDDL() ***");
- // postgre does not support DDL in transaction
- if(db.getDbms() instanceof DBMSHandlerPostgreSQL)
- {
- conn.setAutoCommit(true);
- }
- createDatabase();
- if(db.getDbms() instanceof DBMSHandlerPostgreSQL)
- {
- conn.setAutoCommit(false);
- }
- // Open again
- if (db.isOpen()==false)
- db.open(context);
- }
+ /**
+ * This method runs all the example code
+ */
+ public void run()
+ {
+ // STEP 1: Get a JDBC Connection
+ System.out.println("*** Step 1: getJDBCConnection() ***");
+ Connection conn = getJDBCConnection();
- // STEP 5: Clear Database (Delete all records)
- System.out.println("*** Step 5: clearDatabase() ***");
- clearDatabase();
-
- // STEP 6: Insert Records
- // Insert Departments
- System.out.println("*** Step 6: inserting departments, employees
and employee_department_history records ***");
- int idDevDep = insertDepartment("Development", "ITTK");
- int idProdDep = insertDepartment("Production", "ITTK");
- int idSalDep = insertDepartment("Sales", "ITTK");
-
- // Insert Employees
- int idEmp1 = insertEmployee("Peter", "Sharp", "M");
- int idEmp2 = insertEmployee("Fred", "Bloggs", "M");
- int idEmp3 = insertEmployee("Emma", "White", "F");
-
- // Insert History as batch
- DBSQLScript batch = new DBSQLScript(context);
- insertEmpDepHistory(batch, idEmp1, idDevDep,
DateUtils.getDate(2007, 12, 1));
- insertEmpDepHistory(batch, idEmp1, idProdDep,
DateUtils.getDate(2008, 9, 1));
- insertEmpDepHistory(batch, idEmp1, idSalDep,
DateUtils.getDate(2009, 5, 15));
-
- insertEmpDepHistory(batch, idEmp2, idSalDep,
DateUtils.getDate(2006, 3, 1));
- insertEmpDepHistory(batch, idEmp2, idDevDep,
DateUtils.getDate(2008, 11, 15));
-
- insertEmpDepHistory(batch, idEmp3, idDevDep,
DateUtils.getDate(2006, 9, 15));
- insertEmpDepHistory(batch, idEmp3, idSalDep,
DateUtils.getDate(2007, 6, 1));
- insertEmpDepHistory(batch, idEmp3, idProdDep,
DateUtils.getDate(2008, 7, 31));
- batch.executeBatch();
-
- // commit
- context.commit();
-
- // STEP 7: read from Employee_Info_View
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** read from EMPLOYEE_INFO_VIEW ***");
- DBCommand cmd = db.createCommand();
- cmd.select (db.V_EMPLOYEE_INFO.getColumns());
- cmd.orderBy(db.V_EMPLOYEE_INFO.C_NAME_AND_DEP);
- printQueryResults(cmd);
-
- // STEP 8: prepared Statement sample
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** commandParamsSample: shows how to use
command parameters for the generation of prepared statements ***");
- commandParamsSample(idProdDep, idDevDep);
-
- // STEP 9: bulkReadRecords
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** bulkReadRecords: reads employee records
into a hashmap, reads employee from hashmap and updates employee ***");
- HashMap<Integer, DBRecord> employeeMap = bulkReadRecords(conn);
- DBRecord rec = employeeMap.get(idEmp2);
- rec.setValue(db.T_EMPLOYEES.C_SALUTATION, "Mr.");
- rec.update();
-
- // STEP 10: bulkProcessRecords
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** bulkProcessRecords: creates a checksum for
every employee in the employees table ***");
- bulkProcessRecords();
-
- // STEP 11: querySample
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** querySample: shows how to use DBQuery
class for subqueries and multi table records ***");
- querySample(idEmp2);
-
- // STEP 12: ddlSample
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** ddlSample: shows how to add a column at
runtime and update a record with the added column ***");
- if (db.getDbms() instanceof DBMSHandlerH2) {
- log.info("As H2 does not support changing a table with a view
defined we remove the view");
- System.out.println("*** drop EMPLOYEE_INFO_VIEW ***");
- DBSQLScript script = new DBSQLScript(context);
- db.getDbms().getDDLScript(DDLActionType.DROP,
db.V_EMPLOYEE_INFO, script);
- script.executeAll();
- }
- ddlSample(idEmp2);
- if (db.getDbms() instanceof DBMSHandlerH2) {
- log.info("And put back the view");
- System.out.println("*** create EMPLOYEE_INFO_VIEW ***");
- DBSQLScript script = new DBSQLScript(context);
- db.getDbms().getDDLScript(DDLActionType.CREATE,
db.V_EMPLOYEE_INFO, script);
- script.executeAll();
- }
+ // STEP 2: Choose a dbms
+ System.out.println("*** Step 2: getDatabaseProvider() ***");
+ DBMSHandler dbms = getDBMSHandler(config.getDatabaseProvider());
+
+ // STEP 2.2: Create a Context
+ context = new DBContextStatic(dbms, conn);
+
+ // STEP 3: Open Database (and create if not existing)
+ System.out.println("*** Step 3: openDatabase() ***");
+ db.open(context);
+ carSales.open(context);
+ carSales.queryDemo(context);
+
+ // STEP 5: Clear Database (Delete all records)
+ System.out.println("*** Step 5: clearDatabase() ***");
+ clearDatabase();
+
+ // STEP 6: Insert Records
+ // Insert Departments
+ System.out.println("*** Step 6: inserting departments, employees and
employee_department_history records ***");
+ int idDevDep = insertDepartment("Development", "ITTK");
+ int idProdDep = insertDepartment("Production", "ITTK");
+ int idSalDep = insertDepartment("Sales", "ITTK");
+
+ // Insert Employees
+ int idEmp1 = insertEmployee("Peter", "Sharp", "M");
+ int idEmp2 = insertEmployee("Fred", "Bloggs", "M");
+ int idEmp3 = insertEmployee("Emma", "White", "F");
+
+ // Insert History as batch
+ DBSQLScript batch = new DBSQLScript(context);
+ insertEmpDepHistory(batch, idEmp1, idDevDep, DateUtils.getDate(2007,
12, 1));
+ insertEmpDepHistory(batch, idEmp1, idProdDep, DateUtils.getDate(2008,
9, 1));
+ insertEmpDepHistory(batch, idEmp1, idSalDep, DateUtils.getDate(2009,
5, 15));
+
+ insertEmpDepHistory(batch, idEmp2, idSalDep, DateUtils.getDate(2006,
3, 1));
+ insertEmpDepHistory(batch, idEmp2, idDevDep, DateUtils.getDate(2008,
11, 15));
+
+ insertEmpDepHistory(batch, idEmp3, idDevDep, DateUtils.getDate(2006,
9, 15));
+ insertEmpDepHistory(batch, idEmp3, idSalDep, DateUtils.getDate(2007,
6, 1));
+ insertEmpDepHistory(batch, idEmp3, idProdDep, DateUtils.getDate(2008,
7, 31));
+ batch.executeBatch();
+
+ // commit
+ context.commit();
+
+ // STEP 7: read from Employee_Info_View
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** read from EMPLOYEE_INFO_VIEW ***");
+ DBCommand cmd = db.createCommand();
+ cmd.select (db.V_EMPLOYEE_INFO.getColumns());
+ cmd.orderBy(db.V_EMPLOYEE_INFO.C_NAME_AND_DEP);
+ printQueryResults(cmd);
- // STEP 13: delete records
-
System.out.println("--------------------------------------------------------");
- System.out.println("*** deleteRecordSample: shows how to delete
records (with and without cascade) ***");
- deleteRecordSample(idEmp3, idSalDep);
-
- // Done
-
System.out.println("--------------------------------------------------------");
- System.out.println("DB Sample Advanced finished successfully.");
+ // STEP 8: prepared Statement sample
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** commandParamsSample: shows how to use command
parameters for the generation of prepared statements ***");
+ commandParamsSample(idProdDep, idDevDep);
+
+ // STEP 9: bulkReadRecords
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** bulkReadRecords: reads employee records into a
hashmap, reads employee from hashmap and updates employee ***");
+ HashMap<Integer, DBRecord> employeeMap = bulkReadRecords(conn);
+ DBRecord rec = employeeMap.get(idEmp2);
+ rec.setValue(db.T_EMPLOYEES.C_SALUTATION, "Mr.");
+ rec.update();
- } catch (Exception e)
- {
- // Error
- System.out.println(e.toString());
- e.printStackTrace();
+ // STEP 10: bulkProcessRecords
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** bulkProcessRecords: creates a checksum for
every employee in the employees table ***");
+ bulkProcessRecords();
+
+ // STEP 11: querySample
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** querySample: shows how to use DBQuery class
for subqueries and multi table records ***");
+ querySample(idEmp2);
+
+ // STEP 12: ddlSample
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** ddlSample: shows how to add a column at
runtime and update a record with the added column ***");
+ if (db.getDbms() instanceof DBMSHandlerH2) {
+ log.info("As H2 does not support changing a table with a view
defined we remove the view");
+ System.out.println("*** drop EMPLOYEE_INFO_VIEW ***");
+ DBSQLScript script = new DBSQLScript(context);
+ db.getDbms().getDDLScript(DDLActionType.DROP,
db.V_EMPLOYEE_INFO, script);
+ script.executeAll();
+ }
+ ddlSample(idEmp2);
+ if (db.getDbms() instanceof DBMSHandlerH2) {
+ log.info("And put back the view");
+ System.out.println("*** create EMPLOYEE_INFO_VIEW ***");
+ DBSQLScript script = new DBSQLScript(context);
+ db.getDbms().getDDLScript(DDLActionType.CREATE,
db.V_EMPLOYEE_INFO, script);
+ script.executeAll();
}
+ // STEP 13: delete records
+
System.out.println("--------------------------------------------------------");
+ System.out.println("*** deleteRecordSample: shows how to delete
records (with and without cascade) ***");
+ deleteRecordSample(idEmp3, idSalDep);
+
+ // Done
+
System.out.println("--------------------------------------------------------");
+ System.out.println("DB Sample Advanced finished successfully.");
}
/**
@@ -289,63 +273,10 @@ public class SampleAdvApp
/**
* <PRE>
- * Checks whether the database exists or not by executing
- * select count(*) from DEPARTMENTS
- * If the Departments table does not exist the querySingleInt() function
return -1 for failure.
- * Please note that in this case an error will appear in the log wich can
be ingored.
- * </PRE>
- */
- private static boolean databaseExists()
- {
- // Check whether DB exists
- DBCommand cmd = db.createCommand();
- cmd.select(T_DEP.count());
- // Check using "select count(*) from DEPARTMENTS"
- System.out.println("Checking whether table DEPARTMENTS exists
(SQLException will be logged if not - please ignore) ...");
- return (context.getUtils().querySingleInt(cmd, -1) >= 0);
- }
-
- /**
- * <PRE>
- * Creates a DDL Script for entire SampleDB Database and executes it line
by line.
- * Please make sure you uses the correct DatabaseDriver for your target
dbms.
- * </PRE>
- */
- private static void createDatabase()
- {
- // create DLL for Database Definition
- DBSQLScript script = new DBSQLScript(context);
- db.getCreateDDLScript(script);
- // Show DLL Statement
- System.out.println(script.toString());
- // Execute Script
- script.executeAll();
- // Commit
- context.commit();
- }
-
- private static void checkDataModel()
- {
- try {
- DBModelChecker modelChecker =
context.getDbms().createModelChecker(db);
- // Check data model
- log.info("Checking DataModel for {} using {}",
db.getClass().getSimpleName(), modelChecker.getClass().getSimpleName());
- // dbo schema
- DBModelErrorLogger logger = new DBModelErrorLogger();
- modelChecker.checkModel(db, context.getConnection(), logger);
- // show result
- log.info("Data model check done. Found {} errors and {}
warnings.", logger.getErrorCount(), logger.getWarnCount());
- } catch(Exception e) {
- log.error("FATAL error when checking data model. Probably not
properly implemented by DBMSHandler!");
- }
- }
-
- /**
- * <PRE>
* Empties all Tables.
* </PRE>
*/
- private static void clearDatabase()
+ private void clearDatabase()
{
DBCommand cmd = context.createCommand(db);
// Delete all Employee Department History records
@@ -361,7 +292,7 @@ public class SampleAdvApp
* Insert a Department into the Departments table.
* </PRE>
*/
- private static int insertDepartment(String departmentName, String
businessUnit)
+ private int insertDepartment(String departmentName, String businessUnit)
{
// Insert a Department
DBRecord rec = new DBRecord(context, T_DEP);
@@ -378,7 +309,7 @@ public class SampleAdvApp
* Inserts an Employee into the Employees table.
* </PRE>
*/
- private static int insertEmployee(String firstName, String lastName,
String gender)
+ private int insertEmployee(String firstName, String lastName, String
gender)
{
// Insert an Employee
DBRecord rec = new DBRecord(context, T_EMP);
@@ -396,7 +327,7 @@ public class SampleAdvApp
* Inserts an Employee into the Employees table.
* </PRE>
*/
- private static void insertEmpDepHistory(DBSQLScript script, int
employeeId, int departmentId, Date dateFrom)
+ private void insertEmpDepHistory(DBSQLScript script, int employeeId, int
departmentId, Date dateFrom)
{
// Insert an Employee
/*
@@ -416,7 +347,7 @@ public class SampleAdvApp
}
/* This procedure demonstrates the use of command parameter for prepared
statements */
- private static void commandParamsSample(int idProdDep, int idDevDep)
+ private void commandParamsSample(int idProdDep, int idDevDep)
{
// create a command
DBCommand cmd = db.createCommand();
@@ -472,7 +403,7 @@ public class SampleAdvApp
* <P>
* @param conn a connection to the database
*/
- private static void bulkProcessRecords()
+ private void bulkProcessRecords()
{
// Define the query
DBCommand cmd = db.createCommand();
@@ -517,7 +448,7 @@ public class SampleAdvApp
}
}
- private static int calcCharSum(String value)
+ private int calcCharSum(String value)
{
int sum = 0;
if (value!=null)
@@ -529,7 +460,7 @@ public class SampleAdvApp
return sum;
}
- private static HashMap<Integer, DBRecord> bulkReadRecords(Connection conn)
+ private HashMap<Integer, DBRecord> bulkReadRecords(Connection conn)
{
// Define the query
DBCommand cmd = db.createCommand();
@@ -566,7 +497,7 @@ public class SampleAdvApp
* This function demonstrates the use of the {@link
DBMSHandler#getDDLScript(org.apache.empire.db.DDLActionType,
org.apache.empire.db.DBObject, DBSQLScript)}<BR>
*
*/
- private static void ddlSample(int idTestPerson)
+ private void ddlSample(int idTestPerson)
{
// First, add a new column to the Table object
DBTableColumn C_FOO = db.T_EMPLOYEES.addColumn("FOO",
DataType.VARCHAR, 20, false);
@@ -615,7 +546,7 @@ public class SampleAdvApp
* @param conn
* @param employeeId
*/
- private static void querySample(int employeeId)
+ private void querySample(int employeeId)
{
// Define the sub query
DBCommand subCmd = db.createCommand();
@@ -665,7 +596,7 @@ public class SampleAdvApp
* @param idDepartment the id of the department to delete
* @param conn the connection
*/
- private static void deleteRecordSample(int idEmployee, int idDepartment)
+ private void deleteRecordSample(int idEmployee, int idDepartment)
{
context.commit();
// Delete an employee
@@ -690,7 +621,7 @@ public class SampleAdvApp
* @param cmd the command to be used for performing the query
* @param conn the connection
*/
- private static void printQueryResults(DBCommand cmd)
+ private void printQueryResults(DBCommand cmd)
{
// Query Records and print output
DBReader reader = new DBReader(context);
diff --git
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
index 64d84de..af5eeca 100644
---
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
+++
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvDB.java
@@ -18,17 +18,26 @@
*/
package org.apache.empire.samples.db.advanced;
+import java.sql.SQLException;
+
import org.apache.empire.commons.Options;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBColumn;
import org.apache.empire.db.DBColumnExpr;
import org.apache.empire.db.DBCommand;
import org.apache.empire.db.DBCommandExpr;
+import org.apache.empire.db.DBContext;
import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLScript;
import org.apache.empire.db.DBTableColumn;
import org.apache.empire.db.generic.TDatabase;
import org.apache.empire.db.generic.TTable;
import org.apache.empire.db.generic.TView;
+import org.apache.empire.db.validation.DBModelChecker;
+import org.apache.empire.db.validation.DBModelErrorLogger;
+import org.apache.empire.dbms.postgresql.DBMSHandlerPostgreSQL;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* <PRE>
@@ -49,6 +58,9 @@ public class SampleAdvDB extends TDatabase<SampleAdvDB>
{
// *Deprecated* private static final long serialVersionUID = 1L;
+ // Logger
+ private static final Logger log =
LoggerFactory.getLogger(SampleAdvDB.class);
+
/**
* This class represents the definition of the Departments table.
*/
@@ -279,5 +291,67 @@ public class SampleAdvDB extends TDatabase<SampleAdvDB>
addRelation( T_EMP_DEP_HIST.C_EMPLOYEE_ID .referenceOn(
T_EMPLOYEES.C_EMPLOYEE_ID )).onDeleteCascade();
addRelation( T_EMP_DEP_HIST.C_DEPARTMENT_ID.referenceOn(
T_DEPARTMENTS.C_DEPARTMENT_ID ));
}
+
+ @Override
+ public void open(DBContext context)
+ {
+ // Enable prepared statements
+ setPreparedStatementsEnabled(true);
+ // Check exists
+ if (checkExists(context))
+ { // attach to driver
+ super.open(context);
+ // yes, it exists, then check the model
+ checkDataModel(context);
+ }
+ else
+ { // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, true);
+ // create the database
+ createDatabase(context);
+ // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, false);
+ // attach to driver
+ super.open(context);
+ }
+ }
+
+ private void createDatabase(DBContext context)
+ {
+ // create DDL for Database Definition
+ DBSQLScript script = new DBSQLScript(context);
+ getCreateDDLScript(script);
+ // Show DDL Statement
+ log.info(script.toString());
+ // Execute Script
+ script.executeAll(false);
+ // Commit
+ context.commit();
+ }
+
+ private void checkDataModel(DBContext context)
+ { try {
+ DBModelChecker modelChecker =
context.getDbms().createModelChecker(this);
+ // Check data model
+ log.info("Checking DataModel for {} using {}",
getClass().getSimpleName(), modelChecker.getClass().getSimpleName());
+ // dbo schema
+ DBModelErrorLogger logger = new DBModelErrorLogger();
+ modelChecker.checkModel(this, context.getConnection(), logger);
+ // show result
+ log.info("Data model check done. Found {} errors and {}
warnings.", logger.getErrorCount(), logger.getWarnCount());
+ } catch(Exception e) {
+ log.error("FATAL error when checking data model. Probably not
properly implemented by DBMSHandler!");
+ }
+ }
+
+ private void setAutoCommit(DBContext context, boolean enable)
+ { try {
+ context.getConnection().setAutoCommit(enable);
+ } catch (SQLException e) {
+ log.error("Unable to set AutoCommit on Connection", e);
+ }
+ }
}
diff --git
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
index e9ef32b..0de039c 100644
---
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
+++
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleApp.java
@@ -22,11 +22,11 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.DriverManager;
-import java.sql.SQLException;
import java.time.LocalDate;
import java.util.List;
import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.Record;
import org.apache.empire.data.bean.BeanResult;
import org.apache.empire.data.list.DataListEntry;
import org.apache.empire.db.DBColumnExpr;
@@ -37,15 +37,9 @@ import org.apache.empire.db.DBReader;
import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBRecordBean;
import org.apache.empire.db.DBRowSet.PartialMode;
-import org.apache.empire.db.DBSQLScript;
import org.apache.empire.db.context.DBContextStatic;
import org.apache.empire.db.generic.TRecord;
-import org.apache.empire.db.validation.DBModelChecker;
-import org.apache.empire.db.validation.DBModelErrorLogger;
import org.apache.empire.dbms.DBMSHandler;
-import org.apache.empire.dbms.derby.DBMSHandlerDerby;
-import org.apache.empire.dbms.h2.DBMSHandlerH2;
-import org.apache.empire.dbms.hsql.DBMSHandlerHSql;
import org.apache.empire.dbms.postgresql.DBMSHandlerPostgreSQL;
import org.apache.empire.samples.db.SampleDB.Gender;
import org.apache.empire.samples.db.beans.Department;
@@ -64,7 +58,7 @@ public class SampleApp
private static SampleConfig config = new SampleConfig();
- private final SampleDB db = new SampleDB();
+ private SampleDB db = new SampleDB();
private DBContext context = null;
@@ -84,11 +78,12 @@ public class SampleApp
*/
public static void main(String[] args)
{
+ // Init Configuration
+ config.init((args.length > 0 ? args[0] : "config.xml" ));
+ // create the app
SampleApp app = new SampleApp();
try
- { // Init Configuration
- config.init((args.length > 0 ? args[0] : "config.xml" ));
- // Run
+ { // Run
log.info("Running DB Sample...");
app.run();
// Done
@@ -121,39 +116,18 @@ public class SampleApp
// SECTION 2.2: Create a Context
context = new DBContextStatic(dbms, conn, false, true);
- // SECTION 3: Open Database (and create if not existing)
- log.info("Step 3: openDatabase()");
- boolean clearExistingData = true;
- try {
- // Open the database
- db.open(context);
- // Check whether database exists
- databaseExists();
- log.info("Database already exists. Checking data model...");
- checkDataModel();
-
- } catch(Exception e) {
- // SECTION 4: Create Database
- log.info("Step 4: createDDL()");
- // postgre does not support DDL in transaction
- if(db.getDbms() instanceof DBMSHandlerPostgreSQL)
- {
- setAutoCommit(conn, true);
- }
- createDatabase();
- if(db.getDbms() instanceof DBMSHandlerPostgreSQL)
- {
- setAutoCommit(conn, false);
- }
- // Open again
- if (db.isOpen()==false)
- db.open(context);
- // initial load
- clearExistingData = false;
- }
+ // SECTION 3: Open Database
+ log.info("Step 3: Open database (and create if not existing)");
+ // Open the database (and create if not existing)
+ db.open(context);
// SECTION 5 AND 6: Populate Database and modify Data
- populateAndModify(clearExistingData);
+ DBCommand cmd = db.createCommand();
+ cmd.select(db.EMPLOYEES.count());
+ if (context.getUtils().querySingleInt(cmd)==0)
+ { // Employess table is empty. Populate now
+ populateAndModify();
+ }
// SECTION 7: Option 1: Query Records and print tab-separated
log.info("Step 8 Option 1: queryRecords() / Tab-Output");
@@ -218,15 +192,6 @@ public class SampleApp
}
return conn;
}
-
- private void setAutoCommit(Connection conn, boolean enable)
- {
- try {
- conn.setAutoCommit(enable);
- } catch (SQLException e) {
- log.error("Unable to set AutoCommit on Connection", e);
- }
- }
/**
* Creates an Empire-db DatabaseDriver for the given provider and
applies dbms specific configuration
@@ -260,79 +225,21 @@ public class SampleApp
throw new RuntimeException(e);
}
}
-
- /**
- * <PRE>
- * Checks whether the database exists or not by executing
- * select count(*) from DEPARTMENTS
- * If the Departments table does not exist the querySingleInt()
function return -1 for failure.
- * Please note that in this case an error will appear in the log which
can be ignored.
- * </PRE>
- */
- private boolean databaseExists()
- {
- // Check whether DB exists
- DBCommand cmd = db.createCommand();
- cmd.select(db.DEPARTMENTS.count());
- // Check using "select count(*) from DEPARTMENTS"
- log.info("Checking whether table DEPARTMENTS exists
(SQLException will be logged if not - please ignore) ...");
- return (context.getUtils().querySingleInt(cmd, -1) >= 0);
- }
-
- /**
- * <PRE>
- * Creates a DDL Script for entire SampleDB Database and executes it
line by line.
- * Please make sure you uses the correct DatabaseDriver for your target
DBMS.
- * </PRE>
- */
- private void createDatabase()
- {
- // create DDL for Database Definition
- DBSQLScript script = new DBSQLScript(context);
- db.getCreateDDLScript(script);
- // Show DDL Statement
- log.info(script.toString());
- // Execute Script
- script.executeAll(false);
- // Commit
- context.commit();
- }
-
- private void checkDataModel()
- {
- try {
- DBModelChecker modelChecker =
context.getDbms().createModelChecker(db);
- // Check data model
- log.info("Checking DataModel for {} using {}",
db.getClass().getSimpleName(), modelChecker.getClass().getSimpleName());
- // dbo schema
- DBModelErrorLogger logger = new DBModelErrorLogger();
- modelChecker.checkModel(db, context.getConnection(), logger);
- // show result
- log.info("Data model check done. Found {} errors and {}
warnings.", logger.getErrorCount(), logger.getWarnCount());
- } catch(Exception e) {
- log.error("FATAL error when checking data model. Probably not
properly implemented by DBMSHandler!");
- }
- }
- private void populateAndModify(boolean clearExisting)
+ @SuppressWarnings("unused")
+ private void populateAndModify()
{
- if (clearExisting)
- clearDatabase();
-
+ clearDatabase();
+
log.info("Step 5: insertDepartment() & insertEmployee()");
long idDevDep = insertDepartment("Development", "ITTK");
long idSalDep = insertDepartment("Sales", "ITTK");
// Insert Employees
- long idEmp1 = insertEmployee("Peter", "Sharp", Gender.M, idDevDep);
- long idEmp2 = insertEmployee("Fred", "Bloggs", Gender.M, idDevDep);
- long idEmp3 = insertEmployee("Emma", "White", Gender.F, idSalDep);
- long idEmp4 = insertEmployee("John", "Doe", Gender.M, idSalDep);
- long idEmp5 = insertEmployee("Sarah", "Smith", Gender.F, idDevDep);
- // Insert Payments
- insertPayments(idEmp1, new BigDecimal(2000));
- insertPayments(idEmp3, new BigDecimal(2500));
- insertPayments(idEmp4, new BigDecimal(2200));
- insertPayments(idEmp5, new BigDecimal(1500));
+ long idEmp1 = insertEmployee(idDevDep, "Peter", "Sharp", Gender.M,
25000);
+ long idEmp2 = insertEmployee(idDevDep, "Fred", "Bloggs", Gender.M,
32000);
+ long idEmp3 = insertEmployee(idSalDep, "Emma", "White", Gender.F,
19500);
+ long idEmp4 = insertEmployee(idSalDep, "John", "Doe", Gender.M,
18800);
+ long idEmp5 = insertEmployee(idDevDep, "Sarah", "Smith", Gender.F,
44000);
// commit
context.commit();
@@ -361,6 +268,8 @@ public class SampleApp
context.executeDelete(db.EMPLOYEES, cmd);
// Delete all Departments (no constraints)
context.executeDelete(db.DEPARTMENTS, cmd);
+ // commit
+ context.commit();
}
/**
@@ -386,17 +295,20 @@ public class SampleApp
* Inserts an Employee into the Employees table.
* </PRE>
*/
- private long insertEmployee(String firstName, String lastName, Gender
gender, long departmentId)
+ private long insertEmployee(long departmentId, String firstName, String
lastName, Gender gender, int salary)
{
SampleDB.Employees EMP = db.EMPLOYEES;
// Insert an Employee
DBRecord rec = new DBRecord(context, EMP);
rec.create(null)
+ .set(EMP.DEPARTMENT_ID, departmentId)
.set(EMP.FIRST_NAME, firstName)
.set(EMP.LAST_NAME, lastName)
.set(EMP.GENDER, gender)
- .set(EMP.DEPARTMENT_ID, departmentId)
+ .set(EMP.SALARY, salary)
.update();
+ // insert payments
+ insertPayments(rec);
// Return Employee ID
return rec.getId();
}
@@ -406,20 +318,24 @@ public class SampleApp
* Inserts an Payments for a particular Employee
* </PRE>
*/
- private void insertPayments(long employeeId, BigDecimal monthlySalary)
+ private void insertPayments(DBRecord employee)
{
- SampleDB.Payments PAY = db.PAYMENTS;
+ if (employee.isNull(db.EMPLOYEES.SALARY))
+ return; // No salary
+ // monthlySalary
+ BigDecimal monthlySalary =
employee.getDecimal(db.EMPLOYEES.SALARY).divide(new BigDecimal(12), 2,
RoundingMode.HALF_UP);
// Insert an Employee
LocalDate date = LocalDate.now();
date = date.minusDays(date.getDayOfMonth()-1); // first day of this
month
// Add Payment for each month
+ SampleDB.Payments PAY = db.PAYMENTS;
DBRecord rec = new DBRecord(context, PAY);
for (LocalDate month=date.minusMonths(20); !month.isAfter(date);
month=month.plusMonths(1))
{
BigDecimal variation = new BigDecimal((Math.random()*200) - 100.0);
variation = variation.setScale(2, RoundingMode.HALF_UP);
// insert
- rec.create(DBRecord.key(employeeId, month.getYear(),
month.getMonth()));
+ rec.create(DBRecord.key(employee.getId(), month.getYear(),
month.getMonth()));
rec.set(PAY.AMOUNT, monthlySalary.add(variation));
rec.update();
}
@@ -454,14 +370,14 @@ public class SampleApp
* Updates an employee record by setting the phone number.
* </PRE>
*/
- private void updatePartialRecord(long idEmp, String phoneNumber)
+ private void updatePartialRecord(long employeeId, String phoneNumber)
{
// Shortcut for convenience
SampleDB.Employees EMP = db.EMPLOYEES;
// Update an Employee with partial record
// this will only load the EMPLOYEE ID and the PHONE_NUMBER
DBRecord rec = new DBRecord(context, EMP);
- rec.read(DBRecord.key(idEmp), PartialMode.INCLUDE, EMP.PHONE_NUMBER);
+ rec.read(Record.key(employeeId), PartialMode.INCLUDE, EMP.SALUTATION,
EMP.FIRST_NAME, EMP.LAST_NAME, EMP.PHONE_NUMBER, EMP.EMAIL);
// Set
rec.set(db.EMPLOYEES.PHONE_NUMBER, phoneNumber);
rec.update();
@@ -642,11 +558,11 @@ public class SampleApp
SampleDB.Payments PAY = db.PAYMENTS;
// The following expression concats lastname + ', ' + firstname
- // DBColumnExpr EMPLOYEE_FULLNAME = EMP.LASTNAME.append(",
").append(EMP.FIRSTNAME).as("FULL_NAME");
- DBColumnExpr EMPLOYEE_FULLNAME = EMP.LAST_NAME.concat(", ",
EMP.FIRST_NAME).as("FULL_NAME");
+ DBColumnExpr EMPLOYEE_NAME = EMP.LAST_NAME.append(",
").append(EMP.FIRST_NAME).as("EMPLOYEE_NAME");
DBColumnExpr PAYMENTS_LAST_YEAR =
PAY.AMOUNT.sum().as("PAYMENTS_LAST_YEAR");
- // The following expression extracts the extension number from the
phone field
+ /*
+ // Example: Extracts the extension number from the phone field
// e.g. substr(PHONE_NUMBER,
length(PHONE_NUMBER)-instr(reverse(PHONE_NUMBER), '-')+2) AS PHONE_EXTENSION
// Hint: Since the reverse() function is not supported by HSQLDB there
is special treatment for HSQL
DBColumnExpr PHONE_LAST_DASH;
@@ -656,24 +572,29 @@ public class SampleApp
PHONE_LAST_DASH = EMP.PHONE_NUMBER.indexOf("-",
EMP.PHONE_NUMBER.indexOf("-").plus(1)).plus(1); // HSQLDB only
else PHONE_LAST_DASH =
EMP.PHONE_NUMBER.length().minus(EMP.PHONE_NUMBER.reverse().indexOf("-")).plus(2);
DBColumnExpr PHONE_EXT_NUMBER =
EMP.PHONE_NUMBER.substring(PHONE_LAST_DASH).as("PHONE_EXTENSION");
+ */
- // DBColumnExpr genderExpr =
cmd.select(EMP.GENDER.decode(EMP.GENDER.getOptions()).as(EMP.GENDER.getName()));
+ /*
+ // Example: Select the Gender-Enum as String
+ // e.g. case t2.GENDER when 'U' then 'Unknown' when 'M' then 'Male'
when 'F' then 'Female' end
+ DBColumnExpr GENDER_NAME =
EMP.GENDER.decode(EMP.GENDER.getOptions()).as("GENDER_NAME");
+ */
// Select Employee and Department columns
DBCommand cmd = db.createCommand()
- .select(EMP.ID.as("EMPLOYEE_ID"), EMPLOYEE_FULLNAME)
- .select(EMP.GENDER, EMP.PHONE_NUMBER, PHONE_EXT_NUMBER)
- .select(DEP.NAME.as("DEPARTMENT"))
- .select(DEP.BUSINESS_UNIT)
+ .selectQualified(EMP.ID) // select "EMPLOYEE_ID"
+ .select(EMPLOYEE_NAME, EMP.GENDER, EMP.PHONE_NUMBER, EMP.SALARY)
+ .selectQualified(DEP.NAME) // "DEPARMENT_NAME"
+ .select(DEP.BUSINESS_UNIT) // "BUSINESS_UNIT"
// Joins
.join(EMP.DEPARTMENT_ID, DEP.ID)
.joinLeft(EMP.ID, PAY.EMPLOYEE_ID, PAY.YEAR.is(lastYear))
// Where constraints
- .where(EMP.LAST_NAME.length().isGreaterThan(0))
- .where(EMP.GENDER.in(Gender.M, Gender.F))
- .where(EMP.RETIRED.is(false))
+ .where(EMP.LAST_NAME.length().isGreaterThan(0)) // always true,
just for show
+ .where(EMP.GENDER.in(Gender.M, Gender.F)) // always true,
just for show
+ .where(EMP.RETIRED.is(false)) // always true,
just for show
// Order by
- .orderBy(EMPLOYEE_FULLNAME);
+ .orderBy(EMPLOYEE_NAME);
// Add payment of last year using a SUM aggregation
cmd.groupBy(cmd.getSelectExpressions());
@@ -709,11 +630,11 @@ public class SampleApp
while (reader.moveNext())
{
System.out.println(reader.getString(EMP.ID)
- + "\t" + reader.getString(EMPLOYEE_FULLNAME)
+ + "\t" + reader.getString(EMPLOYEE_NAME)
+ "\t" +
EMP.GENDER.getOptions().get(reader.getString(EMP.GENDER))
- + "\t" + reader.getString(PHONE_EXT_NUMBER)
- + "\t" + reader.getString(DEP.NAME)
- + "\t" +
reader.getString(PAYMENTS_LAST_YEAR));
+ + "\t" + reader.getString(EMP.SALARY)
+ + "\t" + reader.getString(PAYMENTS_LAST_YEAR)
+ + "\t" + reader.getString(DEP.NAME));
}
break;
case BeanList:
diff --git
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
index 1d325e2..2d480d3 100644
---
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
+++
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/SampleDB.java
@@ -18,14 +18,23 @@
*/
package org.apache.empire.samples.db;
+import java.sql.SQLException;
+
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBContext;
import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBSQLScript;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.DBTableColumn;
+import org.apache.empire.db.validation.DBModelChecker;
+import org.apache.empire.db.validation.DBModelErrorLogger;
+import org.apache.empire.dbms.postgresql.DBMSHandlerPostgreSQL;
import org.apache.empire.samples.db.beans.Department;
import org.apache.empire.samples.db.beans.Employee;
import org.apache.empire.samples.db.beans.Payment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* <PRE>
@@ -44,6 +53,9 @@ import org.apache.empire.samples.db.beans.Payment;
*/
public class SampleDB extends DBDatabase
{
+ // Logger
+ private static final Logger log = LoggerFactory.getLogger(SampleDB.class);
+
/**
* Gender enum
*/
@@ -187,5 +199,66 @@ public class SampleDB extends DBDatabase
addRelation( EMPLOYEES.DEPARTMENT_ID.referenceOn( DEPARTMENTS.ID ));
addRelation( PAYMENTS.EMPLOYEE_ID .referenceOn( EMPLOYEES.ID ));
}
+
+ @Override
+ public void open(DBContext context)
+ {
+ // Enable prepared statements
+ // setPreparedStatementsEnabled(true);
+ // Check exists
+ if (checkExists(context))
+ { // attach to driver
+ super.open(context);
+ // yes, it exists, then check the model
+ checkDataModel(context);
+ }
+ else
+ { // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, true);
+ // create the database
+ createDatabase(context);
+ // PostgreSQL does not support DDL in transaction
+ if(getDbms() instanceof DBMSHandlerPostgreSQL)
+ setAutoCommit(context, false);
+ // attach to driver
+ super.open(context);
+ }
+ }
+ private void createDatabase(DBContext context)
+ {
+ // create DDL for Database Definition
+ DBSQLScript script = new DBSQLScript(context);
+ getCreateDDLScript(script);
+ // Show DDL Statement
+ log.info(script.toString());
+ // Execute Script
+ script.executeAll(false);
+ // Commit
+ context.commit();
+ }
+
+ private void checkDataModel(DBContext context)
+ { try {
+ DBModelChecker modelChecker =
context.getDbms().createModelChecker(this);
+ // Check data model
+ log.info("Checking DataModel for {} using {}",
getClass().getSimpleName(), modelChecker.getClass().getSimpleName());
+ // dbo schema
+ DBModelErrorLogger logger = new DBModelErrorLogger();
+ modelChecker.checkModel(this, context.getConnection(), logger);
+ // show result
+ log.info("Data model check done. Found {} errors and {}
warnings.", logger.getErrorCount(), logger.getWarnCount());
+ } catch(Exception e) {
+ log.error("FATAL error when checking data model. Probably not
properly implemented by DBMSHandler!");
+ }
+ }
+
+ private void setAutoCommit(DBContext context, boolean enable)
+ { try {
+ context.getConnection().setAutoCommit(enable);
+ } catch (SQLException e) {
+ log.error("Unable to set AutoCommit on Connection", e);
+ }
+ }
}
diff --git
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/Employee.java
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/Employee.java
index 59f3af2..f5c5197 100644
---
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/Employee.java
+++
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/Employee.java
@@ -28,6 +28,7 @@ import org.apache.empire.db.DBCommand;
import org.apache.empire.db.DBContext;
import org.apache.empire.db.list.DataBean;
import org.apache.empire.samples.db.SampleDB;
+import org.apache.empire.samples.db.SampleDB.Gender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,7 +47,7 @@ public class Employee implements DataBean<SampleDB>
private String lastName; // "LAST_NAME"
private Date dateOfBirth; // "DATE_OF_BIRTH"
private long departmentId;// "DEPARTMENT_ID"
- private String gender; // "GENDER"
+ private Gender gender; // "GENDER"
private String phoneNumber; // "PHONE_NUMBER"
private String email; // "EMAIL"
private BigDecimal salary; // "SALARY"
@@ -68,16 +69,18 @@ public class Employee implements DataBean<SampleDB>
* @param phoneNumber
* @param salary
* @param retired
- public Employee(int id, String firstname, String lastname, Date
dateOfBirth, int departmentId, String gender, String phoneNumber,
- BigDecimal salary, boolean retired, Timestamp timestamp)
+ public Employee(long id, String salutation, String firstName, String
lastName, Date dateOfBirth, long departmentId, Gender gender,
+ String phoneNumber, String email, BigDecimal salary,
boolean retired, Timestamp timestamp)
{
this.id = id;
- this.firstname = firstname;
- this.lastname = lastname;
+ this.salutation = salutation;
+ this.firstName = firstName;
+ this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
this.departmentId = departmentId;
this.gender = gender;
this.phoneNumber = phoneNumber;
+ this.email = email;
this.salary = salary;
this.retired = retired;
@@ -85,11 +88,10 @@ public class Employee implements DataBean<SampleDB>
}
*/
-
/**
* Constructor using fields but without timestamp
*/
- public Employee(long id, String salutation, String firstName, String
lastName, Date dateOfBirth, long departmentId, String gender,
+ public Employee(long id, String salutation, String firstName, String
lastName, Date dateOfBirth, long departmentId, Gender gender,
String phoneNumber, String email, BigDecimal salary,
boolean retired)
{
this.id = id;
@@ -124,8 +126,6 @@ public class Employee implements DataBean<SampleDB>
// Standard constructor
log.info("Employee bean created using standard constructor");
}
-
-
public String getSalutation()
{
@@ -176,13 +176,13 @@ public class Employee implements DataBean<SampleDB>
{
this.departmentId = departmentId;
}
-
- public String getGender()
+
+ public Gender getGender()
{
return gender;
}
- public void setGender(String gender)
+ public void setGender(Gender gender)
{
this.gender = gender;
}
diff --git
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/EmployeeQuery.java
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/EmployeeQuery.java
index 2d2dbac..795deec 100644
---
a/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/EmployeeQuery.java
+++
b/empire-db-examples/empire-db-example-basic/src/main/java/org/apache/empire/samples/db/beans/EmployeeQuery.java
@@ -20,6 +20,8 @@ package org.apache.empire.samples.db.beans;
import java.math.BigDecimal;
+import org.apache.empire.samples.db.SampleDB.Gender;
+
/**
* The SampleBean class is used to demonstrate JavaBean support for
SQL-Queries.
* The SampleBean is used in the SampleApp's queryRecords function.
@@ -27,10 +29,11 @@ import java.math.BigDecimal;
public class EmployeeQuery
{
private int employeeId;
- private String fullName;
- private String gender;
+ private String employeeName;
+ private Gender gender;
private String phoneNumber;
- private String department;
+ private BigDecimal salary;
+ private String departmentName;
private String businessUnit;
private BigDecimal paymentsLastYear;
@@ -38,17 +41,19 @@ public class EmployeeQuery
* Uncomment this if you want to use constructor instead of setters
* Number of arguments and data types must match query!
*
- public SampleBean(int employeeId, String fullName, String gender, String
phoneNumber, String department, String businessUnit, BigDecimal
paymentsLastYear)
+ public EmployeeQuery(int employeeId, String employeeName, Gender gender,
String phoneNumber, BigDecimal salary
+ , String departmentName, String businessUnit,
BigDecimal paymentsLastYear)
{
this.employeeId = employeeId;
- this.fullName = fullName;
+ this.employeeName = employeeName;
this.gender = gender;
this.phoneNumber = phoneNumber;
- this.department = department;
+ this.salary = salary;
+ this.departmentName = departmentName;
this.businessUnit = businessUnit;
this.paymentsLastYear = paymentsLastYear;
}
- */
+ */
public int getEmployeeId()
{
@@ -60,22 +65,22 @@ public class EmployeeQuery
this.employeeId = employeeId;
}
- public String getFullName()
+ public String getEmployeeName()
{
- return fullName;
+ return employeeName;
}
- public void setFullName(String fullName)
+ public void setEmployeeName(String employeeName)
{
- this.fullName = fullName;
+ this.employeeName = employeeName;
}
- public String getGender()
+ public Gender getGender()
{
return gender;
}
- public void setGender(String gender)
+ public void setGender(Gender gender)
{
this.gender = gender;
}
@@ -90,14 +95,24 @@ public class EmployeeQuery
this.phoneNumber = phoneNumber;
}
- public String getDepartment()
+ public BigDecimal getSalary()
+ {
+ return salary;
+ }
+
+ public void setSalary(BigDecimal salary)
{
- return department;
+ this.salary = salary;
+ }
+
+ public String getDepartmentName()
+ {
+ return departmentName;
}
- public void setDepartment(String department)
+ public void setDepartmentName(String departmentName)
{
- this.department = department;
+ this.departmentName = departmentName;
}
public String getBusinessUnit()
@@ -126,14 +141,16 @@ public class EmployeeQuery
StringBuffer buf = new StringBuffer();
buf.append(employeeId);
buf.append("\t");
- buf.append(fullName);
+ buf.append(employeeName);
buf.append("\t");
buf.append(gender);
buf.append("\t");
- buf.append(department);
+ buf.append(departmentName);
buf.append("\t");
buf.append(businessUnit);
buf.append("\t");
+ buf.append(salary);
+ buf.append("\t");
buf.append(paymentsLastYear);
return buf.toString();
}
diff --git a/empire-db/src/main/java/org/apache/empire/data/Column.java
b/empire-db/src/main/java/org/apache/empire/data/Column.java
index 2c100dd..8106735 100644
--- a/empire-db/src/main/java/org/apache/empire/data/Column.java
+++ b/empire-db/src/main/java/org/apache/empire/data/Column.java
@@ -80,13 +80,6 @@ public interface Column extends ColumnExpr
boolean isReadOnly();
/**
- * Returns the enum type for this column
- * <P>
- * @return the enum type
- */
- Class<Enum<?>> getEnumType();
-
- /**
* Checks if the given value is a valid value for this column
* If not, an exception is thrown
* @return the value the validated and possibly converted value
diff --git a/empire-db/src/main/java/org/apache/empire/data/ColumnExpr.java
b/empire-db/src/main/java/org/apache/empire/data/ColumnExpr.java
index 7686852..cf6bfab 100644
--- a/empire-db/src/main/java/org/apache/empire/data/ColumnExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/data/ColumnExpr.java
@@ -60,6 +60,13 @@ public interface ColumnExpr extends Unwrappable<ColumnExpr>
Object getAttribute(String name);
/**
+ * Returns the enum type for this column
+ * <P>
+ * @return the enum type
+ */
+ Class<Enum<?>> getEnumType();
+
+ /**
* Returns an option set with possible column values and their
* corresponding display text.
* @return option set with possible column values and their corresponding
display text
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
index 728a59b..48d7d64 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBColumn.java
@@ -325,7 +325,7 @@ public abstract class DBColumn extends DBColumnExpr
{
if (rowset==null)
throw new ObjectNotValidException(this);
- String rsName = rowset.getName();
+ String rsName = rowset.getEntityName();
if (StringUtils.isEmpty(rsName))
return name;
return rsName + "_" + name;
@@ -378,6 +378,16 @@ public abstract class DBColumn extends DBColumnExpr
{
return (attributes!=null ?
(Class<Enum<?>>)getAttribute(COLATTR_ENUMTYPE) : null);
}
+
+ @Override
+ public Class<?> getJavaType()
+ {
+ Class<Enum<?>> enumType = getEnumType();
+ if (enumType!=null)
+ return enumType;
+ // default
+ return super.getJavaType();
+ }
/**
* Creates and returns a sql-expression that maps enum values by name or
ordinal to their string representation
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
index 3dfed66..8156fef 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommand.java
@@ -221,6 +221,7 @@ public abstract class DBCommand extends DBCommandExpr
/**
* Sets whether or not the select statement should contain
* the distinct directive .
+ * @return itself (this)
*/
public DBCommand selectDistinct()
{
@@ -259,9 +260,10 @@ public abstract class DBCommand extends DBCommandExpr
}
/**
- * Adds a DBColumnExpr object to the Vector: 'select'.
+ * Adds a DBColumnExpr object to the Select collection
*
* @param expr the DBColumnExpr object
+ * @return itself (this)
*/
public DBCommand select(DBColumnExpr expr)
{ // Select this column
@@ -276,6 +278,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a list of columns to the select phrase of an sql statement.
*
* @param exprs an vararg of DBColumnExpr's to select
+ * @return itself (this)
*/
public final DBCommand select(DBColumnExpr... exprs)
{
@@ -290,6 +293,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a collection of columns to the select phrase of an sql statement.
*
* @param columns the column expressions to add
+ * @return itself (this)
*/
public final DBCommand select(Collection<? extends DBColumnExpr> columns)
{
@@ -304,6 +308,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a list of columns with their qualified name to the select phrase
of an sql statement.
*
* @param exprs one or more columns to select
+ * @return itself (this)
*/
public DBCommand selectQualified(DBColumn... columns)
{
@@ -318,6 +323,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a collection of columns to the select phrase of an sql statement.
*
* @param columns the column expressions to add
+ * @return itself (this)
*/
public final DBCommand selectQualified(Collection<? extends DBColumn>
columns)
{
@@ -409,7 +415,9 @@ public abstract class DBCommand extends DBCommandExpr
/**
* Adds a single set expressions to this command
* Use column.to(...) to create a set expression
+ *
* @param expr the DBSetExpr object(s)
+ * @return itself (this)
*/
public DBCommand set(DBSetExpr expr)
{
@@ -449,8 +457,10 @@ public abstract class DBCommand extends DBCommandExpr
/**
* Adds a list of set expressions to this command
- * Use column.to(...) to create a set expression
+ * Use column.to(...) to create a set expression
+ *
* @param expr the DBSetExpr object(s)
+ * @return itself (this)
*/
public final DBCommand set(DBSetExpr... exprs)
{
@@ -555,6 +565,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a join to the list of join expressions.
*
* @param join the join expression
+ * @return itself (this)
*/
public DBCommand join(DBJoinExpr join)
{
@@ -580,8 +591,7 @@ public abstract class DBCommand extends DBCommandExpr
*
* @param left the left join value
* @param right the right join
- *
- * @return the join expresion
+ * @return itself (this)
*/
public final DBCommand join(DBColumnExpr left, DBColumn right,
DBCompareExpr... addlConstraints)
{
@@ -595,8 +605,7 @@ public abstract class DBCommand extends DBCommandExpr
*
* @param left the left join value
* @param right the right join
- *
- * @return the join expresion
+ * @return itself (this)
*/
public final DBCommand joinLeft(DBColumnExpr left, DBColumn right,
DBCompareExpr... addlConstraints)
{
@@ -610,8 +619,7 @@ public abstract class DBCommand extends DBCommandExpr
*
* @param left the left join value
* @param right the right join
- *
- * @return the join expresion
+ * @return itself (this)
*/
public final DBCommand joinRight(DBColumnExpr left, DBColumn right,
DBCompareExpr... addlConstraints)
{
@@ -626,8 +634,7 @@ public abstract class DBCommand extends DBCommandExpr
* @param left the left join value
* @param right the right join
* @param joinType type of join ({@link DBJoinType#INNER}, {@link
DBJoinType#LEFT}, {@link DBJoinType#RIGHT})
- *
- * @return the join expression
+ * @return itself (this)
*/
public final DBCommand join(DBColumnExpr left, DBColumnExpr right,
DBJoinType joinType, DBCompareExpr... addlConstraints)
{
@@ -647,7 +654,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a cross join for two tables or views
* @param left the left RowSet
* @param right the right RowSet
- * @return the join expression
+ * @return itself (this)
*/
public final DBCommand join(DBRowSet left, DBRowSet right)
{
@@ -663,8 +670,7 @@ public abstract class DBCommand extends DBCommandExpr
* @param rowset table or view to join
* @param cmp the compare expression with wich to join the table
* @param joinType type of join ({@link DBJoinType#INNER}, {@link
DBJoinType#LEFT}, {@link DBJoinType#RIGHT})
- *
- * @return the join expresion
+ * @return itself (this)
*/
public final DBCommand join(DBRowSet rowset, DBCompareExpr cmp, DBJoinType
joinType)
{
@@ -678,8 +684,7 @@ public abstract class DBCommand extends DBCommandExpr
*
* @param rowset table of view which to join
* @param cmp the compare expression with wich to join the table
- *
- * @return the join expresion
+ * @return itself (this)
*/
public final DBCommand join(DBRowSet rowset, DBCompareExpr cmp)
{
@@ -824,6 +829,7 @@ public abstract class DBCommand extends DBCommandExpr
* If another restriction already exists for the same column it will be
replaced.
*
* @param expr the DBCompareExpr object
+ * @return itself (this)
*/
public DBCommand where(DBCompareExpr expr)
{
@@ -838,6 +844,7 @@ public abstract class DBCommand extends DBCommandExpr
* If another restriction already exists for the same column it will be
replaced.
*
* @param expr the DBCompareExpr object
+ * @return itself (this)
*/
public final DBCommand where(DBCompareExpr... exprs)
{
@@ -903,6 +910,7 @@ public abstract class DBCommand extends DBCommandExpr
/**
* adds a constraint to the having clause.
* @param expr the DBCompareExpr object
+ * @return itself (this)
*/
public DBCommand having(DBCompareExpr expr)
{
@@ -965,6 +973,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a list of columns to the group by phrase of an sql statement.
*
* @param exprs vararg of columns by which to group the rows
+ * @return itself (this)
*/
public DBCommand groupBy(DBColumnExpr...exprs)
{
@@ -983,6 +992,7 @@ public abstract class DBCommand extends DBCommandExpr
* Adds a collection of columns to the group by phrase of an sql statement.
*
* @param columns the column expressions to add
+ * @return itself (this)
*/
public final DBCommand groupBy(Collection<? extends DBColumnExpr> columns)
{
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
index 0509aac..1246299 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBCommandExpr.java
@@ -421,9 +421,10 @@ public abstract class DBCommandExpr extends DBExpr
/**
* Adds an order by expression the command
- * @param exprs vararg of orderBy expressions
- *
* @see org.apache.empire.db.DBCommandExpr#orderBy(DBColumnExpr, boolean)
+ *
+ * @param exprs vararg of orderBy expressions
+ * @return itself (this)
*/
public DBCommandExpr orderBy(DBOrderByExpr... exprs)
{
@@ -454,6 +455,7 @@ public abstract class DBCommandExpr extends DBExpr
* Adds a list of columns to the orderBy clause in ascending order
*
* @param exprs vararg of column expressions
+ * @return itself (this)
*/
public DBCommandExpr orderBy(DBColumnExpr... exprs)
{
@@ -469,6 +471,7 @@ public abstract class DBCommandExpr extends DBExpr
*
* @param expr the DBColumnExpr object
* @param desc if true, the results from select statement will sort top
down
+ * @return itself (this)
*/
public DBCommandExpr orderBy(DBColumnExpr expr, boolean desc)
{
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
index e6e5ddc..9d2c3ab 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
@@ -321,6 +321,16 @@ public abstract class DBDatabase extends DBObject
}
/**
+ * Checks if the database exists
+ * The implementation depends on the DBMSHandler
+ * @return true if the database exists or false otherwise
+ */
+ public boolean checkExists(DBContext context)
+ {
+ return context.getDbms().checkExists(this, context.getConnection());
+ }
+
+ /**
* Attaches the Database to the DBMS Handler provided with the context
* and allows the Database and the Handler to perform initialization tasks
*
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
index 3033b66..eeff855 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecord.java
@@ -22,11 +22,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.sql.Connection;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.empire.commons.ClassUtils;
-import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.db.DBRowSet.PartialMode;
@@ -77,9 +74,6 @@ public class DBRecord extends DBRecordBase
// options
private boolean enableRollbackHandling;
- // Parent-Record-Map for deferred identity setting
- private Map<DBColumn, DBRecordBase> parentRecordMap;
-
/**
* Custom serialization for transient rowset.
*
@@ -340,8 +334,7 @@ public class DBRecord extends DBRecordBase
if (isRollbackHandlingEnabled())
getContext().appendRollbackHandler(createRollbackHandler());
// set parent record identity
- if (ObjectUtils.isNotEmpty(parentRecordMap))
- assignParentIdentities();
+ assignParentIdentities();
// update
getRowSet().updateRecord(this);
}
@@ -374,86 +367,4 @@ public class DBRecord extends DBRecordBase
}
close();
}
-
- /**
- * Overridden for special deferred parent record handling
- */
- @Override
- public void setValue(int index, Object value)
- {
- if (value instanceof DBRecordBase)
- { // Special case: Value contains parent record
- setParentRecord(getColumn(index), (DBRecordBase)value);
- return;
- }
- super.setValue(index, value);
- }
-
- /**
- * For DBMS with IDENTITY-columns defer setting the parent-id until the
record is inserted
- * The parent record must have a one-column primary key
- * @param parentIdColumn the column for which to set the parent
- * @param record the parent record to be set for the column
- */
- public void setParentRecord(DBColumn parentIdColumn, DBRecordBase record)
- {
- if (!isValid())
- throw new ObjectNotValidException(this);
- // check column
- checkParamNull("parentIdColumn", parentIdColumn);
- // check updateable
- checkUpdateable();
- // remove
- if (record==null)
- { // clear parent
- if (parentRecordMap!=null)
- parentRecordMap.remove(parentIdColumn);
- setValue(parentIdColumn, null);
- return;
- }
- // set key or record
- Object[] key = record.getKey();
- if (key.length!=1)
- throw new NotSupportedException(this, "setParentRecord");
- if (key[0]==null)
- { // preserve until later
- if (parentRecordMap==null)
- parentRecordMap = new HashMap<DBColumn, DBRecordBase>(1);
- // add record to map
- log.info("Deffering setting of {} until the record is saved!",
parentIdColumn.getName());
- parentRecordMap.put(parentIdColumn, record);
- }
- else
- { // set directly
- int index = getFieldIndex(parentIdColumn);
- Object id = getValue(index);
- if (!ObjectUtils.compareEqual(id, key[0]))
- { // set parent-id
- modifyValue(index, key[0], true);
- }
- }
- }
-
- /**
- * For DBMS with IDENTITY-columns the deferred parent-keys are set by this
functions
- * The parent records must have been previously set using setParentRecord
- */
- protected void assignParentIdentities()
- {
- // Check map
- if (parentRecordMap==null)
- return;
- // Apply map
- for (Map.Entry<DBColumn, DBRecordBase> e : parentRecordMap.entrySet())
- {
- DBColumn parentIdColumn = e.getKey();
- Object keyValue = e.getValue().getKey()[0];
- if (keyValue==null)
- throw new ObjectNotValidException(e.getValue());
- // Set key
- log.info("Deffered setting of {} to {}!",
parentIdColumn.getName(), keyValue);
- setValue(parentIdColumn, keyValue);
- }
- parentRecordMap.clear();
- }
}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
index d9d5805..3c87984 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordBase.java
@@ -22,7 +22,9 @@ import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.PropertyUtilsBean;
@@ -41,6 +43,7 @@ import org.apache.empire.db.exceptions.NoPrimaryKeyException;
import org.apache.empire.db.exceptions.RecordReadOnlyException;
import org.apache.empire.exceptions.BeanPropertyGetException;
import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.NotSupportedException;
import org.apache.empire.exceptions.ObjectNotValidException;
import org.apache.empire.xml.XMLUtil;
import org.slf4j.Logger;
@@ -217,6 +220,9 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
Object rowsetData; // Special Rowset Data (usually null)
protected boolean validateFieldValues;
+ // Parent-Record-Map for deferred identity setting
+ private Map<DBColumn, DBRecordBase> parentRecordMap;
+
/**
* Internal constructor for DBRecord
* May be used by derived classes to provide special behaviour
@@ -228,6 +234,31 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
this.fields = null;
this.modified = null;
this.rowsetData = null;
+ this.validateFieldValues = true;
+ this.parentRecordMap = null;
+ }
+
+ /**
+ * helper to check if the object is valid
+ * @throws an ObjectNotValidException if the object is not valid
+ */
+ protected void checkValid()
+ {
+ if (!isValid())
+ throw new ObjectNotValidException(this);
+ }
+
+ /**
+ * helper to check if the object is valid
+ * @throws an ObjectNotValidException if the object is not valid
+ */
+ protected void checkValid(int fieldIndex)
+ {
+ if (!isValid())
+ throw new ObjectNotValidException(this);
+ // Check index
+ if (fieldIndex < 0 || fieldIndex>= fields.length)
+ throw new InvalidArgumentException("index", fieldIndex);
}
/**
@@ -440,10 +471,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
*/
public boolean wasModified(int index)
{
- if (!isValid())
- throw new ObjectNotValidException(this);
- if (index < 0 || index >= fields.length)
- throw new InvalidArgumentException("index", index);
+ checkValid(index);
// Check modified
if (modified == null)
return false;
@@ -539,11 +567,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
@Override
public Object getValue(int index)
{ // Check state
- if (fields == null)
- throw new ObjectNotValidException(this);
- // Check index
- if (index < 0 || index>= fields.length)
- throw new InvalidArgumentException("index", index);
+ checkValid(index);
// Special check for NO_VALUE
if (fields[index] == ObjectUtils.NO_VALUE)
throw new FieldValueNotFetchedException(getColumn(index));
@@ -561,13 +585,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
*/
public boolean isValueValid(int index)
{ // Check state
- if (fields == null)
- throw new ObjectNotValidException(this);
- // Check index
- if (index < 0 || index>= fields.length)
- { // Index out of range
- throw new InvalidArgumentException("index", index);
- }
+ checkValid(index);
// Special check for NO_VALUE
return (fields[index] != ObjectUtils.NO_VALUE);
}
@@ -601,8 +619,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
*/
public void validateAllValues()
{
- if (!this.isValid())
- throw new ObjectNotValidException(this);
+ checkValid();
// Modified
if (modified == null)
return; // nothing to do
@@ -631,12 +648,15 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
@Override
public void setValue(int index, Object value)
{
- if (!isValid())
- throw new ObjectNotValidException(this);
- if (index < 0 || index >= fields.length)
- throw new InvalidArgumentException("index", index);
+ checkValid(index);
// check updatable
checkUpdateable();
+ // Special case ParentRecord
+ if (value instanceof DBRecordBase)
+ { // Special case: Value contains parent record
+ setParentRecord(getColumn(index), (DBRecordBase)value);
+ return;
+ }
// Strings special
if ((value instanceof String) && ((String)value).length()==0)
value = null;
@@ -794,6 +814,50 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
{
return setRecordValues(bean, null);
}
+
+ /**
+ * For DBMS with IDENTITY-columns defer setting the parent-id until the
record is inserted
+ * The parent record must have a one-column primary key
+ * @param parentIdColumn the column for which to set the parent
+ * @param record the parent record to be set for the column
+ */
+ public void setParentRecord(DBColumn parentIdColumn, DBRecordBase record)
+ {
+ checkValid();
+ // check column
+ checkParamNull("parentIdColumn", parentIdColumn);
+ // check updateable
+ checkUpdateable();
+ // remove
+ if (record==null)
+ { // clear parent
+ if (parentRecordMap!=null)
+ parentRecordMap.remove(parentIdColumn);
+ setValue(parentIdColumn, null);
+ return;
+ }
+ // set key or record
+ Object[] key = record.getKey();
+ if (key.length!=1)
+ throw new NotSupportedException(this, "setParentRecord");
+ if (key[0]==null)
+ { // preserve until later
+ if (parentRecordMap==null)
+ parentRecordMap = new HashMap<DBColumn, DBRecordBase>(1);
+ // add record to map
+ log.info("Deffering setting of {} until the record is saved!",
parentIdColumn.getName());
+ parentRecordMap.put(parentIdColumn, record);
+ }
+ else
+ { // set directly
+ int index = getFieldIndex(parentIdColumn);
+ Object id = getValue(index);
+ if (!ObjectUtils.compareEqual(id, key[0]))
+ { // set parent-id
+ modifyValue(index, key[0], true);
+ }
+ }
+ }
/**
* Compares the record to another one
@@ -821,8 +885,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
@Override
public int addXmlMeta(Element parent)
{
- if (!isValid())
- throw new ObjectNotValidException(this);
+ checkValid();
// Add Field Description
int count = 0;
List<DBColumn> columns = getRowSet().getColumns();
@@ -846,8 +909,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
@Override
public int addXmlData(Element parent)
{
- if (!isValid())
- throw new ObjectNotValidException(this);
+ checkValid();
// set row key
Column[] keyColumns = getKeyColumns();
if (keyColumns != null && keyColumns.length > 0)
@@ -897,8 +959,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
@Override
public Document getXmlDocument()
{
- if (!isValid())
- throw new ObjectNotValidException(this);
+ checkValid();
// Create Document
DBXmlDictionary xmlDic = getXmlDictionary();
Element root = XMLUtil.createDocument(xmlDic.getRowSetElementName());
@@ -1016,10 +1077,7 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
*/
protected void modifyValue(int index, Object value, boolean
fireChangeEvent)
{ // Check valid
- if (state == State.Invalid)
- throw new ObjectNotValidException(this);
- if (index < 0 || index >= fields.length)
- throw new InvalidArgumentException("index", index);
+ checkValid(index);
// modified state array
if (modified == null)
{ modified = new boolean[fields.length];
@@ -1092,6 +1150,29 @@ public abstract class DBRecordBase extends DBRecordData
implements Record, Clone
}
/**
+ * For DBMS with IDENTITY-columns the deferred parent-keys are set by this
functions
+ * The parent records must have been previously set using setParentRecord
+ */
+ protected void assignParentIdentities()
+ {
+ // Check map
+ if (parentRecordMap==null)
+ return;
+ // Apply map
+ for (Map.Entry<DBColumn, DBRecordBase> e : parentRecordMap.entrySet())
+ {
+ DBColumn parentIdColumn = e.getKey();
+ Object keyValue = e.getValue().getKey()[0];
+ if (keyValue==null)
+ throw new ObjectNotValidException(e.getValue());
+ // Set key
+ log.info("Deffered setting of {} to {}!",
parentIdColumn.getName(), keyValue);
+ setValue(parentIdColumn, keyValue);
+ }
+ parentRecordMap.clear();
+ }
+
+ /**
* helper function to check if a given field index corresponds to one of
the given columns
* @param index the field index
* @param column one or more columns to check
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordBean.java
b/empire-db/src/main/java/org/apache/empire/db/DBRecordBean.java
index 73638cb..ac91cfe 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordBean.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordBean.java
@@ -289,6 +289,8 @@ public class DBRecordBean extends DBRecordBase
// allow rollback
if (this.enableRollbackHandling &&
context.isRollbackHandlingEnabled())
context.appendRollbackHandler(createRollbackHandler());
+ // set parent record identity
+ assignParentIdentities();
// update
getRowSet().updateRecord(this);
} finally {
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
b/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
index 91e3dd4..6591c03 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRecordData.java
@@ -459,25 +459,21 @@ public abstract class DBRecordData extends DBObject
throw new InvalidArgumentException("bean", bean);
if (StringUtils.isEmpty(property))
throw new InvalidArgumentException("property", property);
- /*
if (log.isTraceEnabled())
- log.trace(bean.getClass().getName() + ": setting property '" +
property + "' to " + String.valueOf(value));
- */
+ log.trace("{}: setting property '{}' to {}",
bean.getClass().getName(), property, value);
/*
if (value instanceof Date)
{ // Patch for date bug in BeanUtils
value = DateUtils.addDate((Date)value, 0, 0, 0);
}
*/
- @SuppressWarnings("unchecked")
- Class<Enum<?>> enumType =
(Class<Enum<?>>)column.getAttribute(Column.COLATTR_ENUMTYPE);
- if (enumType!=null && value!=null)
- { // value to enum
- value = ObjectUtils.getEnum(enumType, value);
- }
// Set Property Value
if (value!=null)
- { // Bean utils will convert if necessary
+ { // Convert to enum
+ Class<Enum<?>> enumType = column.getEnumType();
+ if (enumType!=null)
+ value = ObjectUtils.getEnum(enumType, value);
+ // Bean utils will convert if necessary
BeanUtils.setProperty(bean, property, value);
}
else
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index e9caf45..74ca32a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -141,6 +141,7 @@ public abstract class DBRowSet extends DBExpr implements
Entity
// Members
protected final DBDatabase db; /* transient ? */
protected String comment = null;
+ protected String entityName = null;
protected DBColumn timestampColumn = null;
protected Map<DBColumn, DBColumn> columnReferences = null;
protected List<DBColumn> columns = new
ArrayList<DBColumn>();
@@ -311,6 +312,26 @@ public abstract class DBRowSet extends DBExpr implements
Entity
String schema = db.getSchema();
return (schema!=null) ? schema+"."+name : name;
}
+
+ /**
+ * Returns the entity name for creating qualified names.
+ * This is usually the same as "getName()" but it may be overridden to
return singular instead of plural
+ * @return the entity name
+ */
+ public String getEntityName()
+ {
+ return StringUtils.coalesce(entityName, getName());
+ }
+
+ /**
+ * sets the entity name for creating qualified names.
+ * This is usefull if the table or view name is plural but you want to
qualifiy names in singular
+ * @param entityName the entity name
+ */
+ protected void setEntityName(String entityName)
+ {
+ this.entityName = entityName;
+ }
/**
* returns the bean type for this rowset
@@ -339,6 +360,9 @@ public abstract class DBRowSet extends DBExpr implements
Entity
{
// set
this.beanType = beanType;
+ // set the entity name (if not already set)
+ if (this.entityName==null)
+ this.setEntityName(beanType.getSimpleName().toUpperCase());
// create default factory if not provided
if (factory==null)
factory = new DBBeanListFactoryImpl<T>(beanType, getKeyColumns(),
getColumns());
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
index 6bd941c..d98d0e3 100644
---
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
+++
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAbstractFuncExpr.java
@@ -104,6 +104,15 @@ public abstract class DBAbstractFuncExpr extends
DBColumnExpr
}
/**
+ * Not an Enum. Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
+ /**
* Returns the column name.
*
* @return the column name
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
index 6271425..7698c57 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBAliasExpr.java
@@ -84,6 +84,16 @@ public class DBAliasExpr extends DBColumnExpr
}
/**
+ * Returns the enum type of this Expression (if any)
+ * @return the enum type or null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return expr.getEnumType();
+ }
+
+ /**
* This helper function returns the alias name.
*
* @return the alias name
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
index 8bc4568..9d1a499 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCalcExpr.java
@@ -101,6 +101,15 @@ public class DBCalcExpr extends DBColumnExpr
return type;
}
+ /**
+ * Not an Enum. Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
/** Returns the given expression name. */
@Override
public String getName()
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
index 5f37859..a3b593a 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
@@ -71,6 +71,12 @@ public class DBCaseExpr extends DBColumnExpr
}
@Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return trueExpr.getEnumType();
+ }
+
+ @Override
public String getName()
{
return trueExpr.getName();
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
index 397ef86..81d878e 100644
---
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
+++
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
@@ -74,6 +74,13 @@ public class DBCaseWhenExpr extends DBColumnExpr
}
@Override
+ public Class<Enum<?>> getEnumType()
+ {
+ DBColumnExpr cexp = getFirstColumnExpr();
+ return cexp.getEnumType();
+ }
+
+ @Override
public String getName()
{
DBCompareExpr firstCmpExpr = whenMap.keySet().iterator().next();
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
index b41f8b4..e4cdd18 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBConcatExpr.java
@@ -75,6 +75,15 @@ public class DBConcatExpr extends DBColumnExpr
return DataType.VARCHAR;
}
+ /**
+ * Not an Enum. Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
@Override
public String getName()
{ // Get the expression name
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
index 1b68f57..02e6530 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCountExpr.java
@@ -99,6 +99,15 @@ public class DBCountExpr extends DBColumnExpr
}
/**
+ * Not an Enum. Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
+ /**
* Returns the String "count".
*
* @return the String "count"
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
index 05df709..779228b 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBScalarExpr.java
@@ -116,6 +116,15 @@ public class DBScalarExpr extends DBColumnExpr
}
/**
+ * Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
+ /**
* Returns the column name.
*
* @return the column name
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
index 1a1aff4..d371499 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBValueExpr.java
@@ -120,6 +120,20 @@ public class DBValueExpr extends DBColumnExpr
}
/**
+ * Returns the EnumType if the value is an Enum
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ if (value!=null && value.getClass().isEnum())
+ { @SuppressWarnings("unchecked")
+ Class<Enum<?>> enumType = (Class<Enum<?>>)value.getClass();
+ return enumType;
+ }
+ return null;
+ }
+
+ /**
* Returns the column name.
*
* @return the column name
diff --git
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
index a465c21..77a3639 100644
---
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
+++
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBVarArgsFuncExpr.java
@@ -61,6 +61,12 @@ public class DBVarArgsFuncExpr extends DBColumnExpr
}
@Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
+ @Override
public String getName()
{
return getNameFromTemplate(template);
diff --git
a/empire-db/src/main/java/org/apache/empire/db/list/DBBeanListFactoryImpl.java
b/empire-db/src/main/java/org/apache/empire/db/list/DBBeanListFactoryImpl.java
index cca70a0..e0d3116 100644
---
a/empire-db/src/main/java/org/apache/empire/db/list/DBBeanListFactoryImpl.java
+++
b/empire-db/src/main/java/org/apache/empire/db/list/DBBeanListFactoryImpl.java
@@ -25,6 +25,7 @@ import java.util.List;
import org.apache.empire.commons.ClassUtils;
import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.db.DBColumn;
import org.apache.empire.db.DBColumnExpr;
@@ -36,6 +37,8 @@ import
org.apache.empire.db.exceptions.CommandWithoutSelectException;
import org.apache.empire.exceptions.InternalException;
import org.apache.empire.exceptions.InvalidArgumentException;
import org.apache.empire.exceptions.UnsupportedTypeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* DBRecordListFactoryImpl
@@ -44,6 +47,9 @@ import org.apache.empire.exceptions.UnsupportedTypeException;
*/
public class DBBeanListFactoryImpl<T> implements DBBeanListFactory<T>
{
+ // Logger
+ private static final Logger log =
LoggerFactory.getLogger(DBBeanListFactoryImpl.class);
+
/**
* Finds a suitable constructor for the beanClass
* @param beanType the bean class to instantiate
@@ -88,6 +94,9 @@ public class DBBeanListFactoryImpl<T> implements
DBBeanListFactory<T>
// Check constructor
if (constructor!=null && constructor.getParameterCount()>0 &&
(constructorParams==null ||
constructor.getParameterCount()<constructorParams.size()))
throw new
InvalidArgumentException("constructor||constructorParams", constructor);
+ // log
+ if (constructor!=null && log.isDebugEnabled())
+ log.debug("{}: using constructor with {} params",
constructor.getDeclaringClass().getName(), constructor.getParameterCount());
}
/**
@@ -113,6 +122,9 @@ public class DBBeanListFactoryImpl<T> implements
DBBeanListFactory<T>
this.setterColumns = selectColumns;
}
this.constructor = constructor;
+ // log
+ if (constructor!=null && log.isDebugEnabled())
+ log.debug("{}: using bean constructor with {} params",
beanType.getName(), constructor.getParameterCount());
}
/**
@@ -145,6 +157,9 @@ public class DBBeanListFactoryImpl<T> implements
DBBeanListFactory<T>
}
// found one
this.constructor = constructor;
+ // log
+ if (constructor!=null && log.isDebugEnabled())
+ log.debug("{}: using bean constructor with {} params",
beanType.getName(), constructor.getParameterCount());
}
/**
@@ -207,7 +222,16 @@ public class DBBeanListFactoryImpl<T> implements
DBBeanListFactory<T>
Object[] params = new Object[constructor.getParameterCount()];
int i=0;
for (DBColumnExpr expr : constructorParams)
- params[i++] = recData.getValue(expr);
+ {
+ Class<Enum<?>> enumType = expr.getEnumType();
+ if (enumType!=null)
+ params[i++] = recData.getEnum(expr, enumType);
+ else
+ params[i++] = recData.getValue(expr);
+ // log
+ if (log.isTraceEnabled())
+ log.trace("{}: constructor param '{}' is {}",
constructor.getDeclaringClass().getName(), StringUtils.coalesce(expr.getName(),
String.valueOf(i-1)), params[i-1]);
+ }
// create item
bean = constructor.newInstance(params);
// set remaining properties
diff --git a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
index 3fbbaf3..3c46b26 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandler.java
@@ -40,6 +40,10 @@ import org.apache.empire.db.validation.DBModelChecker;
*/
public interface DBMSHandler
{
+ /**
+ * Checks if a database exists
+ */
+ boolean checkExists(DBDatabase db, Connection conn);
/**
* Called when a database is opened
diff --git
a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
index eb94e4c..11fbd33 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/DBMSHandlerBase.java
@@ -29,6 +29,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.UUID;
@@ -48,6 +49,7 @@ import org.apache.empire.db.DBDDLGenerator.DDLActionType;
import org.apache.empire.db.DBDatabase;
import org.apache.empire.db.DBExpr;
import org.apache.empire.db.DBRelation;
+import org.apache.empire.db.DBRowSet;
import org.apache.empire.db.DBSQLScript;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.DBTableColumn;
@@ -210,6 +212,45 @@ public abstract class DBMSHandlerBase implements
DBMSHandler
reservedSQLKeywords.add(keyWord);
}
}
+
+ /**
+ * checks if the database exists
+ * The default implementation performs a simple count query on the first
table or view
+ * SELECT count(*) FROM table
+ * @return true if the database exists or false otherwise
+ */
+ @Override
+ public boolean checkExists(DBDatabase db, Connection conn)
+ {
+ // Default implementation:
+ // Select the count from ANY table or view
+ List<DBTable> tables = db.getTables();
+ DBRowSet any = (tables.isEmpty() ? db.getViews().get(0) :
tables.get(0));
+ String schema = db.getSchema();
+ String linkName = db.getLinkName();
+ // build the statement
+ StringBuilder sql = new StringBuilder("SELECT count(*) from ");
+ if (schema != null)
+ { // Add Schema
+ sql.append(schema);
+ sql.append(".");
+ }
+ // Append the name
+ appendObjectName(sql, any.getName(), null);
+ if (linkName!=null)
+ { // Database Link
+ sql.append(getSQLPhrase(DBSqlPhrase.SQL_DATABASE_LINK));
+ sql.append(linkName);
+ }
+ // Select now
+ try {
+ querySingleValue(sql.toString(), null, DataType.INTEGER, conn);
+ return true;
+ } catch(QueryFailedException e) {
+ // Database does not exist
+ return false;
+ }
+ }
/**
* Called when a database is opened
@@ -835,8 +876,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
DBBlobData blobData = (DBBlobData)value;
pstmt.setBinaryStream(paramIndex, blobData.getInputStream(),
blobData.getLength());
// log
- if (log.isDebugEnabled())
- log.debug("Statement param {} set to BLOB data", paramIndex);
+ if (log.isTraceEnabled())
+ log.trace("Statement param {} set to BLOB data", paramIndex);
}
else if(value instanceof DBClobData)
{
@@ -844,8 +885,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
DBClobData clobData = (DBClobData)value;
pstmt.setCharacterStream(paramIndex, clobData.getReader(),
clobData.getLength());
// log
- if (log.isDebugEnabled())
- log.debug("Statement param {} set to CLOB data", paramIndex);
+ if (log.isTraceEnabled())
+ log.trace("Statement param {} set to CLOB data", paramIndex);
}
else if(value instanceof Date && !(value instanceof Timestamp))
{
@@ -853,8 +894,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
Timestamp ts = new Timestamp(((Date)value).getTime());
pstmt.setObject(paramIndex, ts);
// log
- if (log.isDebugEnabled())
- log.debug("Statement param {} set to date '{}'", paramIndex,
ts);
+ if (log.isTraceEnabled())
+ log.trace("Statement param {} set to date '{}'", paramIndex,
ts);
}
else if((value instanceof Character)
|| (value instanceof Enum<?>))
@@ -863,15 +904,15 @@ public abstract class DBMSHandlerBase implements
DBMSHandler
String strval = value.toString();
pstmt.setObject(paramIndex, strval);
// log
- if (log.isDebugEnabled())
- log.debug("Statement param {} set to '{}'", paramIndex,
strval);
+ if (log.isTraceEnabled())
+ log.trace("Statement param {} set to '{}'", paramIndex,
strval);
}
else
{ // simple parameter value
pstmt.setObject(paramIndex, value);
// log
- if (log.isDebugEnabled())
- log.debug("Statement param {} set to '{}'", paramIndex, value);
+ if (log.isTraceEnabled())
+ log.trace("Statement param {} set to '{}'", paramIndex, value);
}
}
diff --git
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
index 08b9e27..7fae8bc 100644
---
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
+++
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/OracleRowNumExpr.java
@@ -74,6 +74,15 @@ public class OracleRowNumExpr extends DBColumnExpr
}
/**
+ * Not an Enum. Returns null
+ */
+ @Override
+ public Class<Enum<?>> getEnumType()
+ {
+ return null;
+ }
+
+ /**
* Returns the column name.
*
* @return the column name
diff --git
a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
index ae442b9..cf68e99 100644
---
a/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
+++
b/empire-db/src/main/java/org/apache/empire/dbms/sqlserver/DBMSHandlerMSSQL.java
@@ -220,6 +220,27 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
this.useDateTime2 = useDateTime2;
}
+ /**
+ * checks if the database exists
+ * The default implementation performs a simple count query on the first
table or view
+ * SELECT count(*) FROM table
+ * @return true if the database exists or false otherwise
+ */
+ @Override
+ public boolean checkExists(DBDatabase db, Connection conn)
+ {
+ try
+ { // Set Database
+ if (StringUtils.isNotEmpty(databaseName))
+ executeSQL("USE " + databaseName, null, conn, null);
+ // Perform a query
+ return super.checkExists(db, conn);
+ } catch (SQLException e) {
+ // No, database does not exist
+ return false;
+ }
+ }
+
/** {@inheritDoc} */
@SuppressWarnings("unused")
@Override