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 486e2d4  EMPIREDB-362 Some minor fixes and Rework of Advanced example
486e2d4 is described below

commit 486e2d49029afe1a8987f713fed72291bf37173b
Author: Rainer Döbele <[email protected]>
AuthorDate: Thu Feb 17 11:09:02 2022 +0100

    EMPIREDB-362 Some minor fixes and Rework of Advanced example
---
 .../empire/samples/db/advanced/CarSalesDB.java     | 474 ---------------------
 .../empire/samples/db/advanced/SampleAdvApp.java   | 283 +++++++++++-
 .../{SampleAdvContext.java => SampleContext.java}  |   5 +-
 .../empire/samples/db/advanced/db/CarSalesDB.java  | 343 +++++++++++++++
 .../samples/db/advanced/db/DealerSalesView.java    |  53 +++
 .../samples/db/advanced/records/BrandRecord.java   |  10 +-
 .../samples/db/advanced/records/DealerRecord.java  |  26 ++
 .../samples/db/advanced/records/ModelRecord.java   |  30 ++
 .../main/java/org/apache/empire/data/Record.java   |  13 +
 .../org/apache/empire/data/list/DataListEntry.java |   3 +-
 .../main/java/org/apache/empire/db/DBCommand.java  |  32 +-
 .../main/java/org/apache/empire/db/DBDatabase.java |  10 +-
 .../main/java/org/apache/empire/db/DBRecord.java   |  16 +-
 .../src/main/java/org/apache/empire/db/DBView.java |   9 +-
 .../apache/empire/db/context/DBContextStatic.java  |   8 +-
 .../java/org/apache/empire/dbms/DBMSHandler.java   |   8 +-
 .../org/apache/empire/dbms/DBMSHandlerBase.java    |  27 +-
 .../org/apache/empire/dbms/h2/DBMSHandlerH2.java   |   8 +-
 .../apache/empire/dbms/mysql/DBMSHandlerMySQL.java |   8 +-
 .../apache/empire/dbms/oracle/DBCommandOracle.java |   4 +-
 .../empire/dbms/oracle/DBMSHandlerOracle.java      |   4 +-
 .../dbms/postgresql/DBMSHandlerPostgreSQL.java     |   8 +-
 .../empire/dbms/sqlite/DBMSHandlerSQLite.java      |   8 +-
 .../empire/dbms/sqlserver/DBMSHandlerMSSQL.java    |   8 +-
 24 files changed, 839 insertions(+), 559 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
