From 81cfe8a713c4fdc4ba5cfa9cb7e94d0c14194a68 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Sat, 28 Oct 2023 00:29:14 +0200 Subject: [PATCH] [DEV] update sone modality of test and normalization --- conditioningUnit | 1 - pom.xml | 4 +- src/org/kar/archidata/UserDB.java | 4 +- .../archidata/annotation/AnnotationTools.java | 62 +- src/org/kar/archidata/api/DataResource.java | 14 +- .../DataAccess.java} | 628 ++++++------------ .../DataAccessAddOn.java} | 28 +- .../kar/archidata/dataAccess/DataFactory.java | 382 +++++++++++ .../{sqlWrapper => dataAccess}/Foreign.java | 2 +- .../QueryAnd.java} | 14 +- .../QueryCondition.java} | 8 +- .../QueryItem.java} | 4 +- .../QueryOptions.java} | 12 +- .../QuerryOr.java => dataAccess/QueryOr.java} | 12 +- .../addOn/AddOnManyToMany.java | 24 +- .../addOn/AddOnManyToManyOrdered.java | 22 +- .../addOn/AddOnManyToOne.java | 54 +- .../AddOnSQLTableExternalForeinKeyAsList.java | 108 +++ src/org/kar/archidata/db/DBConfig.java | 4 +- .../archidata/migration/MigrationEngine.java | 119 ++-- .../archidata/migration/MigrationSqlStep.java | 43 +- src/org/kar/archidata/model/GenericData.java | 19 +- .../AddOnSQLTableExternalForeinKeyAsList.java | 103 --- src/org/kar/archidata/util/DataTools.java | 20 +- .../test/kar/archidata/StepwiseExtension.java | 33 + .../test/kar/archidata/TestSimpleTable.java | 40 +- .../archidata/TestSimpleTableSoftDelete.java | 43 +- .../src/test/kar/archidata/TestTypeEnum1.java | 81 +++ .../src/test/kar/archidata/TestTypeEnum2.java | 120 ++++ test/src/test/kar/archidata/TestTypes.java | 350 ++++++++++ .../kar/archidata/model/Enum1ForTest.java | 5 + .../kar/archidata/model/Enum2ForTest.java | 11 + .../test/kar/archidata/model/SimpleTable.java | 1 + .../test/kar/archidata/model/TypesEnum1.java | 15 + .../test/kar/archidata/model/TypesEnum2.java | 15 + .../test/kar/archidata/model/TypesTable.java | 31 + 36 files changed, 1630 insertions(+), 806 deletions(-) delete mode 100644 conditioningUnit rename src/org/kar/archidata/{sqlWrapper/SqlWrapper.java => dataAccess/DataAccess.java} (64%) rename src/org/kar/archidata/{sqlWrapper/SqlWrapperAddOn.java => dataAccess/DataAccessAddOn.java} (87%) create mode 100644 src/org/kar/archidata/dataAccess/DataFactory.java rename src/org/kar/archidata/{sqlWrapper => dataAccess}/Foreign.java (88%) rename src/org/kar/archidata/{sqlWrapper/QuerryAnd.java => dataAccess/QueryAnd.java} (71%) rename src/org/kar/archidata/{sqlWrapper/QuerryCondition.java => dataAccess/QueryCondition.java} (72%) rename src/org/kar/archidata/{sqlWrapper/QuerryItem.java => dataAccess/QueryItem.java} (71%) rename src/org/kar/archidata/{sqlWrapper/QuerryOptions.java => dataAccess/QueryOptions.java} (66%) rename src/org/kar/archidata/{sqlWrapper/QuerryOr.java => dataAccess/QueryOr.java} (70%) rename src/org/kar/archidata/{sqlWrapper => dataAccess}/addOn/AddOnManyToMany.java (91%) rename src/org/kar/archidata/{sqlWrapper => dataAccess}/addOn/AddOnManyToManyOrdered.java (92%) rename src/org/kar/archidata/{sqlWrapper => dataAccess}/addOn/AddOnManyToOne.java (70%) create mode 100644 src/org/kar/archidata/dataAccess/addOn/AddOnSQLTableExternalForeinKeyAsList.java delete mode 100644 src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java create mode 100644 test/src/test/kar/archidata/StepwiseExtension.java create mode 100644 test/src/test/kar/archidata/TestTypeEnum1.java create mode 100644 test/src/test/kar/archidata/TestTypeEnum2.java create mode 100644 test/src/test/kar/archidata/TestTypes.java create mode 100644 test/src/test/kar/archidata/model/Enum1ForTest.java create mode 100644 test/src/test/kar/archidata/model/Enum2ForTest.java create mode 100644 test/src/test/kar/archidata/model/TypesEnum1.java create mode 100644 test/src/test/kar/archidata/model/TypesEnum2.java create mode 100644 test/src/test/kar/archidata/model/TypesTable.java diff --git a/conditioningUnit b/conditioningUnit deleted file mode 100644 index 0637a08..0000000 --- a/conditioningUnit +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/pom.xml b/pom.xml index bbdbff3..ab71c6b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,8 +6,8 @@ 0.4.0 3.1 - 17 - 17 + 21 + 21 3.1.1 diff --git a/src/org/kar/archidata/UserDB.java b/src/org/kar/archidata/UserDB.java index 326ec0c..92c1468 100755 --- a/src/org/kar/archidata/UserDB.java +++ b/src/org/kar/archidata/UserDB.java @@ -4,16 +4,16 @@ import java.io.IOException; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.kar.archidata.dataAccess.DataAccess; import org.kar.archidata.db.DBEntry; import org.kar.archidata.model.User; -import org.kar.archidata.sqlWrapper.SqlWrapper; public class UserDB { public UserDB() {} public static User getUsers(long userId) throws Exception { - return SqlWrapper.get(User.class, userId); + return DataAccess.get(User.class, userId); } public static User getUserOrCreate(long userId, String userLogin) throws Exception { diff --git a/src/org/kar/archidata/annotation/AnnotationTools.java b/src/org/kar/archidata/annotation/AnnotationTools.java index e6fd247..61d0839 100644 --- a/src/org/kar/archidata/annotation/AnnotationTools.java +++ b/src/org/kar/archidata/annotation/AnnotationTools.java @@ -9,15 +9,16 @@ import org.slf4j.LoggerFactory; import jakarta.persistence.Column; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import jakarta.persistence.Table; public class AnnotationTools { static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class); - + public static String getTableName(final Class element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class); if (annotation.length == 0) { - // when no annotation is detected, then the table name is the class name + // when no annotation is detected, then the table name is the class name return element.getSimpleName(); } if (annotation.length > 1) { @@ -29,7 +30,7 @@ public class AnnotationTools { } return tmp; } - + public static String getComment(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLComment.class); if (annotation.length == 0) { @@ -40,7 +41,7 @@ public class AnnotationTools { } return ((SQLComment) annotation[0]).value(); } - + public static String getDefault(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(SQLDefault.class); if (annotation.length == 0) { @@ -51,7 +52,7 @@ public class AnnotationTools { } return ((SQLDefault) annotation[0]).value(); } - + public static Integer getLimitSize(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class); if (annotation.length == 0) { @@ -62,7 +63,7 @@ public class AnnotationTools { } return ((Column) annotation[0]).length(); } - + public static boolean isAnnotationGroup(final Field field, final Class annotationType) { try { final Annotation[] anns = field.getAnnotations(); @@ -85,7 +86,7 @@ public class AnnotationTools { } return false; } - + public static String getFieldName(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class); if (annotation.length == 0) { @@ -94,13 +95,13 @@ public class AnnotationTools { if (annotation.length > 1) { throw new Exception("Must not have more than 1 element @Column on " + element.getClass().getCanonicalName()); } - String name = ((Column) annotation[0]).name(); + final String name = ((Column) annotation[0]).name(); if (name.isBlank()) { return element.getName(); } return name; } - + public static boolean getNotNull(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class); if (annotation.length == 0) { @@ -111,7 +112,7 @@ public class AnnotationTools { } return !((Column) annotation[0]).nullable(); } - + public static boolean isPrimaryKey(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(Column.class); if (annotation.length == 0) { @@ -122,7 +123,7 @@ public class AnnotationTools { } return ((Column) annotation[0]).unique(); } - + public static GenerationType getStrategy(final Field element) throws Exception { final Annotation[] annotation = element.getDeclaredAnnotationsByType(GeneratedValue.class); if (annotation.length == 0) { @@ -133,19 +134,27 @@ public class AnnotationTools { } return ((GeneratedValue) annotation[0]).strategy(); } - + public static boolean isDeletedField(final Field element) throws Exception { return element.getDeclaredAnnotationsByType(SQLDeleted.class).length != 0; } - public static boolean isUpdateField(final Field element) throws Exception { - return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0; + public static boolean isCreatedAtField(final Field element) throws Exception { + return element.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0; } + public static boolean isUpdateAtField(final Field element) throws Exception { + return element.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0; + } + public static boolean isdefaultNotRead(final Field element) throws Exception { return element.getDeclaredAnnotationsByType(SQLNotRead.class).length != 0; } - + + public static boolean isIdField(final Field element) throws Exception { + return element.getDeclaredAnnotationsByType(Id.class).length != 0; + } + public static String getDeletedFieldName(final Class clazz) throws Exception { try { for (final Field elem : clazz.getFields()) { @@ -162,7 +171,7 @@ public class AnnotationTools { } return null; } - + public static String getUpdatedFieldName(final Class clazz) throws Exception { try { for (final Field elem : clazz.getFields()) { @@ -170,7 +179,7 @@ public class AnnotationTools { if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { continue; } - if (AnnotationTools.isUpdateField(elem)) { + if (AnnotationTools.isUpdateAtField(elem)) { return AnnotationTools.getFieldName(elem); } } @@ -179,5 +188,22 @@ public class AnnotationTools { } return null; } - + + public static Field getIdField(final Class clazz) { + try { + for (final Field elem : clazz.getFields()) { + // static field is only for internal global declaration ==> remove it .. + if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { + continue; + } + if (AnnotationTools.isIdField(elem)) { + return elem; + } + } + } catch (final Exception ex) { + ex.printStackTrace(); + } + return null; + } + } diff --git a/src/org/kar/archidata/api/DataResource.java b/src/org/kar/archidata/api/DataResource.java index 8db3e2a..777f4e6 100644 --- a/src/org/kar/archidata/api/DataResource.java +++ b/src/org/kar/archidata/api/DataResource.java @@ -23,10 +23,10 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import org.kar.archidata.annotation.security.PermitTokenInURI; import org.kar.archidata.annotation.security.RolesAllowed; +import org.kar.archidata.dataAccess.QueryCondition; +import org.kar.archidata.dataAccess.DataAccess; import org.kar.archidata.filter.GenericContext; import org.kar.archidata.model.Data; -import org.kar.archidata.sqlWrapper.QuerryCondition; -import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -96,7 +96,7 @@ public class DataResource { public static Data getWithSha512(String sha512) { LOGGER.info("find sha512 = {}", sha512); try { - return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512)); + return DataAccess.getWhere(Data.class, new QueryCondition("sha512", "=", sha512)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -107,7 +107,7 @@ public class DataResource { public static Data getWithId(long id) { LOGGER.info("find id = {}", id); try { - return SqlWrapper.get(Data.class, id); + return DataAccess.get(Data.class, id); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -149,7 +149,7 @@ public class DataResource { injectedData.size = Files.size(Paths.get(tmpPath)); try { - injectedData = SqlWrapper.insert(injectedData); + injectedData = DataAccess.insert(injectedData); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -223,7 +223,7 @@ public class DataResource { public Data getSmall(Long id) { try { - return SqlWrapper.get(Data.class, id); + return DataAccess.get(Data.class, id); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -417,7 +417,7 @@ public class DataResource { } public static void undelete(Long id) throws Exception { - SqlWrapper.unsetDelete(Data.class, id); + DataAccess.unsetDelete(Data.class, id); } } diff --git a/src/org/kar/archidata/sqlWrapper/SqlWrapper.java b/src/org/kar/archidata/dataAccess/DataAccess.java similarity index 64% rename from src/org/kar/archidata/sqlWrapper/SqlWrapper.java rename to src/org/kar/archidata/dataAccess/DataAccess.java index 4114ca7..c3a38fc 100644 --- a/src/org/kar/archidata/sqlWrapper/SqlWrapper.java +++ b/src/org/kar/archidata/dataAccess/DataAccess.java @@ -1,46 +1,47 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.io.IOException; -import java.lang.reflect.Field; -import java.sql.Date; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; import java.sql.Types; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.Date; +import org.aopalliance.reflect.Class; +import org.glassfish.jaxb.runtime.v2.schemagen.xmlschema.List; import org.kar.archidata.GlobalConfiguration; import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.CreationTimestamp; import org.kar.archidata.annotation.DataAddOn; import org.kar.archidata.annotation.SQLDefault; -import org.kar.archidata.annotation.SQLIfNotExists; import org.kar.archidata.annotation.UpdateTimestamp; +import org.kar.archidata.dataAccess.addOn.AddOnManyToMany; +import org.kar.archidata.dataAccess.addOn.AddOnManyToOne; +import org.kar.archidata.dataAccess.addOn.AddOnSQLTableExternalForeinKeyAsList; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany; -import org.kar.archidata.sqlWrapper.addOn.AddOnManyToOne; -import org.kar.archidata.sqlWrapper.addOn.AddOnSQLTableExternalForeinKeyAsList; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.protobuf.Timestamp; +import com.mysql.cj.x.protobuf.MysqlxDatatypes.Scalar.String; +import com.mysql.cj.xdevapi.Statement; -import jakarta.persistence.GenerationType; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.ws.rs.InternalServerErrorException; +import javassist.bytecode.Descriptor.Iterator; -public class SqlWrapper { - static final Logger LOGGER = LoggerFactory.getLogger(SqlWrapper.class); - static final List addOn = new ArrayList<>(); +public class DataAccess { + static final Logger LOGGER = LoggerFactory.getLogger(DataAccess.class); + static final List addOn = new ArrayList<>(); static { addOn.add(new AddOnManyToMany()); @@ -48,8 +49,8 @@ public class SqlWrapper { addOn.add(new AddOnSQLTableExternalForeinKeyAsList()); } - public static void addAddOn(final SqlWrapperAddOn addOn) { - SqlWrapper.addOn.add(addOn); + public static void addAddOn(final DataAccessAddOn addOn) { + DataAccess.addOn.add(addOn); } public static class ExceptionDBInterface extends Exception { @@ -62,7 +63,7 @@ public class SqlWrapper { } } - public SqlWrapper() { + public DataAccess() { } @@ -115,7 +116,7 @@ public class SqlWrapper { return true; } try { - return 1 == SqlWrapper.executeSimpleQuerry("CREATE DATABASE `" + name + "`;", true); + return 1 == DataAccess.executeSimpleQuerry("CREATE DATABASE `" + name + "`;", true); } catch (final SQLException | IOException ex) { ex.printStackTrace(); LOGGER.error("Can not check if the DB exist!!! {}", ex.getMessage()); @@ -170,77 +171,21 @@ public class SqlWrapper { * @return The list of Long value * @throws SQLException if an error is generated in the sql request. */ - public static List getListOfIds(ResultSet rs, int iii, String separator) throws SQLException { - String trackString = rs.getString(iii); + public static List getListOfIds(final ResultSet rs, final int iii, final String separator) throws SQLException { + final String trackString = rs.getString(iii); if (rs.wasNull()) { return null; } - List out = new ArrayList<>(); - String[] elements = trackString.split("-"); - for (String elem : elements) { - Long tmp = Long.parseLong(elem); + final List out = new ArrayList<>(); + final String[] elements = trackString.split("-"); + for (final String elem : elements) { + final Long tmp = Long.parseLong(elem); out.add(tmp); } return out; } - public static String convertTypeInSQL(final Class type) throws Exception { - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - if (type == Long.class || type == long.class) { - return "bigint"; - } - if (type == Integer.class || type == int.class) { - return "int"; - } - if (type == Boolean.class || type == boolean.class) { - return "tinyint(1)"; - } - if (type == Float.class || type == float.class) { - return "float"; - } - if (type == Double.class || type == double.class) { - return "double"; - } - if (type == Timestamp.class) { - return "timestamp(3)"; - } - if (type == Date.class) { - return "date"; - } - if (type == String.class) { - return "text"; - } - } else { - if (type == Long.class || type == long.class) { - return "INTEGER"; - } - if (type == Integer.class || type == int.class) { - return "INTEGER"; - } - if (type == Boolean.class || type == boolean.class) { - return "INTEGER"; - } - if (type == Float.class || type == float.class) { - return "REAL"; - } - if (type == Double.class || type == double.class) { - return "REAL"; - } - if (type == Timestamp.class) { - return "DATETIME"; - } - if (type == Date.class) { - return "DATETIME"; - } - if (type == String.class) { - return "text"; - } - } - throw new Exception("Imcompatible type of element in object for: " + type.getCanonicalName()); - } - - protected static void setValuedb(final Class type, final T data, int index, final Field field, final PreparedStatement ps) - throws IllegalArgumentException, IllegalAccessException, SQLException { + protected static void setValuedb(final Class type, final T data, int index, final Field field, final PreparedStatement ps) throws Exception { if (type == Long.class) { final Object tmp = field.get(data); if (tmp == null) { @@ -298,7 +243,24 @@ public class SqlWrapper { if (tmp == null) { ps.setNull(index++, Types.INTEGER); } else { - ps.setDate(index++, (Date) tmp); + final Timestamp sqlDate = java.sql.Timestamp.from(((Date) tmp).toInstant()); + ps.setTimestamp(index++, sqlDate); + } + } else if (type == LocalDate.class) { + final Object tmp = field.get(data); + if (tmp == null) { + ps.setNull(index++, Types.INTEGER); + } else { + final java.sql.Date sqlDate = java.sql.Date.valueOf((LocalDate) tmp); + ps.setDate(index++, sqlDate); + } + } else if (type == LocalTime.class) { + final Object tmp = field.get(data); + if (tmp == null) { + ps.setNull(index++, Types.INTEGER); + } else { + final java.sql.Time sqlDate = java.sql.Time.valueOf((LocalTime) tmp); + ps.setTime(index++, sqlDate); } } else if (type == String.class) { final Object tmp = field.get(data); @@ -307,11 +269,20 @@ public class SqlWrapper { } else { ps.setString(index++, (String) tmp); } + } else if (type.isEnum()) { + final Object tmp = field.get(data); + if (tmp == null) { + ps.setNull(index++, Types.VARCHAR); + } else { + ps.setString(index++, tmp.toString()); + } + } else { + throw new Exception("Unknown Field Type"); } } - - protected static void setValueFromDb(final Class type, final T data, final int index, final Field field, final ResultSet rs) - throws IllegalArgumentException, IllegalAccessException, SQLException { + + // TODO: maybe wrap this if the use of sqlite ==> maybe some problems came with sqlite ... + protected static void setValueFromDb(final Class type, final T data, final int index, final Field field, final ResultSet rs) throws Exception { if (type == Long.class) { final Long tmp = rs.getLong(index); if (rs.wasNull()) { @@ -384,34 +355,33 @@ public class SqlWrapper { field.setBoolean(data, tmp); } } else if (type == Timestamp.class) { - try { - final Timestamp tmp = rs.getTimestamp(index); - if (rs.wasNull()) { - field.set(data, null); - } else { - field.set(data, tmp); - } - } catch (java.sql.SQLException ex) { - try { - final Date tmp = rs.getDate(index); - if (rs.wasNull()) { - - field.set(data, null); - } else { - field.set(data, new Timestamp(tmp.toInstant().toEpochMilli())); - } - } catch (java.sql.SQLException ex2) { - final String tmp = rs.getString(index); - LOGGER.error("plop {}", tmp); - } - } - } else if (type == Date.class) { - final Date tmp = rs.getDate(index); + final Timestamp tmp = rs.getTimestamp(index); if (rs.wasNull()) { field.set(data, null); } else { field.set(data, tmp); } + } else if (type == Date.class) { + final Timestamp tmp = rs.getTimestamp(index); + if (rs.wasNull()) { + field.set(data, null); + } else { + field.set(data, Date.from(tmp.toInstant())); + } + } else if (type == LocalDate.class) { + final java.sql.Date tmp = rs.getDate(index); + if (rs.wasNull()) { + field.set(data, null); + } else { + field.set(data, tmp.toLocalDate()); + } + } else if (type == LocalTime.class) { + final java.sql.Time tmp = rs.getTime(index); + if (rs.wasNull()) { + field.set(data, null); + } else { + field.set(data, tmp.toLocalTime()); + } } else if (type == String.class) { final String tmp = rs.getString(index); if (rs.wasNull()) { @@ -419,11 +389,27 @@ public class SqlWrapper { } else { field.set(data, tmp); } + } else if (type.isEnum()) { + final String tmp = rs.getString(index); + if (rs.wasNull()) { + field.set(data, null); + } else { + final Object[] arr = type.getEnumConstants(); + for (final Object elem : arr) { + if (elem.toString().equals(tmp)) { + field.set(data, elem); + break; + } + } + // TODO: maybe do something stupid if not exist ??? + } + } else { + throw new Exception("Unknown Field Type"); } } public static boolean isAddOnField(final Field field) { - boolean ret = AnnotationTools.isAnnotationGroup(field, DataAddOn.class); + final boolean ret = AnnotationTools.isAnnotationGroup(field, DataAddOn.class); if (ret) { return true; } @@ -437,8 +423,8 @@ public class SqlWrapper { return ret; } - public static SqlWrapperAddOn findAddOnforField(final Field field) { - for (final SqlWrapperAddOn elem : addOn) { + public static DataAccessAddOn findAddOnforField(final Field field) { + for (final DataAccessAddOn elem : addOn) { if (elem.isCompatibleField(field)) { return elem; } @@ -470,7 +456,7 @@ public class SqlWrapper { if (AnnotationTools.isPrimaryKey(elem)) { continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && addOn.isExternal()) { continue; } @@ -524,7 +510,7 @@ public class SqlWrapper { primaryKeyField = elem; continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && addOn.isExternal()) { continue; } @@ -599,7 +585,22 @@ public class SqlWrapper { return insert(data); } - public static int update(final Class clazz, final long id, final String jsonData) throws Exception { + public static int updateWithJson(final Class clazz, final ID_TYPE id, final String jsonData) throws Exception { + // Find the ID field type .... + final Field idField = AnnotationTools.getIdField(clazz); + if (idField == null) { + throw new Exception("The class have no annotation @Id ==> can not determine the default type searching"); + } + // check the compatibility of the id and the declared ID + if (id instanceof idField.getType()) { + throw new Exception("Request update with the wriong type ..."); + } + + // Udpade Json Value + return updateWithJson(clazz, QueryCondition(AnnotationTools.getFieldName(idField), "=", id), jsonData); + } + + public static int updateWithJson(final Class clazz, final QueryItem condition, final String jsonData) throws Exception { final ObjectMapper mapper = new ObjectMapper(); // parse the object to be sure the data are valid: final T data = mapper.readValue(jsonData, clazz); @@ -609,8 +610,14 @@ public class SqlWrapper { final Iterator iterator = root.fieldNames(); iterator.forEachRemaining(e -> keys.add(e)); return update(data, id, keys); + return 0; } - + + public static int update(final T data, final QueryItem condition) throws Exception { + + return 0; + } + /** * * @param @@ -645,16 +652,16 @@ public class SqlWrapper { primaryKeyField = elem; continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && addOn.isExternal()) { continue; } - final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0; + final boolean createTime = AnnotationTools.isCreatedAtField(elem); if (createTime) { continue; } final String name = AnnotationTools.getFieldName(elem); - final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0; + final boolean updateTime = AnnotationTools.isUpdateAtField(elem); if (!updateTime && !filterValue.contains(name)) { continue; } @@ -695,7 +702,7 @@ public class SqlWrapper { if (AnnotationTools.isPrimaryKey(elem)) { continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && !addOn.canUpdate()) { continue; } @@ -733,44 +740,48 @@ public class SqlWrapper { } static void addElement(final PreparedStatement ps, final Object value, final int iii) throws Exception { - if (value.getClass() == Long.class) { - ps.setLong(iii, (Long) value); - } else if (value.getClass() == Integer.class) { - ps.setInt(iii, (Integer) value); - } else if (value.getClass() == String.class) { - ps.setString(iii, (String) value); - } else if (value.getClass() == Short.class) { - ps.setShort(iii, (Short) value); - } else if (value.getClass() == Byte.class) { - ps.setByte(iii, (Byte) value); - } else if (value.getClass() == Float.class) { - ps.setFloat(iii, (Float) value); - } else if (value.getClass() == Double.class) { - ps.setDouble(iii, (Double) value); - } else if (value.getClass() == Boolean.class) { - ps.setBoolean(iii, (Boolean) value); - } else if (value.getClass() == Boolean.class) { - ps.setBoolean(iii, (Boolean) value); - } else if (value.getClass() == Timestamp.class) { - ps.setTimestamp(iii, (Timestamp) value); - } else if (value.getClass() == Date.class) { - ps.setDate(iii, (Date) value); + if (value instanceof final Long tmp) { + ps.setLong(iii, tmp); + } else if (value instanceof final Integer tmp) { + ps.setInt(iii, tmp); + } else if (value instanceof final String tmp) { + ps.setString(iii, tmp); + } else if (value instanceof final Short tmp) { + ps.setShort(iii, tmp); + } else if (value instanceof final Byte tmp) { + ps.setByte(iii, tmp); + } else if (value instanceof final Float tmp) { + ps.setFloat(iii, tmp); + } else if (value instanceof final Double tmp) { + ps.setDouble(iii, tmp); + } else if (value instanceof final Boolean tmp) { + ps.setBoolean(iii, tmp); + } else if (value instanceof final Boolean tmp) { + ps.setBoolean(iii, tmp); + } else if (value instanceof final Timestamp tmp) { + ps.setTimestamp(iii, tmp); + } else if (value instanceof final Date tmp) { + ps.setTimestamp(iii, java.sql.Timestamp.from((tmp).toInstant())); + } else if (value instanceof final LocalDate tmp) { + ps.setDate(iii, java.sql.Date.valueOf(tmp)); + } else if (value instanceof final LocalTime tmp) { + ps.setTime(iii, java.sql.Time.valueOf(tmp)); + } else if (value.getClass().isEnum()) { + ps.setString(iii, value.toString()); } else { throw new Exception("Not manage type ==> need to add it ..."); } } - public static void whereAppendQuery(final StringBuilder querry, final String tableName, final QuerryItem condition, final QuerryOptions options, String deletedFieldName) + public static void whereAppendQuery(final StringBuilder querry, final String tableName, final QueryItem condition, final QueryOptions options, final String deletedFieldName) throws ExceptionDBInterface { boolean exclude_deleted = true; if (options != null) { - Object data = options.get(QuerryOptions.SQL_DELETED_DISABLE); - if (data instanceof Boolean elem) { + final Object data = options.get(QueryOptions.SQL_DELETED_DISABLE); + if (data instanceof final Boolean elem) { exclude_deleted = !elem; - } else { - if (data != null) { - LOGGER.error("'{}' ==> has not a boolean value: {}", QuerryOptions.SQL_DELETED_DISABLE, data); - } + } else if (data != null) { + LOGGER.error("'{}' ==> has not a boolean value: {}", QueryOptions.SQL_DELETED_DISABLE, data); } } // Check if we have a condition to generate @@ -797,7 +808,7 @@ public class SqlWrapper { } } - public static void whereInjectValue(final PreparedStatement ps, final QuerryItem condition) throws Exception { + public static void whereInjectValue(final PreparedStatement ps, final QueryItem condition) throws Exception { // Check if we have a condition to generate if (condition == null) { return; @@ -826,11 +837,11 @@ public class SqlWrapper { return executeQuerry(querry, false); } - public static T getWhere(final Class clazz, final QuerryItem condition) throws Exception { + public static T getWhere(final Class clazz, final QueryItem condition) throws Exception { return getWhere(clazz, condition, null); } - public static T getWhere(final Class clazz, final QuerryItem condition, final QuerryOptions options) throws Exception { + public static T getWhere(final Class clazz, final QueryItem condition, final QueryOptions options) throws Exception { final List values = getsWhere(clazz, condition, options, 1); if (values.size() == 0) { return null; @@ -838,31 +849,29 @@ public class SqlWrapper { return values.get(0); } - public static List getsWhere(final Class clazz, final QuerryItem condition) throws Exception { + public static List getsWhere(final Class clazz, final QueryItem condition) throws Exception { return getsWhere(clazz, condition, null, null, null); } - public static List getsWhere(final Class clazz, final QuerryItem condition, final QuerryOptions options) throws Exception { + public static List getsWhere(final Class clazz, final QueryItem condition, final QueryOptions options) throws Exception { return getsWhere(clazz, condition, null, options, null); } - public static List getsWhere(final Class clazz, final QuerryItem condition, final QuerryOptions options, final Integer linit) throws Exception { + public static List getsWhere(final Class clazz, final QueryItem condition, final QueryOptions options, final Integer linit) throws Exception { return getsWhere(clazz, condition, null, options, linit); } // TODO: set limit as an querry Option... @SuppressWarnings("unchecked") - public static List getsWhere(final Class clazz, final QuerryItem condition, final String orderBy, final QuerryOptions options, final Integer linit) throws Exception { + public static List getsWhere(final Class clazz, final QueryItem condition, final String orderBy, final QueryOptions options, final Integer linit) throws Exception { boolean readAllfields = false; if (options != null) { - Object data = options.get(QuerryOptions.SQL_NOT_READ_DISABLE); - if (data instanceof Boolean elem) { + final Object data = options.get(QueryOptions.SQL_NOT_READ_DISABLE); + if (data instanceof final Boolean elem) { readAllfields = elem; - } else { - if (data != null) { - LOGGER.error("'{}' ==> has not a boolean value: {}", QuerryOptions.SQL_NOT_READ_DISABLE, data); - } + } else if (data != null) { + LOGGER.error("'{}' ==> has not a boolean value: {}", QueryOptions.SQL_NOT_READ_DISABLE, data); } } @@ -885,7 +894,7 @@ public class SqlWrapper { if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && addOn.isExternal()) { continue; } @@ -939,7 +948,7 @@ public class SqlWrapper { if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { continue; } - final SqlWrapperAddOn addOn = findAddOnforField(elem); + final DataAccessAddOn addOn = findAddOnforField(elem); if (addOn != null && addOn.isExternal()) { continue; } @@ -949,7 +958,7 @@ public class SqlWrapper { continue; } if (addOn != null) { - int nbRowRead = addOn.fillFromQuerry(rs, elem, data, count, options); + final int nbRowRead = addOn.fillFromQuerry(rs, elem, data, count, options); count += nbRowRead; } else { setValueFromDb(elem.getType(), data, count, elem, rs); @@ -977,7 +986,7 @@ public class SqlWrapper { return get(clazz, id, null); } - public static T get(final Class clazz, final long id, final QuerryOptions options) throws Exception { + public static T get(final Class clazz, final long id, final QueryOptions options) throws Exception { Field primaryKeyField = null; for (final Field elem : clazz.getFields()) { // static field is only for internal global declaration ==> remove it .. @@ -989,7 +998,7 @@ public class SqlWrapper { } } if (primaryKeyField != null) { - return SqlWrapper.getWhere(clazz, new QuerryCondition(AnnotationTools.getFieldName(primaryKeyField), "=", id), options); + return DataAccess.getWhere(clazz, new QueryCondition(AnnotationTools.getFieldName(primaryKeyField), "=", id), options); } throw new Exception("Missing primary Key..."); } @@ -1002,13 +1011,13 @@ public class SqlWrapper { return getsWhere(clazz, null); } - public static List gets(final Class clazz, final QuerryOptions options) throws Exception { + public static List gets(final Class clazz, final QueryOptions options) throws Exception { return getsWhere(clazz, null, options); } // TODO : detect the @Id public static int delete(final Class clazz, final long id) throws Exception { - String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz); + final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz); if (hasDeletedFieldName != null) { return deleteSoft(clazz, id); } else { @@ -1016,8 +1025,8 @@ public class SqlWrapper { } } - public static int delete(final Class clazz, final QuerryItem condition) throws Exception { - String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz); + public static int deleteWhere(final Class clazz, final QueryItem condition) throws Exception { + final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz); if (hasDeletedFieldName != null) { return deleteSoftWhere(clazz, condition); } else { @@ -1026,10 +1035,10 @@ public class SqlWrapper { } public static int deleteHard(final Class clazz, final long id) throws Exception { - return deleteHardWhere(clazz, new QuerryCondition("id", "=", id)); + return deleteHardWhere(clazz, new QueryCondition("id", "=", id)); } - public static int deleteHardWhere(final Class clazz, final QuerryItem condition) throws Exception { + public static int deleteHardWhere(final Class clazz, final QueryItem condition) throws Exception { final String tableName = AnnotationTools.getTableName(clazz); final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz); // find the deleted field @@ -1052,7 +1061,7 @@ public class SqlWrapper { } private static int deleteSoft(final Class clazz, final long id) throws Exception { - return deleteSoftWhere(clazz, new QuerryCondition("id", "=", id)); + return deleteSoftWhere(clazz, new QueryCondition("id", "=", id)); } public static String getDBNow() { @@ -1062,7 +1071,7 @@ public class SqlWrapper { return "DATE()"; } - public static int deleteSoftWhere(final Class clazz, final QuerryItem condition) throws Exception { + public static int deleteSoftWhere(final Class clazz, final QueryItem condition) throws Exception { final String tableName = AnnotationTools.getTableName(clazz); final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz); /* @@ -1102,10 +1111,10 @@ public class SqlWrapper { } public static int unsetDelete(final Class clazz, final long id) throws Exception { - return unsetDeleteWhere(clazz, new QuerryCondition("id", "=", id)); + return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id)); } - public static int unsetDeleteWhere(final Class clazz, final QuerryItem condition) throws Exception { + public static int unsetDeleteWhere(final Class clazz, final QueryItem condition) throws Exception { final String tableName = AnnotationTools.getTableName(clazz); final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz); if (deletedFieldName == null) { @@ -1125,7 +1134,7 @@ public class SqlWrapper { querry.append(", "); */ // need to disable the deleted false because the model must be unselected to be updated. - QuerryOptions options = new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true); + final QueryOptions options = new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true); whereAppendQuery(querry, tableName, condition, options, deletedFieldName); try { final PreparedStatement ps = entry.connection.prepareStatement(querry.toString()); @@ -1136,266 +1145,5 @@ public class SqlWrapper { entry = null; } } - - public static List createTable(final Class clazz) throws Exception { - return createTable(clazz, true); - } - - private static boolean isFieldFromSuperClass(Class model, String filedName) { - Class superClass = model.getSuperclass(); - if (superClass == null) { - return false; - } - for (Field field : superClass.getFields()) { - String name; - try { - name = AnnotationTools.getFieldName(field); - if (filedName.equals(name)) { - return true; - } - } catch (Exception e) { - // TODO Auto-generated catch block - LOGGER.trace("Catch error field name in parent create data table: {}", e.getMessage()); - } - } - return false; - } - - public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List preOtherTables, final List postOtherTables, - final boolean createIfNotExist, final boolean createDrop, final int fieldId, final Class classModel) throws Exception { - final String name = AnnotationTools.getFieldName(elem); - final Integer limitSize = AnnotationTools.getLimitSize(elem); - final boolean notNull = AnnotationTools.getNotNull(elem); - - final boolean primaryKey = AnnotationTools.isPrimaryKey(elem); - final GenerationType strategy = AnnotationTools.getStrategy(elem); - - final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0; - final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0; - final String comment = AnnotationTools.getComment(elem); - final String defaultValue = AnnotationTools.getDefault(elem); - - if (fieldId == 0) { - mainTableBuilder.append("\n\t\t`"); - } else { - mainTableBuilder.append(",\n\t\t`"); - } - mainTableBuilder.append(name); - mainTableBuilder.append("` "); - String typeValue = null; - typeValue = convertTypeInSQL(classModel); - if ("text".equals(typeValue) && !"sqlite".equals(ConfigBaseVariable.getDBType())) { - if (limitSize != null) { - mainTableBuilder.append("varchar("); - mainTableBuilder.append(limitSize); - mainTableBuilder.append(")"); - } else { - mainTableBuilder.append("text"); - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append(" CHARACTER SET utf8"); - } - } - } else { - mainTableBuilder.append(typeValue); - } - mainTableBuilder.append(" "); - if (notNull) { - if (!primaryKey || !"sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("NOT NULL "); - } - if (defaultValue == null) { - if (updateTime || createTime) { - mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP"); - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("(3)"); - } - mainTableBuilder.append(" "); - } - if (updateTime) { - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP"); - mainTableBuilder.append("(3)"); - } else { - // TODO: add trigger: - /* - CREATE TRIGGER your_table_trig AFTER UPDATE ON your_table - BEGIN - update your_table SET updated_on = datetime('now') WHERE user_id = NEW.user_id; - END; - */ - StringBuilder triggerBuilder = new StringBuilder(); - triggerBuilder.append("CREATE TRIGGER "); - triggerBuilder.append(tableName); - triggerBuilder.append("_update_trigger AFTER UPDATE ON "); - triggerBuilder.append(tableName); - triggerBuilder.append(" \nBEGIN \n update "); - triggerBuilder.append(tableName); - triggerBuilder.append(" SET "); - triggerBuilder.append(name); - triggerBuilder.append(" = datetime('now') WHERE id = NEW.id; \n"); - triggerBuilder.append("END;"); - - postOtherTables.add(triggerBuilder.toString()); - } - - mainTableBuilder.append(" "); - } - } else { - mainTableBuilder.append("DEFAULT "); - if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && "sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("CURRENT_TIMESTAMP"); - } else { - mainTableBuilder.append(defaultValue); - } - mainTableBuilder.append(" "); - if (updateTime) { - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP"); - mainTableBuilder.append("(3)"); - } - mainTableBuilder.append(" "); - } - } - } else if (defaultValue == null) { - if (updateTime || createTime) { - if ("sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP "); - } else { - mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP(3) "); - } - } else if (primaryKey) { - mainTableBuilder.append("NOT NULL "); - } else { - mainTableBuilder.append("DEFAULT NULL "); - } - } else { - mainTableBuilder.append("DEFAULT "); - mainTableBuilder.append(defaultValue); - mainTableBuilder.append(" "); - - } - if (primaryKey && "sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("PRIMARY KEY "); - - } - if (strategy == GenerationType.IDENTITY) { - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("AUTO_INCREMENT "); - } else { - mainTableBuilder.append("AUTOINCREMENT "); - } - } else if (strategy != null) { - throw new Exception("Can not generate a stategy different of IDENTITY"); - } - - if (comment != null && !"sqlite".equals(ConfigBaseVariable.getDBType())) { - mainTableBuilder.append("COMMENT '"); - mainTableBuilder.append(comment.replace('\'', '\'')); - mainTableBuilder.append("' "); - } - } - - public static List createTable(final Class clazz, final boolean createDrop) throws Exception { - final String tableName = AnnotationTools.getTableName(clazz); - final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0; - final List preActionList = new ArrayList<>(); - final List postActionList = new ArrayList<>(); - final StringBuilder out = new StringBuilder(); - // Drop Table - if (createIfNotExist && createDrop) { - final StringBuilder tableTmp = new StringBuilder(); - tableTmp.append("DROP TABLE IF EXISTS `"); - tableTmp.append(tableName); - tableTmp.append("`;"); - postActionList.add(tableTmp.toString()); - } - // create Table: - out.append("CREATE TABLE `"); - out.append(tableName); - out.append("` ("); - int fieldId = 0; - LOGGER.debug("===> TABLE `{}`", tableName); - final List primaryKeys = new ArrayList<>(); - - for (final Field elem : clazz.getFields()) { - // DEtect the primary key (support only one primary key right now... - if (AnnotationTools.isPrimaryKey(elem)) { - primaryKeys.add(AnnotationTools.getFieldName(elem)); - } - } - // Here we insert the data in the reverse mode ==> the parent class add there parameter at the start (we reorder the field with the parenting). - StringBuilder tmpOut = new StringBuilder(); - StringBuilder reverseOut = new StringBuilder(); - List alreadyAdded = new ArrayList<>(); - Class currentClazz = clazz; - while (currentClazz != null) { - fieldId = 0; - LOGGER.info("parse class: '{}'", currentClazz.getCanonicalName()); - for (final Field elem : clazz.getFields()) { - // static field is only for internal global declaration ==> remove it .. - if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { - continue; - } - final String dataName = AnnotationTools.getFieldName(elem); - if (isFieldFromSuperClass(currentClazz, dataName)) { - LOGGER.trace(" SKIP: '{}'", elem.getName()); - continue; - } - if (alreadyAdded.contains(dataName)) { - LOGGER.trace(" SKIP2: '{}'", elem.getName()); - continue; - } - alreadyAdded.add(dataName); - LOGGER.info(" + '{}'", elem.getName()); - if (isAddOnField(elem)) { - final SqlWrapperAddOn addOn = findAddOnforField(elem); - LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType()); - if (addOn != null) { - addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId); - } else { - throw new Exception( - "Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType()); - } - } else { - LOGGER.info("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType()); - SqlWrapper.createTablesSpecificType(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType()); - } - fieldId++; - } - boolean dataInThisObject = tmpOut.toString().length() > 0; - if (dataInThisObject) { - boolean dataInPreviousObject = reverseOut.toString().length() > 0; - if (dataInPreviousObject) { - tmpOut.append(", "); - tmpOut.append(reverseOut.toString()); - } - reverseOut = tmpOut; - tmpOut = new StringBuilder(); - } - currentClazz = currentClazz.getSuperclass(); - if (currentClazz == Object.class) { - break; - } - } - out.append(reverseOut.toString()); - if (primaryKeys.size() != 0 && !"sqlite".equals(ConfigBaseVariable.getDBType())) { - out.append(",\n\tPRIMARY KEY (`"); - for (int iii = 0; iii < primaryKeys.size(); iii++) { - if (iii != 0) { - out.append(","); - } - out.append(primaryKeys.get(iii)); - } - out.append("`)"); - } - out.append("\n\t)"); - if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { - out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci"); - } - out.append(";"); - preActionList.add(out.toString()); - preActionList.addAll(postActionList); - return preActionList; - } - + } \ No newline at end of file diff --git a/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java b/src/org/kar/archidata/dataAccess/DataAccessAddOn.java similarity index 87% rename from src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java rename to src/org/kar/archidata/dataAccess/DataAccessAddOn.java index b0bcf98..0ec2600 100644 --- a/src/org/kar/archidata/sqlWrapper/SqlWrapperAddOn.java +++ b/src/org/kar/archidata/dataAccess/DataAccessAddOn.java @@ -1,4 +1,4 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.lang.reflect.Field; import java.sql.PreparedStatement; @@ -8,27 +8,27 @@ import java.util.List; import jakarta.validation.constraints.NotNull; -public interface SqlWrapperAddOn { +public interface DataAccessAddOn { /** * Get the Class of the declaration annotation * @return The annotation class */ Class getAnnotationClass(); - + /** * Get the SQL type that is needed to declare for the specific Field Type. * @param elem Field to declare. * @return SQL type to create. */ - String getSQLFieldType(Field elem); - + String getSQLFieldType(Field elem) throws Exception; + /** * Check if the field is manage by the local add-on * @param elem Field to inspect. * @return True of the field is manage by the current Add-on. */ boolean isCompatibleField(Field elem); - + /** * Insert data in the specific field (the field must be in the current db, otherwiise it does not work at all. * @param ps DB statement interface. @@ -38,17 +38,17 @@ public interface SqlWrapperAddOn { * @throws SQLException */ int insertData(PreparedStatement ps, Object data, int iii) throws SQLException; - + // External mean that the type of the object is absolutely not obvious... boolean isExternal(); - - int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QuerryOptions options); - + + int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QueryOptions options); + // Return the number of colomn read - int fillFromQuerry(ResultSet rs, Field elem, Object data, int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException; - + int fillFromQuerry(ResultSet rs, Field elem, Object data, int count, QueryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException; + boolean canUpdate(); - + /** * Create associated table of the specific element. * @param tableName @@ -62,5 +62,5 @@ public interface SqlWrapperAddOn { */ void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List preActionList, List postActionList, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception; - + } diff --git a/src/org/kar/archidata/dataAccess/DataFactory.java b/src/org/kar/archidata/dataAccess/DataFactory.java new file mode 100644 index 0000000..10a2be7 --- /dev/null +++ b/src/org/kar/archidata/dataAccess/DataFactory.java @@ -0,0 +1,382 @@ +package org.kar.archidata.dataAccess; + +import java.lang.reflect.Field; +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.kar.archidata.annotation.AnnotationTools; +import org.kar.archidata.annotation.CreationTimestamp; +import org.kar.archidata.annotation.SQLIfNotExists; +import org.kar.archidata.annotation.UpdateTimestamp; +import org.kar.archidata.util.ConfigBaseVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.persistence.GenerationType; + +public class DataFactory { + static final Logger LOGGER = LoggerFactory.getLogger(DataFactory.class); + + public static String convertTypeInSQL(final Class type, final String fieldName) throws Exception { + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + if (type == Long.class || type == long.class) { + return "bigint"; + } + if (type == Integer.class || type == int.class) { + return "int"; + } + if (type == Boolean.class || type == boolean.class) { + return "tinyint(1)"; + } + if (type == Float.class || type == float.class) { + return "float"; + } + if (type == Double.class || type == double.class) { + return "double"; + } + if (type == Date.class || type == Timestamp.class) { + return "timestamp(3)"; + } + if (type == LocalDate.class) { + return "date"; + } + if (type == LocalTime.class) { + return "time"; + } + if (type == String.class) { + return "text"; + } + if (type.isEnum()) { + final Object[] arr = type.getEnumConstants(); + final StringBuilder out = new StringBuilder(); + out.append("ENUM("); + boolean first = true; + for (final Object elem : arr) { + if (!first) { + out.append(","); + } + first = false; + out.append("'"); + out.append(elem.toString()); + out.append("'"); + } + out.append(")"); + return out.toString(); + } + } else { + if (type == Long.class || type == long.class) { + return "INTEGER"; + } + if (type == Integer.class || type == int.class) { + return "INTEGER"; + } + if (type == Boolean.class || type == boolean.class) { + return "INTEGER"; + } + if (type == Float.class || type == float.class) { + return "REAL"; + } + if (type == Double.class || type == double.class) { + return "REAL"; + } + if (type == Date.class || type == Timestamp.class) { + return "DATETIME"; + } + if (type == LocalDate.class) { + return "DATE"; + } + if (type == LocalTime.class) { + return "TIME"; + } + if (type == String.class) { + return "text"; + } + if (type.isEnum()) { + final Object[] arr = type.getEnumConstants(); + final StringBuilder out = new StringBuilder(); + out.append("TEXT CHECK("); + out.append(fieldName); + out.append(" IN ("); + boolean first = true; + for (final Object elem : arr) { + if (!first) { + out.append(","); + } + first = false; + out.append("'"); + out.append(elem.toString()); + out.append("'"); + } + out.append(" ) )"); + return out.toString(); + } + } + throw new Exception("Imcompatible type of element in object for: " + type.getCanonicalName()); + } + + public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List preOtherTables, final List postOtherTables, + final boolean createIfNotExist, final boolean createDrop, final int fieldId, final Class classModel) throws Exception { + final String name = AnnotationTools.getFieldName(elem); + final Integer limitSize = AnnotationTools.getLimitSize(elem); + final boolean notNull = AnnotationTools.getNotNull(elem); + + final boolean primaryKey = AnnotationTools.isPrimaryKey(elem); + final GenerationType strategy = AnnotationTools.getStrategy(elem); + + final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0; + final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0; + final String comment = AnnotationTools.getComment(elem); + final String defaultValue = AnnotationTools.getDefault(elem); + + if (fieldId == 0) { + mainTableBuilder.append("\n\t\t`"); + } else { + mainTableBuilder.append(",\n\t\t`"); + } + mainTableBuilder.append(name); + mainTableBuilder.append("` "); + String typeValue = null; + typeValue = convertTypeInSQL(classModel, name); + if ("text".equals(typeValue) && !"sqlite".equals(ConfigBaseVariable.getDBType())) { + if (limitSize != null) { + mainTableBuilder.append("varchar("); + mainTableBuilder.append(limitSize); + mainTableBuilder.append(")"); + } else { + mainTableBuilder.append("text"); + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append(" CHARACTER SET utf8"); + } + } + } else { + mainTableBuilder.append(typeValue); + } + mainTableBuilder.append(" "); + if (notNull) { + if (!primaryKey || !"sqlite".equalsIgnoreCase(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("NOT NULL "); + } + if (defaultValue == null) { + if (updateTime || createTime) { + mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP"); + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("(3)"); + } + mainTableBuilder.append(" "); + } + if (updateTime) { + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP"); + mainTableBuilder.append("(3)"); + } else { + // TODO: add trigger: + /* + CREATE TRIGGER your_table_trig AFTER UPDATE ON your_table + BEGIN + update your_table SET updated_on = datetime('now') WHERE user_id = NEW.user_id; + END; + */ + final StringBuilder triggerBuilder = new StringBuilder(); + triggerBuilder.append("CREATE TRIGGER "); + triggerBuilder.append(tableName); + triggerBuilder.append("_update_trigger AFTER UPDATE ON "); + triggerBuilder.append(tableName); + triggerBuilder.append(" \nBEGIN \n update "); + triggerBuilder.append(tableName); + triggerBuilder.append(" SET "); + triggerBuilder.append(name); + triggerBuilder.append(" = datetime('now') WHERE id = NEW.id; \n"); + triggerBuilder.append("END;"); + + postOtherTables.add(triggerBuilder.toString()); + } + + mainTableBuilder.append(" "); + } + } else { + mainTableBuilder.append("DEFAULT "); + if ("CURRENT_TIMESTAMP(3)".equals(defaultValue) && "sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("CURRENT_TIMESTAMP"); + } else { + mainTableBuilder.append(defaultValue); + } + mainTableBuilder.append(" "); + if (updateTime) { + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("ON UPDATE CURRENT_TIMESTAMP"); + mainTableBuilder.append("(3)"); + } + mainTableBuilder.append(" "); + } + } + } else if (defaultValue == null) { + if (updateTime || createTime) { + if ("sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP "); + } else { + mainTableBuilder.append("DEFAULT CURRENT_TIMESTAMP(3) "); + } + } else if (primaryKey) { + mainTableBuilder.append("NOT NULL "); + } else { + mainTableBuilder.append("DEFAULT NULL "); + } + } else { + mainTableBuilder.append("DEFAULT "); + mainTableBuilder.append(defaultValue); + mainTableBuilder.append(" "); + + } + if (primaryKey && "sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("PRIMARY KEY "); + + } + if (strategy == GenerationType.IDENTITY) { + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("AUTO_INCREMENT "); + } else { + mainTableBuilder.append("AUTOINCREMENT "); + } + } else if (strategy != null) { + throw new Exception("Can not generate a stategy different of IDENTITY"); + } + + if (comment != null && !"sqlite".equals(ConfigBaseVariable.getDBType())) { + mainTableBuilder.append("COMMENT '"); + mainTableBuilder.append(comment.replace('\'', '\'')); + mainTableBuilder.append("' "); + } + } + + private static boolean isFieldFromSuperClass(final Class model, final String filedName) { + final Class superClass = model.getSuperclass(); + if (superClass == null) { + return false; + } + for (final Field field : superClass.getFields()) { + String name; + try { + name = AnnotationTools.getFieldName(field); + if (filedName.equals(name)) { + return true; + } + } catch (final Exception e) { + // TODO Auto-generated catch block + LOGGER.trace("Catch error field name in parent create data table: {}", e.getMessage()); + } + } + return false; + } + + public static List createTable(final Class clazz) throws Exception { + return createTable(clazz, true); + } + + public static List createTable(final Class clazz, final boolean createDrop) throws Exception { + final String tableName = AnnotationTools.getTableName(clazz); + final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0; + final List preActionList = new ArrayList<>(); + final List postActionList = new ArrayList<>(); + final StringBuilder out = new StringBuilder(); + // Drop Table + if (createIfNotExist && createDrop) { + final StringBuilder tableTmp = new StringBuilder(); + tableTmp.append("DROP TABLE IF EXISTS `"); + tableTmp.append(tableName); + tableTmp.append("`;"); + postActionList.add(tableTmp.toString()); + } + // create Table: + out.append("CREATE TABLE `"); + out.append(tableName); + out.append("` ("); + int fieldId = 0; + LOGGER.debug("===> TABLE `{}`", tableName); + final List primaryKeys = new ArrayList<>(); + + for (final Field elem : clazz.getFields()) { + // DEtect the primary key (support only one primary key right now... + if (AnnotationTools.isPrimaryKey(elem)) { + primaryKeys.add(AnnotationTools.getFieldName(elem)); + } + } + // Here we insert the data in the reverse mode ==> the parent class add there parameter at the start (we reorder the field with the parenting). + StringBuilder tmpOut = new StringBuilder(); + StringBuilder reverseOut = new StringBuilder(); + final List alreadyAdded = new ArrayList<>(); + Class currentClazz = clazz; + while (currentClazz != null) { + fieldId = 0; + LOGGER.info("parse class: '{}'", currentClazz.getCanonicalName()); + for (final Field elem : clazz.getFields()) { + // static field is only for internal global declaration ==> remove it .. + if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) { + continue; + } + final String dataName = AnnotationTools.getFieldName(elem); + if (isFieldFromSuperClass(currentClazz, dataName)) { + LOGGER.trace(" SKIP: '{}'", elem.getName()); + continue; + } + if (alreadyAdded.contains(dataName)) { + LOGGER.trace(" SKIP2: '{}'", elem.getName()); + continue; + } + alreadyAdded.add(dataName); + LOGGER.info(" + '{}'", elem.getName()); + if (DataAccess.isAddOnField(elem)) { + final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem); + LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType()); + if (addOn != null) { + addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId); + } else { + throw new Exception( + "Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType()); + } + } else { + LOGGER.info("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType()); + DataFactory.createTablesSpecificType(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType()); + } + fieldId++; + } + final boolean dataInThisObject = tmpOut.toString().length() > 0; + if (dataInThisObject) { + final boolean dataInPreviousObject = reverseOut.toString().length() > 0; + if (dataInPreviousObject) { + tmpOut.append(", "); + tmpOut.append(reverseOut.toString()); + } + reverseOut = tmpOut; + tmpOut = new StringBuilder(); + } + currentClazz = currentClazz.getSuperclass(); + if (currentClazz == Object.class) { + break; + } + } + out.append(reverseOut.toString()); + if (primaryKeys.size() != 0 && !"sqlite".equals(ConfigBaseVariable.getDBType())) { + out.append(",\n\tPRIMARY KEY (`"); + for (int iii = 0; iii < primaryKeys.size(); iii++) { + if (iii != 0) { + out.append(","); + } + out.append(primaryKeys.get(iii)); + } + out.append("`)"); + } + out.append("\n\t)"); + if (!"sqlite".equals(ConfigBaseVariable.getDBType())) { + out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci"); + } + out.append(";"); + preActionList.add(out.toString()); + preActionList.addAll(postActionList); + return preActionList; + } + +} \ No newline at end of file diff --git a/src/org/kar/archidata/sqlWrapper/Foreign.java b/src/org/kar/archidata/dataAccess/Foreign.java similarity index 88% rename from src/org/kar/archidata/sqlWrapper/Foreign.java rename to src/org/kar/archidata/dataAccess/Foreign.java index 1cf8d72..4d3cfb2 100644 --- a/src/org/kar/archidata/sqlWrapper/Foreign.java +++ b/src/org/kar/archidata/dataAccess/Foreign.java @@ -1,4 +1,4 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; // Mark as deprecated while the concept is not ready ... @Deprecated diff --git a/src/org/kar/archidata/sqlWrapper/QuerryAnd.java b/src/org/kar/archidata/dataAccess/QueryAnd.java similarity index 71% rename from src/org/kar/archidata/sqlWrapper/QuerryAnd.java rename to src/org/kar/archidata/dataAccess/QueryAnd.java index 5c82bf5..b745857 100644 --- a/src/org/kar/archidata/sqlWrapper/QuerryAnd.java +++ b/src/org/kar/archidata/dataAccess/QueryAnd.java @@ -1,17 +1,17 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.List; -public class QuerryAnd implements QuerryItem { - protected final List childs; +public class QueryAnd implements QueryItem { + protected final List childs; - public QuerryAnd(List childs) { + public QueryAnd(List childs) { this.childs = childs; } - public QuerryAnd(QuerryItem... items) { + public QueryAnd(QueryItem... items) { this.childs = new ArrayList<>(); for (int iii = 0; iii < items.length; iii++) { this.childs.add(items[iii]); @@ -23,7 +23,7 @@ public class QuerryAnd implements QuerryItem { querry.append(" ("); } boolean first = true; - for (QuerryItem elem : this.childs) { + for (QueryItem elem : this.childs) { if (first) { first = false; } else { @@ -39,7 +39,7 @@ public class QuerryAnd implements QuerryItem { @Override public int injectQuerry(PreparedStatement ps, int iii) throws Exception { - for (QuerryItem elem : this.childs) { + for (QueryItem elem : this.childs) { iii = elem.injectQuerry(ps, iii); } return iii; diff --git a/src/org/kar/archidata/sqlWrapper/QuerryCondition.java b/src/org/kar/archidata/dataAccess/QueryCondition.java similarity index 72% rename from src/org/kar/archidata/sqlWrapper/QuerryCondition.java rename to src/org/kar/archidata/dataAccess/QueryCondition.java index 50f3dd2..ac7ef7a 100644 --- a/src/org/kar/archidata/sqlWrapper/QuerryCondition.java +++ b/src/org/kar/archidata/dataAccess/QueryCondition.java @@ -1,13 +1,13 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.sql.PreparedStatement; -public class QuerryCondition implements QuerryItem { +public class QueryCondition implements QueryItem { private final String key; private final String comparator; private final Object value; - public QuerryCondition(String key, String comparator, Object value) { + public QueryCondition(String key, String comparator, Object value) { this.key = key; this.comparator = comparator; this.value = value; @@ -25,7 +25,7 @@ public class QuerryCondition implements QuerryItem { @Override public int injectQuerry(PreparedStatement ps, int iii) throws Exception { - SqlWrapper.addElement(ps, this.value, iii++); + DataAccess.addElement(ps, this.value, iii++); return iii; } } diff --git a/src/org/kar/archidata/sqlWrapper/QuerryItem.java b/src/org/kar/archidata/dataAccess/QueryItem.java similarity index 71% rename from src/org/kar/archidata/sqlWrapper/QuerryItem.java rename to src/org/kar/archidata/dataAccess/QueryItem.java index 8a12e1a..a4a21e2 100644 --- a/src/org/kar/archidata/sqlWrapper/QuerryItem.java +++ b/src/org/kar/archidata/dataAccess/QueryItem.java @@ -1,8 +1,8 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.sql.PreparedStatement; -public interface QuerryItem { +public interface QueryItem { void generateQuerry(StringBuilder querry, String tableName); int injectQuerry(PreparedStatement ps, int iii) throws Exception; diff --git a/src/org/kar/archidata/sqlWrapper/QuerryOptions.java b/src/org/kar/archidata/dataAccess/QueryOptions.java similarity index 66% rename from src/org/kar/archidata/sqlWrapper/QuerryOptions.java rename to src/org/kar/archidata/dataAccess/QueryOptions.java index a5bae06..e0e27ef 100644 --- a/src/org/kar/archidata/sqlWrapper/QuerryOptions.java +++ b/src/org/kar/archidata/dataAccess/QueryOptions.java @@ -1,28 +1,28 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.util.HashMap; import java.util.Map; -public class QuerryOptions { +public class QueryOptions { public static final String SQL_NOT_READ_DISABLE = "SQLNotRead_disable"; public static final String SQL_DELETED_DISABLE = "SQLDeleted_disable"; private final Map options = new HashMap<>(); - public QuerryOptions() { + public QueryOptions() { } - public QuerryOptions(String key, Object value) { + public QueryOptions(String key, Object value) { this.options.put(key, value); } - public QuerryOptions(String key, Object value, String key2, Object value2) { + public QueryOptions(String key, Object value, String key2, Object value2) { this.options.put(key, value); this.options.put(key2, value2); } - public QuerryOptions(String key, Object value, String key2, Object value2, String key3, Object value3) { + public QueryOptions(String key, Object value, String key2, Object value2, String key3, Object value3) { this.options.put(key, value); this.options.put(key2, value2); this.options.put(key3, value3); diff --git a/src/org/kar/archidata/sqlWrapper/QuerryOr.java b/src/org/kar/archidata/dataAccess/QueryOr.java similarity index 70% rename from src/org/kar/archidata/sqlWrapper/QuerryOr.java rename to src/org/kar/archidata/dataAccess/QueryOr.java index e558277..304b95f 100644 --- a/src/org/kar/archidata/sqlWrapper/QuerryOr.java +++ b/src/org/kar/archidata/dataAccess/QueryOr.java @@ -1,12 +1,12 @@ -package org.kar.archidata.sqlWrapper; +package org.kar.archidata.dataAccess; import java.sql.PreparedStatement; import java.util.List; -public class QuerryOr implements QuerryItem { - protected final List childs; +public class QueryOr implements QueryItem { + protected final List childs; - public QuerryOr(List childs) { + public QueryOr(List childs) { this.childs = childs; } @@ -15,7 +15,7 @@ public class QuerryOr implements QuerryItem { querry.append(" ("); } boolean first = true; - for (QuerryItem elem : this.childs) { + for (QueryItem elem : this.childs) { if (first) { first = false; } else { @@ -31,7 +31,7 @@ public class QuerryOr implements QuerryItem { @Override public int injectQuerry(PreparedStatement ps, int iii) throws Exception { - for (QuerryItem elem : this.childs) { + for (QueryItem elem : this.childs) { iii = elem.injectQuerry(ps, iii); } return iii; diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToMany.java b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToMany.java similarity index 91% rename from src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToMany.java rename to src/org/kar/archidata/dataAccess/addOn/AddOnManyToMany.java index 60b099a..6b682e1 100644 --- a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToMany.java +++ b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToMany.java @@ -1,4 +1,4 @@ -package org.kar.archidata.sqlWrapper.addOn; +package org.kar.archidata.dataAccess.addOn; import java.lang.reflect.Field; import java.sql.PreparedStatement; @@ -9,11 +9,11 @@ import java.util.List; import org.kar.archidata.GlobalConfiguration; import org.kar.archidata.annotation.AnnotationTools; +import org.kar.archidata.dataAccess.QueryOptions; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataAccessAddOn; +import org.kar.archidata.dataAccess.DataAccess.ExceptionDBInterface; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; -import org.kar.archidata.sqlWrapper.SqlWrapper.ExceptionDBInterface; -import org.kar.archidata.sqlWrapper.SqlWrapperAddOn; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory; import jakarta.persistence.ManyToMany; import jakarta.validation.constraints.NotNull; -public class AddOnManyToMany implements SqlWrapperAddOn { +public class AddOnManyToMany implements DataAccessAddOn { static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class); static final String SEPARATOR = "-"; @@ -54,7 +54,7 @@ public class AddOnManyToMany implements SqlWrapperAddOn { @Override public int generateQuerry(@NotNull final String tableName, @NotNull final Field elem, @NotNull final StringBuilder querry, @NotNull final String name, @NotNull final int elemCount, - QuerryOptions options) { + QueryOptions options) { String localName = name; if (name.endsWith("s")) { localName = name.substring(0, name.length() - 1); @@ -104,8 +104,8 @@ public class AddOnManyToMany implements SqlWrapperAddOn { } @Override - public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { - List idList = SqlWrapper.getListOfIds(rs, count, SEPARATOR); + public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QueryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { + List idList = DataAccess.getListOfIds(rs, count, SEPARATOR); elem.set(data, idList); return 1; } @@ -122,8 +122,8 @@ public class AddOnManyToMany implements SqlWrapperAddOn { // real add in the BDD: try { // prepare the request: - final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + SqlWrapper.getDBNow() + ", " - + SqlWrapper.getDBNow() + ", ?, ?)"; + final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + DataAccess.getDBNow() + ", " + + DataAccess.getDBNow() + ", ?, ?)"; final PreparedStatement ps = entry.connection.prepareStatement(querry, Statement.RETURN_GENERATED_KEYS); int iii = 1; ps.setLong(iii++, localKey); @@ -157,7 +157,7 @@ public class AddOnManyToMany implements SqlWrapperAddOn { public static void removeLink(final Class clazz, final long localKey, final String table, final long remoteKey) throws Exception { final String tableName = AnnotationTools.getTableName(clazz); DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); - final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + SqlWrapper.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + DataAccess.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + "_id` = ?"; try { final PreparedStatement ps = entry.connection.prepareStatement(querry); diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToManyOrdered.java b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToManyOrdered.java similarity index 92% rename from src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToManyOrdered.java rename to src/org/kar/archidata/dataAccess/addOn/AddOnManyToManyOrdered.java index 14000fc..54b619a 100644 --- a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToManyOrdered.java +++ b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToManyOrdered.java @@ -1,4 +1,4 @@ -package org.kar.archidata.sqlWrapper.addOn; +package org.kar.archidata.dataAccess.addOn; import java.lang.reflect.Field; import java.sql.PreparedStatement; @@ -10,11 +10,11 @@ import java.util.List; import org.kar.archidata.GlobalConfiguration; import org.kar.archidata.annotation.AnnotationTools; import org.kar.archidata.annotation.addOn.DataAddOnManyToManyOrdered; +import org.kar.archidata.dataAccess.QueryOptions; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataAccessAddOn; +import org.kar.archidata.dataAccess.DataAccess.ExceptionDBInterface; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; -import org.kar.archidata.sqlWrapper.SqlWrapper.ExceptionDBInterface; -import org.kar.archidata.sqlWrapper.SqlWrapperAddOn; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,7 +25,7 @@ import jakarta.validation.constraints.NotNull; * Manage the decorator element @DataAddOnManyToManyOrdered to be injected in the DB. * The objective of this table is to manage a link between 2 table that have a specific order (Only work in 1 direction) */ -public class AddOnManyToManyOrdered implements SqlWrapperAddOn { +public class AddOnManyToManyOrdered implements DataAccessAddOn { static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToManyOrdered.class); static final String SEPARATOR = "-"; @@ -57,7 +57,7 @@ public class AddOnManyToManyOrdered implements SqlWrapperAddOn { } @Override - public int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QuerryOptions options) { + public int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QueryOptions options) { String localName = name; if (name.endsWith("s")) { localName = name.substring(0, name.length() - 1); @@ -103,7 +103,7 @@ public class AddOnManyToManyOrdered implements SqlWrapperAddOn { } @Override - public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { + public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QueryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { //throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB"); return 0; } @@ -120,8 +120,8 @@ public class AddOnManyToManyOrdered implements SqlWrapperAddOn { // real add in the BDD: try { // prepare the request: - final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + SqlWrapper.getDBNow() + ", " - + SqlWrapper.getDBNow() + ", ?, ?)"; + final String querry = "INSERT INTO " + tableName + "_link_" + table + " (create_date, modify_date, " + tableName + "_id, " + table + "_id)" + " VALUES (" + DataAccess.getDBNow() + ", " + + DataAccess.getDBNow() + ", ?, ?)"; final PreparedStatement ps = entry.connection.prepareStatement(querry, Statement.RETURN_GENERATED_KEYS); int iii = 1; ps.setLong(iii++, localKey); @@ -155,7 +155,7 @@ public class AddOnManyToManyOrdered implements SqlWrapperAddOn { public static void removeLink(final Class clazz, final long localKey, final String table, final long remoteKey) throws Exception { final String tableName = AnnotationTools.getTableName(clazz); DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); - final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + SqlWrapper.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + DataAccess.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table + "_id` = ?"; try { final PreparedStatement ps = entry.connection.prepareStatement(querry); diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToOne.java b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToOne.java similarity index 70% rename from src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToOne.java rename to src/org/kar/archidata/dataAccess/addOn/AddOnManyToOne.java index 76e58da..848a095 100644 --- a/src/org/kar/archidata/sqlWrapper/addOn/AddOnManyToOne.java +++ b/src/org/kar/archidata/dataAccess/addOn/AddOnManyToOne.java @@ -1,4 +1,4 @@ -package org.kar.archidata.sqlWrapper.addOn; +package org.kar.archidata.dataAccess.addOn; import java.lang.reflect.Field; import java.sql.PreparedStatement; @@ -9,18 +9,19 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; -import org.kar.archidata.sqlWrapper.SqlWrapperAddOn; +import org.kar.archidata.annotation.AnnotationTools; +import org.kar.archidata.dataAccess.DataAccessAddOn; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.dataAccess.QueryOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import jakarta.persistence.ManyToOne; import jakarta.validation.constraints.NotNull; -public class AddOnManyToOne implements SqlWrapperAddOn { +public class AddOnManyToOne implements DataAccessAddOn { static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class); - + /** * Convert the list if external id in a string '-' separated * @param ids List of value (null are removed) @@ -30,7 +31,7 @@ public class AddOnManyToOne implements SqlWrapperAddOn { final List tmp = new ArrayList<>(ids); return tmp.stream().map(String::valueOf).collect(Collectors.joining("-")); } - + /** * extract a list of "-" separated element from a SQL input data. * @param rs Result Set of the BDD @@ -51,75 +52,78 @@ public class AddOnManyToOne implements SqlWrapperAddOn { } return out; } - + @Override public Class getAnnotationClass() { return ManyToOne.class; } - + @Override - public String getSQLFieldType(final Field elem) { + public String getSQLFieldType(final Field elem) throws Exception { + final String fieldName = AnnotationTools.getFieldName(elem); try { - return SqlWrapper.convertTypeInSQL(Long.class); - } catch (Exception e) { + return DataFactory.convertTypeInSQL(Long.class, fieldName); + } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } - + @Override public boolean isCompatibleField(final Field elem) { final ManyToOne decorators = elem.getDeclaredAnnotation(ManyToOne.class); return decorators != null; } - + @Override public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException { if (data == null) { ps.setNull(iii++, Types.BIGINT); } else { @SuppressWarnings("unchecked") - String dataTmp = getStringOfIds((List) data); + final String dataTmp = getStringOfIds((List) data); ps.setString(iii++, dataTmp); } return iii++; } - + @Override public boolean isExternal() { // TODO Auto-generated method stub return false; } - + @Override - public int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QuerryOptions options) { + public int generateQuerry(@NotNull final String tableName, @NotNull final Field elem, @NotNull final StringBuilder querry, @NotNull final String name, @NotNull final int elemCount, + final QueryOptions options) { querry.append(" "); querry.append(tableName); querry.append("."); querry.append(name); return 1; } - + @Override - public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { - Long foreignKey = rs.getLong(count); + public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, final QueryOptions options) + throws SQLException, IllegalArgumentException, IllegalAccessException { + final Long foreignKey = rs.getLong(count); if (rs.wasNull()) { return 0; } elem.set(data, foreignKey); return 1; } - + @Override public boolean canUpdate() { return true; } - + // TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system @Override - public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List preActionList, List postActionList, + public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List preActionList, final List postActionList, final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception { - SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class); + DataFactory.createTablesSpecificType(tableName, elem, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, Long.class); } } diff --git a/src/org/kar/archidata/dataAccess/addOn/AddOnSQLTableExternalForeinKeyAsList.java b/src/org/kar/archidata/dataAccess/addOn/AddOnSQLTableExternalForeinKeyAsList.java new file mode 100644 index 0000000..a1ce9be --- /dev/null +++ b/src/org/kar/archidata/dataAccess/addOn/AddOnSQLTableExternalForeinKeyAsList.java @@ -0,0 +1,108 @@ +package org.kar.archidata.dataAccess.addOn; + +import java.lang.reflect.Field; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.kar.archidata.annotation.AnnotationTools; +import org.kar.archidata.annotation.addOn.SQLTableExternalForeinKeyAsList; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataAccessAddOn; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.dataAccess.QueryOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.validation.constraints.NotNull; + +public class AddOnSQLTableExternalForeinKeyAsList implements DataAccessAddOn { + static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class); + static final String SEPARATOR = "-"; + + /** + * Convert the list if external id in a string '-' separated + * @param ids List of value (null are removed) + * @return '-' string separated + */ + protected static String getStringOfIds(final List ids) { + final List tmp = new ArrayList<>(ids); + return tmp.stream().map(String::valueOf).collect(Collectors.joining(SEPARATOR)); + } + + @Override + public Class getAnnotationClass() { + return SQLTableExternalForeinKeyAsList.class; + } + + @Override + public String getSQLFieldType(final Field elem) throws Exception { + final String fieldName = AnnotationTools.getFieldName(elem); + try { + return DataFactory.convertTypeInSQL(String.class, fieldName); + } catch (final Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + @Override + public boolean isCompatibleField(final Field elem) { + final SQLTableExternalForeinKeyAsList decorators = elem.getDeclaredAnnotation(SQLTableExternalForeinKeyAsList.class); + return decorators != null; + } + + @Override + public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException { + if (data == null) { + ps.setNull(iii++, Types.BIGINT); + } else { + @SuppressWarnings("unchecked") + final String dataTmp = getStringOfIds((List) data); + ps.setString(iii++, dataTmp); + } + return iii++; + } + + @Override + public boolean isExternal() { + // TODO Auto-generated method stub + return false; + } + + @Override + public int generateQuerry(@NotNull final String tableName, @NotNull final Field elem, @NotNull final StringBuilder querry, @NotNull final String name, @NotNull final int elemCount, + final QueryOptions options) { + querry.append(" "); + querry.append(tableName); + querry.append("."); + querry.append(name); + return 1; + } + + @Override + public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, final QueryOptions options) + throws SQLException, IllegalArgumentException, IllegalAccessException { + final List idList = DataAccess.getListOfIds(rs, count, SEPARATOR); + elem.set(data, idList); + return 1; + } + + @Override + public boolean canUpdate() { + return true; + } + + @Override + public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List preActionList, final List postActionList, + final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception { + // TODO Auto-generated method stub + + DataFactory.createTablesSpecificType(tableName, elem, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, String.class); + } +} diff --git a/src/org/kar/archidata/db/DBConfig.java b/src/org/kar/archidata/db/DBConfig.java index 0966a84..a43167e 100644 --- a/src/org/kar/archidata/db/DBConfig.java +++ b/src/org/kar/archidata/db/DBConfig.java @@ -1,11 +1,11 @@ package org.kar.archidata.db; -import org.kar.archidata.sqlWrapper.SqlWrapper; +import org.kar.archidata.dataAccess.DataAccess; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DBConfig { - static final Logger LOGGER = LoggerFactory.getLogger(SqlWrapper.class); + static final Logger LOGGER = LoggerFactory.getLogger(DataAccess.class); private final String type; private final String hostname; private final int port; diff --git a/src/org/kar/archidata/migration/MigrationEngine.java b/src/org/kar/archidata/migration/MigrationEngine.java index 5727021..5a9f638 100644 --- a/src/org/kar/archidata/migration/MigrationEngine.java +++ b/src/org/kar/archidata/migration/MigrationEngine.java @@ -5,64 +5,65 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.dataAccess.QueryOptions; import org.kar.archidata.db.DBConfig; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MigrationEngine { final static Logger LOGGER = LoggerFactory.getLogger(MigrationEngine.class); - + // List of order migrations private final List datas; // initialization of the migration if the DB is not present... private MigrationInterface init; - + /** * Migration engine constructor (empty). */ public MigrationEngine() { - this(new ArrayList(), null); + this(new ArrayList<>(), null); } - + /** * Migration engine constructor (specific mode). * @param datas All the migration ordered. * @param init Initialization migration model. */ - public MigrationEngine(List datas, MigrationInterface init) { + public MigrationEngine(final List datas, final MigrationInterface init) { this.datas = datas; this.init = init; } - + /** * Add a Migration in the list * @param migration Migration to add. */ - public void add(MigrationInterface migration) { + public void add(final MigrationInterface migration) { this.datas.add(migration); } - + /** * Set first initialization class * @param migration migration class for first init. */ - public void setInit(MigrationInterface migration) { - init = migration; + public void setInit(final MigrationInterface migration) { + this.init = migration; } - + /** * Get the current version/migration name * @return Model represent the last migration. If null then no migration has been done. */ public MigrationModel getCurrentVersion() { - if (!SqlWrapper.isTableExist("KAR_migration")) { + if (!DataAccess.isTableExist("KAR_migration")) { return null; } try { - List data = SqlWrapper.gets(MigrationModel.class, new QuerryOptions("SQLNotRead_disable", true)); + final List data = DataAccess.gets(MigrationModel.class, new QueryOptions("SQLNotRead_disable", true)); if (data == null) { LOGGER.error("Can not collect the migration table in the DB:{}"); return null; @@ -72,52 +73,52 @@ public class MigrationEngine { return null; } LOGGER.debug("List of migrations:"); - for (MigrationModel elem : data) { + for (final MigrationModel elem : data) { LOGGER.debug(" - date={} name={} end={}", elem.updatedAt, elem.name, elem.terminated); } return data.get(data.size() - 1); - } catch (Exception ex) { + } catch (final Exception ex) { LOGGER.error("Fail to Request migration table in the DB:{}", ex.getMessage()); ex.printStackTrace(); } return null; } - + /** * Process the automatic migration of the system * @param config SQL connection for the migration * @throws InterruptedException user interrupt the migration * @throws IOException Error if access on the DB */ - public void migrate(DBConfig config) throws InterruptedException, IOException { + public void migrate(final DBConfig config) throws InterruptedException, IOException { LOGGER.info("Execute migration ... [BEGIN]"); - + // STEP 1: Check the DB exist: LOGGER.info("Verify existance of '{}'", config.getDbName()); - boolean exist = SqlWrapper.isDBExist(config.getDbName()); + boolean exist = DataAccess.isDBExist(config.getDbName()); if (!exist) { LOGGER.warn("DB: '{}' DOES NOT EXIST ==> create one", config.getDbName()); // create the local DB: - SqlWrapper.createDB(config.getDbName()); + DataAccess.createDB(config.getDbName()); } - exist = SqlWrapper.isDBExist(config.getDbName()); + exist = DataAccess.isDBExist(config.getDbName()); while (!exist) { LOGGER.error("DB: '{}' DOES NOT EXIST after trying to create one ", config.getDbName()); LOGGER.error("Waiting administrator create a new one, we check after 30 seconds..."); Thread.sleep(30000); - exist = SqlWrapper.isDBExist(config.getDbName()); + exist = DataAccess.isDBExist(config.getDbName()); } LOGGER.info("DB '{}' exist.", config.getDbName()); // STEP 2: Check migration table exist: LOGGER.info("Verify existance of migration table '{}'", "KAR_migration"); - exist = SqlWrapper.isTableExist("KAR_migration"); + exist = DataAccess.isTableExist("KAR_migration"); if (!exist) { LOGGER.info("'{}' Does not exist create a new one...", "KAR_migration"); // create the table: List sqlQuery; try { - sqlQuery = SqlWrapper.createTable(MigrationModel.class, false); - } catch (Exception ex) { + sqlQuery = DataFactory.createTable(MigrationModel.class, false); + } catch (final Exception ex) { ex.printStackTrace(); while (true) { LOGGER.error("Fail to create the local DB SQL model for migaration ==> wait administrator interventions"); @@ -126,7 +127,7 @@ public class MigrationEngine { } LOGGER.info("Create Table with : {}", sqlQuery.get(0)); try { - SqlWrapper.executeQuerry(sqlQuery.get(0)); + DataAccess.executeQuerry(sqlQuery.get(0)); } catch (SQLException | IOException ex) { ex.printStackTrace(); while (true) { @@ -135,7 +136,7 @@ public class MigrationEngine { } } } - MigrationModel currentVersion = getCurrentVersion(); + final MigrationModel currentVersion = getCurrentVersion(); List toApply = new ArrayList<>(); if (currentVersion == null) { //This is a first migration @@ -146,10 +147,10 @@ public class MigrationEngine { toApply.add(this.init); } if (this.datas.size() == 0) { - // nothing to do the initialization model is alone and it is the first time + // nothing to do the initialization model is alone and it is the first time } else { // we insert a placeholder to simulate all migration is well done. - String placeholderName = this.datas.get(this.datas.size() - 1).getName(); + final String placeholderName = this.datas.get(this.datas.size() - 1).getName(); MigrationModel migrationResult = new MigrationModel(); migrationResult.name = placeholderName; migrationResult.stepId = 0; @@ -157,14 +158,14 @@ public class MigrationEngine { migrationResult.count = 0; migrationResult.log = "Place-holder for first initialization"; try { - migrationResult = SqlWrapper.insert(migrationResult); - } catch (Exception e) { + migrationResult = DataAccess.insert(migrationResult); + } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } else { - if (currentVersion.terminated == false) { + if (!currentVersion.terminated) { while (true) { LOGGER.error("An error occured in the last migration: '{}' defect @{}/{} ==> wait administrator interventions", currentVersion.name, currentVersion.stepId, currentVersion.count); Thread.sleep(60 * 60 * 1000); @@ -186,18 +187,18 @@ public class MigrationEngine { } } } - DBEntry entry = DBEntry.createInterface(config); - int id = 0; - int count = toApply.size(); - for (MigrationInterface elem : toApply) { + final DBEntry entry = DBEntry.createInterface(config); + final int id = 0; + final int count = toApply.size(); + for (final MigrationInterface elem : toApply) { migrateSingle(entry, elem, id, count); } LOGGER.info("Execute migration ... [ END ]"); } - - public void migrateSingle(DBEntry entry, MigrationInterface elem, int id, int count) { + + public void migrateSingle(final DBEntry entry, final MigrationInterface elem, final int id, final int count) { LOGGER.info("Migrate: [{}/{}] {} [BEGIN]", id, count, elem.getName()); - StringBuilder log = new StringBuilder(); + final StringBuilder log = new StringBuilder(); log.append("Start migration"); MigrationModel migrationResult = new MigrationModel(); migrationResult.name = elem.getName(); @@ -206,25 +207,25 @@ public class MigrationEngine { migrationResult.count = elem.getNumberOfStep(); migrationResult.log = log.toString(); try { - migrationResult = SqlWrapper.insert(migrationResult); - } catch (Exception e) { + migrationResult = DataAccess.insert(migrationResult); + } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } - + if (elem.applyMigration(entry, log, migrationResult)) { migrationResult.terminated = true; try { - SqlWrapper.update(migrationResult, migrationResult.id, List.of("terminated")); - } catch (Exception e) { + DataAccess.update(migrationResult, migrationResult.id, List.of("terminated")); + } catch (final Exception e) { e.printStackTrace(); } } else { try { log.append("Fail in the migration engine..."); migrationResult.log = log.toString(); - SqlWrapper.update(migrationResult, migrationResult.id, List.of("log")); - } catch (Exception e) { + DataAccess.update(migrationResult, migrationResult.id, List.of("log")); + } catch (final Exception e) { e.printStackTrace(); } while (true) { @@ -232,7 +233,7 @@ public class MigrationEngine { migrationResult.count); try { Thread.sleep(60 * 60 * 1000); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } @@ -240,10 +241,10 @@ public class MigrationEngine { } LOGGER.info("Migrate: [{}/{}] {} [ END ]", id, count, elem.getName()); } - - public void revertTo(DBEntry entry, String migrationName) { - MigrationModel currentVersion = getCurrentVersion(); - List toApply = new ArrayList<>(); + + public void revertTo(final DBEntry entry, final String migrationName) { + final MigrationModel currentVersion = getCurrentVersion(); + final List toApply = new ArrayList<>(); boolean find = false; for (int iii = this.datas.size() - 1; iii >= 0; iii--) { if (!find) { @@ -257,16 +258,16 @@ public class MigrationEngine { } toApply.add(this.datas.get(iii)); } - int id = 0; - int count = toApply.size(); - for (MigrationInterface elem : toApply) { + final int id = 0; + final int count = toApply.size(); + for (final MigrationInterface elem : toApply) { revertSingle(entry, elem, id, count); } } - - public void revertSingle(DBEntry entry, MigrationInterface elem, int id, int count) { + + public void revertSingle(final DBEntry entry, final MigrationInterface elem, final int id, final int count) { LOGGER.info("Revert migration: {} [BEGIN]", elem.getName()); - + LOGGER.info("Revert migration: {} [ END ]", elem.getName()); } } diff --git a/src/org/kar/archidata/migration/MigrationSqlStep.java b/src/org/kar/archidata/migration/MigrationSqlStep.java index 2eb06ae..47152c7 100644 --- a/src/org/kar/archidata/migration/MigrationSqlStep.java +++ b/src/org/kar/archidata/migration/MigrationSqlStep.java @@ -5,8 +5,9 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,11 +15,11 @@ import org.slf4j.LoggerFactory; record Action( String action, List filterDB) { - public Action(String action) { + public Action(final String action) { this(action, List.of()); } - - public Action(String action, String filterDB) { + + public Action(final String action, final String filterDB) { this(action, List.of(filterDB)); } } @@ -26,32 +27,32 @@ record Action( public class MigrationSqlStep implements MigrationInterface { final static Logger LOGGER = LoggerFactory.getLogger(MigrationSqlStep.class); private final List actions = new ArrayList<>(); - + @Override public String getName() { return getClass().getCanonicalName(); } - + public void display() { for (int iii = 0; iii < this.actions.size(); iii++) { final Action action = this.actions.get(iii); LOGGER.info(" >>>> SQL ACTION : {}/{} ==> filter='{}'\n{}", iii, this.actions.size(), action.filterDB(), action.action()); } } - + @Override public boolean applyMigration(final DBEntry entry, final StringBuilder log, final MigrationModel model) { for (int iii = 0; iii < this.actions.size(); iii++) { log.append("action [" + (iii + 1) + "/" + this.actions.size() + "]\n"); LOGGER.info(" >>>> SQL ACTION : {}/{}", iii + 1, this.actions.size()); final Action action = this.actions.get(iii); - + LOGGER.info("SQL request: ```{}``` on '{}' current={}", action.action(), action.filterDB(), ConfigBaseVariable.getDBType()); log.append("SQL: " + action.action() + " on " + action.filterDB() + "\n"); boolean isValid = true; if (action.filterDB() != null && action.filterDB().size() > 0) { isValid = false; - for (String elem : action.filterDB()) { + for (final String elem : action.filterDB()) { if (ConfigBaseVariable.getDBType().equals(elem)) { isValid = true; } @@ -63,7 +64,7 @@ public class MigrationSqlStep implements MigrationInterface { continue; } try { - SqlWrapper.executeQuerry(action.action()); + DataAccess.executeQuerry(action.action()); } catch (SQLException | IOException ex) { ex.printStackTrace(); LOGGER.info("SQL request ERROR: ", ex.getMessage()); @@ -71,7 +72,7 @@ public class MigrationSqlStep implements MigrationInterface { model.stepId = iii + 1; model.log = log.toString(); try { - SqlWrapper.update(model, model.id, List.of("stepId", "log")); + DataAccess.update(model, model.id, List.of("stepId", "log")); } catch (final Exception e) { e.printStackTrace(); } @@ -82,7 +83,7 @@ public class MigrationSqlStep implements MigrationInterface { model.stepId = iii + 1; model.log = log.toString(); try { - SqlWrapper.update(model, model.id, List.of("stepId", "log")); + DataAccess.update(model, model.id, List.of("stepId", "log")); } catch (final Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -96,30 +97,30 @@ public class MigrationSqlStep implements MigrationInterface { } return true; } - + @Override public boolean revertMigration(final DBEntry entry, final StringBuilder log) { return false; } - + public void addAction(final String action) { this.actions.add(new Action(action)); } - - public void addAction(final String action, String filterdBType) { + + public void addAction(final String action, final String filterdBType) { this.actions.add(new Action(action, filterdBType)); } - + public void addClass(final Class clazz) throws Exception { - final List tmp = SqlWrapper.createTable(clazz, false); - for (String elem : tmp) { + final List tmp = DataFactory.createTable(clazz, false); + for (final String elem : tmp) { this.actions.add(new Action(elem)); } } - + @Override public int getNumberOfStep() { return this.actions.size(); } - + } diff --git a/src/org/kar/archidata/model/GenericData.java b/src/org/kar/archidata/model/GenericData.java index 3ce5623..3bb64d6 100644 --- a/src/org/kar/archidata/model/GenericData.java +++ b/src/org/kar/archidata/model/GenericData.java @@ -1,6 +1,6 @@ package org.kar.archidata.model; -import java.sql.Timestamp; +import java.util.Date; import org.kar.archidata.annotation.CreationTimestamp; import org.kar.archidata.annotation.SQLComment; @@ -11,6 +11,8 @@ import jakarta.persistence.Column; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; public class GenericData { @Id @@ -18,29 +20,16 @@ public class GenericData { @Column(nullable = false, unique = true) @SQLComment("Primary key of the base") public Long id = null; - @SQLNotRead - @CreationTimestamp - @Column(nullable = false) - @SQLComment("Create time of the object") - public Timestamp createdAt = null; - @SQLNotRead - @UpdateTimestamp - @Column(nullable = false) - @SQLComment("When update the object") - public Timestamp updatedAt = null; -} -/* TODO Later: @SQLNotRead @CreationTimestamp @Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) @SQLComment("Create time of the object") public Date createdAt = null; - @SQLNotRead @UpdateTimestamp @Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) @SQLComment("When update the object") public Date updatedAt = null; -*/ +} diff --git a/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java b/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java deleted file mode 100644 index f17c5da..0000000 --- a/src/org/kar/archidata/sqlWrapper/addOn/AddOnSQLTableExternalForeinKeyAsList.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.kar.archidata.sqlWrapper.addOn; - -import java.lang.reflect.Field; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.kar.archidata.annotation.addOn.SQLTableExternalForeinKeyAsList; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; -import org.kar.archidata.sqlWrapper.SqlWrapperAddOn; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import jakarta.validation.constraints.NotNull; - -public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn { - static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class); - static final String SEPARATOR = "-"; - - /** - * Convert the list if external id in a string '-' separated - * @param ids List of value (null are removed) - * @return '-' string separated - */ - protected static String getStringOfIds(List ids) { - List tmp = new ArrayList<>(); - for (Long elem : ids) { - tmp.add(elem); - } - return tmp.stream().map(x -> String.valueOf(x)).collect(Collectors.joining(SEPARATOR)); - } - - @Override - public Class getAnnotationClass() { - return SQLTableExternalForeinKeyAsList.class; - } - - public String getSQLFieldType(Field elem) { - try { - return SqlWrapper.convertTypeInSQL(String.class); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; - } - - public boolean isCompatibleField(Field elem) { - SQLTableExternalForeinKeyAsList decorators = elem.getDeclaredAnnotation(SQLTableExternalForeinKeyAsList.class); - return decorators != null; - } - - public int insertData(PreparedStatement ps, Object data, int iii) throws SQLException { - if (data == null) { - ps.setNull(iii++, Types.BIGINT); - } else { - @SuppressWarnings("unchecked") - String dataTmp = getStringOfIds((List) data); - ps.setString(iii++, dataTmp); - } - return iii++; - } - - @Override - public boolean isExternal() { - // TODO Auto-generated method stub - return false; - } - - @Override - public int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QuerryOptions options) { - querry.append(" "); - querry.append(tableName); - querry.append("."); - querry.append(name); - return 1; - } - - @Override - public int fillFromQuerry(ResultSet rs, Field elem, Object data, int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException { - List idList = SqlWrapper.getListOfIds(rs, count, SEPARATOR); - elem.set(data, idList); - return 1; - } - - @Override - public boolean canUpdate() { - return true; - } - - @Override - public void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List preActionList, List postActionList, boolean createIfNotExist, boolean createDrop, - int fieldId) throws Exception { - // TODO Auto-generated method stub - - SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, String.class); - } -} diff --git a/src/org/kar/archidata/util/DataTools.java b/src/org/kar/archidata/util/DataTools.java index a493f85..8970945 100644 --- a/src/org/kar/archidata/util/DataTools.java +++ b/src/org/kar/archidata/util/DataTools.java @@ -14,11 +14,11 @@ import java.sql.SQLException; import java.util.List; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.kar.archidata.dataAccess.QueryAnd; +import org.kar.archidata.dataAccess.QueryCondition; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.addOn.AddOnManyToMany; import org.kar.archidata.model.Data; -import org.kar.archidata.sqlWrapper.QuerryAnd; -import org.kar.archidata.sqlWrapper.QuerryCondition; -import org.kar.archidata.sqlWrapper.SqlWrapper; -import org.kar.archidata.sqlWrapper.addOn.AddOnManyToMany; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,7 +77,7 @@ public class DataTools { public static Data getWithSha512(String sha512) { try { - return SqlWrapper.getWhere(Data.class, new QuerryCondition("sha512", "=", sha512)); + return DataAccess.getWhere(Data.class, new QueryCondition("sha512", "=", sha512)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -87,7 +87,7 @@ public class DataTools { public static Data getWithId(long id) { try { - return SqlWrapper.getWhere(Data.class, new QuerryAnd(List.of(new QuerryCondition("deleted", "=", false), new QuerryCondition("id", "=", id)))); + return DataAccess.getWhere(Data.class, new QueryAnd(List.of(new QueryCondition("deleted", "=", false), new QueryCondition("id", "=", id)))); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -130,7 +130,7 @@ public class DataTools { out.sha512 = sha512; out.mimeType = mimeType; out.size = fileSize; - out = SqlWrapper.insert(out); + out = DataAccess.insert(out); } catch (SQLException ex) { ex.printStackTrace(); return null; @@ -152,7 +152,7 @@ public class DataTools { public static void undelete(Long id) { try { - SqlWrapper.unsetDelete(Data.class, id); + DataAccess.unsetDelete(Data.class, id); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -252,7 +252,7 @@ public class DataTools { LOGGER.info(" - file_name: ", fileName); LOGGER.info(" - fileInputStream: {}", fileInputStream); LOGGER.info(" - fileMetaData: {}", fileMetaData); - T media = SqlWrapper.get(clazz, id); + T media = DataAccess.get(clazz, id); if (media == null) { return Response.notModified("Media Id does not exist or removed...").build(); } @@ -283,7 +283,7 @@ public class DataTools { // Fist step: retrieve all the Id of each parents:... LOGGER.info("Find typeNode"); AddOnManyToMany.addLink(clazz, id, "cover", data.id); - return Response.ok(SqlWrapper.get(clazz, id)).build(); + return Response.ok(DataAccess.get(clazz, id)).build(); } catch (Exception ex) { System.out.println("Cat ann unexpected error ... "); ex.printStackTrace(); diff --git a/test/src/test/kar/archidata/StepwiseExtension.java b/test/src/test/kar/archidata/StepwiseExtension.java new file mode 100644 index 0000000..2879060 --- /dev/null +++ b/test/src/test/kar/archidata/StepwiseExtension.java @@ -0,0 +1,33 @@ +package test.kar.archidata; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestExecutionExceptionHandler; + +class StepwiseExtension implements ExecutionCondition, TestExecutionExceptionHandler { + @Override + public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext extensionContext) { + final ExtensionContext.Namespace namespace = namespaceFor(extensionContext); + final ExtensionContext.Store store = storeFor(extensionContext, namespace); + final String value = store.get(StepwiseExtension.class, String.class); + return value == null ? ConditionEvaluationResult.enabled("No test failures in stepwise tests") + : ConditionEvaluationResult.disabled(String.format("Stepwise test disabled due to previous failure in '%s'", value)); + } + + @Override + public void handleTestExecutionException(final ExtensionContext extensionContext, final Throwable throwable) throws Throwable { + final ExtensionContext.Namespace namespace = namespaceFor(extensionContext); + final ExtensionContext.Store store = storeFor(extensionContext, namespace); + store.put(StepwiseExtension.class, extensionContext.getDisplayName()); + throw throwable; + } + + private ExtensionContext.Namespace namespaceFor(final ExtensionContext extensionContext) { + return ExtensionContext.Namespace.create(StepwiseExtension.class, extensionContext.getParent()); + } + + private ExtensionContext.Store storeFor(final ExtensionContext extensionContext, final ExtensionContext.Namespace namespace) { + return extensionContext.getParent().get().getStore(namespace); + } +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/TestSimpleTable.java b/test/src/test/kar/archidata/TestSimpleTable.java index 3716539..0650752 100644 --- a/test/src/test/kar/archidata/TestSimpleTable.java +++ b/test/src/test/kar/archidata/TestSimpleTable.java @@ -13,16 +13,19 @@ import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; import org.kar.archidata.GlobalConfiguration; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.dataAccess.QueryOptions; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import test.kar.archidata.model.SimpleTable; +@ExtendWith(StepwiseExtension.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class TestSimpleTable { final static private Logger LOGGER = LoggerFactory.getLogger(TestSimpleTable.class); @@ -43,7 +46,7 @@ public class TestSimpleTable { startAction = null; // Connect the dataBase... - DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); + final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); entry.connect(); } @@ -58,21 +61,21 @@ public class TestSimpleTable { @Test public void testTableInsertAndRetrieve() throws Exception { TestSimpleTable.startAction = Timestamp.from(Instant.now()); - List sqlCommand = SqlWrapper.createTable(SimpleTable.class); - for (String elem : sqlCommand) { + final List sqlCommand = DataFactory.createTable(SimpleTable.class); + for (final String elem : sqlCommand) { LOGGER.debug("request: '{}'", elem); - SqlWrapper.executeSimpleQuerry(elem, false); + DataAccess.executeSimpleQuerry(elem, false); } - SimpleTable test = new SimpleTable(); + final SimpleTable test = new SimpleTable(); test.data = TestSimpleTable.DATA_INJECTED; - SimpleTable insertedData = SqlWrapper.insert(test); + final SimpleTable insertedData = DataAccess.insert(test); Assertions.assertNotNull(insertedData); Assertions.assertNotNull(insertedData.id); Assertions.assertTrue(insertedData.id >= 0); // Try to retrieve all the data: - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, insertedData.id); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, insertedData.id); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); @@ -87,7 +90,7 @@ public class TestSimpleTable { @Test public void testReadAllValuesUnreadable() throws Exception { // check the full values - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true)); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QueryOptions(QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); @@ -95,7 +98,7 @@ public class TestSimpleTable { Assertions.assertEquals(TestSimpleTable.DATA_INJECTED, retrieve.data); Assertions.assertNotNull(retrieve.createdAt); LOGGER.info("start @ {} create @ {}", retrieve.createdAt.toInstant(), TestSimpleTable.startAction.toInstant()); - // Gros travail sur les timestamp a faire pour que ce soit correct ... + // Gros travail sur les timestamp a faire pour que ce soit correct ... // Assertions.assertTrue(retrieve.createdAt.after(this.startAction)); Assertions.assertNotNull(retrieve.updatedAt); // Assertions.assertTrue(retrieve.updatedAt.after(this.startAction)); @@ -112,10 +115,10 @@ public class TestSimpleTable { } // Delete the entry: - SimpleTable test = new SimpleTable(); + final SimpleTable test = new SimpleTable(); test.data = TestSimpleTable.DATA_INJECTED_2; - SqlWrapper.update(test, TestSimpleTable.idOfTheObject, List.of("data")); - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true)); + DataAccess.update(test, TestSimpleTable.idOfTheObject, List.of("data")); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QueryOptions(QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); Assertions.assertEquals(TestSimpleTable.idOfTheObject, retrieve.id); @@ -130,8 +133,8 @@ public class TestSimpleTable { @Test public void testDeleteTheObject() throws Exception { // Delete the entry: - SqlWrapper.delete(SimpleTable.class, TestSimpleTable.idOfTheObject); - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject); + DataAccess.delete(SimpleTable.class, TestSimpleTable.idOfTheObject); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, TestSimpleTable.idOfTheObject); Assertions.assertNull(retrieve); } @@ -140,7 +143,7 @@ public class TestSimpleTable { public void testReadDeletedObject() throws Exception { // check if we set get deleted element - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true)); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true)); Assertions.assertNull(retrieve); } @@ -149,7 +152,8 @@ public class TestSimpleTable { @Test public void testReadAllValuesUnreadableOfDeletedObject() throws Exception { // check if we set get deleted element with all data - SimpleTable retrieve = SqlWrapper.get(SimpleTable.class, TestSimpleTable.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true)); + final SimpleTable retrieve = DataAccess.get(SimpleTable.class, TestSimpleTable.idOfTheObject, + new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true, QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNull(retrieve); } diff --git a/test/src/test/kar/archidata/TestSimpleTableSoftDelete.java b/test/src/test/kar/archidata/TestSimpleTableSoftDelete.java index 8243f41..58c126c 100644 --- a/test/src/test/kar/archidata/TestSimpleTableSoftDelete.java +++ b/test/src/test/kar/archidata/TestSimpleTableSoftDelete.java @@ -13,16 +13,19 @@ import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; import org.kar.archidata.GlobalConfiguration; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.dataAccess.QueryOptions; import org.kar.archidata.db.DBEntry; -import org.kar.archidata.sqlWrapper.QuerryOptions; -import org.kar.archidata.sqlWrapper.SqlWrapper; import org.kar.archidata.util.ConfigBaseVariable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import test.kar.archidata.model.SimpleTableSoftDelete; +@ExtendWith(StepwiseExtension.class) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class TestSimpleTableSoftDelete { final static private Logger LOGGER = LoggerFactory.getLogger(TestSimpleTableSoftDelete.class); @@ -43,7 +46,7 @@ public class TestSimpleTableSoftDelete { startAction = null; // Connect the dataBase... - DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); + final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); entry.connect(); } @@ -58,21 +61,21 @@ public class TestSimpleTableSoftDelete { @Test public void testTableInsertAndRetrieve() throws Exception { TestSimpleTableSoftDelete.startAction = Timestamp.from(Instant.now()); - List sqlCommand = SqlWrapper.createTable(SimpleTableSoftDelete.class); - for (String elem : sqlCommand) { + final List sqlCommand = DataFactory.createTable(SimpleTableSoftDelete.class); + for (final String elem : sqlCommand) { LOGGER.debug("request: '{}'", elem); - SqlWrapper.executeSimpleQuerry(elem, false); + DataAccess.executeSimpleQuerry(elem, false); } - SimpleTableSoftDelete test = new SimpleTableSoftDelete(); + final SimpleTableSoftDelete test = new SimpleTableSoftDelete(); test.data = TestSimpleTableSoftDelete.DATA_INJECTED; - SimpleTableSoftDelete insertedData = SqlWrapper.insert(test); + final SimpleTableSoftDelete insertedData = DataAccess.insert(test); Assertions.assertNotNull(insertedData); Assertions.assertNotNull(insertedData.id); Assertions.assertTrue(insertedData.id >= 0); // Try to retrieve all the data: - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, insertedData.id); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, insertedData.id); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); @@ -88,7 +91,7 @@ public class TestSimpleTableSoftDelete { @Test public void testReadAllValuesUnreadable() throws Exception { // check the full values - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_NOT_READ_DISABLE, true)); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QueryOptions(QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); @@ -96,7 +99,7 @@ public class TestSimpleTableSoftDelete { Assertions.assertEquals(TestSimpleTableSoftDelete.DATA_INJECTED, retrieve.data); Assertions.assertNotNull(retrieve.createdAt); LOGGER.info("start @ {} create @ {}", retrieve.createdAt.toInstant(), TestSimpleTableSoftDelete.startAction.toInstant()); - // Gros travail sur les timestamp a faire pour que ce soit correct ... + // Gros travail sur les timestamp a faire pour que ce soit correct ... // Assertions.assertTrue(retrieve.createdAt.after(this.startAction)); Assertions.assertNotNull(retrieve.updatedAt); // Assertions.assertTrue(retrieve.updatedAt.after(this.startAction)); @@ -115,11 +118,11 @@ public class TestSimpleTableSoftDelete { } // Delete the entry: - SimpleTableSoftDelete test = new SimpleTableSoftDelete(); + final SimpleTableSoftDelete test = new SimpleTableSoftDelete(); test.data = TestSimpleTableSoftDelete.DATA_INJECTED_2; - SqlWrapper.update(test, TestSimpleTableSoftDelete.idOfTheObject, List.of("data")); - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, - new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true)); + DataAccess.update(test, TestSimpleTableSoftDelete.idOfTheObject, List.of("data")); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, + new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true, QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id); @@ -141,8 +144,8 @@ public class TestSimpleTableSoftDelete { Thread.sleep(Duration.ofMillis(15)); } // Delete the entry: - SqlWrapper.delete(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject); - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject); + DataAccess.delete(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject); Assertions.assertNull(retrieve); } @@ -151,7 +154,7 @@ public class TestSimpleTableSoftDelete { public void testReadDeletedObject() throws Exception { // check if we set get deleted element - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true)); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id); @@ -166,8 +169,8 @@ public class TestSimpleTableSoftDelete { @Test public void testReadAllValuesUnreadableOfDeletedObject() throws Exception { // check if we set get deleted element with all data - SimpleTableSoftDelete retrieve = SqlWrapper.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, - new QuerryOptions(QuerryOptions.SQL_DELETED_DISABLE, true, QuerryOptions.SQL_NOT_READ_DISABLE, true)); + final SimpleTableSoftDelete retrieve = DataAccess.get(SimpleTableSoftDelete.class, TestSimpleTableSoftDelete.idOfTheObject, + new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true, QueryOptions.SQL_NOT_READ_DISABLE, true)); Assertions.assertNotNull(retrieve); Assertions.assertNotNull(retrieve.id); Assertions.assertEquals(TestSimpleTableSoftDelete.idOfTheObject, retrieve.id); diff --git a/test/src/test/kar/archidata/TestTypeEnum1.java b/test/src/test/kar/archidata/TestTypeEnum1.java new file mode 100644 index 0000000..2b574ca --- /dev/null +++ b/test/src/test/kar/archidata/TestTypeEnum1.java @@ -0,0 +1,81 @@ +package test.kar.archidata; + +import java.io.IOException; +import java.util.List; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.kar.archidata.GlobalConfiguration; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.db.DBEntry; +import org.kar.archidata.util.ConfigBaseVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import test.kar.archidata.model.Enum1ForTest; +import test.kar.archidata.model.TypesEnum1; + +@ExtendWith(StepwiseExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class TestTypeEnum1 { + final static private Logger LOGGER = LoggerFactory.getLogger(TestTypeEnum1.class); + + @BeforeAll + public static void configureWebServer() throws Exception { + ConfigBaseVariable.dbType = "sqlite"; + ConfigBaseVariable.dbHost = "memory"; + // for test we need to connect all time the DB + ConfigBaseVariable.dbKeepConnected = "true"; + + // Connect the dataBase... + final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); + entry.connect(); + } + + @AfterAll + public static void removeDataBase() throws IOException { + LOGGER.info("Remove the test db"); + DBEntry.closeAllForceMode(); + ConfigBaseVariable.clearAllValue(); + } + + @Order(1) + @Test + public void testCreateTable() throws Exception { + final List sqlCommand = DataFactory.createTable(TypesEnum1.class); + for (final String elem : sqlCommand) { + LOGGER.debug("request: '{}'", elem); + DataAccess.executeSimpleQuerry(elem, false); + } + } + + @Order(2) + @Test + public void testEnum() throws Exception { + + final TypesEnum1 test = new TypesEnum1(); + test.data = Enum1ForTest.ENUM_VALUE_3; + final TypesEnum1 insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesEnum1 retrieve = DataAccess.get(TypesEnum1.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.data); + Assertions.assertEquals(insertedData.data, retrieve.data); + + DataAccess.delete(TypesEnum1.class, insertedData.id); + } +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/TestTypeEnum2.java b/test/src/test/kar/archidata/TestTypeEnum2.java new file mode 100644 index 0000000..f09ba99 --- /dev/null +++ b/test/src/test/kar/archidata/TestTypeEnum2.java @@ -0,0 +1,120 @@ +package test.kar.archidata; + +import java.io.IOException; +import java.util.List; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.kar.archidata.GlobalConfiguration; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.db.DBEntry; +import org.kar.archidata.util.ConfigBaseVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import test.kar.archidata.model.Enum2ForTest; +import test.kar.archidata.model.TypesEnum2; + +@ExtendWith(StepwiseExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class TestTypeEnum2 { + final static private Logger LOGGER = LoggerFactory.getLogger(TestTypeEnum2.class); + + @BeforeAll + public static void configureWebServer() throws Exception { + ConfigBaseVariable.dbType = "sqlite"; + ConfigBaseVariable.dbHost = "memory"; + // for test we need to connect all time the DB + ConfigBaseVariable.dbKeepConnected = "true"; + + // Connect the dataBase... + final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); + entry.connect(); + } + + @AfterAll + public static void removeDataBase() throws IOException { + LOGGER.info("Remove the test db"); + DBEntry.closeAllForceMode(); + ConfigBaseVariable.clearAllValue(); + } + + @Order(1) + @Test + public void testCreateTable() throws Exception { + final List sqlCommand = DataFactory.createTable(TypesEnum2.class); + for (final String elem : sqlCommand) { + LOGGER.debug("request: '{}'", elem); + DataAccess.executeSimpleQuerry(elem, false); + } + } + + @Order(2) + @Test + public void testEnum() throws Exception { + + final TypesEnum2 test = new TypesEnum2(); + test.data = Enum2ForTest.ENUM_VALUE_4; + final TypesEnum2 insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + TypesEnum2 retrieve = DataAccess.get(TypesEnum2.class, insertedData.id); + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.data); + Assertions.assertEquals(insertedData.data, retrieve.data); + + // Update data to null + retrieve.data = null; + int ret = DataAccess.update(retrieve, retrieve.id); + Assertions.assertEquals(1, ret); + + // get new data + retrieve = DataAccess.get(TypesEnum2.class, insertedData.id); + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNull(retrieve.data); + + // Remove the data + ret = DataAccess.delete(TypesEnum2.class, insertedData.id); + Assertions.assertEquals(1, ret); + + // Get the removed data: + retrieve = DataAccess.get(TypesEnum2.class, insertedData.id); + Assertions.assertNull(retrieve); + } + + @Order(3) + @Test + public void testNull() throws Exception { + + final TypesEnum2 test = new TypesEnum2(); + test.data = null; + final TypesEnum2 insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesEnum2 retrieve = DataAccess.get(TypesEnum2.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNull(retrieve.data); + + DataAccess.delete(TypesEnum2.class, insertedData.id); + } +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/TestTypes.java b/test/src/test/kar/archidata/TestTypes.java new file mode 100644 index 0000000..cfe82ad --- /dev/null +++ b/test/src/test/kar/archidata/TestTypes.java @@ -0,0 +1,350 @@ +package test.kar.archidata; + +import java.io.IOException; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Date; +import java.util.List; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.kar.archidata.GlobalConfiguration; +import org.kar.archidata.dataAccess.DataAccess; +import org.kar.archidata.dataAccess.DataFactory; +import org.kar.archidata.db.DBEntry; +import org.kar.archidata.util.ConfigBaseVariable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import test.kar.archidata.model.TypesTable; + +@ExtendWith(StepwiseExtension.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class TestTypes { + final static private Logger LOGGER = LoggerFactory.getLogger(TestTypes.class); + + @BeforeAll + public static void configureWebServer() throws Exception { + ConfigBaseVariable.dbType = "sqlite"; + ConfigBaseVariable.dbHost = "memory"; + // for test we need to connect all time the DB + ConfigBaseVariable.dbKeepConnected = "true"; + + // Connect the dataBase... + final DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig); + entry.connect(); + } + + @AfterAll + public static void removeDataBase() throws IOException { + LOGGER.info("Remove the test db"); + DBEntry.closeAllForceMode(); + ConfigBaseVariable.clearAllValue(); + } + + @Order(1) + @Test + public void testCreateTable() throws Exception { + final List sqlCommand = DataFactory.createTable(TypesTable.class); + for (final String elem : sqlCommand) { + LOGGER.debug("request: '{}'", elem); + DataAccess.executeSimpleQuerry(elem, false); + } + } + + @Order(2) + @Test + public void testInteger() throws Exception { + + final TypesTable test = new TypesTable(); + test.intData = 95; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.intData); + Assertions.assertEquals(insertedData.intData, retrieve.intData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(3) + @Test + public void testLong() throws Exception { + + final TypesTable test = new TypesTable(); + test.longData = 541684354354L; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.longData); + Assertions.assertEquals(insertedData.longData, retrieve.longData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(4) + @Test + public void testfloat() throws Exception { + + final TypesTable test = new TypesTable(); + test.floatData = 153154.0f; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.floatData); + Assertions.assertEquals(insertedData.floatData, retrieve.floatData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(5) + @Test + public void testDouble() throws Exception { + + final TypesTable test = new TypesTable(); + test.doubleData = 153152654654.0; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.doubleData); + Assertions.assertEquals(insertedData.doubleData, retrieve.doubleData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(6) + @Test + public void testText() throws Exception { + + final TypesTable test = new TypesTable(); + test.textData = "lkjlkjlkjmlkqjsdùkljqsùmckljvùwxmckvmwlkdnfqmsjdvnmclkwsjdn;vbcm = 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.textData); + Assertions.assertEquals(insertedData.textData, retrieve.textData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(7) + @Test + public void testVarChar() throws Exception { + + final TypesTable test = new TypesTable(); + test.varcharData = "123456789123456789"; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.varcharData); + Assertions.assertEquals(insertedData.varcharData, retrieve.varcharData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(8) + @Test + public void testBooleanTrue() throws Exception { + + final TypesTable test = new TypesTable(); + test.booleanData = true; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.booleanData); + Assertions.assertEquals(insertedData.booleanData, retrieve.booleanData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(9) + @Test + public void testBooleanFalse() throws Exception { + + final TypesTable test = new TypesTable(); + test.booleanData = false; + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + Assertions.assertNotNull(retrieve.booleanData); + Assertions.assertEquals(insertedData.booleanData, retrieve.booleanData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(10) + @Test + public void testTimeStamp() throws Exception { + + final TypesTable test = new TypesTable(); + test.timeStampData = Timestamp.from(Instant.now()); + LOGGER.debug("Timestamp = {}", test.timeStampData); + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + LOGGER.debug("Retreive Timestamp = {}", retrieve.timeStampData); + Assertions.assertNotNull(retrieve.timeStampData); + // Can not compare the exact timestamp due to aproximation and model of storing data : + //Assertions.assertEquals(insertedData.timeStampData, retrieve.timeStampData); + Assertions.assertEquals(insertedData.timeStampData.toInstant().toEpochMilli(), retrieve.timeStampData.toInstant().toEpochMilli()); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(11) + @Test + public void testDate() throws Exception { + + final TypesTable test = new TypesTable(); + test.dateFullData = Date.from(Instant.now()); + LOGGER.debug("Date = {}", test.dateFullData); + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + LOGGER.debug("Retreive Date = {}", retrieve.dateFullData); + Assertions.assertNotNull(retrieve.dateFullData); + Assertions.assertEquals(insertedData.dateFullData, retrieve.dateFullData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(12) + @Test + public void testLocalDate() throws Exception { + + final TypesTable test = new TypesTable(); + test.dateData = LocalDate.now(); + LOGGER.debug("LocalDate = {}", test.dateData); + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + LOGGER.debug("Retreive LocalDate = {}", retrieve.dateData); + Assertions.assertNotNull(retrieve.dateData); + Assertions.assertEquals(insertedData.dateData, retrieve.dateData); + + DataAccess.delete(TypesTable.class, insertedData.id); + } + + @Order(13) + @Test + public void testLocalTime() throws Exception { + + final TypesTable test = new TypesTable(); + test.timeData = LocalTime.now(); + LOGGER.debug("LocalTime = {}", test.timeData); + final TypesTable insertedData = DataAccess.insert(test); + Assertions.assertNotNull(insertedData); + Assertions.assertNotNull(insertedData.id); + Assertions.assertTrue(insertedData.id >= 0); + + // Try to retrieve all the data: + final TypesTable retrieve = DataAccess.get(TypesTable.class, insertedData.id); + + Assertions.assertNotNull(retrieve); + Assertions.assertNotNull(retrieve.id); + Assertions.assertEquals(insertedData.id, retrieve.id); + LOGGER.debug("Retreive LocalTime = {}", retrieve.timeData); + Assertions.assertNotNull(insertedData.timeData); + Assertions.assertEquals(insertedData.timeData.getHour(), retrieve.timeData.getHour()); + Assertions.assertEquals(insertedData.timeData.getMinute(), retrieve.timeData.getMinute()); + Assertions.assertEquals(insertedData.timeData.getSecond(), retrieve.timeData.getSecond()); + + DataAccess.delete(TypesTable.class, insertedData.id); + } +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/model/Enum1ForTest.java b/test/src/test/kar/archidata/model/Enum1ForTest.java new file mode 100644 index 0000000..074dc44 --- /dev/null +++ b/test/src/test/kar/archidata/model/Enum1ForTest.java @@ -0,0 +1,5 @@ +package test.kar.archidata.model; + +public enum Enum1ForTest { + ENUM_VALUE_1, ENUM_VALUE_2, ENUM_VALUE_3, ENUM_VALUE_4, ENUM_VALUE_5, +} diff --git a/test/src/test/kar/archidata/model/Enum2ForTest.java b/test/src/test/kar/archidata/model/Enum2ForTest.java new file mode 100644 index 0000000..8c4b6f2 --- /dev/null +++ b/test/src/test/kar/archidata/model/Enum2ForTest.java @@ -0,0 +1,11 @@ +package test.kar.archidata.model; + +public enum Enum2ForTest { + ENUM_VALUE_1(5), ENUM_VALUE_2(6), ENUM_VALUE_3(55), ENUM_VALUE_4(84241), ENUM_VALUE_5(54546); + + private final int value; + + private Enum2ForTest(final int value) { + this.value = value; + } +} diff --git a/test/src/test/kar/archidata/model/SimpleTable.java b/test/src/test/kar/archidata/model/SimpleTable.java index 52b71a0..94d3783 100644 --- a/test/src/test/kar/archidata/model/SimpleTable.java +++ b/test/src/test/kar/archidata/model/SimpleTable.java @@ -4,4 +4,5 @@ import org.kar.archidata.model.GenericData; public class SimpleTable extends GenericData { public String data; + } \ No newline at end of file diff --git a/test/src/test/kar/archidata/model/TypesEnum1.java b/test/src/test/kar/archidata/model/TypesEnum1.java new file mode 100644 index 0000000..e50dcd3 --- /dev/null +++ b/test/src/test/kar/archidata/model/TypesEnum1.java @@ -0,0 +1,15 @@ +package test.kar.archidata.model; + +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +public class TypesEnum1 { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, unique = true) + public Long id = null; + + public Enum1ForTest data; +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/model/TypesEnum2.java b/test/src/test/kar/archidata/model/TypesEnum2.java new file mode 100644 index 0000000..489fed3 --- /dev/null +++ b/test/src/test/kar/archidata/model/TypesEnum2.java @@ -0,0 +1,15 @@ +package test.kar.archidata.model; + +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +public class TypesEnum2 { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, unique = true) + public Long id = null; + + public Enum2ForTest data; +} \ No newline at end of file diff --git a/test/src/test/kar/archidata/model/TypesTable.java b/test/src/test/kar/archidata/model/TypesTable.java new file mode 100644 index 0000000..9dfbc41 --- /dev/null +++ b/test/src/test/kar/archidata/model/TypesTable.java @@ -0,0 +1,31 @@ +package test.kar.archidata.model; + +import java.sql.Timestamp; +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Date; + +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +public class TypesTable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false, unique = true) + public Long id = null; + + public Double doubleData; + public Float floatData; + public Integer intData; + public Long longData; + public String textData; + @Column(length = 25) + public String varcharData; + public Boolean booleanData; + public Timestamp timeStampData; // THIS is SQL we do not need to be link with it ... + public Date dateFullData; // same as SQL time-stamp + public LocalDate dateData; // just the Date YYYY-MM-DD + public LocalTime timeData; // just the time HH:MM:SS.mmm +} \ No newline at end of file