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);
+    }
 }

Reply via email to