deleted file mode 100644
index fcf05ac..0000000
--- 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/CarSalesDB.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-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;
-
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.data.DataType;
-import org.apache.empire.data.list.DataListEntry;
-import org.apache.empire.db.DBCommand;
-import org.apache.empire.db.DBContext;
-import org.apache.empire.db.DBRecord;
-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.apache.empire.samples.db.advanced.records.BrandRecord;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * <PRE>
- * This file contains the definition of the data model in Java.
- * The SampleDB data model consists of three tables and a foreign key relation.
- * The tables are defined as nested classes here, but you may put them in 
separate files if you want to.
- *
- * PLEASE NOTE THE NAMING CONVENTION:
- * Since all tables, views and columns are declared as "final" constants they 
are all in upper case.
- * We recommend using a prefix of T_ for tables and C_ for columns in order to 
keep them together
- * when listed in your IDE's code completion.
- * There is no need to stick to this convention but it makes life just another 
little bit easier.
- *
- * You may declare other database tables or views in the same way.
- * </PRE>
- */
-public class CarSalesDB extends TDatabase<CarSalesDB>
-{
-    // Logger
-    private static final Logger log = 
LoggerFactory.getLogger(CarSalesDB.class);
-
-    /**
-     * EngineType enum
-     */
-    public enum EngineType
-    {
-        P("Petrol"),
-        D("Diese"),
-        H("Hybrid"),
-        E("Electric");
-        
-        private final String title;
-        private EngineType(String title)
-        {
-            this.title = title;
-        }
-        @Override
-        public String toString()
-        {
-            return title;
-        }
-    }
-
-    /**
-     * EngineType enum
-     */
-    public enum DealershipType
-    {
-        B("Brand"),
-        I("Independent"),
-        F("Franchise"),
-        U("Used cars"),
-        G("Small garage");
-        
-        private final String title;
-        private DealershipType(String title)
-        {
-            this.title = title;
-        }
-        @Override
-        public String toString()
-        {
-            return title;
-        }
-    }
-
-    /**
-     * This class represents the Brand table.
-     */
-    public static class Brand extends TTable<CarSalesDB>
-    {
-        public final DBTableColumn WMI;
-        public final DBTableColumn NAME;
-        public final DBTableColumn COUNTRY;
-        public final DBTableColumn UPDATE_TIMESTAMP;
-
-        public Brand(CarSalesDB db)
-        {
-            super("BRAND", db);
-            // ID
-            WMI             = addColumn("WMI",              DataType.VARCHAR,  
     3, true); // World Manufacturer code
-            NAME            = addColumn("NAME",             DataType.VARCHAR,  
    80, true);
-            COUNTRY         = addColumn("COUNTRY",          DataType.VARCHAR,  
    80, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,     0, true);
-
-            // Primary Key (automatically set due to AUTOINC column)
-            setPrimaryKey(WMI);
-        }
-    }
-
-    /**
-     * This class represents the Model table.
-     */
-    public static class Model extends TTable<CarSalesDB>
-    {
-        public final DBTableColumn ID;
-        public final DBTableColumn NAME;
-        public final DBTableColumn CONFIG_NAME;
-        public final DBTableColumn WMI;
-        public final DBTableColumn TRIM;
-        public final DBTableColumn ENGINE_TYPE;
-        public final DBTableColumn ENGINE_POWER;
-        public final DBTableColumn BASE_PRICE;
-        public final DBTableColumn UPDATE_TIMESTAMP;
-
-        public Model(CarSalesDB db)
-        {
-            super("MODEL", db);
-            
-            // ID
-            ID              = addColumn("ID",               DataType.AUTOINC,  
    0, true, "MODEL_ID_SEQUENCE");  // Optional Sequence name for some DBMS 
(e.g. Oracle)
-            NAME            = addColumn("NAME",             DataType.VARCHAR,  
   20, true);
-            CONFIG_NAME     = addColumn("CONFIGURATION",    DataType.VARCHAR,  
   40, true);
-            WMI             = addColumn("WMI",              DataType.VARCHAR,  
    3, true);
-            TRIM            = addColumn("TRIM",             DataType.VARCHAR,  
   20, true);
-            ENGINE_TYPE     = addColumn("ENGINE_TYPE",      DataType.CHAR,     
    1, true, EngineType.class);
-            ENGINE_POWER    = addColumn("ENGINE_POWER",     DataType.DECIMAL,  
  4.0, true);
-            BASE_PRICE      = addColumn("BASE_PRICE",       DataType.DECIMAL,  
  8.2, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,    0, true);
-            
-            // Primary Key (automatically set due to AUTOINC column)
-            // setPrimaryKey(ID);
-        }
-    }
-
-    /**
-     * This class represents the Dealer table.
-     */
-    public static class Dealer extends TTable<CarSalesDB>
-    {
-        public final DBTableColumn ID;
-        public final DBTableColumn COMPANY_NAME;
-        public final DBTableColumn STREET;
-        public final DBTableColumn CITY;
-        public final DBTableColumn YEAR_FOUNDED;
-        public final DBTableColumn UPDATE_TIMESTAMP;
-
-        public Dealer(CarSalesDB db)
-        {
-            super("DEALER", db);
-            
-            // ID
-            ID              = addColumn("ID",               DataType.AUTOINC,  
    0, true, "DEALER_ID_SEQUENCE");  // Optional Sequence name for some DBMS 
(e.g. Oracle)
-            COMPANY_NAME    = addColumn("COMPANY_NAME",     DataType.VARCHAR,  
   40, true);
-            STREET          = addColumn("ADDRESS",          DataType.VARCHAR,  
   40, false);
-            CITY            = addColumn("CITY",             DataType.VARCHAR,  
   20, true);
-            YEAR_FOUNDED    = addColumn("YEAR_FOUNDED",     DataType.DECIMAL,  
  4.0, false);
-            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,    0, true);
-            
-            // Primary Key (automatically set due to AUTOINC column)
-            // setPrimaryKey(ID);
-        }
-    }
-
-    /**
-     * This class represents the Dealer table.
-     */
-    public static class DealerBrands extends TTable<CarSalesDB>
-    {
-        public final DBTableColumn DEALER_ID;
-        public final DBTableColumn BRAND_WMI;
-        public final DBTableColumn TYPE;
-
-        public DealerBrands(CarSalesDB db)
-        {
-            super("DEALER_BRANDS", db);
-            
-            // ID
-            DEALER_ID       = addForgeinKey(db.DEALER, "DEALER_ID", true);
-            BRAND_WMI       = addForgeinKey(db.BRAND,  "BRAND_WMI", true);
-            TYPE            = addColumn("TYPE",        DataType.CHAR,     1, 
true, DealershipType.class);
-            // Primary Key (automatically set due to AUTOINC column)
-            // setPrimaryKey(ID);
-        }
-    }
-
-    /**
-     * This class represents the Sales table.
-     */
-    public static class Sales extends TTable<CarSalesDB>
-    {
-        public final DBTableColumn MODEL_ID;
-        public final DBTableColumn YEAR;
-        public final DBTableColumn MONTH;
-        public final DBTableColumn CAR_COLOR;
-        public final DBTableColumn PRICE;
-
-        public Sales(CarSalesDB db)
-        {
-            super("SALES", db);
-            
-            // ID
-            MODEL_ID        = addColumn("MODEL_ID",         DataType.INTEGER,  
    0, true);
-            YEAR            = addColumn("YEAR",             DataType.DECIMAL,  
  4.0, true);
-            MONTH           = addColumn("MONTH",            DataType.DECIMAL,  
  2.0, true);
-            CAR_COLOR       = addColumn("CAR_COLOR",        DataType.VARCHAR,  
   20, false);
-            PRICE           = addColumn("PRICE",            DataType.DECIMAL,  
  8.2, true);
-
-            // No primary key!
-        }
-    }
-    
-    // Declare all Tables and Views here
-    public final Brand   BRAND = new Brand(this);
-    public final Model   MODEL = new Model(this);
-    public final Dealer  DEALER = new Dealer(this);
-    public final DealerBrands DEALER_BRANDS = new DealerBrands(this);
-    public final Sales   SALES = new Sales(this);
-    
-    private boolean wasCreated;
-
-
-    /**
-     * Constructor of the SampleDB data model
-     *
-     * Put all foreign key relations here.
-     */
-    public CarSalesDB()
-    {
-        // Define Foreign-Key Relations
-        addRelation( MODEL.WMI.referenceOn( BRAND.WMI ));
-        addRelation( SALES.MODEL_ID.referenceOn( MODEL.ID ));
-    }
-    
-    public boolean wasCreated()
-    {
-        return wasCreated;
-    }
-
-    @Override
-    public void open(DBContext context)
-    {
-        // Enable prepared statements
-        setPreparedStatementsEnabled(true);
-        // Check exists
-        if (checkExists(context))
-        {   // attach to driver
-            super.open(context);
-            // remember
-            wasCreated = false;
-            // 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
-            wasCreated = true;
-            // Commit
-            context.commit();
-        }
-    }
-
-    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);
-    }
-    
-    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);
-        }
-    }
-    
-    public void populate(SampleAdvContext context)
-    {
-        BrandRecord brandVW    = new BrandRecord(context); brandVW   
.insert("WVW", "VW",     "Germany");
-        BrandRecord brandFord  = new BrandRecord(context); brandFord 
.insert("1F",  "Ford",   "USA");
-        BrandRecord brandTesla = new BrandRecord(context); 
brandTesla.insert("5YJ", "Tesla",  "USA");
-        BrandRecord brandToy   = new BrandRecord(context); brandToy  
.insert("JT",  "Toyota", "Japan");
-        
-        DBRecord model = new DBRecord(context, MODEL);
-        // VW
-        model.create().set(MODEL.WMI, brandVW).set(MODEL.NAME, 
"Golf").set(MODEL.CONFIG_NAME, "Golf Style 1,5 l TSI").set(MODEL.TRIM, 
"Style").set(MODEL.ENGINE_TYPE, EngineType.P).set(MODEL.ENGINE_POWER, 
130).set(MODEL.BASE_PRICE,30970).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandVW).set(MODEL.NAME, 
"Golf").set(MODEL.CONFIG_NAME, "Golf R-Line 2,0 l TSI 4MOTION").set(MODEL.TRIM, 
"R-Line").set(MODEL.ENGINE_TYPE, EngineType.P).set(MODEL.ENGINE_POWER, 
190).set(MODEL.BASE_PRICE,38650).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandVW).set(MODEL.NAME, 
"Tiguan").set(MODEL.CONFIG_NAME, "Tiguan Life 1,5 l TSI").set(MODEL.TRIM, 
"Life").set(MODEL.ENGINE_TYPE, EngineType.P).set(MODEL.ENGINE_POWER, 
150).set(MODEL.BASE_PRICE,32545).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandVW).set(MODEL.NAME, 
"Tiguan").set(MODEL.CONFIG_NAME, "Tiguan Elegance 2,0 l TDI 
SCR").set(MODEL.TRIM, "Elegance").set(MODEL.ENGINE_TYPE, 
EngineType.D).set(MODEL.ENGINE_POWER, 
150).set(MODEL.BASE_PRICE,40845).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandVW).set(MODEL.NAME, 
"Tiguan").set(MODEL.CONFIG_NAME, "Tiguan R-Line 1,4 l eHybrid").set(MODEL.TRIM, 
"R-Line").set(MODEL.ENGINE_TYPE, EngineType.H).set(MODEL.ENGINE_POWER, 
150).set(MODEL.BASE_PRICE,48090).update();generateRandomSales(model);
-        // Tesla
-        model.create().set(MODEL.WMI, brandTesla).set(MODEL.NAME, "Model 
3").set(MODEL.CONFIG_NAME, "Model 3 LR").set(MODEL.TRIM, "Long 
Range").set(MODEL.ENGINE_TYPE, EngineType.E).set(MODEL.ENGINE_POWER, 
261).set(MODEL.BASE_PRICE,45940).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandTesla).set(MODEL.NAME, "Model 
3").set(MODEL.CONFIG_NAME, "Model 3 Performance").set(MODEL.TRIM, 
"Performance").set(MODEL.ENGINE_TYPE, EngineType.E).set(MODEL.ENGINE_POWER, 
487).set(MODEL.BASE_PRICE,53940).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandTesla).set(MODEL.NAME, "Model 
Y").set(MODEL.CONFIG_NAME, "Model Y LR").set(MODEL.TRIM, "Long 
Range").set(MODEL.ENGINE_TYPE, EngineType.E).set(MODEL.ENGINE_POWER, 
345).set(MODEL.BASE_PRICE,53940).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandTesla).set(MODEL.NAME, "Model 
Y").set(MODEL.CONFIG_NAME, "Model Y Performance").set(MODEL.TRIM, 
"Performance").set(MODEL.ENGINE_TYPE, EngineType.E).set(MODEL.ENGINE_POWER, 
450).set(MODEL.BASE_PRICE,58940).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandTesla).set(MODEL.NAME, "Model 
S").set(MODEL.CONFIG_NAME, "Model S Plaid").set(MODEL.TRIM, 
"Plaid").set(MODEL.ENGINE_TYPE, EngineType.E).set(MODEL.ENGINE_POWER, 
1020).set(MODEL.BASE_PRICE,126990).update(); // no sales
-        // Ford
-        model.create().set(MODEL.WMI, brandFord).set(MODEL.NAME, 
"Mustang").set(MODEL.CONFIG_NAME, "Mustang GT 5,0 l Ti-VCT V8").set(MODEL.TRIM, 
"GT").set(MODEL.ENGINE_TYPE, EngineType.P).set(MODEL.ENGINE_POWER, 
449).set(MODEL.BASE_PRICE,54300).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandFord).set(MODEL.NAME, 
"Mustang").set(MODEL.CONFIG_NAME, "Mustang Mach1 5,0 l Ti-VCT 
V8").set(MODEL.TRIM, "Mach1").set(MODEL.ENGINE_TYPE, 
EngineType.P).set(MODEL.ENGINE_POWER, 
460).set(MODEL.BASE_PRICE,62800).update();generateRandomSales(model);
-        // Toyota
-        model.create().set(MODEL.WMI, brandToy).set(MODEL.NAME, 
"Prius").set(MODEL.CONFIG_NAME, "Prius Hybrid 1,8-l-VVT-i").set(MODEL.TRIM, 
"Basis").set(MODEL.ENGINE_TYPE, EngineType.H).set(MODEL.ENGINE_POWER, 
122).set(MODEL.BASE_PRICE,38000).update();generateRandomSales(model);
-        model.create().set(MODEL.WMI, brandToy).set(MODEL.NAME, 
"Supra").set(MODEL.CONFIG_NAME, "GR Supra Pure 2,0 l Twin-Scroll 
Turbo").set(MODEL.TRIM, "Pure").set(MODEL.ENGINE_TYPE, 
EngineType.P).set(MODEL.ENGINE_POWER, 
258).set(MODEL.BASE_PRICE,49290).update();generateRandomSales(model);
-    }
-    
-    private void generateRandomSales(DBRecord model)
-    {
-        int baseYear = LocalDate.now().getYear()-3;
-        BigDecimal price = model.getDecimal(MODEL.BASE_PRICE);
-        if (ObjectUtils.isEmpty(price))
-            return;
-        DBRecord sale = new DBRecord(model.getContext(), SALES);
-        for (int i = (int)(Math.random()*99)+5; i>0; i--)
-        {
-            int year  = (int)(Math.random()*3)+baseYear;
-            int month = (int)(Math.random()*12)+1;
-            BigDecimal variation = new BigDecimal((Math.random()*200) - 100.0);
-            variation = variation.setScale(2, RoundingMode.HALF_UP);
-            sale.create()
-                .set(SALES.MODEL_ID, model.getId())
-                .set(SALES.YEAR, year)
-                .set(SALES.MONTH, month)
-                .set(SALES.PRICE, price.add(variation))
-                .update();
-        }
-    }
-    
-    public static class QueryResult 
-    {
-        private String brand;
-        private String model;
-        private BigDecimal basePrice;
-        private int salesCount;
-        private BigDecimal avgSalesPrice;
-        private BigDecimal priceDifference;
-        
-        public QueryResult(String brand, String model, BigDecimal basePrice
-                         , int salesCount, BigDecimal avgSalesPrice, 
BigDecimal priceDifference)
-        {
-            this.brand = brand;
-            this.model = model;
-            this.basePrice = basePrice;
-            this.salesCount = salesCount;
-            this.avgSalesPrice = avgSalesPrice;
-            this.priceDifference = priceDifference;
-        }
-    }
-    
-    public void queryDemo(DBContext context)
-    {
-        /*
-        DBCommand cmd = this.createCommand()
-           .select(BRAND.NAME.as("BRAND"), MODEL.NAME.as("MODEL"), 
MODEL.BASE_PRICE.avg(), SALES.MODEL_ID.count(), SALES.PRICE.avg())
-           
.select(SALES.PRICE.avg().minus(MODEL.BASE_PRICE.avg()).round(2).as("DIFFERENCE"))
-           .join(MODEL.WMI, BRAND.ID)
-           .joinLeft(MODEL.ID, SALES.MODEL_ID, SALES.YEAR.is(2021))
-           .where(MODEL.ENGINE_TYPE.in(EngineType.H, EngineType.E)) // Hybrid 
and Electric
-           .where(MODEL.BASE_PRICE.isGreaterThan(30000))
-           .groupBy(BRAND.NAME, MODEL.NAME)
-           .having(SALES.MODEL_ID.count().isGreaterThan(10))
-           .orderBy(BRAND.NAME.desc(), MODEL.NAME.asc());
-        */
-        DBCommand cmd = context.createCommand()
-           .selectQualified(BRAND.NAME, MODEL.CONFIG_NAME) 
-           .select  (MODEL.BASE_PRICE)
-           .select  (SALES.MODEL_ID.count(), SALES.PRICE.avg())
-           .select  (SALES.PRICE.avg().minus(MODEL.BASE_PRICE.avg()).round(2))
-           .join    (MODEL.WMI, BRAND.WMI)
-           .joinLeft(MODEL.ID, SALES.MODEL_ID, SALES.YEAR.is(2021))  // only 
year 2021
-           .where   (MODEL.ENGINE_TYPE.in(EngineType.P, EngineType.H, 
EngineType.E)) // Petrol, Hybrid, Electric
-           .where   (MODEL.BASE_PRICE.isGreaterThan(30000))
-           .groupBy (BRAND.NAME, MODEL.CONFIG_NAME, MODEL.BASE_PRICE)
-           .having  (SALES.MODEL_ID.count().isGreaterThan(5))
-           .orderBy (BRAND.NAME.desc(), MODEL.CONFIG_NAME.asc());
-        
-        /*
-        List<DataListEntry> list = context.getUtils().queryDataList(cmd);
-        for (DataListEntry dle : list)
-        {
-            System.out.println(dle.toString());
-        }
-        */
-        DataListEntry entry = context.getUtils().queryDataEntry(cmd);
-        for (int i=0; i<entry.getFieldCount(); i++)
-            log.info("col {} -> {}", entry.getColumn(i).getName(), 
entry.getColumn(i).getBeanPropertyName());
-     
-        List<QueryResult> list = context.getUtils().queryBeanList(cmd, 
QueryResult.class, null);
-        log.info("queryBeanList returnes {} items", list.size());
-        
-    }
-    
-    public void updateDemo(DBContext context)
-    {
-        
-        DBCommand cmd = context.createCommand()
-            .set  (MODEL.BASE_PRICE.to(55000))  // set the price-tag
-            .join (MODEL.WMI, BRAND.WMI)
-            .where(BRAND.NAME.is("Tesla"))
-            .where(MODEL.NAME.is("Model 3").and(MODEL.TRIM.is("Performance")));
-
-        /*
-         * Clone test
-        DBCommand cl1 = cmd.clone();
-        cl1.set(MODEL.BASE_PRICE.to(66000));  // set the price-tag
-        cl1.where(BRAND.NAME.is("Foo"));
-        log.info("cmd= {} params={}", cmd.getUpdate(), cmd.getParamValues());
-        log.info("cmd= {} params={}", cl1.getUpdate(), cl1.getParamValues());
-         */
-
-        // and off you go...
-        context.executeUpdate(cmd);
-    }
-    
-}
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 3b94ac8..176220c 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
@@ -18,15 +18,21 @@
  */
 package org.apache.empire.samples.db.advanced;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.time.LocalDate;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.List;
 
