From b480ef05e8dd2bded8ec33674c4b7491d9e3a46f Mon Sep 17 00:00:00 2001 From: Felix Berger Date: Wed, 9 Nov 2022 12:07:49 +0100 Subject: [PATCH] #860 Added first tests for sql generation --- .../templates/devon4j/utils/SQLUtil.java | 35 +- .../templates/SQLTemplateGenerationTest.java | 31 +- .../testclasses/SQLTestEntityDataTypes.java | 424 ++++++++++++++++++ .../devon4j/test/utils/SQLUtilTest.java | 40 ++ 4 files changed, 512 insertions(+), 18 deletions(-) create mode 100644 cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/testclasses/SQLTestEntityDataTypes.java diff --git a/cobigen-templates/templates-devon4j/src/main/java/com/devonfw/cobigen/templates/devon4j/utils/SQLUtil.java b/cobigen-templates/templates-devon4j/src/main/java/com/devonfw/cobigen/templates/devon4j/utils/SQLUtil.java index e43b2ff188..dcc122978d 100644 --- a/cobigen-templates/templates-devon4j/src/main/java/com/devonfw/cobigen/templates/devon4j/utils/SQLUtil.java +++ b/cobigen-templates/templates-devon4j/src/main/java/com/devonfw/cobigen/templates/devon4j/utils/SQLUtil.java @@ -1,6 +1,7 @@ package com.devonfw.cobigen.templates.devon4j.utils; -import java.util.*; +import java.util.Map; +import java.util.Objects; import java.util.function.Function; /** @@ -85,15 +86,14 @@ public String foreignKeyStatement(Map field) { public String basicStatement(Map field) { - Map columnAnnotation = chainAccess(field, new String[] {"annotations", "javax_persistence_Column"}); - String fieldName = getFieldName(field), - typeString = Objects.requireNonNull(getValue(field, "type")), + Map columnAnnotation = chainAccess(field, new String[] { "annotations", "javax_persistence_Column" }); + String fieldName = getFieldName(field), typeString = Objects.requireNonNull(getValue(field, "type")), fieldType = mapType(typeString); Integer fieldLength = 255; - boolean nullable = true, - unique = false; + boolean nullable = true, unique = false; // Try to infer fieldType from possible annotations - Map enumerateAnnotation = chainAccess(field, new String[]{"annotations", "javax_persistence_Enumerated"}); + Map enumerateAnnotation = chainAccess(field, + new String[] { "annotations", "javax_persistence_Enumerated" }); if (enumerateAnnotation != null) { String enumType = Objects.requireNonNull(getValue(enumerateAnnotation, "value")); if (enumType.equals("STRING")) { @@ -105,37 +105,45 @@ public String basicStatement(Map field) { // Parse @Column if present if (columnAnnotation != null) { Integer columnLength = Integer.parseInt(Objects.requireNonNull(getValue(columnAnnotation, "length"))); - if (columnLength != null) fieldLength = columnLength; + if (columnLength != null) + fieldLength = columnLength; nullable = isNullable(columnAnnotation); unique = isUnique(columnAnnotation); } // If fieldType is still empty throw exception - if (fieldType == null) throw new IllegalArgumentException("Couldn't map Java type to SQL type for typeString: " + typeString); + if (fieldType == null) + throw new IllegalArgumentException("Couldn't map Java type to SQL type for typeString: " + typeString); // Add size to VARCHAR fields if (fieldType.equals("VARCHAR")) { fieldType = String.format("VARCHAR(%d)", fieldLength); } String statement = String.format("%s %s", fieldName, fieldType); - if (!nullable) statement += " NOT NULL"; - if (unique) statement += " UNIQUE"; + if (!nullable) + statement += " NOT NULL"; + if (unique) + statement += " UNIQUE"; return statement; } /** * Extracts value of nullable from @Column and @JoinColumn annotations + * * @param columnAnnotation Map for the Column and JoinColumn annotations */ private static boolean isNullable(Map columnAnnotation) { + return Boolean.parseBoolean(getValue(columnAnnotation, "nullable")); } /** * Extracts value of unique from @Column and @JoinColumn annotations + * * @param columnAnnotation Map for the Column and JoinColumn annotations */ private static boolean isUnique(Map columnAnnotation) { + return Boolean.parseBoolean(getValue(columnAnnotation, "unique")); } @@ -143,8 +151,9 @@ private static boolean isUnique(Map columnAnnotation) { * Helper function to map simple SQL types, returns null on unmappable type */ public static String mapType(String typeString) { + // Shortcut for case insensitive regex matching with start and ending ignore - Function match = (regex) -> typeString.matches(".*" + "(?i)" + regex + ".*"); + Function match = (regex) -> typeString.matches("(?i).*" + regex + ".*"); if (match.apply("(integer)|(int)")) { return "INTEGER"; } else if (match.apply("long")) { @@ -175,7 +184,7 @@ public static String mapType(String typeString) { return "CLOB"; } else if (match.apply("(Class)|(Locale)|(TimeZone)|(Currency)")) { return "VARCHAR"; - }else { + } else { return null; } } diff --git a/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/SQLTemplateGenerationTest.java b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/SQLTemplateGenerationTest.java index 6032c14909..1e34995e6b 100644 --- a/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/SQLTemplateGenerationTest.java +++ b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/SQLTemplateGenerationTest.java @@ -1,24 +1,45 @@ package com.devonfw.cobigen.templates.devon4j.test.templates; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + import com.devonfw.cobigen.templates.devon4j.test.templates.testclasses.SQLTestEntity; +import com.devonfw.cobigen.templates.devon4j.test.templates.testclasses.SQLTestEntityDataTypes; import com.devonfw.cobigen.templates.devon4j.utils.SQLUtil; -import org.assertj.core.api.Assertions; -import org.junit.Assert; -import org.junit.Test; public class SQLTemplateGenerationTest extends AbstractJavaTemplateTest { @Test public void generateSQLTest() { - String output = this.process(SQLTestEntity.class); + + String output = process(SQLTestEntity.class); } @Override public Class[] getUtils() { + return new Class[] { SQLUtil.class }; } @Override public String getTemplatePath() { - return "src/main/templates/sql_java_app/templates/V0000__Create_${variables.entityName}Entity.sql.ftl"; + + return "src/main/templates/sql_java_app/templates/V0000__Create_${variables.entityName}Entity.sql.ftl"; + } + + /** + * Test the correct generation of data types + */ + @Test + public void testDatatypeMapping() { + + String ouptut = process(SQLTestEntityDataTypes.class); + assertThat(ouptut).contains("_timestamp2 TIMESTAMP").contains("_blob2 BLOB").contains("_bit BIT,") + .contains("_date DATE").contains("_tinyint TINYINT").contains("_integer2 INTEGER").contains("_bigint BIGINT") + .contains("_varchar3 VARCHAR").contains("_integer1 INTEGER").contains("_varchar4 VARCHAR") + .contains("_clob CLOB").contains("_blob BLOB").contains("_varchar VARCHAR").contains("_char2 CHAR(1)") + .contains(" _smallint SMALLINT").contains(" _char CHAR(1)").contains("_timestamp TIMESTAMP") + .contains("_time TIME").contains("_numeric NUMERIC").contains("_varchar2 VARCHAR"); + } } diff --git a/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/testclasses/SQLTestEntityDataTypes.java b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/testclasses/SQLTestEntityDataTypes.java new file mode 100644 index 0000000000..2ada680372 --- /dev/null +++ b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/templates/testclasses/SQLTestEntityDataTypes.java @@ -0,0 +1,424 @@ +package com.devonfw.cobigen.templates.devon4j.test.templates.testclasses; + +import java.math.BigDecimal; +import java.security.Timestamp; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Time; +import java.util.Calendar; +import java.util.Currency; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +/** + * Test class to test sql data type mapping + * + */ +@Entity +@Table(name = "SQLDataTypeTest") +public class SQLTestEntityDataTypes { + + @Column() + private int _integer1; + + @Column() + private Integer _integer2; + + @Column() + private long _bigint; + + @Column() + private short _smallint; + + @Column() + private BigDecimal _numeric; + + @Column() + private String _varchar; + + @Column() + private char _char; + + @Column() + private Character _char2; + + @Column() + private byte _tinyint; + + @Column() + private boolean _bit; + + @Column() + private Date _date; + + @Column() + private Time _time; + + @Column() + private Timestamp _timestamp; + + @Column() + private Calendar _timestamp2; + + @Column() + private byte[] _blob; + + @Column() + private Blob _blob2; + + @Column() + private Clob _clob; + + @Column() + private Class _varchar2; + + @Column() + private Locale _varchar3; + + private TimeZone _varchar4; + + @Column() + private Currency _varchar5; + + /** + * @return _integer1 + */ + public int get_integer1() { + + return this._integer1; + } + + /** + * @param _integer1 new value of {@link #get_integer1}. + */ + public void set_integer1(int _integer1) { + + this._integer1 = _integer1; + } + + /** + * @return _integer2 + */ + public Integer get_integer2() { + + return this._integer2; + } + + /** + * @param _integer2 new value of {@link #get_integer2}. + */ + public void set_integer2(Integer _integer2) { + + this._integer2 = _integer2; + } + + /** + * @return _bigint + */ + public long get_bigint() { + + return this._bigint; + } + + /** + * @param _bigint new value of {@link #get_bigint}. + */ + public void set_bigint(long _bigint) { + + this._bigint = _bigint; + } + + /** + * @return _smallint + */ + public short get_smallint() { + + return this._smallint; + } + + /** + * @param _smallint new value of {@link #get_smallint}. + */ + public void set_smallint(short _smallint) { + + this._smallint = _smallint; + } + + /** + * @return _numeric + */ + public BigDecimal get_numeric() { + + return this._numeric; + } + + /** + * @param _numeric new value of {@link #get_numeric}. + */ + public void set_numeric(BigDecimal _numeric) { + + this._numeric = _numeric; + } + + /** + * @return _varchar + */ + public String get_varchar() { + + return this._varchar; + } + + /** + * @param _varchar new value of {@link #get_varchar}. + */ + public void set_varchar(String _varchar) { + + this._varchar = _varchar; + } + + /** + * @return _char + */ + public char get_char() { + + return this._char; + } + + /** + * @param _char new value of {@link #get_char}. + */ + public void set_char(char _char) { + + this._char = _char; + } + + /** + * @return _character + */ + public Character get_character() { + + return this._character; + } + + /** + * @param _character new value of {@link #get_character}. + */ + public void set_character(Character _character) { + + this._character = _character; + } + + /** + * @return _tinyint + */ + public byte get_tinyint() { + + return this._tinyint; + } + + /** + * @param _tinyint new value of {@link #get_tinyint}. + */ + public void set_tinyint(byte _tinyint) { + + this._tinyint = _tinyint; + } + + /** + * @return _bit + */ + public boolean is_bit() { + + return this._bit; + } + + /** + * @param _bit new value of {@link #get_bit}. + */ + public void set_bit(boolean _bit) { + + this._bit = _bit; + } + + /** + * @return _date + */ + public Date get_date() { + + return this._date; + } + + /** + * @param _date new value of {@link #get_date}. + */ + public void set_date(Date _date) { + + this._date = _date; + } + + /** + * @return _time + */ + public Time get_time() { + + return this._time; + } + + /** + * @param _time new value of {@link #get_time}. + */ + public void set_time(Time _time) { + + this._time = _time; + } + + /** + * @return _timestamp + */ + public Timestamp get_timestamp() { + + return this._timestamp; + } + + /** + * @param _timestamp new value of {@link #get_timestamp}. + */ + public void set_timestamp(Timestamp _timestamp) { + + this._timestamp = _timestamp; + } + + /** + * @return _timestamp2 + */ + public Calendar get_timestamp2() { + + return this._timestamp2; + } + + /** + * @param _timestamp2 new value of {@link #get_timestamp2}. + */ + public void set_timestamp2(Calendar _timestamp2) { + + this._timestamp2 = _timestamp2; + } + + /** + * @return _blob + */ + public byte[] get_blob() { + + return this._blob; + } + + /** + * @param _blob new value of {@link #get_blob}. + */ + public void set_blob(byte[] _blob) { + + this._blob = _blob; + } + + /** + * @return _blob2 + */ + public Blob get_blob2() { + + return this._blob2; + } + + /** + * @param _blob2 new value of {@link #get_blob2}. + */ + public void set_blob2(Blob _blob2) { + + this._blob2 = _blob2; + } + + /** + * @return _clob + */ + public Clob get_clob() { + + return this._clob; + } + + /** + * @param _clob new value of {@link #get_clob}. + */ + public void set_clob(Clob _clob) { + + this._clob = _clob; + } + + // /** + // * @return _varchar2 + // */ + // public Class get_varchar2() { + // + // return this._varchar2; + // } + + // /** + // * @param _varchar2 new value of {@link #get_varchar2}. + // */ + // public void set_varchar2(Class _varchar2) { + // + // this._varchar2 = _varchar2; + // } + + /** + * @return _varchar3 + */ + public Locale get_varchar3() { + + return this._varchar3; + } + + /** + * @param _varchar3 new value of {@link #get_varchar3}. + */ + public void set_varchar3(Locale _varchar3) { + + this._varchar3 = _varchar3; + } + + /** + * @return _varchar4 + */ + public TimeZone get_varchar4() { + + return this._varchar4; + } + + /** + * @param _varchar4 new value of {@link #get_varchar4}. + */ + public void set_varchar4(TimeZone _varchar4) { + + this._varchar4 = _varchar4; + } + + /** + * @return _carchar5 + */ + public Currency get_carchar5() { + + return this._varchar5; + } + + /** + * @param _carchar5 new value of {@link #get_carchar5}. + */ + public void set_carchar5(Currency _carchar5) { + + this._varchar5 = _carchar5; + } + +} diff --git a/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/utils/SQLUtilTest.java b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/utils/SQLUtilTest.java index 1962ac57e4..b220511c0b 100644 --- a/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/utils/SQLUtilTest.java +++ b/cobigen-templates/templates-devon4j/src/test/java/com/devonfw/cobigen/templates/devon4j/test/utils/SQLUtilTest.java @@ -1,5 +1,45 @@ package com.devonfw.cobigen.templates.devon4j.test.utils; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import com.devonfw.cobigen.templates.devon4j.utils.SQLUtil; + public class SQLUtilTest { + @Test + public void testClassTypeMapping() { + + // Test fails + assertThat(SQLUtil.mapType("Class")).isEqualTo("VARCHAR"); + } + + @Test + public void testByteArray() { + + // Test fails + assertThat(SQLUtil.mapType("byte[]")).isEqualTo("BLOB"); + } + + @Test + public void testTimestamp() { + + // Test fails + assertThat(SQLUtil.mapType("Timestamp")).isEqualTo("TIMESTAMP"); + } + + @Test + public void testTimeZone() { + + // Test fails + assertThat(SQLUtil.mapType("TimeZone")).isEqualTo("VARCHAR"); + } + + @Test + public void testCalendar() { + + assertThat(SQLUtil.mapType("Calendar")).isEqualTo("TIMESTAMP"); + } + }