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

Reply via email to