-import org.apache.empire.commons.DateUtils;
+import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.commons.Options;
 import org.apache.empire.commons.StringUtils;
 import org.apache.empire.data.DataType;
+import org.apache.empire.data.list.DataListEntry;
 import org.apache.empire.db.DBCmdParam;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBCommand;
@@ -39,7 +45,13 @@ import org.apache.empire.db.DBTableColumn;
 import org.apache.empire.db.exceptions.ConstraintViolationException;
 import org.apache.empire.db.exceptions.StatementFailedException;
 import org.apache.empire.dbms.DBMSHandler;
-import org.apache.empire.dbms.h2.DBMSHandlerH2;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB.DealershipType;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB.EngineType;
+import org.apache.empire.samples.db.advanced.db.DealerSalesView;
+import org.apache.empire.samples.db.advanced.records.BrandRecord;
+import org.apache.empire.samples.db.advanced.records.DealerRecord;
+import org.apache.empire.samples.db.advanced.records.ModelRecord;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,13 +63,13 @@ public class SampleAdvApp
     
     private static SampleAdvConfig config = new SampleAdvConfig();
 
-    private final SampleAdvDB db = new SampleAdvDB();
 
     private final CarSalesDB carSales = new CarSalesDB();
     
-    private SampleAdvContext context;
+    private SampleContext context;
     
     // Shortcuts
+    private final SampleAdvDB db = new SampleAdvDB();
     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;
@@ -106,22 +118,27 @@ public class SampleAdvApp
         DBMSHandler dbms = getDBMSHandler(config.getDatabaseProvider());
         
         // STEP 2.2: Create a Context
-        context = new SampleAdvContext(carSales, dbms, conn);
+        context = new SampleContext(carSales, dbms, conn);
         // set optional context features
         context.setPreparedStatementsEnabled(false);
         context.setRollbackHandlingEnabled(true);
 
         // STEP 3: Open Database (and create if not existing)
         System.out.println("*** Step 3: openDatabase() ***");
-        db.open(context);
+        // db.open(context);
         carSales.open(context);
         if (carSales.wasCreated())
         {   // newly created
-            carSales.populate(context);            
+            populateDatabase();            
+            insertSalesUsingBatch();
+            context.commit();
         }
-        carSales.queryDemo(context);
-        carSales.updateDemo(context);
+        // do simple stuff
+        queryViewDemo();
+        simpleQueryDemo();
+        simpleUpdateDemo();
 
