blob: 12d5fe24ea6363a4cde7a1fb25581f06ad8f7f96 [file] [log] [blame]
/**
* 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.metamodel.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
import junit.framework.TestCase;
import org.apache.metamodel.DataContext;
import org.apache.metamodel.MetaModelHelper;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.data.DataSetTableModel;
import org.apache.metamodel.data.Row;
import org.apache.metamodel.jdbc.dialects.HsqldbQueryRewriter;
import org.apache.metamodel.jdbc.dialects.IQueryRewriter;
import org.apache.metamodel.query.FromItem;
import org.apache.metamodel.query.JoinType;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.query.SelectItem;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
/**
* Test case that tests hsqldb interaction. The test uses an embedded copy of
* the "pentaho sampledata" sample database that can be found at
* http://pentaho.sourceforge.net.
*/
public class HsqldbTest extends TestCase {
private static final String CONNECTION_STRING = "jdbc:hsqldb:res:metamodel";
private static final String USERNAME = "SA";
private static final String PASSWORD = "";
private Connection _connection;
@Override
protected void setUp() throws Exception {
super.setUp();
Class.forName("org.hsqldb.jdbcDriver");
_connection = DriverManager.getConnection(CONNECTION_STRING, USERNAME, PASSWORD);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
_connection.close();
}
public void testApproximateCount() throws Exception {
final JdbcDataContext dataContext = new JdbcDataContext(_connection);
final DataSet dataSet = dataContext.executeQuery("SELECT APPROXIMATE COUNT(*) FROM customers");
assertTrue(dataSet.next());
assertEquals(122, dataSet.getRow().getValue(0));
assertFalse(dataSet.next());
}
public void testTimestampValueInsertSelect() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:" + getName(), USERNAME, PASSWORD);
JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.NANOSECONDS);
}
public void testCreateInsertAndUpdate() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:" + getName(), USERNAME, PASSWORD);
JdbcDataContext dc = new JdbcDataContext(connection);
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(dc, "metamodel_test_simple");
}
public void testCompositePrimaryKeyCreation() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:" + getName(), USERNAME, PASSWORD);
JdbcDataContext dc = new JdbcDataContext(connection);
JdbcTestTemplates.compositeKeyCreation(dc, "metamodel_test_composite_keys");
}
public void testGetSchemas() throws Exception {
assertNotNull(_connection);
JdbcDataContext dc = new JdbcDataContext(_connection);
assertEquals("[Schema[name=INFORMATION_SCHEMA], " + "Schema[name=PUBLIC]]", Arrays.toString(dc.getSchemas()));
Schema defaultSchema = dc.getDefaultSchema();
Schema publicSchema = dc.getSchemaByName("PUBLIC");
assertSame(defaultSchema, publicSchema);
Table[] tables = publicSchema.getTables();
assertEquals(13, tables.length);
assertEquals("[Table[name=CUSTOMERS,type=TABLE,remarks=null], "
+ "Table[name=CUSTOMER_W_TER,type=TABLE,remarks=null], "
+ "Table[name=DEPARTMENT_MANAGERS,type=TABLE,remarks=null], "
+ "Table[name=DIM_TIME,type=TABLE,remarks=null], " + "Table[name=EMPLOYEES,type=TABLE,remarks=null], "
+ "Table[name=OFFICES,type=TABLE,remarks=null], "
+ "Table[name=ORDERDETAILS,type=TABLE,remarks=null], "
+ "Table[name=ORDERFACT,type=TABLE,remarks=null], " + "Table[name=ORDERS,type=TABLE,remarks=null], "
+ "Table[name=PAYMENTS,type=TABLE,remarks=null], " + "Table[name=PRODUCTS,type=TABLE,remarks=null], "
+ "Table[name=QUADRANT_ACTUALS,type=TABLE,remarks=null], "
+ "Table[name=TRIAL_BALANCE,type=TABLE,remarks=null]]", Arrays.toString(tables));
Table empTable = publicSchema.getTableByName("EMPLOYEES");
assertEquals(
"[Column[name=EMPLOYEENUMBER,columnNumber=0,type=INTEGER,nullable=false,nativeType=INTEGER,columnSize=0], "
+ "Column[name=LASTNAME,columnNumber=1,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50], "
+ "Column[name=FIRSTNAME,columnNumber=2,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50], "
+ "Column[name=EXTENSION,columnNumber=3,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=10], "
+ "Column[name=EMAIL,columnNumber=4,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=100], "
+ "Column[name=OFFICECODE,columnNumber=5,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=20], "
+ "Column[name=REPORTSTO,columnNumber=6,type=INTEGER,nullable=true,nativeType=INTEGER,columnSize=0], "
+ "Column[name=JOBTITLE,columnNumber=7,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50]]",
Arrays.toString(empTable.getColumns()));
assertEquals(
"[Column[name=EMPLOYEENUMBER,columnNumber=0,type=INTEGER,nullable=false,nativeType=INTEGER,columnSize=0]]",
Arrays.toString(empTable.getPrimaryKeys()));
// Only a single relationship registered in the database
assertEquals(
"[Relationship[primaryTable=PRODUCTS,primaryColumns=[PRODUCTCODE],foreignTable=ORDERFACT,foreignColumns=[PRODUCTCODE]]]",
Arrays.toString(publicSchema.getRelationships()));
}
public void testExecuteQuery() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
Schema schema = dc.getDefaultSchema();
Table productsTable = schema.getTableByName("PRODUCTS");
Table factTable = schema.getTableByName("ORDERFACT");
Query q = new Query().from(new FromItem(JoinType.INNER, productsTable.getRelationships(factTable)[0])).select(
productsTable.getColumns()[0], factTable.getColumns()[0]);
assertEquals(
"SELECT \"PRODUCTS\".\"PRODUCTCODE\", \"ORDERFACT\".\"ORDERNUMBER\" FROM PUBLIC.\"PRODUCTS\" INNER JOIN PUBLIC.\"ORDERFACT\" ON \"PRODUCTS\".\"PRODUCTCODE\" = \"ORDERFACT\".\"PRODUCTCODE\"",
q.toString());
assertEquals(25000, dc.getFetchSizeCalculator().getFetchSize(q));
DataSet data = dc.executeQuery(q);
TableModel tableModel = new DataSetTableModel(data);
assertEquals(2, tableModel.getColumnCount());
assertEquals(2996, tableModel.getRowCount());
assertEquals(110, MetaModelHelper.executeSingleRowQuery(dc, new Query().selectCount().from(productsTable))
.getValue(0));
}
public void testLimit() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
Schema schema = dc.getDefaultSchema();
Table productsTable = schema.getTableByName("PRODUCTS");
DataSet ds = dc.query().from(productsTable).select("PRODUCTCODE").limit(2).execute();
assertTrue(ds.next());
assertEquals("Row[values=[S10_1678]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[S10_1949]]", ds.getRow().toString());
assertFalse(ds.next());
ds.close();
}
public void testOffset() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
Schema schema = dc.getDefaultSchema();
Table productsTable = schema.getTableByName("PRODUCTS");
DataSet ds = dc.query().from(productsTable).select("PRODUCTCODE").offset(2).execute();
assertTrue(ds.next());
assertEquals("Row[values=[S10_2016]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[S10_4698]]", ds.getRow().toString());
assertTrue(ds.next());
assertTrue(ds.next());
assertTrue(ds.next());
ds.close();
}
public void testLimitAndOffset() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
Schema schema = dc.getDefaultSchema();
Table productsTable = schema.getTableByName("PRODUCTS");
DataSet ds = dc.query().from(productsTable).select("PRODUCTCODE").limit(2).offset(2).execute();
assertTrue(ds.next());
assertEquals("Row[values=[S10_2016]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[S10_4698]]", ds.getRow().toString());
assertFalse(ds.next());
ds.close();
}
public void testQueryRewriterQuoteAliases() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
IQueryRewriter queryRewriter = dc.getQueryRewriter();
assertSame(HsqldbQueryRewriter.class, queryRewriter.getClass());
Schema schema = dc.getSchemaByName("PUBLIC");
Table productsTable = schema.getTableByName("PRODUCTS");
Query q = new Query().from(productsTable, "pro-ducts").select(
new SelectItem(productsTable.getColumnByName("PRODUCTCODE")).setAlias("c|o|d|e"));
q.setMaxRows(5);
assertEquals("SELECT pro-ducts.\"PRODUCTCODE\" AS c|o|d|e FROM PUBLIC.\"PRODUCTS\" pro-ducts", q.toString());
String queryString = queryRewriter.rewriteQuery(q);
assertEquals(
"SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// We have to test that no additional quoting characters are added every
// time we run the rewriting
queryString = queryRewriter.rewriteQuery(q);
queryString = queryRewriter.rewriteQuery(q);
assertEquals(
"SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// Test that the original query is still the same (ie. it has been
// cloned for execution)
assertEquals("SELECT pro-ducts.\"PRODUCTCODE\" AS c|o|d|e FROM PUBLIC.\"PRODUCTS\" pro-ducts", q.toString());
DataSet data = dc.executeQuery(q);
assertNotNull(data);
data.close();
}
public void testQualifiedLabel() throws Exception {
DataContext dc = new JdbcDataContext(_connection);
Column column = dc.getDefaultSchema().getTableByName("PRODUCTS").getColumnByName("PRODUCTCODE");
assertEquals("PUBLIC.PRODUCTS.PRODUCTCODE", column.getQualifiedLabel());
assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PUBLIC.PRODUCTS")
.toString());
assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PRODUCTS").toString());
assertEquals(
"Column[name=PRODUCTCODE,columnNumber=0,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50]",
dc.getColumnByQualifiedLabel("PUBLIC.PRODUCTS.PRODUCTCODE").toString());
assertEquals(
"Column[name=PRODUCTCODE,columnNumber=0,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50]",
dc.getColumnByQualifiedLabel("PRODUCTS.PRODUCTCODE").toString());
}
public void testQuoteInWhereClause() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:quote_in_where", USERNAME, PASSWORD);
{
Statement st = connection.createStatement();
st.executeUpdate("CREATE TABLE testtable (name VARCHAR(255));");
st.close();
}
{
PreparedStatement st = connection.prepareStatement("INSERT INTO testtable VALUES (?)");
st.setString(1, "hello");
st.executeUpdate();
st.setString(1, "hi");
st.executeUpdate();
st.setString(1, "m'jello");
st.executeUpdate();
st.close();
}
JdbcDataContext dc = new JdbcDataContext(connection);
Table table = dc.getDefaultSchema().getTableByName("testtable");
Query q = dc.query().from(table).selectCount().toQuery();
Row row = MetaModelHelper.executeSingleRowQuery(dc, q);
assertEquals(3, ((Number) row.getValue(0)).intValue());
q = dc.query().from(table).selectCount().where("name").isEquals("m'jello").toQuery();
assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm'jello'", q.toSql());
assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm''jello'", dc
.getQueryRewriter().rewriteQuery(q));
row = MetaModelHelper.executeSingleRowQuery(dc, q);
assertEquals(1, ((Number) row.getValue(0)).intValue());
}
public void testWhereColInValues() throws Exception {
DataContext dc = new JdbcDataContext(_connection);
DataSet ds = dc.query().from("QUADRANT_ACTUALS").select("REGION").and("DEPARTMENT").where("DEPARTMENT")
.in("Sales", "Finance").execute();
assertTrue(ds.next());
assertEquals("Row[values=[Central, Sales]]", ds.getRow().toString());
while (ds.next()) {
Object deptValue = ds.getRow().getValue(1);
assertTrue("Sales".equals(deptValue) || "Finance".equals(deptValue));
}
ds.close();
}
public void testAutomaticConversionWhenInsertingString() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:auto_conversion", USERNAME, PASSWORD);
JdbcTestTemplates.automaticConversionWhenInsertingString(connection);
}
public void testWorkingWithDates() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:working_with_dates", USERNAME, PASSWORD);
final JdbcDataContext dc = new JdbcDataContext(connection);
final Schema schema = dc.getDefaultSchema();
JdbcTestTemplates.createInsertAndUpdateDateTypes(dc, schema, "test_table");
}
public void testCharOfSizeOn() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:char_of_size_one", USERNAME, PASSWORD);
JdbcTestTemplates.meaningOfOneSizeChar(connection);
}
public void testInsertOfDifferentTypes() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME,
PASSWORD);
try {
connection.createStatement().execute("DROP TABLE my_table");
} catch (Exception e) {
// do nothing
}
JdbcDataContext dc = new JdbcDataContext(connection);
final Schema schema = dc.getDefaultSchema();
dc.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback cb) {
Table table = cb.createTable(schema, "my_table").withColumn("id").ofType(ColumnType.INTEGER)
.ofNativeType("IDENTITY").nullable(false).withColumn("name").ofType(ColumnType.VARCHAR)
.ofSize(10).withColumn("foo").ofType(ColumnType.BOOLEAN).nullable(true).withColumn("bar")
.ofType(ColumnType.BOOLEAN).nullable(true).execute();
assertEquals("MY_TABLE", table.getName());
}
});
try {
dc.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
callback.insertInto("my_table").value("name", "row 1").value("foo", true).execute();
callback.insertInto("my_table").value("name", "row 2").value("bar", true).execute();
callback.insertInto("my_table").value("name", "row 3").value("foo", true).execute();
callback.insertInto("my_table").value("name", "row 4").value("foo", true).execute();
callback.insertInto("my_table").value("name", "row 5").value("bar", true).execute();
callback.insertInto("my_table").value("name", "row 6").value("foo", true).value("bar", true)
.execute();
callback.insertInto("my_table").value("name", "row 7").value("foo", true).value("bar", true)
.execute();
callback.insertInto("my_table").value("name", "row 8").value("foo", false).value("bar", false)
.execute();
}
});
DataSet ds = dc.query().from("my_table").select("id").and("name").execute();
assertTrue(ds.next());
assertEquals("Row[values=[0, row 1]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[1, row 2]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[2, row 3]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[3, row 4]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[4, row 5]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[5, row 6]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[6, row 7]]", ds.getRow().toString());
assertTrue(ds.next());
assertEquals("Row[values=[7, row 8]]", ds.getRow().toString());
assertFalse(ds.next());
ds.close();
} finally {
connection.createStatement().execute("DROP TABLE my_table");
}
}
public void testDifferentOperators() throws Exception {
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:different_operators", USERNAME, PASSWORD);
JdbcTestTemplates.differentOperatorsTest(conn);
}
public void testInterpretationOfNull() throws Exception {
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:interpretation_of_null", USERNAME, PASSWORD);
JdbcTestTemplates.interpretationOfNulls(conn);
}
}