This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/master by this push:
new 85c0d6d CAY-2694 Precision issues with reverse / forward engineering
of time types on MySQL
85c0d6d is described below
commit 85c0d6d995b0c29bcd7d703a7da8aaf67d476074
Author: Nikita Timofeev <[email protected]>
AuthorDate: Wed Mar 10 19:31:34 2021 +0300
CAY-2694 Precision issues with reverse / forward engineering of time types
on MySQL
---
RELEASE-NOTES.txt | 1 +
.../org/apache/cayenne/dba/mysql/MySQLAdapter.java | 34 +++++++++++---
.../apache/cayenne/dba/mysql/MySQLAdapterIT.java | 53 +++++++++++++++++++++-
3 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 2343ab7..8445176 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -29,6 +29,7 @@ CAY-2686 SQL translator incorrectly quotes fully qualified
tables' names
CAY-2687 Modeler Migrate Repeatedly Asks to Set Column Type for MySQL
CAY-2690 dbimport skips length changes for BINARY and VARBINARY columns
CAY-2691 MySQL driver 8.0.x stores LocalDateTime differently than 5.1.x
+CAY-2694 Precision issues with reverse / forward engineering of time types on
MySQL
CAY-2695 Reverse engineering on SQLite fails due to feature not being supported
CAY-2698 EventSubject.getSubject() is not thread safe
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
index 32044e0..1573379 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
@@ -213,6 +213,16 @@ public class MySQLAdapter extends JdbcAdapter {
type = Types.LONGVARCHAR;
}
+ // driver reports column size that we should "translate" to the
column precision
+ // see CAY-2694 for details
+ if(type == Types.TIME) {
+ precision = Math.max(0, size - 9);
+ size = -1;
+ } else if(type == Types.TIMESTAMP) {
+ precision = Math.max(0, size - 20);
+ size = -1;
+ }
+
return super.buildAttribute(name, typeName, type, size,
precision, allowNulls);
}
@@ -321,7 +331,22 @@ public class MySQLAdapter extends JdbcAdapter {
sqlBuffer.append(' ').append(type);
// append size and precision (if applicable)s
- if (typeSupportsLength(column.getType())) {
+ appendLengthAndScale(sqlBuffer, column);
+
+ sqlBuffer.append(column.isMandatory() ? " NOT NULL" : " NULL");
+
+ if (column.isGenerated()) {
+ sqlBuffer.append(" AUTO_INCREMENT");
+ }
+ }
+
+ private void appendLengthAndScale(StringBuffer sqlBuffer, DbAttribute
column) {
+ if(column.getType() == Types.TIME || column.getType() ==
Types.TIMESTAMP) {
+ int scale = column.getScale();
+ if(scale >= 0) {
+ sqlBuffer.append('(').append(scale).append(')');
+ }
+ } else if (typeSupportsLength(column.getType())) {
int len = column.getMaxLength();
int scale = TypesMapping.isDecimal(column.getType()) ?
column.getScale() : -1;
@@ -341,14 +366,9 @@ public class MySQLAdapter extends JdbcAdapter {
sqlBuffer.append(')');
}
}
-
- sqlBuffer.append(column.isMandatory() ? " NOT NULL" : " NULL");
-
- if (column.isGenerated()) {
- sqlBuffer.append(" AUTO_INCREMENT");
- }
}
+
@Override
public boolean typeSupportsLength(int type) {
// As of MySQL 5.6.4 the "TIMESTAMP" and "TIME" types support
length,
diff --git
a/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLAdapterIT.java
b/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLAdapterIT.java
index e11c0b8..2a9991d 100644
---
a/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLAdapterIT.java
+++
b/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLAdapterIT.java
@@ -19,6 +19,8 @@
package org.apache.cayenne.dba.mysql;
+import java.sql.Types;
+
import org.apache.cayenne.di.AdhocObjectFactory;
import org.apache.cayenne.di.Inject;
import org.apache.cayenne.map.DbAttribute;
@@ -28,11 +30,12 @@ import org.apache.cayenne.unit.di.server.ServerCase;
import org.apache.cayenne.unit.di.server.UseServerRuntime;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
public class MySQLAdapterIT extends ServerCase {
-
+
@Inject
private AdhocObjectFactory objectFactory;
@@ -67,4 +70,52 @@ public class MySQLAdapterIT extends ServerCase {
assertTrue(b2.indexOf("PK2") > 0);
assertTrue(b2.indexOf("PK1") > b2.indexOf("PK2"));
}
+
+ @Test
+ public void testCreateTableAppendColumnWithTimeAndTimestamp() {
+ MySQLAdapter adapter = objectFactory.newInstance(
+ MySQLAdapter.class,
+ MySQLAdapter.class.getName());
+
+ DbEntity e = new DbEntity("Test");
+ DbAttribute dblPrec1 = new DbAttribute("dbl1");
+ dblPrec1.setType(Types.TIMESTAMP);
+ dblPrec1.setScale(3);
+ e.addAttribute(dblPrec1);
+
+ DbAttribute dblPrec2 = new DbAttribute("dbl2");
+ dblPrec2.setType(Types.TIME);
+ dblPrec2.setScale(6);
+ e.addAttribute(dblPrec2);
+
+ String sql = adapter.createTable(e);
+
+ // CAY-2694.
+ assertTrue(sql.indexOf("TIME(6)") > 0);
+ assertTrue(sql.indexOf("DATETIME(3)") > 0);
+ assertEquals("CREATE TABLE Test (dbl1 DATETIME(3) NULL, dbl2 TIME(6)
NULL) ENGINE=InnoDB", sql);
+ }
+
+ @Test
+ public void testCreateTableAppendColumnWithTimeAndTimestampWihoutScale() {
+ MySQLAdapter adapter = objectFactory.newInstance(
+ MySQLAdapter.class,
+ MySQLAdapter.class.getName());
+
+ DbEntity e = new DbEntity("Test");
+ DbAttribute dblPrec1 = new DbAttribute("dbl1");
+ dblPrec1.setType(Types.TIMESTAMP);
+ e.addAttribute(dblPrec1);
+
+ DbAttribute dblPrec2 = new DbAttribute("dbl2");
+ dblPrec2.setType(Types.TIME);
+ e.addAttribute(dblPrec2);
+
+ String sql = adapter.createTable(e);
+
+ // CAY-2694.
+ assertTrue(sql.indexOf("TIME") > 0);
+ assertTrue(sql.indexOf("DATETIME") > 0);
+ assertEquals("CREATE TABLE Test (dbl1 DATETIME NULL, dbl2 TIME NULL)
ENGINE=InnoDB", sql);
+ }
}