+        /*
         // STEP 5: Clear Database (Delete all records)
         System.out.println("*** Step 5: clearDatabase() ***");
         clearDatabase();
@@ -209,12 +226,260 @@ public class SampleAdvApp
         
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.");
     }
 
+    public void populateDatabase()
+    {
+        // Add some brands
+        BrandRecord brandVW    = (new BrandRecord(context)).insert("WVW", 
"Volkswagen", "Germany");
+        BrandRecord brandFord  = (new BrandRecord(context)).insert("1F",  
"Ford",       "USA");
+        BrandRecord brandTesla = (new BrandRecord(context)).insert("5YJ", 
"Tesla",      "USA");
+        BrandRecord brandToy   = (new BrandRecord(context)).insert("JT",  
"Toyota",     "Japan");
+        
+        // Add some models
+        ModelRecord model = new ModelRecord(context);
+        model.insert(brandVW,   "Golf",     "Golf Style 1,5 l TSI",         
"Style",         EngineType.P, 130, 30970d);
+        model.insert(brandVW,   "Golf",     "Golf R-Line 2,0 l TSI 
4MOTION","R-Line",        EngineType.P, 190, 38650d);
+        model.insert(brandVW,   "Tiguan",   "Tiguan Life 1,5 l TSI",        
"Life",          EngineType.P, 150, 32545d);
+        model.insert(brandVW,   "Tiguan",   "Tiguan Elegance 2,0 l TDI 
SCR","Elegance",      EngineType.D, 150, 40845d);
+        model.insert(brandVW,   "Tiguan",   "Tiguan R-Line 1,4 l eHybrid",  
"R-Line",        EngineType.H, 150, 48090d);
+        // Tesla
+        model.insert(brandTesla,"Model 3",  "Model 3 LR",                   
"Long Range",    EngineType.E, 261, 45940d);
+        model.insert(brandTesla,"Model 3",  "Model 3 Performance",          
"Performance",   EngineType.E, 487, 53940d);
+        model.insert(brandTesla,"Model Y",  "Model Y LR",                   
"Long Range",    EngineType.E, 345, 53940d);
+        model.insert(brandTesla,"Model Y",  "Model Y Performance",          
"Performance",   EngineType.E, 450, 58940d);
+        model.insert(brandTesla,"Model S",  "Model S Plaid",                
"Plaid",         EngineType.E, 1020,0d);
+        // Ford
+        model.insert(brandFord, "Mustang",  "Mustang GT 5,0 l Ti-VCT V8",      
     "GT",    EngineType.P, 449, 54300d);
+        model.insert(brandFord, "Mustang",  "Mustang Mach1 5,0 l Ti-VCT V8",   
     "Mach1", EngineType.P, 460, 62800d);
+        // Toyota
+        model.insert(brandToy,  "Prius",    "Prius Hybrid 1,8-l-VVT-i",        
     "Basis", EngineType.H, 122, 38000d);    
+        model.insert(brandToy,  "Supra",    "GR Supra Pure 2,0 l Twin-Scroll 
Turbo","Pure",  EngineType.P, 258, 49290d);
+        
+        // Add some dealers
+        DealerRecord dealerDE = (new 
DealerRecord(context)).insert("Autozentrum Schmitz",      "Munich",       
"Germany");
+        DealerRecord dealerUK = (new DealerRecord(context)).insert("Beadles 
Volkswagen",       "Dartford",     "United Kingdom");
+        DealerRecord dealerUS = (new DealerRecord(context)).insert("Auto 
Nation",              "Los Angeles",  "USA");
+        DealerRecord dealerFR = (new DealerRecord(context)).insert("Vauban 
Motors Argenteuil", "Paris",        "France");
+        DealerRecord dealerIT = (new 
DealerRecord(context)).insert("Autorigoldi S.p.A.",       "Milan",        
"Italy");
+        
+        // Add brands to dealers
+        CarSalesDB.DealerBrands DB = carSales.DEALER_BRANDS;
+        DBRecord rec = new DBRecord(context, DB);
+        rec.create(DBRecord.key(dealerDE, brandTesla)).set(DB.DEALERSHIP_TYPE, 
DealershipType.B).update();
+        rec.create(DBRecord.key(dealerDE, brandVW))   .set(DB.DEALERSHIP_TYPE, 
DealershipType.U).update();
+        rec.create(DBRecord.key(dealerUK, brandVW))   .set(DB.DEALERSHIP_TYPE, 
DealershipType.B).update();
+        rec.create(DBRecord.key(dealerUK, brandFord)) .set(DB.DEALERSHIP_TYPE, 
DealershipType.I).update();
+        rec.create(DBRecord.key(dealerUS, brandFord)) .set(DB.DEALERSHIP_TYPE, 
DealershipType.B).update();
+        rec.create(DBRecord.key(dealerUS, brandTesla)).set(DB.DEALERSHIP_TYPE, 
DealershipType.I).update();
+        rec.create(DBRecord.key(dealerFR, brandToy))  .set(DB.DEALERSHIP_TYPE, 
DealershipType.B).update();
+        rec.create(DBRecord.key(dealerIT, brandToy))  .set(DB.DEALERSHIP_TYPE, 
DealershipType.G).update();
+        rec.create(DBRecord.key(dealerIT, brandVW))   .set(DB.DEALERSHIP_TYPE, 
DealershipType.B).update();
+        
+    }
+    
+    private void insertSalesUsingBatch()
+    {
+        CarSalesDB db = this.carSales;
+        DBSQLScript batch = new DBSQLScript(context);
+        // get list of all dealers
+        DBCommand cmd = context.createCommand();
+        cmd.select(db.DEALER.ID);
+        List<Long> dealerIdList = 
context.getUtils().querySimpleList(Long.class, cmd);
+        // get all models
+        cmd.clear();
+        cmd.select(db.MODEL.ID, db.MODEL.CONFIG_NAME, db.MODEL.BASE_PRICE);  
// select the ones we need (optional)
+        // no constraints on model
+        List<DataListEntry> modelList = context.getUtils().queryDataList(cmd);
+        for (DataListEntry model : modelList)
+        {
+            int count = generateRandomSales(batch, model, dealerIdList);
+            log.info("{} Sales added for Model {}", count, 
model.getString(db.MODEL.CONFIG_NAME));
+        }
+        // execute the batch
+        int count = batch.executeBatch();
+        log.info("{} Sales added with batch", count);
+    }
+    
+    private int generateRandomSales(DBSQLScript batch, DataListEntry model, 
List<Long> dealerIdList)
+    {
+        CarSalesDB db = this.carSales;
+        BigDecimal price = model.getDecimal(db.MODEL.BASE_PRICE);
+        if (ObjectUtils.isEmpty(price))
+            return 0;
+        int count = 0;
+        int baseYear = LocalDate.now().getYear()-3;
+        DBCommand cmd = context.createCommand();
+        for (int i = (int)(Math.random()*99)+25; i>0; i--)
+        {
+            int dealIdx = (int)(Math.random()*dealerIdList.size());
+            int year  = (int)(Math.random()*3)+baseYear;
+            int month = (int)(Math.random()*12)+1;
+            BigDecimal variation = new BigDecimal((Math.random()*200) - 100.0);
+            variation = variation.setScale(2, RoundingMode.HALF_UP);
+            cmd.set(db.SALES.MODEL_ID.to(model.getRecordId(db.MODEL)))
+               .set(db.SALES.DEALER_ID.to(dealerIdList.get(dealIdx)))
+               .set(db.SALES.YEAR.to(year))
+               .set(db.SALES.MONTH.to(month))
+               .set(db.SALES.PRICE.to(price.add(variation)));
+            // add to batch
+            batch.addInsert(cmd);
+            count++;
+        }
+        return count;
+    }
+    
+    /**
+     * The result Bean for the query Example
+     * @author rainer
+     */
+    public static class QueryResult implements Serializable
+    {
+        private static final long serialVersionUID = 1L;
+        
+        private String brand;
+        private String model;
+        private BigDecimal basePrice;
+        private int salesCount;
+        private BigDecimal avgSalesPrice;
+        private BigDecimal priceDifference;
+        
+        public QueryResult(String brand, String model, BigDecimal basePrice
+                         , int salesCount, BigDecimal avgSalesPrice, 
BigDecimal priceDifference)
+        {
+            this.brand = brand;
+            this.model = model;
+            this.basePrice = basePrice;
+            this.salesCount = salesCount;
+            this.avgSalesPrice = avgSalesPrice;
+            this.priceDifference = priceDifference;
+        }
+
+        public String getBrand()
+        {
+            return brand;
+        }
+
+        public String getModel()
+        {
+            return model;
+        }
+
+        public BigDecimal getBasePrice()
+        {
+            return basePrice;
+        }
+
+        public int getSalesCount()
+        {
+            return salesCount;
+        }
+
+        public BigDecimal getAvgSalesPrice()
+        {
+            return avgSalesPrice;
+        }
+
+        public BigDecimal getPriceDifference()
+        {
+            return priceDifference;
+        }
+    }
+    
+    public void simpleQueryDemo()
+    {
+        // shortcuts (for convenience)
+        CarSalesDB.Brand BRAND = carSales.BRAND;
+        CarSalesDB.Model MODEL = carSales.MODEL;
+        CarSalesDB.Sales SALES = carSales.SALES;
+        // create command
+        DBCommand cmd = context.createCommand()
+           .selectQualified(BRAND.NAME, MODEL.CONFIG_NAME) 
+           .select  (MODEL.BASE_PRICE)
+           .select  (SALES.MODEL_ID.count(), SALES.PRICE.avg())
+           .select  (SALES.PRICE.avg().minus(MODEL.BASE_PRICE.avg()).round(2))
+           .join    (MODEL.WMI, BRAND.WMI)
+           .joinLeft(MODEL.ID, SALES.MODEL_ID, SALES.YEAR.is(2021))  // only 
year 2021
+           .where   (MODEL.ENGINE_TYPE.in(EngineType.P, EngineType.H, 
EngineType.E)) // Petrol, Hybrid, Electric
+           .where   (MODEL.BASE_PRICE.isGreaterThan(30000))
+           .groupBy (BRAND.NAME, MODEL.CONFIG_NAME, MODEL.BASE_PRICE)
+           .having  (SALES.MODEL_ID.count().isGreaterThan(5))
+           .orderBy (BRAND.NAME.desc(), MODEL.CONFIG_NAME.asc());
+        
+        /*
+        List<DataListEntry> list = context.getUtils().queryDataList(cmd);
+        for (DataListEntry dle : list)
+        {
+            System.out.println(dle.toString());
+        }
+        */
+        DataListEntry entry = context.getUtils().queryDataEntry(cmd);
+        for (int i=0; i<entry.getFieldCount(); i++)
+            log.info("col {} -> {}", entry.getColumn(i).getName(), 
entry.getColumn(i).getBeanPropertyName());
+     
+        List<QueryResult> list = context.getUtils().queryBeanList(cmd, 
QueryResult.class, null);
+        log.info("queryBeanList returnes {} items", list.size());
+        
+    }
+    
+    public void simpleUpdateDemo()
+    {
+        // shortcuts (for convenience)
+        CarSalesDB.Brand BRAND = carSales.BRAND;
+        CarSalesDB.Model MODEL = carSales.MODEL;
+        // create command
+        DBCommand cmd = context.createCommand()
+            .set  (MODEL.BASE_PRICE.to(55000))  // set the price-tag
+            .join (MODEL.WMI, BRAND.WMI)
+            .where(BRAND.NAME.is("Tesla"))
+            .where(MODEL.NAME.is("Model 3").and(MODEL.TRIM.is("Performance")));
+
+        /*
+         * Clone test
+        DBCommand cl1 = cmd.clone();
+        cl1.set(MODEL.BASE_PRICE.to(66000));  // set the price-tag
+        cl1.where(BRAND.NAME.is("Foo"));
+        log.info("cmd= {} params={}", cmd.getUpdate(), cmd.getParamValues());
+        log.info("cmd= {} params={}", cl1.getUpdate(), cl1.getParamValues());
+         */
+
+        // and off you go...
+        context.executeUpdate(cmd);
+    }
+    
+    private void queryViewDemo()
+    {
+        /*
+        DBRecord rec = new DBRecord(context, carSales.DEALER_BRANDS);
+        rec.read(DBRecord.key(1, "5YJ"));
+        DealershipType dst1 = 
rec.getEnum(carSales.DEALER_BRANDS.DEALERSHIP_TYPE);
+        String dsn1 = rec.getString(carSales.DEALER_BRANDS.DEALERSHIP_TYPE);
+        log.info("DealershipType {}", dsn1);
+        */
+        
+        // shortcuts (for convenience)
+        DealerSalesView DSV = carSales.DEALER_SALES_VIEW;
+        // create command
+        DBCommand cmd = context.createCommand()
+           .select  (DSV.getColumns())
+           .orderBy (DSV.SALE_YEAR, DSV.DEALER_COUNTRY);
+        
+        List<DataListEntry> list = context.getUtils().queryDataList(cmd);
+        for (DataListEntry dle : list)
+        {
+            DealershipType dst = dle.getEnum(DSV.DEALERSHIP_TYPE);
+            Options opt = DSV.DEALERSHIP_TYPE.getOptions();
+            String dsn = dle.getString(DSV.DEALERSHIP_TYPE);
+            log.info("DealershipType {}-->{}", dsn, 
dle.format(DSV.DEALERSHIP_TYPE));
+            System.out.println(dle.toString());
+        }
+    }
+    
     /**
      * <PRE>
      * Opens and returns a JDBC-Connection.
diff --git 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvContext.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleContext.java
similarity index 86%
rename from 
empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvContext.java
rename to 
empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleContext.java
index b970d40..3398dfc 100644
--- 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleAdvContext.java
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/SampleContext.java
@@ -22,12 +22,13 @@ import java.sql.Connection;
 
 import org.apache.empire.db.context.DBContextStatic;
 import org.apache.empire.dbms.DBMSHandler;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB;
 
-public class SampleAdvContext extends DBContextStatic
+public class SampleContext extends DBContextStatic
 {
     private final CarSalesDB database;
     
-    public SampleAdvContext(CarSalesDB db, DBMSHandler dbmsHandler, Connection 
conn)
+    public SampleContext(CarSalesDB db, DBMSHandler dbmsHandler, Connection 
conn)
     {
         super(dbmsHandler, conn);
         // set database
diff --git 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/CarSalesDB.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/CarSalesDB.java
new file mode 100644
index 0000000..4e76b9d
--- /dev/null
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/CarSalesDB.java
@@ -0,0 +1,343 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.samples.db.advanced.db;
+
+import java.sql.SQLException;
+
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBContext;
+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;
+
+/**
+ * <PRE>
+ * This file contains the definition of the data model in Java.
+ * The SampleDB data model consists of three tables and a foreign key relation.
+ * The tables are defined as nested classes here, but you may put them in 
separate files if you want to.
+ *
+ * PLEASE NOTE THE NAMING CONVENTION:
+ * Since all tables, views and columns are declared as "final" constants they 
are all in upper case.
+ * We recommend using a prefix of T_ for tables and C_ for columns in order to 
keep them together
+ * when listed in your IDE's code completion.
+ * There is no need to stick to this convention but it makes life just another 
little bit easier.
+ *
+ * You may declare other database tables or views in the same way.
+ * </PRE>
+ */
+public class CarSalesDB extends TDatabase<CarSalesDB>
+{
+    // Logger
+    private static final Logger log = 
LoggerFactory.getLogger(CarSalesDB.class);
+
+    /**
+     * EngineType enum
+     */
+    public enum EngineType
+    {
+        P("Petrol"),
+        D("Diese"),
+        H("Hybrid"),
+        E("Electric");
+        
+        private final String title;
+        private EngineType(String title)
+        {
+            this.title = title;
+        }
+        @Override
+        public String toString()
+        {
+            return title;
+        }
+    }
+
+    /**
+     * EngineType enum
+     */
+    public enum DealershipType
+    {
+        B("Brand"),
+        I("Independent"),
+        F("Franchise"),
+        U("Used cars"),
+        G("Small garage");
+        
+        private final String title;
+        private DealershipType(String title)
+        {
+            this.title = title;
+        }
+        @Override
+        public String toString()
+        {
+            return title;
+        }
+    }
+
+    /**
+     * This class represents the Brand table.
+     */
+    public static class Brand extends TTable<CarSalesDB>
+    {
+        public final DBTableColumn WMI;
+        public final DBTableColumn NAME;
+        public final DBTableColumn COUNTRY;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public Brand(CarSalesDB db)
+        {
+            super("BRANDS", db);
+            // ID
+            WMI             = addColumn("WMI",              DataType.VARCHAR,  
     3, true); // World Manufacturer Index (see Wikipedia)
+            NAME            = addColumn("NAME",             DataType.VARCHAR,  
    80, true);
+            COUNTRY         = addColumn("COUNTRY",          DataType.VARCHAR,  
    40, false);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,     0, true);
+
+            // Primary Key (automatically set due to AUTOINC column)
+            setPrimaryKey(WMI);
+        }
+    }
+
+    /**
+     * This class represents the Model table.
+     */
+    public static class Model extends TTable<CarSalesDB>
+    {
+        public final DBTableColumn ID;
+        public final DBTableColumn NAME;
+        public final DBTableColumn CONFIG_NAME;
+        public final DBTableColumn WMI;
+        public final DBTableColumn TRIM;
+        public final DBTableColumn ENGINE_TYPE;
+        public final DBTableColumn ENGINE_POWER;
+        public final DBTableColumn BASE_PRICE;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public Model(CarSalesDB db)
+        {
+            super("MODELS", db);
+            
+            // ID
+            ID              = addColumn("ID",               DataType.AUTOINC,  
    0, true, "MODEL_ID_SEQUENCE");  // Optional Sequence name for some DBMS 
(e.g. Oracle)
+            NAME            = addColumn("NAME",             DataType.VARCHAR,  
   20, true);
+            CONFIG_NAME     = addColumn("CONFIGURATION",    DataType.VARCHAR,  
   40, true);
+            WMI             = addForgeinKey(db.BRAND, "WMI", true);
+            TRIM            = addColumn("TRIM",             DataType.VARCHAR,  
   20, true);
+            ENGINE_TYPE     = addColumn("ENGINE_TYPE",      DataType.CHAR,     
    1, true, EngineType.class);
+            ENGINE_POWER    = addColumn("ENGINE_POWER",     DataType.DECIMAL,  
  4.0, true);
+            BASE_PRICE      = addColumn("BASE_PRICE",       DataType.DECIMAL,  
  8.2, false);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,    0, true);
+            
+            // Primary Key (automatically set due to AUTOINC column, but we'll 
set it anyway)
+            setPrimaryKey(ID);
+        }
+    }
+
+    /**
+     * This class represents the Dealer table.
+     */
+    public static class Dealer extends TTable<CarSalesDB>
+    {
+        public final DBTableColumn ID;
+        public final DBTableColumn COMPANY_NAME;
+        public final DBTableColumn STREET;
+        public final DBTableColumn CITY;
+        public final DBTableColumn COUNTRY;
+        public final DBTableColumn YEAR_FOUNDED;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public Dealer(CarSalesDB db)
+        {
+            super("DEALERS", db);
+            
+            // ID
+            ID              = addColumn("ID",               DataType.AUTOINC,  
    0, true, "DEALER_ID_SEQUENCE");  // Optional Sequence name for some DBMS 
(e.g. Oracle)
+            COMPANY_NAME    = addColumn("COMPANY_NAME",     DataType.VARCHAR,  
   40, true);
+            STREET          = addColumn("ADDRESS",          DataType.VARCHAR,  
   40, false);
+            CITY            = addColumn("CITY",             DataType.VARCHAR,  
   20, true);
+            COUNTRY         = addColumn("COUNTRY",          DataType.VARCHAR,  
   40, true);
+            YEAR_FOUNDED    = addColumn("YEAR_FOUNDED",     DataType.DECIMAL,  
  4.0, false);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", 
DataType.TIMESTAMP,    0, true);
+            
+            // Primary Key (automatically set due to AUTOINC column, but we'll 
set it anyway)
+            setPrimaryKey(ID);
+        }
+    }
+
+    /**
+     * This class represents the Relationship between Brands and Dealers
+     */
+    public static class DealerBrands extends TTable<CarSalesDB>
+    {
+        public final DBTableColumn DEALER_ID;
+        public final DBTableColumn WMI;
+        public final DBTableColumn DEALERSHIP_TYPE;
+        public final DBTableColumn YEAR_BEGIN;
+
+        public DealerBrands(CarSalesDB db)
+        {
+            super("DEALER_BRANDS", db);
+            
+            // Key columns
+            DEALER_ID       = addForgeinKey(db.DEALER,  "DEALER_ID", true);
+            WMI             = addForgeinKey(db.BRAND,   "WMI", true);
+            // Data columns
+            DEALERSHIP_TYPE = addColumn("DEALERSHIP_TYPE",   DataType.CHAR,    
  1, true, DealershipType.class);
+            YEAR_BEGIN      = addColumn("YEAR_BEGIN",        DataType.DECIMAL, 
4.0, false);
+            // Primary Key
+            setPrimaryKey(DEALER_ID, WMI);
+        }
+    }
+
+    /**
+     * This class represents the Sales table.
+     */
+    public static class Sales extends TTable<CarSalesDB>
+    {
+        public final DBTableColumn MODEL_ID;
+        public final DBTableColumn DEALER_ID;
+        public final DBTableColumn YEAR;
+        public final DBTableColumn MONTH;
+        public final DBTableColumn CAR_COLOR;
+        public final DBTableColumn PRICE;
+
+        public Sales(CarSalesDB db)
+        {
+            super("SALES", db);
+            
+            // ID
+            MODEL_ID        = addForgeinKey(db.MODEL,  "MODEL_ID",  true);
+            DEALER_ID       = addForgeinKey(db.DEALER, "DEALER_ID", true);
+            YEAR            = addColumn("YEAR",             DataType.DECIMAL,  
  4.0, true);
+            MONTH           = addColumn("MONTH",            DataType.DECIMAL,  
  2.0, true);
+            CAR_COLOR       = addColumn("CAR_COLOR",        DataType.VARCHAR,  
   20, false);
+            PRICE           = addColumn("PRICE",            DataType.DECIMAL,  
  8.2, true);
+
+            /*
+             *  No primary key!
+             */
+        }
+    }
+    
+    // Declare all Tables and Views here
+    public final Brand           BRAND             = new Brand(this);
+    public final Model           MODEL             = new Model(this);
+    public final Dealer          DEALER            = new Dealer(this);
+    public final DealerBrands    DEALER_BRANDS     = new DealerBrands(this);
+    public final Sales           SALES             = new Sales(this);
+    // Views
+    public final DealerSalesView DEALER_SALES_VIEW = new DealerSalesView(this);
+
+    // Flag indicating whether Database was newly created
+    private boolean wasCreated;
+
+    /**
+     * Constructor of the SampleDB data model
+     * Put all foreign key relations here, which have not already been defined 
by addForeignKey()
+     */
+    public CarSalesDB()
+    {
+        // Define other Foreign-Key Relations
+        // e.g. Multicolum etc.
+        // addRelation( SALES.MODEL_ID.referenceOn( MODEL.ID )
+        //            , SALES.MODEL_ID.referenceOn( target ));
+    }
+    
+    /**
+     * Returns whether or not the Database was created on opening(true) or 
whether it already existed (false)
+     * @return true if the database was newly created or false otherwise
+     */
+    public boolean wasCreated()
+    {
+        return wasCreated;
+    }
+
+    @Override
+    public void open(DBContext context)
+    {
+        // Enable prepared statements
+        setPreparedStatementsEnabled(true);
+        // Check exists
+        if (checkExists(context))
+        {   // attach to driver
+            super.open(context);
+            // remember
+            wasCreated = false;
+            // 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
+            wasCreated = true;
+            // Commit
+            context.commit();
+        }
+    }
+
+    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);
+    }
+    
+    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-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/DealerSalesView.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/DealerSalesView.java
new file mode 100644
index 0000000..83b4455
--- /dev/null
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/db/DealerSalesView.java
@@ -0,0 +1,53 @@
+package org.apache.empire.samples.db.advanced.db;
+
+import org.apache.empire.data.DataType;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBCommandExpr;
+import org.apache.empire.db.generic.TView;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB.DealershipType;
+
+public class DealerSalesView extends TView<CarSalesDB>
+{
+    public final DBViewColumn DEALER_NAME;
+    public final DBViewColumn DEALER_COUNTRY;
+    public final DBViewColumn BRAND_SOLD;
+    public final DBViewColumn SALE_YEAR;
+    public final DBViewColumn SALE_COUNT;
+    public final DBViewColumn DEALERSHIP_TYPE;
+
+    public DealerSalesView(CarSalesDB db)
+    {
+        super("DEALER_SALES_VIEW", db);
+        // add columns
+        DEALER_NAME    = addColumn("DEALER_NAME",     db.DEALER.COMPANY_NAME);
+        DEALER_COUNTRY = addColumn("DEALER_COUNTRY",  db.DEALER.COUNTRY);
+        BRAND_SOLD     = addColumn("BRAND_SOLD",      db.BRAND.NAME);
+        DEALERSHIP_TYPE= addColumn("DEALERSHIP_TYPE", 
db.DEALER_BRANDS.DEALERSHIP_TYPE);
+        SALE_YEAR      = addColumn("SALE_YEAR",       db.SALES.YEAR);
+        SALE_COUNT     = addColumn("SALE_COUNT",      DataType.INTEGER);
+    }
+
+    @Override
+    public DBCommandExpr createCommand()
+    {
+        DBCommand cmd = newCommand();
+        // select
+        cmd.select(DB.DEALER.COMPANY_NAME, DB.DEALER.COUNTRY);
+        cmd.select(DB.BRAND.NAME, DB.DEALER_BRANDS.DEALERSHIP_TYPE);
+        cmd.select(DB.SALES.YEAR, DB.SALES.count());
+        // joins
+        cmd.join (DB.DEALER.ID, DB.SALES.DEALER_ID);
+        cmd.join (DB.SALES.MODEL_ID, DB.MODEL.ID);
+        cmd.join (DB.MODEL.WMI, DB.BRAND.WMI);
+        cmd.joinLeft(DB.DEALER.ID, DB.DEALER_BRANDS.DEALER_ID,
+                     DB.DEALER_BRANDS.WMI.is(DB.MODEL.WMI), 
+                     DB.DEALER_BRANDS.DEALERSHIP_TYPE.isNot(DealershipType.U));
+        // aggregation
+        cmd.groupBy(DB.DEALER.COMPANY_NAME, DB.DEALER.COUNTRY);
+        cmd.groupBy(DB.BRAND.NAME, DB.DEALER_BRANDS.DEALERSHIP_TYPE);
+        cmd.groupBy(DB.SALES.YEAR);
+        // done
+        return cmd;
+    }
+
+}
diff --git 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/BrandRecord.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/BrandRecord.java
index baa88e2..6267509 100644
--- 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/BrandRecord.java
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/BrandRecord.java
@@ -19,25 +19,27 @@
 package org.apache.empire.samples.db.advanced.records;
 
 import org.apache.empire.db.generic.TRecord;
