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 2015/10/19 11:19:48 UTC
metamodel git commit: METAMODEL-198: Fixed Closes #59
Repository: metamodel
Updated Branches:
refs/heads/master 499aca4d6 -> 5370703a7
METAMODEL-198: Fixed
Closes #59
Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/5370703a
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/5370703a
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/5370703a
Branch: refs/heads/master
Commit: 5370703a7379c654888e1f442166926be34b9b9f
Parents: 499aca4
Author: Kasper Sørensen <i....@gmail.com>
Authored: Mon Oct 19 11:19:41 2015 +0200
Committer: Kasper Sørensen <i....@gmail.com>
Committed: Mon Oct 19 11:19:41 2015 +0200
----------------------------------------------------------------------
CHANGES.md | 4 +
jdbc/pom.xml | 4 +-
.../apache/metamodel/jdbc/JdbcDataContext.java | 4 +
.../org/apache/metamodel/jdbc/JdbcUtils.java | 33 +++-
.../jdbc/dialects/DefaultQueryRewriter.java | 38 +++-
.../jdbc/dialects/SQLiteQueryRewriter.java | 40 ++++
.../org/apache/metamodel/jdbc/DerbyTest.java | 26 ++-
.../apache/metamodel/jdbc/H2databaseTest.java | 5 +
.../org/apache/metamodel/jdbc/HsqldbTest.java | 6 +
.../metamodel/jdbc/JdbcTestTemplates.java | 181 ++++++++++++++++++-
.../org/apache/metamodel/jdbc/SqliteTest.java | 24 ++-
.../jdbc/integrationtests/DB2Test.java | 4 +-
.../jdbc/integrationtests/MysqlTest.java | 11 ++
.../jdbc/integrationtests/OracleTest.java | 11 ++
.../jdbc/integrationtests/PostgresqlTest.java | 10 +
.../SQLServerJtdsDriverTest.java | 10 +
16 files changed, 381 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index a753469..ea13708 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,7 @@
+### Apache MetaModel (work in progress)
+
+ * [METAMODEL-198] - Fixed support for JDBC TIMESTAMP precision to match the underlying database's precision.
+
### Apache MetaModel 4.4.0
* [METAMODEL-192] - Added support for Scalar functions. We have a basic set of datatype conversion functions as well as support for UDF via implementing the ScalarFunction interface.
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/pom.xml
----------------------------------------------------------------------
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index cc7aab2..56aee2e 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -72,9 +72,9 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>postgresql</groupId>
+ <groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
- <version>9.1-901.jdbc4</version>
+ <version>9.3-1104-jdbc4</version>
<scope>test</scope>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcDataContext.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcDataContext.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcDataContext.java
index db0ca11..27f638b 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcDataContext.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcDataContext.java
@@ -54,6 +54,7 @@ import org.apache.metamodel.jdbc.dialects.MysqlQueryRewriter;
import org.apache.metamodel.jdbc.dialects.OracleQueryRewriter;
import org.apache.metamodel.jdbc.dialects.PostgresqlQueryRewriter;
import org.apache.metamodel.jdbc.dialects.SQLServerQueryRewriter;
+import org.apache.metamodel.jdbc.dialects.SQLiteQueryRewriter;
import org.apache.metamodel.query.CompiledQuery;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.query.SelectItem;
@@ -87,6 +88,7 @@ public class JdbcDataContext extends AbstractDataContext implements UpdateableDa
public static final String DATABASE_PRODUCT_DB2_PREFIX = "DB2/";
public static final String DATABASE_PRODUCT_ORACLE = "Oracle";
public static final String DATABASE_PRODUCT_HIVE = "Apache Hive";
+ public static final String DATABASE_PRODUCT_SQLITE = "SQLite";
public static final ColumnType COLUMN_TYPE_CLOB_AS_STRING = new ColumnTypeImpl("CLOB", SuperColumnType.LITERAL_TYPE,
String.class, true);
@@ -234,6 +236,8 @@ public class JdbcDataContext extends AbstractDataContext implements UpdateableDa
setQueryRewriter(new H2QueryRewriter(this));
} else if (DATABASE_PRODUCT_HIVE.equals(_databaseProductName)) {
setQueryRewriter(new HiveQueryRewriter(this));
+ } else if (DATABASE_PRODUCT_SQLITE.equals(_databaseProductName)) {
+ setQueryRewriter(new SQLiteQueryRewriter(this));
} else {
setQueryRewriter(new DefaultQueryRewriter(this));
}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcUtils.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcUtils.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcUtils.java
index ea06751..1073d6f 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcUtils.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcUtils.java
@@ -25,6 +25,8 @@ import java.sql.Clob;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@@ -126,13 +128,11 @@ public final class JdbcUtils {
cal.setTime((Date) value);
st.setDate(valueIndex, new java.sql.Date(cal.getTimeInMillis()), cal);
} else if (type == ColumnType.TIME && value instanceof Date) {
- Calendar cal = Calendar.getInstance();
- cal.setTime((Date) value);
- st.setTime(valueIndex, new java.sql.Time(cal.getTimeInMillis()), cal);
+ final Time time = toTime((Date) value);
+ st.setTime(valueIndex, time);
} else if (type == ColumnType.TIMESTAMP && value instanceof Date) {
- Calendar cal = Calendar.getInstance();
- cal.setTime((Date) value);
- st.setTimestamp(valueIndex, new java.sql.Timestamp(cal.getTimeInMillis()), cal);
+ final Timestamp ts = toTimestamp((Date) value);
+ st.setTimestamp(valueIndex, ts);
} else if (type == ColumnType.CLOB || type == ColumnType.NCLOB) {
if (value instanceof InputStream) {
InputStream inputStream = (InputStream) value;
@@ -182,6 +182,24 @@ public final class JdbcUtils {
}
}
+ private static Time toTime(Date value) {
+ if (value instanceof Time) {
+ return (Time) value;
+ }
+ final Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) value);
+ return new java.sql.Time(cal.getTimeInMillis());
+ }
+
+ private static Timestamp toTimestamp(Date value) {
+ if (value instanceof Timestamp) {
+ return (Timestamp) value;
+ }
+ final Calendar cal = Calendar.getInstance();
+ cal.setTime((Date) value);
+ return new Timestamp(cal.getTimeInMillis());
+ }
+
public static String getValueAsSql(Column column, Object value, IQueryRewriter queryRewriter) {
if (value == null) {
return "NULL";
@@ -211,7 +229,8 @@ public final class JdbcUtils {
if (!inlineValues) {
if (isPreparedParameterCandidate(whereItem)) {
// replace operator with parameter
- whereItem = new FilterItem(whereItem.getSelectItem(), whereItem.getOperator(), new QueryParameter());
+ whereItem = new FilterItem(whereItem.getSelectItem(), whereItem.getOperator(),
+ new QueryParameter());
}
}
final String whereItemLabel = queryRewriter.rewriteFilterItem(whereItem);
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
index 56e10c3..13db9df 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
@@ -18,6 +18,7 @@
*/
package org.apache.metamodel.jdbc.dialects;
+import java.sql.Timestamp;
import java.util.List;
import java.util.ListIterator;
@@ -114,6 +115,9 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
FilterItem replacementFilterItem = new FilterItem(item.getSelectItem(), item.getOperator(), str);
return super.rewriteFilterItem(replacementFilterItem);
}
+ } else if (operand instanceof Timestamp) {
+ final String timestampLiteral = rewriteTimestamp((Timestamp) operand);
+ return rewriteFilterItemWithOperandLiteral(item, timestampLiteral);
} else if (operand instanceof Iterable || operand.getClass().isArray()) {
// operand is a set of values (typically in combination with an
// IN operator). Each individual element must be escaped.
@@ -145,7 +149,39 @@ public class DefaultQueryRewriter extends AbstractQueryRewriter {
}
return super.rewriteFilterItem(item);
}
-
+
+ /**
+ * Rewrites a (non-compound) {@link FilterItem} when it's operand has
+ * already been rewritten into a SQL literal.
+ *
+ * @param item
+ * @param operandLiteral
+ * @return
+ */
+ protected String rewriteFilterItemWithOperandLiteral(FilterItem item, String operandLiteral) {
+ final OperatorType operator = item.getOperator();
+ final SelectItem selectItem = item.getSelectItem();
+ final StringBuilder sb = new StringBuilder();
+ sb.append(selectItem.getSameQueryAlias(false));
+ FilterItem.appendOperator(sb, item.getOperand(), operator);
+ sb.append(operandLiteral);
+ return sb.toString();
+ }
+
+ /**
+ * Rewrites a {@link Timestamp} into it's literal representation as known by
+ * this SQL dialect.
+ *
+ * This default implementation returns the JDBC spec's escape syntax for a
+ * timestamp: {ts 'yyyy-mm-dd hh:mm:ss.f . . .'}
+ *
+ * @param ts
+ * @return
+ */
+ protected String rewriteTimestamp(Timestamp ts) {
+ return "{ts '" + ts.toString() + "'}";
+ }
+
@Override
public boolean isScalarFunctionSupported(ScalarFunction function) {
return false;
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/SQLiteQueryRewriter.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/SQLiteQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/SQLiteQueryRewriter.java
new file mode 100644
index 0000000..c32b849
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/SQLiteQueryRewriter.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.apache.metamodel.jdbc.dialects;
+
+import java.sql.Timestamp;
+
+import org.apache.metamodel.jdbc.JdbcDataContext;
+
+/**
+ * Query rewriter for SQLite database
+ */
+public class SQLiteQueryRewriter extends DefaultQueryRewriter {
+
+ public SQLiteQueryRewriter(JdbcDataContext dataContext) {
+ super(dataContext);
+ }
+
+ @Override
+ protected String rewriteTimestamp(Timestamp ts) {
+ // SQLite's driver does not support the JDBC escape syntax.
+ // see http://www.sqlite.org/lang_datefunc.html
+ return "'" + ts.toString() + "'";
+ }
+}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/DerbyTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/DerbyTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/DerbyTest.java
index cee8454..2d0de42 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/DerbyTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/DerbyTest.java
@@ -23,6 +23,7 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
@@ -59,8 +60,8 @@ public class DerbyTest extends TestCase {
File dbFile = new File("src/test/resources/derby_testdb.jar");
assertTrue(dbFile.exists());
Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
- _connection = DriverManager.getConnection("jdbc:derby:jar:(" + dbFile.getAbsolutePath()
- + ")derby_testdb;territory=en");
+ _connection = DriverManager
+ .getConnection("jdbc:derby:jar:(" + dbFile.getAbsolutePath() + ")derby_testdb;territory=en");
}
@Override
@@ -75,6 +76,11 @@ public class DerbyTest extends TestCase {
}
}
+ public void testTimestampValueInsertSelect() throws Exception {
+ Connection conn = DriverManager.getConnection("jdbc:derby:target/temp_derby;create=true");
+ JdbcTestTemplates.timestampValueInsertSelect(conn, TimeUnit.NANOSECONDS);
+ }
+
public void testCreateInsertAndUpdate() throws Exception {
Connection conn = DriverManager.getConnection("jdbc:derby:target/temp_derby;create=true");
JdbcDataContext dc = new JdbcDataContext(conn);
@@ -89,7 +95,7 @@ public class DerbyTest extends TestCase {
public void testDifferentOperators() throws Exception {
Connection conn = DriverManager.getConnection("jdbc:derby:target/temp_derby;create=true");
-
+
JdbcTestTemplates.differentOperatorsTest(conn);
}
@@ -118,7 +124,8 @@ public class DerbyTest extends TestCase {
}
public void testQueryWithFilter() throws Exception {
- JdbcDataContext dc = new JdbcDataContext(_connection, new TableType[] { TableType.TABLE, TableType.VIEW }, null);
+ JdbcDataContext dc = new JdbcDataContext(_connection, new TableType[] { TableType.TABLE, TableType.VIEW },
+ null);
Query q = dc.query().from("APP", "CUSTOMERS").select("CUSTOMERNUMBER").where("ADDRESSLINE2").isNotNull()
.toQuery();
assertEquals(25000, dc.getFetchSizeCalculator().getFetchSize(q));
@@ -180,8 +187,7 @@ public class DerbyTest extends TestCase {
assertEquals(11, schemas.length);
assertEquals("Schema[name=APP]", schemas[0].toString());
assertEquals(13, schemas[0].getTableCount());
- assertEquals("[Table[name=CUSTOMERS,type=TABLE,remarks=], "
- + "Table[name=CUSTOMER_W_TER,type=TABLE,remarks=], "
+ assertEquals("[Table[name=CUSTOMERS,type=TABLE,remarks=], " + "Table[name=CUSTOMER_W_TER,type=TABLE,remarks=], "
+ "Table[name=DEPARTMENT_MANAGERS,type=TABLE,remarks=], "
+ "Table[name=EMPLOYEES,type=TABLE,remarks=], " + "Table[name=OFFICES,type=TABLE,remarks=], "
+ "Table[name=ORDERDETAILS,type=TABLE,remarks=], " + "Table[name=ORDERFACT,type=TABLE,remarks=], "
@@ -239,7 +245,8 @@ public class DerbyTest extends TestCase {
}
public void testQueryRewriterQuoteAliases() throws Exception {
- JdbcDataContext dc = new JdbcDataContext(_connection, new TableType[] { TableType.TABLE, TableType.VIEW }, null);
+ JdbcDataContext dc = new JdbcDataContext(_connection, new TableType[] { TableType.TABLE, TableType.VIEW },
+ null);
IQueryRewriter queryRewriter = dc.getQueryRewriter();
assertSame(DefaultQueryRewriter.class, queryRewriter.getClass());
@@ -304,7 +311,8 @@ public class DerbyTest extends TestCase {
.ofType(ColumnType.INTEGER).execute();
writtenTableRef.set(writtenTable);
String sql = createTableBuilder.createSqlStatement();
- assertEquals("CREATE TABLE APP.test_table (id INTEGER, name VARCHAR(255), age INTEGER, PRIMARY KEY(id))",
+ assertEquals(
+ "CREATE TABLE APP.test_table (id INTEGER, name VARCHAR(255), age INTEGER, PRIMARY KEY(id))",
sql.replaceAll("\"", "|"));
assertNotNull(writtenTable);
}
@@ -393,7 +401,7 @@ public class DerbyTest extends TestCase {
JdbcTestTemplates.convertClobToString(dc);
}
-
+
public void testInterpretationOfNull() throws Exception {
Connection conn = DriverManager.getConnection("jdbc:derby:target/temp_derby;create=true");
JdbcTestTemplates.interpretationOfNulls(conn);
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
index 118864c..6560247 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
@@ -24,6 +24,7 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
@@ -80,6 +81,10 @@ public class H2databaseTest extends TestCase {
JdbcDataContext dc = new JdbcDataContext(conn);
JdbcTestTemplates.compositeKeyCreation(dc, "metamodel_test_composite_keys");
}
+
+ public void testTimestampValueInsertSelect() throws Exception {
+ JdbcTestTemplates.timestampValueInsertSelect(conn, TimeUnit.NANOSECONDS);
+ }
public void testUsingSingleUpdates() throws Exception {
final JdbcDataContext dc = new JdbcDataContext(conn);
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
index 1d69d6f..db969c4 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
@@ -23,6 +23,7 @@ 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;
@@ -70,6 +71,11 @@ public class HsqldbTest extends TestCase {
super.tearDown();
_connection.close();
}
+
+ 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);
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/JdbcTestTemplates.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/JdbcTestTemplates.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/JdbcTestTemplates.java
index e04e4c6..2d5840f 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/JdbcTestTemplates.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/JdbcTestTemplates.java
@@ -28,17 +28,21 @@ import java.io.StringReader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.apache.metamodel.BatchUpdateScript;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.create.ColumnCreationBuilder;
import org.apache.metamodel.create.CreateTable;
+import org.apache.metamodel.create.TableCreationBuilder;
import org.apache.metamodel.data.DataSet;
import org.apache.metamodel.data.Row;
import org.apache.metamodel.drop.DropTable;
@@ -49,6 +53,7 @@ import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.update.Update;
import org.apache.metamodel.util.DateUtils;
+import org.apache.metamodel.util.FileHelper;
import org.apache.metamodel.util.Month;
import org.junit.Ignore;
@@ -584,8 +589,9 @@ public class JdbcTestTemplates {
}
dataContext.executeUpdate(new CreateTable(defaultSchema, testTableName).withColumn("mykey1")
- .ofType(ColumnType.INTEGER).nullable(false).asPrimaryKey().withColumn("mykey2").ofType(ColumnType.INTEGER)
- .nullable(false).asPrimaryKey().withColumn("name").ofType(ColumnType.VARCHAR).ofSize(20));
+ .ofType(ColumnType.INTEGER).nullable(false).asPrimaryKey().withColumn("mykey2")
+ .ofType(ColumnType.INTEGER).nullable(false).asPrimaryKey().withColumn("name")
+ .ofType(ColumnType.VARCHAR).ofSize(20));
try {
final Table table = defaultSchema.getTableByName(testTableName);
assertNotNull(table);
@@ -633,4 +639,175 @@ public class JdbcTestTemplates {
dataContext.executeUpdate(new DropTable(defaultSchema, testTableName));
}
}
+
+ /**
+ *
+ * @param conn
+ * @param databasePrecision
+ * the precision with which the database can handle timestamp
+ * values. Expected values: {@link TimeUnit#SECONDS},
+ * {@link TimeUnit#MILLISECONDS}, {@link TimeUnit#MICROSECONDS}
+ * or {@link TimeUnit#NANOSECONDS}.
+ *
+ * @throws Exception
+ */
+ public static void timestampValueInsertSelect(Connection conn, TimeUnit databasePrecision) throws Exception {
+ timestampValueInsertSelect(conn, databasePrecision, null);
+ }
+
+ public static void timestampValueInsertSelect(Connection conn, TimeUnit databasePrecision, final String nativeType)
+ throws Exception {
+ assertNotNull(conn);
+
+ final Statement statement = conn.createStatement();
+ try {
+ // clean up, if nescesary
+ statement.execute("DROP TABLE test_table");
+ } catch (SQLException e) {
+ // do nothing
+ } finally {
+ FileHelper.safeClose(statement);
+ }
+
+ assertFalse(conn.isReadOnly());
+
+ JdbcDataContext dc = new JdbcDataContext(conn);
+ final Schema schema = dc.getDefaultSchema();
+
+ final Timestamp timestamp1;
+ switch (databasePrecision) {
+ case SECONDS:
+ timestamp1 = Timestamp.valueOf("2015-10-16 16:33:33");
+ break;
+ case MILLISECONDS:
+ timestamp1 = Timestamp.valueOf("2015-10-16 16:33:33.456");
+ break;
+ case MICROSECONDS:
+ timestamp1 = Timestamp.valueOf("2015-10-16 16:33:33.456001");
+ break;
+ case NANOSECONDS:
+ timestamp1 = Timestamp.valueOf("2015-10-16 16:33:33.456001234");
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported database precision: " + databasePrecision);
+ }
+
+ final Timestamp timestamp2;
+ switch (databasePrecision) {
+ case SECONDS:
+ timestamp2 = Timestamp.valueOf("2015-10-16 16:33:34");
+ break;
+ case MILLISECONDS:
+ timestamp2 = Timestamp.valueOf("2015-10-16 16:33:34.683");
+ break;
+ case MICROSECONDS:
+ timestamp2 = Timestamp.valueOf("2015-10-16 16:33:34.683005");
+ break;
+ case NANOSECONDS:
+ timestamp2 = Timestamp.valueOf("2015-10-16 16:33:34.683005678");
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported database precision: " + databasePrecision);
+ }
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback cb) {
+ TableCreationBuilder tableBuilder = cb.createTable(schema, "test_table");
+ tableBuilder.withColumn("id").ofType(ColumnType.INTEGER);
+ tableBuilder.withColumn("insertiontime").ofType(ColumnType.TIMESTAMP);
+ if (nativeType == null) {
+ tableBuilder.withColumn("insertiontime").ofType(ColumnType.TIMESTAMP);
+ } else {
+ tableBuilder.withColumn("insertiontime").ofType(ColumnType.TIMESTAMP).ofNativeType(nativeType);
+ }
+ Table table = tableBuilder.execute();
+
+ cb.insertInto(table).value("id", 1).value("insertiontime", timestamp1).execute();
+ cb.insertInto(table).value("id", 2).value("insertiontime", timestamp2).execute();
+ }
+ });
+
+ DataSet ds = dc.query().from("test_table").select("id").and("insertiontime").execute();
+ assertTrue(ds.next());
+
+ switch (databasePrecision) {
+ case SECONDS:
+ assertEquals("Row[values=[1, 2015-10-16 16:33:33]]", ds.getRow().toString());
+ break;
+ case MILLISECONDS:
+ assertEquals("Row[values=[1, 2015-10-16 16:33:33.456]]", ds.getRow().toString());
+ break;
+ case MICROSECONDS:
+ assertEquals("Row[values=[1, 2015-10-16 16:33:33.456001]]", ds.getRow().toString());
+ break;
+ case NANOSECONDS:
+ assertEquals("Row[values=[1, 2015-10-16 16:33:33.456001234]]", ds.getRow().toString());
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported database precision: " + databasePrecision);
+ }
+ assertTrue(ds.getRow().getValue(0) instanceof Number);
+ assertTrue(ds.next());
+
+ switch (databasePrecision) {
+ case SECONDS:
+ assertEquals("Row[values=[2, 2015-10-16 16:33:34]]", ds.getRow().toString());
+ break;
+ case MILLISECONDS:
+ assertEquals("Row[values=[2, 2015-10-16 16:33:34.683]]", ds.getRow().toString());
+ break;
+ case MICROSECONDS:
+ assertEquals("Row[values=[2, 2015-10-16 16:33:34.683005]]", ds.getRow().toString());
+ break;
+ case NANOSECONDS:
+ assertEquals("Row[values=[2, 2015-10-16 16:33:34.683005678]]", ds.getRow().toString());
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported database precision: " + databasePrecision);
+ }
+ assertFalse(ds.next());
+ ds.close();
+
+ if (databasePrecision != TimeUnit.SECONDS) {
+ Query query = dc.query().from("test_table").select("id").where("insertiontime").lessThan(timestamp2)
+ .toQuery();
+ try {
+ ds = dc.executeQuery(query);
+ } catch (Exception e) {
+ System.out.println("Failing query was: " + dc.getQueryRewriter().rewriteQuery(query));
+ throw e;
+ }
+ assertTrue(ds.next());
+ assertEquals("Row[values=[1]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+
+ ds = dc.query().from("test_table").select("id").where("insertiontime").greaterThan(timestamp1).execute();
+ assertTrue(ds.next());
+ assertEquals("Row[values=[2]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.deleteFrom("test_table").where("insertiontime").eq(timestamp1).execute();
+ }
+ });
+
+ ds = dc.query().from("test_table").selectCount().execute();
+ assertTrue(ds.next());
+ assertEquals("Row[values=[1]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+ }
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.dropTable("test_table").execute();
+ }
+ });
+ }
}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/SqliteTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/SqliteTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/SqliteTest.java
index c8cfd28..3a8d1a4 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/SqliteTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/SqliteTest.java
@@ -24,6 +24,7 @@ import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import junit.framework.TestCase;
@@ -31,6 +32,7 @@ import org.apache.metamodel.DataContext;
import org.apache.metamodel.UpdateCallback;
import org.apache.metamodel.UpdateScript;
import org.apache.metamodel.data.DataSet;
+import org.apache.metamodel.jdbc.dialects.SQLiteQueryRewriter;
import org.apache.metamodel.query.OperatorType;
import org.apache.metamodel.query.Query;
import org.apache.metamodel.schema.Column;
@@ -70,6 +72,10 @@ public class SqliteTest extends TestCase {
_connection.close();
}
+ public void testTimestampValueInsertSelect() throws Exception {
+ JdbcTestTemplates.timestampValueInsertSelect(_connection, TimeUnit.SECONDS);
+ }
+
public void testCreateInsertAndUpdate() throws Exception {
JdbcDataContext dc = new JdbcDataContext(_connection);
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(dc, "metamodel_test_simple");
@@ -84,6 +90,11 @@ public class SqliteTest extends TestCase {
JdbcTestTemplates.differentOperatorsTest(_connection);
}
+ public void testGetQueryRewriter() throws Exception {
+ JdbcDataContext dc = new JdbcDataContext(_connection);
+ assertTrue(dc.getQueryRewriter() instanceof SQLiteQueryRewriter);
+ }
+
public void testGetSchemas() throws Exception {
DataContext dc = new JdbcDataContext(_connection);
String[] schemaNames = dc.getSchemaNames();
@@ -99,9 +110,8 @@ public class SqliteTest extends TestCase {
+ "Table[name=auth_cookie,type=TABLE,remarks=null], " + "Table[name=session,type=TABLE,remarks=null], "
+ "Table[name=session_attribute,type=TABLE,remarks=null], "
+ "Table[name=attachment,type=TABLE,remarks=null], " + "Table[name=wiki,type=TABLE,remarks=null], "
- + "Table[name=revision,type=TABLE,remarks=null], "
- + "Table[name=node_change,type=TABLE,remarks=null], " + "Table[name=ticket,type=TABLE,remarks=null], "
- + "Table[name=ticket_change,type=TABLE,remarks=null], "
+ + "Table[name=revision,type=TABLE,remarks=null], " + "Table[name=node_change,type=TABLE,remarks=null], "
+ + "Table[name=ticket,type=TABLE,remarks=null], " + "Table[name=ticket_change,type=TABLE,remarks=null], "
+ "Table[name=ticket_custom,type=TABLE,remarks=null], " + "Table[name=enum,type=TABLE,remarks=null], "
+ "Table[name=component,type=TABLE,remarks=null], " + "Table[name=milestone,type=TABLE,remarks=null], "
+ "Table[name=version,type=TABLE,remarks=null], " + "Table[name=report,type=TABLE,remarks=null]]",
@@ -137,8 +147,8 @@ public class SqliteTest extends TestCase {
Table wikiTable = schema.getTableByName("WIKI");
- Query q = new Query().selectCount().from(wikiTable)
- .where(wikiTable.getColumnByName("name"), OperatorType.LIKE, "Trac%");
+ Query q = new Query().selectCount().from(wikiTable).where(wikiTable.getColumnByName("name"), OperatorType.LIKE,
+ "Trac%");
assertEquals("SELECT COUNT(*) FROM wiki WHERE wiki.name LIKE 'Trac%'", q.toString());
assertEquals(1, dc.getFetchSizeCalculator().getFetchSize(q));
assertEquals(37, dc.executeQuery(q).toObjectArrays().get(0)[0]);
@@ -165,8 +175,8 @@ public class SqliteTest extends TestCase {
assertEquals("wiki.name", nameColumn.getQualifiedLabel());
assertEquals(
- "Column[name=name,columnNumber=0,type=VARCHAR,nullable=true,nativeType=TEXT,columnSize=2000000000]", dc
- .getColumnByQualifiedLabel("wiki.name").toString());
+ "Column[name=name,columnNumber=0,type=VARCHAR,nullable=true,nativeType=TEXT,columnSize=2000000000]",
+ dc.getColumnByQualifiedLabel("wiki.name").toString());
assertEquals("Table[name=wiki,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("WIKI").toString());
}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/DB2Test.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/DB2Test.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/DB2Test.java
index c0aeb83..aef6f51 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/DB2Test.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/DB2Test.java
@@ -45,12 +45,12 @@ public class DB2Test extends AbstractJdbIntegrationTest {
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(getDataContext(), "metamodel_db2_test");
}
-
+
public void testCompositePrimaryKeyCreation() throws Exception {
if (!isConfigured()) {
return;
}
-
+
JdbcTestTemplates.compositeKeyCreation(getDataContext(), "metamodel_test_composite_keys");
}
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/MysqlTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/MysqlTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/MysqlTest.java
index 4ac0947..ba273e3 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/MysqlTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/MysqlTest.java
@@ -18,11 +18,13 @@
*/
package org.apache.metamodel.jdbc.integrationtests;
+import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
@@ -73,6 +75,15 @@ public class MysqlTest extends AbstractJdbIntegrationTest {
JdbcTestTemplates.compositeKeyCreation(getDataContext(), "metamodel_test_composite_keys");
}
+
+ public void testTimestampValueInsertSelect() throws Exception {
+ if (!isConfigured()) {
+ return;
+ }
+
+ final Connection connection = getConnection();
+ JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.MICROSECONDS, "TIMESTAMP(6)");
+ }
public void testInterpretationOfNull() throws Exception {
if (!isConfigured()) {
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/OracleTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/OracleTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/OracleTest.java
index d16547f..6924362 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/OracleTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/OracleTest.java
@@ -18,8 +18,10 @@
*/
package org.apache.metamodel.jdbc.integrationtests;
+import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
@@ -87,6 +89,15 @@ public class OracleTest extends AbstractJdbIntegrationTest {
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(getDataContext(), "metamodel_test_simple");
}
+
+ public void testTimestampValueInsertSelect() throws Exception {
+ if (!isConfigured()) {
+ return;
+ }
+
+ final Connection connection = getConnection();
+ JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.MICROSECONDS, null);
+ }
public void testCompositePrimaryKeyCreation() throws Exception {
if (!isConfigured()) {
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/PostgresqlTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/PostgresqlTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/PostgresqlTest.java
index a68cc99..5cf6822 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/PostgresqlTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/PostgresqlTest.java
@@ -23,6 +23,7 @@ import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
@@ -64,6 +65,15 @@ public class PostgresqlTest extends AbstractJdbIntegrationTest {
protected String getPropertyPrefix() {
return "postgresql";
}
+
+ public void testTimestampValueInsertSelect() throws Exception {
+ if (!isConfigured()) {
+ return;
+ }
+
+ final Connection connection = getConnection();
+ JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.MICROSECONDS);
+ }
public void testCreateInsertAndUpdate() throws Exception {
if (!isConfigured()) {
http://git-wip-us.apache.org/repos/asf/metamodel/blob/5370703a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/SQLServerJtdsDriverTest.java
----------------------------------------------------------------------
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/SQLServerJtdsDriverTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/SQLServerJtdsDriverTest.java
index 336814e..c72d2f3 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/SQLServerJtdsDriverTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/integrationtests/SQLServerJtdsDriverTest.java
@@ -21,6 +21,7 @@ package org.apache.metamodel.jdbc.integrationtests;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.metamodel.UpdateCallback;
@@ -62,6 +63,15 @@ public class SQLServerJtdsDriverTest extends AbstractJdbIntegrationTest {
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(getDataContext(), "metamodel_test_simple");
}
+ public void testTimestampValueInsertSelect() throws Exception {
+ if (!isConfigured()) {
+ return;
+ }
+
+ final Connection connection = getConnection();
+ JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.NANOSECONDS, "datetime");
+ }
+
public void testCreateTableInUpdateScript() throws Exception {
if (!isConfigured()) {
return;