You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2013/07/22 10:10:39 UTC

[26/64] [partial] Hard rename of all 'org/eobjects' folders to 'org/apache'.

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/QueryPostprocessDataContextTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/QueryPostprocessDataContextTest.java b/core/src/test/java/org/apache/metamodel/QueryPostprocessDataContextTest.java
new file mode 100644
index 0000000..0562bc5
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/QueryPostprocessDataContextTest.java
@@ -0,0 +1,861 @@
+/**
+ * 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.eobjects.metamodel;
+
+import java.nio.channels.UnsupportedAddressTypeException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.TableModel;
+
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.data.DataSetTableModel;
+import org.eobjects.metamodel.data.Row;
+import org.eobjects.metamodel.query.CompiledQuery;
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.query.FromItem;
+import org.eobjects.metamodel.query.FunctionType;
+import org.eobjects.metamodel.query.GroupByItem;
+import org.eobjects.metamodel.query.JoinType;
+import org.eobjects.metamodel.query.OperatorType;
+import org.eobjects.metamodel.query.OrderByItem;
+import org.eobjects.metamodel.query.QueryParameter;
+import org.eobjects.metamodel.query.OrderByItem.Direction;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.MutableColumn;
+import org.eobjects.metamodel.schema.MutableSchema;
+import org.eobjects.metamodel.schema.MutableTable;
+import org.eobjects.metamodel.schema.Relationship;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+
+public class QueryPostprocessDataContextTest extends MetaModelTestCase {
+
+    private final Schema schema = getExampleSchema();
+    private final Table table1 = schema.getTableByName(TABLE_CONTRIBUTOR);
+    private final Table table2 = schema.getTableByName(TABLE_ROLE);
+
+    public void testAggregateQueryNoWhereClause() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+        Table table = dc.getDefaultSchema().getTables()[0];
+        assertSingleRowResult("Row[values=[4]]", dc.query().from(table).selectCount().execute());
+    }
+
+    public void testAggregateQueryRegularWhereClause() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+        Table table = dc.getDefaultSchema().getTables()[0];
+        assertSingleRowResult("Row[values=[3]]", dc.query().from(table).selectCount().where("baz").eq("world")
+                .execute());
+    }
+
+    public void testAggregateQueryWhereClauseExcludingAll() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+        assertSingleRowResult("Row[values=[0]]",
+                dc.query().from("tab").selectCount().where("baz").eq("non_existing_value").execute());
+    }
+
+    public void testMixedAggregateAndRawQueryOnEmptyTable() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+        Table emptyTable = dc.getTableByQualifiedLabel("an_empty_table");
+
+        assertSingleRowResult("Row[values=[0, null]]", dc.query().from(emptyTable).selectCount().and("foo").execute());
+    }
+
+    private void assertSingleRowResult(String rowStr, DataSet ds) {
+        assertTrue("DataSet had no rows", ds.next());
+        Row row = ds.getRow();
+        assertEquals(rowStr, row.toString());
+        assertFalse("DataSet had more than a single row!", ds.next());
+        ds.close();
+    }
+
+    public void testMixedAggregateAndRawQuery() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+        Table table = dc.getDefaultSchema().getTables()[0];
+        Column[] columns = table.getColumns();
+
+        Query query = dc.query().from(table).select(FunctionType.MAX, columns[0]).and(columns[1]).toQuery();
+        assertEquals("SELECT MAX(tab.foo), tab.bar FROM sch.tab", query.toSql());
+
+        DataSet ds = dc.executeQuery(query);
+        assertTrue(ds.next());
+        assertEquals("Row[values=[4, hello]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[4, 1]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[4, hi]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[4, yo]]", ds.getRow().toString());
+        assertFalse(ds.next());
+    }
+
+    public void testSelectItemReferencesToFromItems() throws Exception {
+        MockDataContext dc = new MockDataContext("sch", "tab", "1");
+
+        Table table = dc.getDefaultSchema().getTables()[0];
+
+        Query q = new Query();
+        FromItem fromItem1 = q.from(table, "t1").getFromClause().getItem(0);
+        FromItem fromItem2 = q.from(table, "t2").getFromClause().getItem(1);
+        q.select(table.getColumnByName("foo"), fromItem1);
+        q.select(table.getColumnByName("foo"), fromItem2);
+        q.where(q.getSelectClause().getItem(0), OperatorType.EQUALS_TO, "2");
+        assertEquals("SELECT t1.foo, t2.foo FROM sch.tab t1, sch.tab t2 WHERE t1.foo = '2'", q.toSql());
+
+        DataSet ds = dc.executeQuery(q);
+        SelectItem[] selectItems = ds.getSelectItems();
+        assertEquals(2, selectItems.length);
+        assertEquals("t1.foo", selectItems[0].toSql());
+        assertEquals("t2.foo", selectItems[1].toSql());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[2, 1]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[2, 2]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[2, 3]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[2, 4]]", ds.getRow().toString());
+        assertFalse(ds.next());
+        ds.close();
+    }
+
+    private DataContext getDataContext() {
+        QueryPostprocessDataContext dataContext = new QueryPostprocessDataContext() {
+
+            @Override
+            public DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) {
+                if (table == table1) {
+                    Column[] columns1 = table1.getColumns();
+                    SelectItem[] selectItems = new SelectItem[columns1.length];
+                    for (int i = 0; i < selectItems.length; i++) {
+                        SelectItem selectItem = new SelectItem(columns1[i]);
+                        selectItems[i] = selectItem;
+                    }
+                    List<Object[]> data = new ArrayList<Object[]>();
+                    data.add(new Object[] { 1, "kasper", "denmark" });
+                    data.add(new Object[] { 2, "asbjorn", "denmark" });
+                    data.add(new Object[] { 3, "johny", "israel" });
+                    data.add(new Object[] { 4, "daniel", "canada" });
+                    data.add(new Object[] { 5, "sasidhar", "unknown" });
+                    data.add(new Object[] { 6, "jesper", "denmark" });
+                    if (maxRows != -1) {
+                        for (int i = data.size() - 1; i >= maxRows; i--) {
+                            data.remove(i);
+                        }
+                    }
+                    return createDataSet(selectItems, data);
+                } else if (table == table2) {
+                    Column[] columns2 = table2.getColumns();
+                    SelectItem[] selectItems = new SelectItem[columns2.length];
+                    for (int i = 0; i < selectItems.length; i++) {
+                        SelectItem selectItem = new SelectItem(columns2[i]);
+                        selectItems[i] = selectItem;
+                    }
+                    List<Object[]> data = new ArrayList<Object[]>();
+                    data.add(new Object[] { 1, 1, "founder" });
+                    data.add(new Object[] { 1, 1, "developer" });
+                    data.add(new Object[] { 1, 2, "developer" });
+                    data.add(new Object[] { 2, 1, "developer" });
+                    data.add(new Object[] { 2, 3, "developer" });
+                    data.add(new Object[] { 4, 1, "advisor" });
+                    data.add(new Object[] { 5, 2, "developer" });
+                    data.add(new Object[] { 6, 1, "founder" });
+                    if (maxRows != -1) {
+                        for (int i = data.size() - 1; i >= maxRows; i--) {
+                            data.remove(i);
+                        }
+                    }
+                    return createDataSet(selectItems, data);
+                }
+                throw new IllegalArgumentException("This test only accepts table1 and table2");
+            }
+
+            @Override
+            protected String getMainSchemaName() throws MetaModelException {
+                return schema.getName();
+            }
+
+            @Override
+            protected Schema getMainSchema() throws MetaModelException {
+                return schema;
+            }
+        };
+        return dataContext;
+    }
+
+    public void testDistinct() throws Exception {
+
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+
+        Query q = new Query().select(roleColumn).from(table2).orderBy(roleColumn);
+        q.getSelectClause().setDistinct(true);
+
+        DataContext dc = getDataContext();
+        DataSet data = dc.executeQuery(q);
+        assertTrue(data.next());
+        assertEquals("advisor", data.getRow().getValue(roleColumn));
+        assertTrue(data.next());
+        assertEquals("developer", data.getRow().getValue(roleColumn));
+        assertTrue(data.next());
+        assertEquals("founder", data.getRow().getValue(roleColumn));
+        assertFalse(data.next());
+    }
+
+    public void testInformationSchema() throws Exception {
+        DataContext dc = getDataContext();
+        assertEquals("[information_schema, MetaModelSchema]", Arrays.toString(dc.getSchemaNames()));
+        Schema informationSchema = dc.getSchemaByName("information_schema");
+        assertEquals(
+                "[Table[name=tables,type=TABLE,remarks=null], Table[name=columns,type=TABLE,remarks=null], Table[name=relationships,type=TABLE,remarks=null]]",
+                Arrays.toString(informationSchema.getTables()));
+        assertEquals(
+                "[Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=columns,foreignColumns=[table]], "
+                        + "Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=relationships,foreignColumns=[primary_table]], "
+                        + "Relationship[primaryTable=tables,primaryColumns=[name],foreignTable=relationships,foreignColumns=[foreign_table]], "
+                        + "Relationship[primaryTable=columns,primaryColumns=[name],foreignTable=relationships,foreignColumns=[primary_column]], "
+                        + "Relationship[primaryTable=columns,primaryColumns=[name],foreignTable=relationships,foreignColumns=[foreign_column]]]",
+                Arrays.toString(informationSchema.getRelationships()));
+        Table tablesTable = informationSchema.getTableByName("tables");
+        assertEquals(
+                "[Column[name=name,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=type,columnNumber=1,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=num_columns,columnNumber=2,type=INTEGER,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=remarks,columnNumber=3,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]]",
+                Arrays.toString(tablesTable.getColumns()));
+        Table columnsTable = informationSchema.getTableByName("columns");
+        assertEquals(
+                "[Column[name=name,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=type,columnNumber=1,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=native_type,columnNumber=2,type=VARCHAR,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=size,columnNumber=3,type=INTEGER,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=nullable,columnNumber=4,type=BOOLEAN,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=indexed,columnNumber=5,type=BOOLEAN,nullable=true,nativeType=null,columnSize=null], "
+                        + "Column[name=table,columnNumber=6,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=remarks,columnNumber=7,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]]",
+                Arrays.toString(columnsTable.getColumns()));
+        Table relationshipsTable = informationSchema.getTableByName("relationships");
+        assertEquals(
+                "[Column[name=primary_table,columnNumber=0,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=primary_column,columnNumber=1,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=foreign_table,columnNumber=2,type=VARCHAR,nullable=false,nativeType=null,columnSize=null], "
+                        + "Column[name=foreign_column,columnNumber=3,type=VARCHAR,nullable=false,nativeType=null,columnSize=null]]",
+                Arrays.toString(relationshipsTable.getColumns()));
+
+        DataSet dataSet = dc.query().from(tablesTable).select(tablesTable.getColumns()).execute();
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[contributor, TABLE, 3, null]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[project, TABLE, 4, null]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[role, TABLE, 3, null]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[project_contributor, VIEW, 3, null]]", dataSet.getRow().toString());
+        assertFalse(dataSet.next());
+        dataSet.close();
+
+        Relationship relationship = tablesTable.getRelationships(columnsTable)[0];
+        FromItem joinFromItem = new FromItem(JoinType.INNER, relationship);
+        Query q = new Query().select(tablesTable.getColumnByName("name")).select(columnsTable.getColumnByName("name"))
+                .select(columnsTable.getBooleanColumns()).from(joinFromItem);
+
+        assertEquals("SELECT tables.name, columns.name, columns.nullable, columns.indexed "
+                + "FROM information_schema.tables INNER JOIN information_schema.columns "
+                + "ON tables.name = columns.table", q.toString());
+
+        dataSet = dc.executeQuery(q);
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[contributor, contributor_id, false, true]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[contributor, name, false, false]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[contributor, country, true, false]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[project, project_id, false, false]]", dataSet.getRow().toString());
+        assertTrue(dataSet.next());
+        assertEquals("Row[values=[project, name, false, false]]", dataSet.getRow().toString());
+        dataSet.close();
+    }
+
+    public void testOrderByWithoutSelecting() throws Exception {
+        Query q = new Query();
+        q.from(new FromItem(table2).setAlias("r"));
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+        Column projectIdColumn = table2.getColumnByName(COLUMN_ROLE_PROJECT_ID);
+        q.select(new SelectItem(projectIdColumn));
+        q.orderBy(roleColumn);
+        assertEquals("SELECT r.project_id FROM MetaModelSchema.role r ORDER BY r.name ASC", q.toString());
+
+        DataContext dc = getDataContext();
+        DataSet data = dc.executeQuery(q);
+        assertEquals(1, data.getSelectItems().length);
+
+        @SuppressWarnings("deprecation")
+        TableModel tableModel = data.toTableModel();
+
+        // should correspond to these lines:
+
+        // data.add(new Object[] { 4, 1, "advisor" });
+        // data.add(new Object[] { 1, 1, "developer" });
+        // data.add(new Object[] { 1, 2, "developer" });
+        // data.add(new Object[] { 2, 1, "developer" });
+        // data.add(new Object[] { 2, 3, "developer" });
+        // data.add(new Object[] { 5, 2, "developer" });
+        // data.add(new Object[] { 1, 1, "founder" });
+        // data.add(new Object[] { 6, 1, "founder" });
+
+        assertEquals(8, tableModel.getRowCount());
+        assertEquals(1, tableModel.getColumnCount());
+        assertEquals(1, tableModel.getValueAt(0, 0));
+        assertEquals(1, tableModel.getValueAt(1, 0));
+        assertEquals(2, tableModel.getValueAt(2, 0));
+        assertEquals(1, tableModel.getValueAt(3, 0));
+        assertEquals(3, tableModel.getValueAt(4, 0));
+        assertEquals(2, tableModel.getValueAt(5, 0));
+        assertEquals(1, tableModel.getValueAt(6, 0));
+        assertEquals(1, tableModel.getValueAt(7, 0));
+    }
+
+    public void testGroupByWithoutSelecting() throws Exception {
+        Query q = new Query();
+        q.from(new FromItem(table2).setAlias("r"));
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+        Column projectIdColumn = table2.getColumnByName(COLUMN_ROLE_PROJECT_ID);
+        q.select(new SelectItem(FunctionType.SUM, projectIdColumn));
+        q.groupBy(new GroupByItem(new SelectItem(roleColumn)));
+        q.orderBy(roleColumn);
+        assertEquals("SELECT SUM(r.project_id) FROM MetaModelSchema.role r GROUP BY r.name ORDER BY r.name ASC",
+                q.toString());
+
+        DataContext dc = getDataContext();
+        DataSet data = dc.executeQuery(q);
+        assertEquals(1, data.getSelectItems().length);
+        assertEquals("SUM(r.project_id)", data.getSelectItems()[0].toString());
+
+        @SuppressWarnings("deprecation")
+        TableModel tableModel = data.toTableModel();
+        assertEquals(3, tableModel.getRowCount());
+        assertEquals(1, tableModel.getColumnCount());
+        assertEquals(1.0, tableModel.getValueAt(0, 0));
+        assertEquals(9.0, tableModel.getValueAt(1, 0));
+        assertEquals(2.0, tableModel.getValueAt(2, 0));
+
+        q = dc.query().from(table2).select("name").orderBy("name").toQuery();
+        q.getSelectClause().setDistinct(true);
+
+        tableModel = new DataSetTableModel(dc.executeQuery(q));
+        assertEquals(3, tableModel.getRowCount());
+        assertEquals(1, tableModel.getColumnCount());
+        assertEquals("advisor", tableModel.getValueAt(0, 0));
+        assertEquals("developer", tableModel.getValueAt(1, 0));
+        assertEquals("founder", tableModel.getValueAt(2, 0));
+    }
+
+    public void testSimpleGroupBy() throws Exception {
+        Query q = new Query();
+        q.from(new FromItem(table2).setAlias("r"));
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+        q.select(new SelectItem(roleColumn));
+        q.groupBy(new GroupByItem(new SelectItem(roleColumn)));
+        assertEquals("SELECT r.name FROM MetaModelSchema.role r GROUP BY r.name", q.toString());
+
+        DataContext dc = getDataContext();
+        DataSet data = dc.executeQuery(q);
+        assertEquals(1, data.getSelectItems().length);
+        assertEquals("r.name", data.getSelectItems()[0].toString());
+        TableModel tableModel = new DataSetTableModel(data);
+        assertEquals(3, tableModel.getRowCount());
+
+        q.select(new SelectItem(FunctionType.COUNT, "*", "c"));
+        q.where(new FilterItem(new SelectItem(roleColumn), OperatorType.EQUALS_TO, "founder"));
+        data = dc.executeQuery(q);
+        assertEquals(2, data.getSelectItems().length);
+        assertEquals("r.name", data.getSelectItems()[0].toString());
+        assertEquals("COUNT(*) AS c", data.getSelectItems()[1].toString());
+        tableModel = new DataSetTableModel(data);
+        assertEquals(1, tableModel.getRowCount());
+        assertEquals("founder", tableModel.getValueAt(0, 0));
+        assertEquals(2l, tableModel.getValueAt(0, 1));
+
+        q.select(new SelectItem(FunctionType.SUM, table2.getColumns()[0]));
+        assertEquals(
+                "SELECT r.name, COUNT(*) AS c, SUM(r.contributor_id) FROM MetaModelSchema.role r WHERE r.name = 'founder' GROUP BY r.name",
+                q.toString());
+        data = dc.executeQuery(q);
+        assertEquals(3, data.getSelectItems().length);
+        assertEquals("r.name", data.getSelectItems()[0].toString());
+        assertEquals("COUNT(*) AS c", data.getSelectItems()[1].toString());
+        assertEquals("SUM(r.contributor_id)", data.getSelectItems()[2].toString());
+        tableModel = new DataSetTableModel(data);
+        assertEquals(1, tableModel.getRowCount());
+        assertEquals("founder", tableModel.getValueAt(0, 0));
+        assertEquals(2l, tableModel.getValueAt(0, 1));
+        assertEquals(7.0, tableModel.getValueAt(0, 2));
+    }
+
+    public void testSimpleHaving() throws Exception {
+        Query q = new Query();
+        q.from(table2, "c");
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+        Column contributorIdColumn = table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID);
+
+        q.groupBy(roleColumn);
+        SelectItem countSelectItem = new SelectItem(FunctionType.COUNT, contributorIdColumn).setAlias("my_count");
+        q.select(new SelectItem(roleColumn), countSelectItem);
+        q.having(new FilterItem(countSelectItem, OperatorType.GREATER_THAN, 1));
+        q.orderBy(new OrderByItem(countSelectItem));
+        assertEquals(
+                "SELECT c.name, COUNT(c.contributor_id) AS my_count FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(c.contributor_id) > 1 ORDER BY COUNT(c.contributor_id) ASC",
+                q.toString());
+
+        DataSet data = getDataContext().executeQuery(q);
+        assertTrue(data.next());
+        assertEquals("Row[values=[founder, 2]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[developer, 5]]", data.getRow().toString());
+        assertFalse(data.next());
+    }
+
+    public void testHavingFunctionNotSelected() throws Exception {
+        Query q = new Query();
+        q.from(table2, "c");
+        Column roleColumn = table2.getColumnByName(COLUMN_ROLE_ROLE_NAME);
+        Column contributorIdColumn = table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID);
+
+        q.groupBy(roleColumn);
+        SelectItem countSelectItem = new SelectItem(FunctionType.COUNT, contributorIdColumn).setAlias("my_count");
+        q.select(new SelectItem(roleColumn));
+        q.having(new FilterItem(countSelectItem, OperatorType.GREATER_THAN, 3));
+        assertEquals("SELECT c.name FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(c.contributor_id) > 3",
+                q.toString());
+
+        DataSet data = getDataContext().executeQuery(q);
+        assertTrue(data.next());
+        assertEquals("Row[values=[developer]]", data.getRow().toString());
+        assertFalse(data.next());
+        data.close();
+
+        q.getHavingClause().removeItems();
+        q.having(new FilterItem(SelectItem.getCountAllItem(), OperatorType.GREATER_THAN, 3));
+        assertEquals("SELECT c.name FROM MetaModelSchema.role c GROUP BY c.name HAVING COUNT(*) > 3", q.toString());
+        data = getDataContext().executeQuery(q);
+        assertTrue(data.next());
+        assertEquals("Row[values=[developer]]", data.getRow().toString());
+        assertFalse(data.next());
+        data.close();
+    }
+
+    public void testCompiledQueryParameterInWhereClause() throws Exception {
+        DataContext dc = getDataContext();
+        QueryParameter param1 = new QueryParameter();
+        CompiledQuery compiledQuery = dc.query().from(table1).select("name").where(COLUMN_CONTRIBUTOR_COUNTRY)
+                .eq(param1).compile();
+        try {
+            assertEquals(1, compiledQuery.getParameters().size());
+            assertSame(param1, compiledQuery.getParameters().get(0));
+
+            DataSet ds = dc.executeQuery(compiledQuery, "denmark");
+            try {
+                assertTrue(ds.next());
+                assertEquals("Row[values=[kasper]]", ds.getRow().toString());
+                assertTrue(ds.next());
+                assertEquals("Row[values=[asbjorn]]", ds.getRow().toString());
+                assertTrue(ds.next());
+                assertEquals("Row[values=[jesper]]", ds.getRow().toString());
+                assertFalse(ds.next());
+            } finally {
+                ds.close();
+            }
+
+            try {
+                ds = dc.executeQuery(compiledQuery, "canada");
+                assertTrue(ds.next());
+                assertEquals("Row[values=[daniel]]", ds.getRow().toString());
+                assertFalse(ds.next());
+            } finally {
+                ds.close();
+            }
+        } finally {
+            compiledQuery.close();
+        }
+    }
+
+    public void testCompiledQueryParameterInSubQuery() throws Exception {
+        final DataContext dc = getDataContext();
+
+        final QueryParameter param1 = new QueryParameter();
+        final Query subQuery = dc.query().from(table1).select("name").where(COLUMN_CONTRIBUTOR_COUNTRY).eq(param1)
+                .toQuery();
+
+        final FromItem subQueryFromItem = new FromItem(subQuery);
+        final Query query = new Query().select(new SelectItem(subQuery.getSelectClause().getItem(0), subQueryFromItem))
+                .from(subQueryFromItem);
+
+        final CompiledQuery compiledQuery = dc.compileQuery(query);
+
+        try {
+            assertEquals(1, compiledQuery.getParameters().size());
+            assertSame(param1, compiledQuery.getParameters().get(0));
+
+            DataSet ds = dc.executeQuery(compiledQuery, "denmark");
+            List<Object[]> objectArrays = ds.toObjectArrays();
+            assertEquals(3, objectArrays.size());
+
+        } finally {
+            compiledQuery.close();
+        }
+    }
+
+    public void testSelectCount() throws Exception {
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.selectCount();
+
+        Row row = MetaModelHelper.executeSingleRowQuery(dc, q);
+        assertEquals("6", row.getValue(0).toString());
+    }
+
+    public void testSimpleSelect() throws Exception {
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.select(table1.getColumns());
+        DataSet dataSet = dc.executeQuery(q);
+        assertTrue(dataSet.next());
+        Row row = dataSet.getRow();
+        assertEquals("Row[values=[1, kasper, denmark]]", row.toString());
+        assertTrue(dataSet.next());
+        assertTrue(dataSet.next());
+        assertTrue(dataSet.next());
+        assertTrue(dataSet.next());
+        assertTrue(dataSet.next());
+        assertFalse(dataSet.next());
+    }
+
+    public void testCarthesianProduct() throws Exception {
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.from(table2);
+        q.select(table1.getColumns());
+        q.select(table2.getColumns());
+        DataSet data = dc.executeQuery(q);
+        assertEquals(table1.getColumnCount() + table2.getColumnCount(), data.getSelectItems().length);
+        for (int i = 0; i < 6 * 8; i++) {
+            assertTrue(data.next());
+            if (i == 0) {
+                assertEquals("Row[values=[1, kasper, denmark, 1, 1, founder]]", data.getRow().toString());
+            } else if (i == 1) {
+                assertEquals("Row[values=[1, kasper, denmark, 1, 1, developer]]", data.getRow().toString());
+            }
+        }
+        assertFalse(data.next());
+    }
+    
+    public void testJoinAndFirstRow() throws Exception {
+        DataSet data;
+
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.from(table2);
+        q.select(table1.getColumns());
+        q.select(table2.getColumns());
+        data = dc.executeQuery(q);
+        assertEquals(48, data.toObjectArrays().size());
+        
+        q.setFirstRow(3);
+        data = dc.executeQuery(q);
+        assertEquals(46, data.toObjectArrays().size());
+    }
+
+    public void testSimpleWhere() throws Exception {
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.select(table1.getColumns());
+        SelectItem countrySelectItem = q.getSelectClause().getSelectItem(
+                table1.getColumnByName(COLUMN_CONTRIBUTOR_COUNTRY));
+        q.where(new FilterItem(countrySelectItem, OperatorType.EQUALS_TO, "denmark"));
+
+        DataSet data = dc.executeQuery(q);
+        for (int i = 0; i < 3; i++) {
+            assertTrue("Assertion failed at i=" + i, data.next());
+        }
+        assertFalse(data.next());
+    }
+
+    public void testMaxRows() throws Exception {
+        DataContext dc = getDataContext();
+        Query q = new Query();
+        q.from(table1);
+        q.select(table1.getColumns());
+        q.setMaxRows(3);
+        DataSet data1 = dc.executeQuery(q);
+
+        assertTrue(data1.next());
+        assertEquals("Row[values=[1, kasper, denmark]]", data1.getRow().toString());
+        assertTrue(data1.next());
+        assertEquals("Row[values=[2, asbjorn, denmark]]", data1.getRow().toString());
+        assertTrue(data1.next());
+        assertEquals("Row[values=[3, johny, israel]]", data1.getRow().toString());
+
+        assertFalse(data1.next());
+        data1.close();
+
+        q = new Query();
+        q.from(table1);
+        q.select(table1.getColumns());
+        q.setFirstRow(2);
+        q.setMaxRows(2);
+        DataSet data2 = dc.executeQuery(q);
+        assertTrue(data2.next());
+        assertEquals("Row[values=[2, asbjorn, denmark]]", data2.getRow().toString());
+        assertTrue(data2.next());
+        assertEquals("Row[values=[3, johny, israel]]", data2.getRow().toString());
+
+        assertFalse(data2.next());
+        data2.close();
+    }
+
+    public void testCarthesianProductWithWhere() throws Exception {
+        DataContext dc = getDataContext();
+
+        SelectItem s1 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_NAME));
+        SelectItem s2 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_ROLE_NAME));
+        FromItem f1 = new FromItem(table1);
+        FromItem f2 = new FromItem(table2);
+
+        Query q = new Query();
+        q.select(s1);
+        q.select(s2);
+        q.from(f1);
+        q.from(f2);
+        SelectItem s3 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_CONTRIBUTOR_ID));
+        SelectItem s4 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_CONTRIBUTOR_ID));
+        q.where(new FilterItem(s3, OperatorType.EQUALS_TO, s4));
+        assertEquals(
+                "SELECT contributor.name, role.name FROM MetaModelSchema.contributor, MetaModelSchema.role WHERE contributor.contributor_id = role.contributor_id",
+                q.toString());
+
+        DataSet data = dc.executeQuery(q);
+        assertEquals(2, data.getSelectItems().length);
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, founder]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[daniel, advisor]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[sasidhar, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[jesper, founder]]", data.getRow().toString());
+        assertFalse(data.next());
+    }
+
+    public void testSelectDistinct() throws Exception {
+        // there will be three distinct values in bar column: hello (x2), hi,
+        // howdy
+        MockDataContext dc = new MockDataContext("sch", "tab", "hello");
+
+        Table table = dc.getTableByQualifiedLabel("sch.tab");
+        Query q = dc.query().from(table).select("bar").toQuery();
+        q.getSelectClause().setDistinct(true);
+        q.orderBy(table.getColumnByName("bar"));
+
+        DataSet ds = dc.executeQuery(q);
+        assertTrue(ds.next());
+        assertEquals("Row[values=[hello]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[hi]]", ds.getRow().toString());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[yo]]", ds.getRow().toString());
+        assertFalse(ds.next());
+    }
+
+    public void testSubSelectionAndInnerJoin() throws Exception {
+        DataContext dc = getDataContext();
+
+        SelectItem s1 = new SelectItem(table1.getColumnByName(COLUMN_CONTRIBUTOR_NAME));
+        SelectItem s2 = new SelectItem(table2.getColumnByName(COLUMN_ROLE_ROLE_NAME));
+        FromItem fromItem = new FromItem(JoinType.INNER, table1.getRelationships(table2)[0]);
+
+        Query q = new Query();
+        q.select(s1);
+        q.select(s2);
+        q.from(fromItem);
+        assertEquals(
+                "SELECT contributor.name, role.name FROM MetaModelSchema.contributor INNER JOIN MetaModelSchema.role ON contributor.contributor_id = role.contributor_id",
+                q.toString());
+
+        DataSet data = dc.executeQuery(q);
+        assertEquals(2, data.getSelectItems().length);
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, founder]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[daniel, advisor]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[sasidhar, developer]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[jesper, founder]]", data.getRow().toString());
+        assertFalse(data.next());
+    }
+
+    public void testSubquery() throws Exception {
+        Query q1 = new Query();
+        q1.from(table1);
+        q1.select(table1.getColumns());
+
+        Query q2 = new Query();
+        FromItem fromItem = new FromItem(q1);
+        q2.from(fromItem);
+        SelectItem selectItem = new SelectItem(q1.getSelectClause().getItems().get(1), fromItem);
+        selectItem.setAlias("e");
+        q2.select(selectItem);
+        assertEquals(
+                "SELECT name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor)",
+                q2.toString());
+
+        fromItem.setAlias("c");
+        assertEquals(
+                "SELECT c.name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor) c",
+                q2.toString());
+
+        DataContext dc = getDataContext();
+        DataSet data = dc.executeQuery(q2);
+        assertEquals(1, data.getSelectItems().length);
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[johny]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[daniel]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[sasidhar]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[jesper]]", data.getRow().toString());
+        assertFalse(data.next());
+
+        // Create a sub-query for a sub-query
+        Query q3 = new Query();
+        fromItem = new FromItem(q2);
+        q3.from(fromItem);
+        selectItem = new SelectItem(q2.getSelectClause().getItems().get(0), fromItem);
+        selectItem.setAlias("f");
+        q3.select(selectItem);
+        fromItem.setAlias("d");
+        assertEquals(
+                "SELECT d.e AS f FROM (SELECT c.name AS e FROM (SELECT contributor.contributor_id, contributor.name, contributor.country FROM MetaModelSchema.contributor) c) d",
+                q3.toString());
+        data = dc.executeQuery(q3);
+        assertEquals(1, data.getSelectItems().length);
+        assertTrue(data.next());
+        assertEquals("Row[values=[kasper]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[asbjorn]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[johny]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[daniel]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[sasidhar]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[jesper]]", data.getRow().toString());
+        assertFalse(data.next());
+    }
+
+    public void testOrderBy() throws Exception {
+        Query q = new Query();
+        q.from(new FromItem(table1).setAlias("c"));
+        q.select(table1.getColumns());
+        OrderByItem countryOrderBy = new OrderByItem(q.getSelectClause().getItem(2), Direction.DESC);
+        OrderByItem nameOrderBy = new OrderByItem(q.getSelectClause().getItem(1));
+        q.orderBy(countryOrderBy, nameOrderBy);
+
+        assertEquals(
+                "SELECT c.contributor_id, c.name, c.country FROM MetaModelSchema.contributor c ORDER BY c.country DESC, c.name ASC",
+                q.toString());
+
+        DataSet data = getDataContext().executeQuery(q);
+        assertTrue(data.next());
+        assertEquals("Row[values=[5, sasidhar, unknown]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[3, johny, israel]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[2, asbjorn, denmark]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[6, jesper, denmark]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[1, kasper, denmark]]", data.getRow().toString());
+        assertTrue(data.next());
+        assertEquals("Row[values=[4, daniel, canada]]", data.getRow().toString());
+        assertFalse(data.next());
+    }
+
+    public void testExecuteCount() throws Exception {
+        QueryPostprocessDataContext dc = new QueryPostprocessDataContext() {
+            @Override
+            protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) {
+                throw new UnsupportedAddressTypeException();
+            }
+
+            @Override
+            protected Number executeCountQuery(Table table, List<FilterItem> whereItems,
+                    boolean functionApproximationAllowed) {
+                return 1337;
+            }
+
+            @Override
+            protected String getMainSchemaName() throws MetaModelException {
+                return "sch";
+            }
+
+            @Override
+            protected Schema getMainSchema() throws MetaModelException {
+                MutableSchema schema = new MutableSchema(getMainSchemaName());
+                MutableTable table = new MutableTable("tabl").setSchema(schema);
+                return schema.addTable(table.addColumn(new MutableColumn("col").setTable(table)));
+            }
+        };
+
+        DataSet ds = dc.query().from("sch.tabl").selectCount().execute();
+        assertTrue(ds.next());
+        assertEquals("Row[values=[1337]]", ds.getRow().toString());
+        assertFalse(ds.next());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/SchemaNameComparatorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/SchemaNameComparatorTest.java b/core/src/test/java/org/apache/metamodel/SchemaNameComparatorTest.java
new file mode 100644
index 0000000..f03ff11
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/SchemaNameComparatorTest.java
@@ -0,0 +1,40 @@
+/**
+ * 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.eobjects.metamodel;
+
+import java.util.Comparator;
+
+import junit.framework.TestCase;
+
+public class SchemaNameComparatorTest extends TestCase {
+
+	final Comparator<? super String> comp = SchemaNameComparator.getInstance();
+
+	public void testNormalComparison() throws Exception {
+		assertTrue(comp.compare("foo", "bar") > 0);
+		assertTrue(comp.compare("bar", "foo") < 0);
+		assertTrue(comp.compare("bar", "bar") == 0);
+	}
+
+	public void testNull() throws Exception {
+		assertTrue(comp.compare(null, null) == 0);
+		assertTrue(comp.compare("foo", null) > 0);
+		assertTrue(comp.compare(null, "foo") < 0);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/ColumnTypeDetectorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/ColumnTypeDetectorTest.java b/core/src/test/java/org/apache/metamodel/convert/ColumnTypeDetectorTest.java
new file mode 100644
index 0000000..e36df03
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/ColumnTypeDetectorTest.java
@@ -0,0 +1,72 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import junit.framework.TestCase;
+
+public class ColumnTypeDetectorTest extends TestCase {
+
+	public void testBooleanConverter() throws Exception {
+		ColumnTypeDetector d = new ColumnTypeDetector();
+
+		d.registerValue("1");
+		d.registerValue("true");
+		d.registerValue("0");
+
+		assertEquals(StringToBooleanConverter.class, d.createConverter()
+				.getClass());
+
+		d.registerValue("2");
+
+		assertNull(d.createConverter());
+	}
+
+	public void testIntegerAndDoubleConverter() throws Exception {
+		ColumnTypeDetector d = new ColumnTypeDetector();
+
+		d.registerValue("123");
+		d.registerValue("0");
+
+		assertEquals(StringToIntegerConverter.class, d.createConverter()
+				.getClass());
+
+		d.registerValue("1123.23");
+		d.registerValue("0.0");
+
+		assertEquals(StringToDoubleConverter.class, d.createConverter()
+				.getClass());
+
+		d.registerValue("abc");
+
+		assertNull(d.createConverter());
+	}
+
+	public void testDateConverter() throws Exception {
+		ColumnTypeDetector d = new ColumnTypeDetector();
+
+		d.registerValue("2010-12-30");
+
+		assertEquals(StringToDateConverter.class, d.createConverter()
+				.getClass());
+
+		d.registerValue("2 abc");
+
+		assertNull(d.createConverter());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/ConvertedDataSetInterceptorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/ConvertedDataSetInterceptorTest.java b/core/src/test/java/org/apache/metamodel/convert/ConvertedDataSetInterceptorTest.java
new file mode 100644
index 0000000..4e1b0db
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/ConvertedDataSetInterceptorTest.java
@@ -0,0 +1,92 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.DataContext;
+import org.eobjects.metamodel.MockUpdateableDataContext;
+import org.eobjects.metamodel.UpdateableDataContext;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.data.InMemoryDataSet;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Table;
+
+public class ConvertedDataSetInterceptorTest extends TestCase {
+
+	public void testConvertedQuery() throws Exception {
+		UpdateableDataContext dc = new MockUpdateableDataContext();
+		Column fooColumn = dc.getColumnByQualifiedLabel("schema.table.foo");
+		assertNotNull(fooColumn);
+
+		dc = Converters.addTypeConverter(dc, fooColumn,
+				new StringToIntegerConverter());
+
+		Table table = dc.getDefaultSchema().getTableByName("table");
+		Query query = dc.query().from(table).select(table.getColumns())
+				.toQuery();
+		assertEquals("SELECT table.foo, table.bar FROM schema.table",
+				query.toSql());
+
+		DataSet ds = dc.executeQuery(query);
+		assertEquals(ConvertedDataSet.class, ds.getClass());
+
+		assertTrue(ds.next());
+		assertEquals("Row[values=[1, hello]]", ds.getRow().toString());
+		assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+		assertEquals(String.class, ds.getRow().getValue(1).getClass());
+
+		assertTrue(ds.next());
+		assertEquals("Row[values=[2, there]]", ds.getRow().toString());
+		assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+		assertEquals(String.class, ds.getRow().getValue(1).getClass());
+
+		assertTrue(ds.next());
+		assertEquals("Row[values=[3, world]]", ds.getRow().toString());
+		assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+		assertEquals(String.class, ds.getRow().getValue(1).getClass());
+
+		assertFalse(ds.next());
+		ds.close();
+	}
+
+	public void testNonConvertedQuery() throws Exception {
+		MockUpdateableDataContext source = new MockUpdateableDataContext();
+		Column fooColumn = source.getColumnByQualifiedLabel("schema.table.foo");
+		assertNotNull(fooColumn);
+
+		Map<Column, TypeConverter<?, ?>> converters = new HashMap<Column, TypeConverter<?, ?>>();
+		converters.put(fooColumn, new StringToIntegerConverter());
+		DataContext converted = Converters.addTypeConverter(source, fooColumn,
+				new StringToIntegerConverter());
+
+		// only select "bar" which is not converted
+		Table table = converted.getDefaultSchema().getTableByName("table");
+		Query query = converted.query().from(table).select("bar").toQuery();
+		assertEquals("SELECT table.bar FROM schema.table", query.toSql());
+
+		DataSet ds = converted.executeQuery(query);
+		assertEquals(InMemoryDataSet.class, ds.getClass());
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/ConvertedRowInsertionInterceptorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/ConvertedRowInsertionInterceptorTest.java b/core/src/test/java/org/apache/metamodel/convert/ConvertedRowInsertionInterceptorTest.java
new file mode 100644
index 0000000..9f4fbcb
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/ConvertedRowInsertionInterceptorTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.MockUpdateableDataContext;
+import org.eobjects.metamodel.UpdateCallback;
+import org.eobjects.metamodel.UpdateScript;
+import org.eobjects.metamodel.UpdateableDataContext;
+import org.eobjects.metamodel.schema.Column;
+
+public class ConvertedRowInsertionInterceptorTest extends TestCase {
+
+	public void testConvertedInsert() throws Exception {
+		MockUpdateableDataContext source = new MockUpdateableDataContext();
+		Column fooColumn = source.getColumnByQualifiedLabel("schema.table.foo");
+		assertNotNull(fooColumn);
+
+		UpdateableDataContext intercepted = Converters.addTypeConverter(source,
+				fooColumn, new StringToIntegerConverter());
+
+		final List<Object[]> values = source.getValues();
+
+		assertEquals(3, values.size());
+
+		intercepted.executeUpdate(new UpdateScript() {
+			@Override
+			public void run(UpdateCallback callback) {
+				callback.insertInto("schema.table").value(0, 1).value(1, "2")
+						.execute();
+				callback.insertInto("schema.table").value(0, 3).value(1, "4")
+						.execute();
+			}
+		});
+
+		assertEquals(5, values.size());
+		assertEquals("1", values.get(3)[0]);
+		assertEquals("2", values.get(3)[1]);
+		assertEquals("3", values.get(4)[0]);
+		assertEquals("4", values.get(4)[1]);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/ConvertersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/ConvertersTest.java b/core/src/test/java/org/apache/metamodel/convert/ConvertersTest.java
new file mode 100644
index 0000000..61e1495
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/ConvertersTest.java
@@ -0,0 +1,160 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.MockUpdateableDataContext;
+import org.eobjects.metamodel.UpdateCallback;
+import org.eobjects.metamodel.UpdateScript;
+import org.eobjects.metamodel.UpdateableDataContext;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.query.Query;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Table;
+
+public class ConvertersTest extends TestCase {
+
+    public void testAutoDetectConverters() throws Exception {
+        final MockUpdateableDataContext decoratedDataContext = new MockUpdateableDataContext();
+        final Table table = decoratedDataContext.getDefaultSchema().getTables()[0];
+        Map<Column, TypeConverter<?, ?>> converters = Converters.autoDetectConverters(decoratedDataContext, table, 2);
+        assertEquals(1, converters.size());
+        assertEquals(
+                "[Column[name=foo,columnNumber=0,type=VARCHAR,nullable=null,nativeType=null,columnSize=null]]",
+                converters.keySet().toString());
+        assertEquals(StringToIntegerConverter.class, converters.values().iterator().next().getClass());
+
+        final UpdateableDataContext dc = Converters.addTypeConverters(decoratedDataContext, converters);
+
+        DataSet ds = dc.query().from(table).select(table.getColumns()).execute();
+        assertEquals(ConvertedDataSet.class, ds.getClass());
+        assertTrue(ds.next());
+        assertEquals("Row[values=[1, hello]]", ds.getRow().toString());
+        assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+        assertEquals(1, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+        assertEquals(2, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+        assertEquals(3, ds.getRow().getValue(0));
+        assertFalse(ds.next());
+        ds.close();
+
+        dc.executeUpdate(new UpdateScript() {
+            @Override
+            public void run(UpdateCallback callback) {
+                callback.insertInto(table).value("foo", 4).value("bar", "mrrrrh").execute();
+            }
+        });
+
+        // query the decorator
+        ds = dc.query().from(table).select(table.getColumns()).where("foo").eq(4).execute();
+        assertTrue(ds.next());
+        assertEquals("Row[values=[4, mrrrrh]]", ds.getRow().toString());
+        assertEquals(Integer.class, ds.getRow().getValue(0).getClass());
+        assertEquals(4, ds.getRow().getValue(0));
+        assertFalse(ds.next());
+        ds.close();
+
+        // query the decorated
+        Object[] physicalRow = decoratedDataContext.getValues().get(3);
+        assertEquals("[4, mrrrrh]", Arrays.toString(physicalRow));
+        assertEquals(String.class, physicalRow[0].getClass());
+    }
+
+    public void testScenario() throws Exception {
+        UpdateableDataContext dc = new MockUpdateableDataContext();
+        List<Object[]> physicalValuesList = ((MockUpdateableDataContext) dc).getValues();
+        assertEquals(3, physicalValuesList.size());
+        for (Object[] physicalValues : physicalValuesList) {
+            assertEquals("foo is expected to be string", String.class, physicalValues[0].getClass());
+        }
+
+        final Table table = dc.getDefaultSchema().getTables()[0];
+        Map<Column, TypeConverter<?, ?>> converters = Converters.autoDetectConverters(dc, table, 1000);
+        assertEquals(1, converters.size());
+        dc = Converters.addTypeConverters(dc, converters);
+
+        final Query q = dc.query().from(table).select("foo").toQuery();
+        assertEquals("SELECT table.foo FROM schema.table", q.toSql());
+        DataSet ds = dc.executeQuery(q);
+        assertTrue(ds.next());
+        assertEquals(1, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(2, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(3, ds.getRow().getValue(0));
+        assertFalse(ds.next());
+
+        dc.executeUpdate(new UpdateScript() {
+            @Override
+            public void run(UpdateCallback callback) {
+                callback.insertInto(table).value("foo", 4).value("bar", "heidiho!").execute();
+            }
+        });
+
+        ds = dc.executeQuery(q);
+        assertTrue(ds.next());
+        assertEquals(1, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(2, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(3, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(4, ds.getRow().getValue(0));
+        assertFalse(ds.next());
+        
+        assertEquals(4, physicalValuesList.size());
+        for (Object[] physicalValues : physicalValuesList) {
+            assertEquals("foo is expected to be string", String.class, physicalValues[0].getClass());
+        }
+        
+        dc.executeUpdate(new UpdateScript() {
+            @Override
+            public void run(UpdateCallback callback) {
+                callback.insertInto(table).value("foo", 5).value("bar", "hejsa...").execute();
+                callback.update(table).where("foo").lessThan(3).value("foo", 100).execute();
+            }
+        });
+        
+        ds = dc.executeQuery(q);
+        assertTrue(ds.next());
+        assertEquals(3, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(4, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(5, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(100, ds.getRow().getValue(0));
+        assertTrue(ds.next());
+        assertEquals(100, ds.getRow().getValue(0));
+        assertFalse(ds.next());
+        
+        assertEquals(5, physicalValuesList.size());
+        for (Object[] physicalValues : physicalValuesList) {
+            assertEquals("foo is expected to be string", String.class, physicalValues[0].getClass());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/StringToBooleanConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/StringToBooleanConverterTest.java b/core/src/test/java/org/apache/metamodel/convert/StringToBooleanConverterTest.java
new file mode 100644
index 0000000..7f14f68
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/StringToBooleanConverterTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import junit.framework.TestCase;
+
+public class StringToBooleanConverterTest extends TestCase {
+
+	private StringToBooleanConverter conv = new StringToBooleanConverter();
+
+	public void testToVirtual() throws Exception {
+		assertNull(conv.toVirtualValue(null));
+		assertNull(conv.toVirtualValue(""));
+		assertEquals(true, conv.toVirtualValue("true").booleanValue());
+	}
+
+	public void testToPhysical() throws Exception {
+		assertNull(conv.toPhysicalValue(null));
+		assertEquals("true", conv.toPhysicalValue(true));
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/StringToDateConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/StringToDateConverterTest.java b/core/src/test/java/org/apache/metamodel/convert/StringToDateConverterTest.java
new file mode 100644
index 0000000..dc936f3
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/StringToDateConverterTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.util.DateUtils;
+import org.eobjects.metamodel.util.Month;
+
+public class StringToDateConverterTest extends TestCase {
+
+	public void testToVirtualSimpleDateFormat() throws Exception {
+		StringToDateConverter conv = new StringToDateConverter("yyyy-MM-dd");
+		assertNull(conv.toVirtualValue(null));
+		assertNull(conv.toVirtualValue(""));
+
+		assertEquals(DateUtils.get(2010, Month.DECEMBER, 31),
+				conv.toVirtualValue("2010-12-31"));
+	}
+
+	public void testToVirtualNoArgs() throws Exception {
+		StringToDateConverter conv = new StringToDateConverter();
+		assertNull(conv.toVirtualValue(null));
+		assertNull(conv.toVirtualValue(""));
+
+		assertEquals(DateUtils.get(2010, Month.DECEMBER, 31),
+				conv.toVirtualValue("2010-12-31"));
+	}
+
+	public void testToPhysicalSimpleDateFormat() throws Exception {
+		StringToDateConverter conv = new StringToDateConverter("yyyy-MM-dd");
+		assertNull(conv.toPhysicalValue(null));
+		Date input = DateUtils.get(2010, Month.DECEMBER, 31);
+		String physicalValue = conv.toPhysicalValue(input);
+		assertEquals("2010-12-31", physicalValue);
+	}
+
+	public void testToPhysicalNoArgs() throws Exception {
+		StringToDateConverter conv = new StringToDateConverter();
+		assertNull(conv.toPhysicalValue(null));
+		Date input = DateUtils.get(2010, Month.DECEMBER, 31);
+		String physicalValue = conv.toPhysicalValue(input);
+		Date virtualValue = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
+				DateFormat.MEDIUM).parse(physicalValue);
+		assertEquals(virtualValue, input);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/StringToDoubleConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/StringToDoubleConverterTest.java b/core/src/test/java/org/apache/metamodel/convert/StringToDoubleConverterTest.java
new file mode 100644
index 0000000..854326e
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/StringToDoubleConverterTest.java
@@ -0,0 +1,39 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import junit.framework.TestCase;
+
+public class StringToDoubleConverterTest extends TestCase {
+
+	private StringToDoubleConverter conv = new StringToDoubleConverter();
+
+	public void testToVirtual() throws Exception {
+		assertNull(conv.toVirtualValue(null));
+		assertNull(conv.toVirtualValue(""));
+		assertEquals(123d, conv.toVirtualValue("123").doubleValue());
+		assertEquals(123.0d, conv.toVirtualValue("123.0").doubleValue());
+	}
+
+	public void testToPhysical() throws Exception {
+		assertNull(conv.toPhysicalValue(null));
+		assertEquals("123.0", conv.toPhysicalValue(123d));
+		assertEquals("123.0", conv.toPhysicalValue(123.0d));
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/convert/StringToIntegerConverterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/convert/StringToIntegerConverterTest.java b/core/src/test/java/org/apache/metamodel/convert/StringToIntegerConverterTest.java
new file mode 100644
index 0000000..d077cf4
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/convert/StringToIntegerConverterTest.java
@@ -0,0 +1,37 @@
+/**
+ * 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.eobjects.metamodel.convert;
+
+import junit.framework.TestCase;
+
+public class StringToIntegerConverterTest extends TestCase {
+
+	private StringToIntegerConverter conv = new StringToIntegerConverter();
+
+	public void testToVirtual() throws Exception {
+		assertNull(conv.toVirtualValue(null));
+		assertNull(conv.toVirtualValue(""));
+		assertEquals(123, conv.toVirtualValue("123").intValue());
+	}
+
+	public void testToPhysical() throws Exception {
+		assertNull(conv.toPhysicalValue(null));
+		assertEquals("123", conv.toPhysicalValue(123));
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/create/AbstractCreateTableBuilderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/create/AbstractCreateTableBuilderTest.java b/core/src/test/java/org/apache/metamodel/create/AbstractCreateTableBuilderTest.java
new file mode 100644
index 0000000..b5a44aa
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/create/AbstractCreateTableBuilderTest.java
@@ -0,0 +1,110 @@
+/**
+ * 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.eobjects.metamodel.create;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.UpdateCallback;
+import org.eobjects.metamodel.schema.ColumnType;
+import org.eobjects.metamodel.schema.MutableColumn;
+import org.eobjects.metamodel.schema.MutableSchema;
+import org.eobjects.metamodel.schema.MutableTable;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.util.MutableRef;
+
+public class AbstractCreateTableBuilderTest extends TestCase {
+
+    public void testExecute() throws Exception {
+        final MutableRef<Boolean> executed = new MutableRef<Boolean>(false);
+
+        Schema schema = new MutableSchema("schema");
+        AbstractTableCreationBuilder<UpdateCallback> builder = new AbstractTableCreationBuilder<UpdateCallback>(null,
+                schema, "tablename") {
+            @Override
+            public Table execute() throws MetaModelException {
+                executed.set(true);
+                return getTable();
+            }
+        };
+
+        assertFalse(executed.get().booleanValue());
+
+        builder.withColumn("foo").ofType(ColumnType.VARCHAR).asPrimaryKey().ofNativeType("vch").ofSize(1234)
+                .nullable(true);
+        builder.withColumn("bar").withColumn("baz").nullable(false);
+        Table table = builder.execute();
+
+        assertTrue(executed.get().booleanValue());
+
+        assertEquals("tablename", table.getName());
+        assertEquals(3, table.getColumnCount());
+        assertEquals(
+                "Column[name=foo,columnNumber=0,type=VARCHAR,nullable=true,nativeType=vch,columnSize=1234]",
+                table.getColumns()[0].toString());
+        assertEquals(
+                "Column[name=bar,columnNumber=1,type=null,nullable=null,nativeType=null,columnSize=null]",
+                table.getColumns()[1].toString());
+        assertEquals(
+                "Column[name=baz,columnNumber=2,type=null,nullable=false,nativeType=null,columnSize=null]",
+                table.getColumns()[2].toString());
+
+        assertEquals("CREATE TABLE schema.tablename (foo VARCHAR(1234) PRIMARY KEY,bar,baz NOT NULL)", builder.toSql());
+    }
+
+    public void testLike() throws Exception {
+        final MutableRef<Boolean> executed = new MutableRef<Boolean>(false);
+
+        Schema schema = new MutableSchema("schema");
+        AbstractTableCreationBuilder<UpdateCallback> builder = new AbstractTableCreationBuilder<UpdateCallback>(null,
+                schema, "tablename") {
+            @Override
+            public Table execute() throws MetaModelException {
+                executed.set(true);
+                return toTable();
+            }
+        };
+
+        assertFalse(executed.get().booleanValue());
+
+        MutableTable likeTable = new MutableTable("blablablabla");
+        likeTable.addColumn(new MutableColumn("foo", ColumnType.VARCHAR, likeTable, 0, 1234, "vch", true, null, false,
+                null));
+        likeTable.addColumn(new MutableColumn("bar"));
+        likeTable.addColumn(new MutableColumn("baz"));
+
+        builder.like(likeTable);
+        Table table = builder.execute();
+
+        assertTrue(executed.get().booleanValue());
+
+        assertEquals("tablename", table.getName());
+        assertEquals(3, table.getColumnCount());
+        assertEquals(
+                "Column[name=foo,columnNumber=0,type=VARCHAR,nullable=true,nativeType=vch,columnSize=1234]",
+                table.getColumns()[0].toString());
+        assertEquals(
+                "Column[name=bar,columnNumber=1,type=null,nullable=null,nativeType=null,columnSize=null]",
+                table.getColumns()[1].toString());
+        assertEquals(
+                "Column[name=baz,columnNumber=2,type=null,nullable=null,nativeType=null,columnSize=null]",
+                table.getColumns()[2].toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/create/SyntaxExamplesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/create/SyntaxExamplesTest.java b/core/src/test/java/org/apache/metamodel/create/SyntaxExamplesTest.java
new file mode 100644
index 0000000..264fd91
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/create/SyntaxExamplesTest.java
@@ -0,0 +1,38 @@
+/**
+ * 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.eobjects.metamodel.create;
+
+import junit.framework.TestCase;
+
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+
+public abstract class SyntaxExamplesTest extends TestCase {
+
+	private TableCreatable dc;
+	private Table table;
+	private Column col;
+	private Schema schema;
+
+	public void testCreateLikeExistingStructure() throws Exception {
+		dc.createTable(schema, "foo").like(table).withColumn("bar").like(col)
+				.nullable(false).execute();
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/data/DataSetIteratorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/data/DataSetIteratorTest.java b/core/src/test/java/org/apache/metamodel/data/DataSetIteratorTest.java
new file mode 100644
index 0000000..96443d2
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/data/DataSetIteratorTest.java
@@ -0,0 +1,74 @@
+/**
+ * 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.eobjects.metamodel.data;
+
+import org.easymock.EasyMock;
+
+import junit.framework.TestCase;
+
+public class DataSetIteratorTest extends TestCase {
+
+	public void testHasNextAndNextAndClose() throws Exception {
+		DataSet ds = EasyMock.createMock(DataSet.class);
+		Row row = EasyMock.createMock(Row.class);
+
+		EasyMock.expect(ds.next()).andReturn(true);
+		EasyMock.expect(ds.getRow()).andReturn(row);
+		EasyMock.expect(ds.next()).andReturn(true);
+		EasyMock.expect(ds.getRow()).andReturn(row);
+		EasyMock.expect(ds.next()).andReturn(false);
+		ds.close();
+
+		EasyMock.replay(ds, row);
+
+		DataSetIterator it = new DataSetIterator(ds);
+
+		// multiple hasNext calls does not iterate before next is called
+		assertTrue(it.hasNext());
+		assertTrue(it.hasNext());
+		assertTrue(it.hasNext());
+
+		assertSame(row, it.next());
+
+		assertTrue(it.hasNext());
+		assertTrue(it.hasNext());
+
+		assertSame(row, it.next());
+		assertFalse(it.hasNext());
+		assertFalse(it.hasNext());
+		assertFalse(it.hasNext());
+
+		assertNull(it.next());
+
+		EasyMock.verify(ds, row);
+	}
+
+	public void testRemove() throws Exception {
+		DataSet ds = EasyMock.createMock(DataSet.class);
+		DataSetIterator it = new DataSetIterator(ds);
+
+		try {
+			it.remove();
+			fail("Exception expected");
+		} catch (UnsupportedOperationException e) {
+			assertEquals("DataSet is read-only, remove() is not supported.",
+					e.getMessage());
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/data/DataSetTableModelTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/data/DataSetTableModelTest.java b/core/src/test/java/org/apache/metamodel/data/DataSetTableModelTest.java
new file mode 100644
index 0000000..b125f8f
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/data/DataSetTableModelTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.eobjects.metamodel.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.table.TableModel;
+
+import org.eobjects.metamodel.MetaModelHelper;
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.MutableColumn;
+
+import junit.framework.TestCase;
+
+public class DataSetTableModelTest extends TestCase {
+
+    public void testToTableModel() throws Exception {
+        SelectItem[] selectItems = MetaModelHelper.createSelectItems(new MutableColumn("CUSTOMERNUMBER"),
+                new MutableColumn("CUSTOMERNAME"), new MutableColumn("CONTACTLASTNAME"));
+        CachingDataSetHeader header = new CachingDataSetHeader(selectItems);
+        List<Row> rows = new ArrayList<Row>();
+        rows.add(new DefaultRow(header, new Object[] { 1, "John", "Doe" }));
+        rows.add(new DefaultRow(header, new Object[] { 2, "John", "Taylor" }));
+        DataSet data = new InMemoryDataSet(header, rows);
+
+        @SuppressWarnings("deprecation")
+        TableModel tableModel = data.toTableModel();
+        data.close();
+
+        assertEquals(3, tableModel.getColumnCount());
+        assertEquals("CUSTOMERNUMBER", tableModel.getColumnName(0));
+        assertEquals("CUSTOMERNAME", tableModel.getColumnName(1));
+        assertEquals("CONTACTLASTNAME", tableModel.getColumnName(2));
+        assertEquals(2, tableModel.getRowCount());
+
+        // Take a small sample from the data
+        assertEquals("Taylor", tableModel.getValueAt(1, 2).toString());
+        
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java b/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
new file mode 100644
index 0000000..7ab78c1
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
@@ -0,0 +1,109 @@
+/**
+ * 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.eobjects.metamodel.data;
+
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+import java.lang.reflect.Field;
+
+import org.eobjects.metamodel.query.SelectItem;
+import org.eobjects.metamodel.schema.MutableColumn;
+import org.eobjects.metamodel.util.FileHelper;
+
+import junit.framework.TestCase;
+
+public class DefaultRowTest extends TestCase {
+
+    SelectItem[] items = new SelectItem[] { new SelectItem(new MutableColumn("foo")),
+            new SelectItem(new MutableColumn("bar")) };
+    Object[] values = new Object[] { "foo", "bar" };
+
+    public void testDeserializeBackwardsCompatible() throws Exception {
+        Object obj;
+        FileInputStream fileIn = new FileInputStream("src/test/resources/metamodel-3.0-default-row.ser");
+        try {
+            ObjectInputStream ois = new ObjectInputStream(fileIn);
+            obj = ois.readObject();
+            ois.close();
+        } finally {
+            FileHelper.safeClose(fileIn);
+        }
+
+        assertTrue(obj instanceof Row);
+        assertTrue(obj instanceof DefaultRow);
+
+        Row row = (Row) obj;
+        assertEquals(2, row.size());
+        SelectItem[] selectItems = row.getSelectItems();
+        assertEquals("foo", selectItems[0].toString());
+        assertEquals("bar", selectItems[1].toString());
+
+        assertEquals("foo", row.getValue(0));
+        assertEquals("bar", row.getValue(1));
+
+        assertEquals(Style.NO_STYLE, row.getStyle(0));
+        assertEquals(Style.NO_STYLE, row.getStyle(1));
+    }
+
+    public void testGetValueOfColumn() throws Exception {
+        DefaultRow row = new DefaultRow(new SimpleDataSetHeader(items), values);
+        assertEquals("foo", row.getValue(new MutableColumn("foo")));
+        assertNull(row.getValue(new MutableColumn("hello world")));
+    }
+
+    public void testCustomStyles() throws Exception {
+        Style[] styles = new Style[] { Style.NO_STYLE, new StyleBuilder().bold().create() };
+        DefaultRow row = new DefaultRow(new SimpleDataSetHeader(items), values, styles);
+
+        Field field = DefaultRow.class.getDeclaredField("_styles");
+        assertNotNull(field);
+
+        field.setAccessible(true);
+        assertNotNull(field.get(row));
+
+        assertEquals(Style.NO_STYLE, row.getStyle(0));
+        assertEquals("font-weight: bold;", row.getStyle(1).toCSS());
+    }
+
+    public void testNoStylesReference() throws Exception {
+        Style[] styles = new Style[] { Style.NO_STYLE, Style.NO_STYLE };
+        DefaultRow row = new DefaultRow(new SimpleDataSetHeader(items), values, styles);
+
+        Field field = DefaultRow.class.getDeclaredField("_styles");
+        assertNotNull(field);
+
+        field.setAccessible(true);
+        assertNull(field.get(row));
+
+        assertEquals(Style.NO_STYLE, row.getStyle(0));
+        assertEquals(Style.NO_STYLE, row.getStyle(items[0]));
+        assertEquals(Style.NO_STYLE, row.getStyle(items[0].getColumn()));
+    }
+
+    public void testNullStyle() throws Exception {
+        Style[] styles = new Style[] { Style.NO_STYLE, null };
+
+        try {
+            new DefaultRow(new SimpleDataSetHeader(items), values, styles);
+            fail("Exception expected");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Elements in the style array cannot be null", e.getMessage());
+        }
+    }
+}