-import org.apache.empire.samples.db.advanced.CarSalesDB;
-import org.apache.empire.samples.db.advanced.SampleAdvContext;
+import org.apache.empire.samples.db.advanced.SampleContext;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB;
 
 public class BrandRecord extends TRecord<CarSalesDB.Brand>
 {
     private static final long serialVersionUID = 1L;
 
-    public BrandRecord(SampleAdvContext context)
+    public BrandRecord(SampleContext context)
     {
         super(context, context.getDatabase().BRAND);
     }
     
-    public void insert(String wmi, String name, String country)
+    public BrandRecord insert(String wmi, String name, String country)
     {
+        // RS = RowSet
         create();
         set(RS.WMI,     wmi);
         set(RS.NAME,    name);
         set(RS.COUNTRY, country);
         update();
+        return this;
     }
 
 }
diff --git 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/DealerRecord.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/DealerRecord.java
new file mode 100644
index 0000000..7ca4385
--- /dev/null
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/DealerRecord.java
@@ -0,0 +1,26 @@
+package org.apache.empire.samples.db.advanced.records;
+
+import org.apache.empire.db.generic.TRecord;
+import org.apache.empire.samples.db.advanced.SampleContext;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB;
+
+public class DealerRecord extends TRecord<CarSalesDB.Dealer>
+{
+    private static final long serialVersionUID = 1L;
+
+    public DealerRecord(SampleContext context)
+    {
+        super(context, context.getDatabase().DEALER);
+    }
+    
+    public DealerRecord insert(String companyName, String city, String country)
+    {
+        // RS = RowSet
+        create();
+        set(RS.COMPANY_NAME, companyName);
+        set(RS.CITY,         city);
+        set(RS.COUNTRY,      country);
+        update();
+        return this;
+    }
+}
diff --git 
a/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/ModelRecord.java
 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/ModelRecord.java
new file mode 100644
index 0000000..78f8e1b
--- /dev/null
+++ 
b/empire-db-examples/empire-db-example-advanced/src/main/java/org/apache/empire/samples/db/advanced/records/ModelRecord.java
@@ -0,0 +1,30 @@
+package org.apache.empire.samples.db.advanced.records;
+
+import org.apache.empire.db.generic.TRecord;
+import org.apache.empire.samples.db.advanced.SampleContext;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB;
+import org.apache.empire.samples.db.advanced.db.CarSalesDB.EngineType;
+
+public class ModelRecord extends TRecord<CarSalesDB.Model>
+{
+    private static final long serialVersionUID = 1L;
+
+    public ModelRecord(SampleContext context)
+    {
+        super(context, context.getDatabase().MODEL);
+    }
+    
+    public void insert(BrandRecord brand, String modelName, String configName, 
String trim, EngineType engineType, int enginePower, double basePrice)
+    {
+        // RS = RowSet
+        create();
+        set(RS.WMI             , brand);
+        set(RS.NAME            , modelName);
+        set(RS.CONFIG_NAME     , configName);
+        set(RS.TRIM            , trim);
+        set(RS.ENGINE_TYPE     , engineType);
+        set(RS.ENGINE_POWER    , enginePower);
+        set(RS.BASE_PRICE      , basePrice);
+        update();
+    }
+}
diff --git a/empire-db/src/main/java/org/apache/empire/data/Record.java 
b/empire-db/src/main/java/org/apache/empire/data/Record.java
index fca7fc8..d5ef0c7 100644
--- a/empire-db/src/main/java/org/apache/empire/data/Record.java
+++ b/empire-db/src/main/java/org/apache/empire/data/Record.java
@@ -44,6 +44,19 @@ public interface Record extends RecordData
     {
         if (values.length==0)
             throw new InvalidArgumentException("values", values);
+        // check values
+        for (int i=0; i<values.length; i++) {
+            // Replace record with key
+            if (values[i] instanceof Record)
+                values[i]=((Record)values[i]).getKey();
+            // Replace key with value
+            if (values[i] instanceof Object[]) {   
+               Object[] key = (Object[])values[i];
+               if (key.length!=1)
+                   throw new InvalidArgumentException("values", values[i]);
+               values[i]=key[0];
+            }
+        }
         return values;
     }
 
diff --git 
a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java 
b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
index cb33954..d718faa 100644
--- a/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
+++ b/empire-db/src/main/java/org/apache/empire/data/list/DataListEntry.java
@@ -24,7 +24,6 @@ import java.util.Collection;
 import java.util.Date;
 
 import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.StringUtils;
 import org.apache.empire.data.Column;
 import org.apache.empire.data.ColumnExpr;
 import org.apache.empire.data.EntityType;
@@ -239,7 +238,7 @@ public class DataListEntry implements RecordData, 
Serializable
     public String getString(int index)
     {   // Get String value
         Object o = getValue(index);
-        return StringUtils.toString(o);
+        return ObjectUtils.getString(o);
     }
 
     public final String getString(ColumnExpr column)
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 c959656..ba39c30 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
@@ -57,31 +57,31 @@ public abstract class DBCommand extends DBCommandExpr
     // *Deprecated* private static final long serialVersionUID = 1L;
 
     // Logger
-    protected static final Logger log = 
LoggerFactory.getLogger(DBCommand.class);
+    protected static final Logger log             = 
LoggerFactory.getLogger(DBCommand.class);
 
     // Distinct Select
-    protected boolean                selectDistinct = false;
+    protected boolean             selectDistinct  = false;
     // Lists
-    protected List<DBColumnExpr>     select         = null;
-    protected List<DBSetExpr>        set            = null;
-    protected List<DBJoinExpr>       joins          = null; // Join Info
-    protected List<DBCompareExpr>    where          = null;
-    protected List<DBCompareExpr>    having         = null;
-    protected List<DBColumnExpr>     groupBy        = null;
-    
-    // Parameters for prepared Statements
-    protected boolean                preparedStatementsEnabled = false; /* 
flag for automatic prepared statements */
-    protected List<DBCmdParam>       cmdParams      = null;
-    private int                      paramUsageCount= 0;
+    protected List<DBColumnExpr>  select          = null;
+    protected List<DBSetExpr>     set             = null;
+    protected List<DBJoinExpr>    joins           = null;
+    protected List<DBCompareExpr> where           = null;
+    protected List<DBCompareExpr> having          = null;
+    protected List<DBColumnExpr>  groupBy         = null;
+
+    // Parameters for prepared Statements generation
+    protected boolean             autoPrepareStmt = false;
+    protected List<DBCmdParam>    cmdParams       = null;
+    private int                   paramUsageCount = 0;
 
     /**
      * Constructs a new DBCommand object and set the specified DBDatabase 
object.
      * 
      * @param db the current database object
      */
-    protected DBCommand(boolean preparedStatementsEnabled)
+    protected DBCommand(boolean autoPrepareStmt)
     {
-        this.preparedStatementsEnabled = preparedStatementsEnabled;
+        this.autoPrepareStmt = autoPrepareStmt;
     }
 
     /**
@@ -1219,7 +1219,7 @@ public abstract class DBCommand extends DBCommandExpr
      */
     protected boolean isPreparedStatementsEnabled()
     {
-        return this.preparedStatementsEnabled;
+        return this.autoPrepareStmt;
     }
     
     /**
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 0e2f75e..8d5de63 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
@@ -154,7 +154,7 @@ public abstract class DBDatabase extends DBObject
      * Note: This will only apply for update and insert commands as well as 
for read operations on a DBRecord.
      * For custom SQL commands parameters must be explicitly declared using 
cmd.addCmdParam();   
      */
-    private boolean preparedStatementsEnabled = false;
+    private boolean autoPrepareStmt = false;
 
     /**
      * Constructs a new DBDatabase object and sets the specified schema object.
@@ -305,7 +305,7 @@ public abstract class DBDatabase extends DBObject
      */
     public boolean isPreparedStatementsEnabled()
     {
-        return preparedStatementsEnabled;
+        return autoPrepareStmt;
     }
 
     /**
@@ -313,11 +313,11 @@ public abstract class DBDatabase extends DBObject
      * Note: For custom SQL commands parameters must be explicitly declared 
using cmd.addCmdParam();   
      * @param preparedStatementsEnabled
      */
-    public void setPreparedStatementsEnabled(boolean preparedStatementsEnabled)
+    public void setPreparedStatementsEnabled(boolean autoPrepareStmt)
     {
-        this.preparedStatementsEnabled = preparedStatementsEnabled;
+        this.autoPrepareStmt = autoPrepareStmt;
         // log prepared statement 
-        log.info("PreparedStatementsEnabled is " + preparedStatementsEnabled);
+        log.info("PreparedStatementsEnabled is " + autoPrepareStmt);
     }
 
     /**
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 e322ab9..e047b20 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
@@ -26,6 +26,7 @@ import java.sql.Connection;
 import org.apache.empire.commons.ClassUtils;
 import org.apache.empire.commons.StringUtils;
 import org.apache.empire.data.Column;
+import org.apache.empire.data.Record;
 import org.apache.empire.db.DBRowSet.PartialMode;
 import org.apache.empire.db.exceptions.NoPrimaryKeyException;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
@@ -58,12 +59,25 @@ public class DBRecord extends DBRecordBase
     /**
      * varArgs to Array
      * @param values
-     * @return
+     * @return the key
      */
     public static Object[] key(Object... values)
     {
         if (values.length==0)
             throw new InvalidArgumentException("values", values);
+        // check values
+        for (int i=0; i<values.length; i++) {
+            // Replace record with key
+            if (values[i] instanceof Record)
+                values[i]=((Record)values[i]).getKey();
+            // Replace key with value
+            if (values[i] instanceof Object[]) {   
+               Object[] key = (Object[])values[i];
+               if (key.length!=1)
+                   throw new InvalidArgumentException("values", values[i]);
+               values[i]=key[0];
+            }
+        }
         return values;
     }
 
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBView.java 
b/empire-db/src/main/java/org/apache/empire/db/DBView.java
index 2ba45f1..ce520be 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBView.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBView.java
@@ -21,6 +21,7 @@ package org.apache.empire.db;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.empire.commons.Options;
+import org.apache.empire.data.Column;
 import org.apache.empire.data.DataType;
 import org.apache.empire.db.expr.column.DBValueExpr;
 import org.apache.empire.exceptions.InvalidArgumentException;
@@ -66,11 +67,15 @@ public abstract class DBView extends DBRowSet
             DataType exprType = expr.getDataType();
             if (exprType==DataType.AUTOINC)
                 exprType= DataType.INTEGER;
-            this.dataType = exprType; 
-            // Update Column
+            this.dataType = exprType;
+            // Source Column
             this.sourceColumn = expr.getSourceColumn();
             // from update column
             this.size = (sourceColumn!=null ? sourceColumn.getSize() : size);
+            // Copy enumType
+            Class<Enum<?>> enumType = expr.getEnumType();
+            if (enumType!=null)
+                setAttribute(Column.COLATTR_ENUMTYPE, enumType);
             // Add to view
             if (view != null)
                 view.addColumn(this);
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/context/DBContextStatic.java 
b/empire-db/src/main/java/org/apache/empire/db/context/DBContextStatic.java
index f4ad1cd..9819e7c 100644
--- a/empire-db/src/main/java/org/apache/empire/db/context/DBContextStatic.java
+++ b/empire-db/src/main/java/org/apache/empire/db/context/DBContextStatic.java
@@ -34,7 +34,7 @@ public class DBContextStatic extends DBContextBase
     private final boolean closeOnDiscard;
     // features
     private boolean enableRollbackHandling = false;
-    private boolean preparedStatementsEnabled = false;
+    private boolean autoPrepareStmt = false;
     
     /**
      *  Global DBRollbackManager
@@ -77,7 +77,7 @@ public class DBContextStatic extends DBContextBase
     @Override
     public boolean isPreparedStatementsEnabled()
     {
-        return preparedStatementsEnabled;
+        return autoPrepareStmt;
     }
     
     /**
@@ -87,9 +87,9 @@ public class DBContextStatic extends DBContextBase
      */
     public DBContextStatic setPreparedStatementsEnabled(boolean enabled)
     {
-        this.preparedStatementsEnabled = enabled;
+        this.autoPrepareStmt = enabled;
         // log prepared statement 
-        log.info("PreparedStatementsEnabled has been set to " + 
preparedStatementsEnabled);
+        log.info("PreparedStatementsEnabled has been set to " + 
autoPrepareStmt);
         return this;
     }
 
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 4102494..3da3c1e 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
@@ -56,11 +56,11 @@ public interface DBMSHandler
     void detachDatabase(DBDatabase db, Connection conn);
     
     /**
-     * This function creates a DBCommand derived object this database
-     * @param db the database for which to create a command object for
-     * @return a DBCommand object
+     * This function creates a DBCommand for this DBMS
+     * @param autoPrepareStmt whether or not the Command should automatically 
generate a prepared statement (using ?)
+     * @return a DBMS specific DBCommand object
      */
-    DBCommand createCommand(boolean preparedStatementsEnabled);
+    DBCommand createCommand(boolean autoPrepareStmt);
 
     /**
      * This function gives the dbms a chance to provide a custom 
implementation 
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 65b4c63..d59223d 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
@@ -88,9 +88,9 @@ public abstract class DBMSHandlerBase implements DBMSHandler
      */
     public static final class DBMSCommand extends DBCommand 
     {
-        protected DBMSCommand(boolean preparedStatementsEnabled)
+        protected DBMSCommand(boolean autoPrepareStmt)
         {
-            super(preparedStatementsEnabled);
+            super(autoPrepareStmt);
         }
     }
 
@@ -289,9 +289,9 @@ public abstract class DBMSHandlerBase implements DBMSHandler
      * @return a DBCommand object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
-        return new DBMSCommand(preparedStatementsEnabled);
+        return new DBMSCommand(autoPrepareStmt);
     }
 
     /**
@@ -623,10 +623,10 @@ public abstract class DBMSHandlerBase implements 
DBMSHandler
 
     /**
      * Executes a list of sql statements as batch
-     * @param sqlCmd
-     * @param sqlCmdParams
-     * @param conn
-     * @return
+     * @param sqlCmd an array of sql statements
+     * @param sqlCmdParams and array of statement parameters
+     * @param conn a JDBC connection
+     * @return an array containing the number of records affected by each 
statement
      * @throws SQLException
      */
     @Override
@@ -660,7 +660,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
                         if (cmd==null)
                             break;
                         // new statement
-                        log.debug("Creating prepared statement for batch: 
"+cmd);
+                        if (log.isTraceEnabled())
+                            log.trace("Creating prepared statement for batch: 
{}", cmd);
                         pstmt = conn.prepareStatement(cmd);
                         lastCmd = cmd;
                     }
@@ -669,7 +670,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
                     {   
                         prepareStatement(pstmt, sqlCmdParams[i]); 
                     }   
-                    log.debug("Adding batch with {} params.", 
(sqlCmdParams[i]!=null ? sqlCmdParams[i].length : 0));
+                    if (log.isTraceEnabled())
+                        log.trace("Adding batch with {} params.", 
(sqlCmdParams[i]!=null ? sqlCmdParams[i].length : 0));
                     pstmt.addBatch();
                 }
                 return result; 
@@ -684,7 +686,8 @@ public abstract class DBMSHandlerBase implements DBMSHandler
                 for (int i=0; i<sqlCmd.length; i++)
                 {
                     String cmd = sqlCmd[i];
-                    log.debug("Adding statement to batch: "+cmd);
+                    if (log.isTraceEnabled())
+                        log.trace("Adding statement to batch: {}", cmd);
                     stmt.addBatch(cmd);
                 }
                 log.debug("Executing batch containing {} statements", 
sqlCmd.length);
@@ -751,7 +754,7 @@ public abstract class DBMSHandlerBase implements DBMSHandler
             // Check Result
             if (rs.next() == false)
             {   // no result
-                log.debug("querySingleValue returned no result");
+                log.trace("querySingleValue for {} returned no result", 
sqlCmd);
                 return ObjectUtils.NO_VALUE;
             }
             // Read value
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java 
b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
index 87673b1..3f4eafd 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/h2/DBMSHandlerH2.java
@@ -61,9 +61,9 @@ public class DBMSHandlerH2 extends DBMSHandlerBase
            protected int limitRows = -1;
            protected int skipRows  =  0;
         
-        public DBCommandH2(boolean preparedStatementsEnabled)
+        public DBCommandH2(boolean autoPrepareStmt)
         {
-            super(preparedStatementsEnabled);
+            super(autoPrepareStmt);
         }
     
            @Override
@@ -192,10 +192,10 @@ public class DBMSHandlerH2 extends DBMSHandlerBase
      * @return the new DBCommandDerby object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create command object
-        return new DBCommandH2(preparedStatementsEnabled);
+        return new DBCommandH2(autoPrepareStmt);
     }
 
     /**
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java 
b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
index 26faef5..d613fce 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/mysql/DBMSHandlerMySQL.java
@@ -65,9 +65,9 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
         protected int limit = -1;
         protected int skip  = -1;
         
-        public DBCommandMySQL(boolean preparedStatementsEnabled)
+        public DBCommandMySQL(boolean autoPrepareStmt)
         {
-            super(preparedStatementsEnabled);
+            super(autoPrepareStmt);
         }
         
         @Override
@@ -904,10 +904,10 @@ public class DBMSHandlerMySQL extends DBMSHandlerBase
      * @return the new DBCommandMySQL object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create command object
-        return new DBCommandMySQL(preparedStatementsEnabled);
+        return new DBCommandMySQL(autoPrepareStmt);
     }
 
     @Override
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java 
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
index d5e878d..241187c 100644
--- a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
+++ b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBCommandOracle.java
@@ -67,9 +67,9 @@ public class DBCommandOracle extends DBCommand
      * 
      * @param db the oracle database object this command belongs to
      */
-    public DBCommandOracle(boolean preparedStatementsEnabled)
+    public DBCommandOracle(boolean autoPrepareStmt)
     {
-        super(preparedStatementsEnabled);
+        super(autoPrepareStmt);
     }
 
     public String getOptimizerHint()
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java 
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
index b7f69a5..d30941b 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/oracle/DBMSHandlerOracle.java
@@ -151,10 +151,10 @@ public class DBMSHandlerOracle extends DBMSHandlerBase
      * @return the new DBCommandOracle object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create oracle command
-        return new DBCommandOracle(preparedStatementsEnabled);
+        return new DBCommandOracle(autoPrepareStmt);
     }
 
     /**
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
 
b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
index 7770f17..f2916c2 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/postgresql/DBMSHandlerPostgreSQL.java
@@ -86,9 +86,9 @@ public class DBMSHandlerPostgreSQL extends DBMSHandlerBase
         protected int limit = -1;
         protected int skip  = -1;
         
-        public DBCommandPostreSQL(boolean preparedStatementsEnabled)
+        public DBCommandPostreSQL(boolean autoPrepareStmt)
         {
-            super(preparedStatementsEnabled);
+            super(autoPrepareStmt);
         }
         
         @Override
@@ -293,10 +293,10 @@ public class DBMSHandlerPostgreSQL extends DBMSHandlerBase
      * @return the new DBCommandPostgreSQL object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create command object
-        return new DBCommandPostreSQL(preparedStatementsEnabled);
+        return new DBCommandPostreSQL(autoPrepareStmt);
     }
 
     /**
diff --git 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
index 1f549b5..7a93b1d 100644
--- 
a/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
+++ 
b/empire-db/src/main/java/org/apache/empire/dbms/sqlite/DBMSHandlerSQLite.java
@@ -73,9 +73,9 @@ public class DBMSHandlerSQLite extends DBMSHandlerBase
          *            the database
          * @see org.apache.empire.db.DBCommand
          */
-        public DBCommandSQLite(boolean preparedStatementsEnabled)
+        public DBCommandSQLite(boolean autoPrepareStmt)
         {
-            super(preparedStatementsEnabled);
+            super(autoPrepareStmt);
         }
         
         @Override
@@ -268,10 +268,10 @@ public class DBMSHandlerSQLite extends DBMSHandlerBase
      * @return the new DBCommandSQLite object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create command object
-        return new DBCommandSQLite(preparedStatementsEnabled);
+        return new DBCommandSQLite(autoPrepareStmt);
     }
     
     /**
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 07630ec..79f6cf4 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
@@ -64,9 +64,9 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
         // *Deprecated* private static final long serialVersionUID = 1L;
         protected int limit = -1;
 
-        public DBCommandMSSQL(boolean preparedStatementsEnabled)
+        public DBCommandMSSQL(boolean autoPrepareStmt)
        {
-               super(preparedStatementsEnabled);
+               super(autoPrepareStmt);
        }
         
         @Override
@@ -277,10 +277,10 @@ public class DBMSHandlerMSSQL extends DBMSHandlerBase
      * @return the new DBCommandMSSQL object
      */
     @Override
-    public DBCommand createCommand(boolean preparedStatementsEnabled)
+    public DBCommand createCommand(boolean autoPrepareStmt)
     {
         // create command object
-        return new DBCommandMSSQL(preparedStatementsEnabled);
+        return new DBCommandMSSQL(autoPrepareStmt);
     }
 
     /**

Reply via email to