[DEV] update sone modality of test and normalization

This commit is contained in:
Edouard DUPIN 2023-10-28 00:29:14 +02:00
parent bfb329b5be
commit 81cfe8a713
36 changed files with 1630 additions and 806 deletions

View File

@ -1 +0,0 @@
[]

View File

@ -6,8 +6,8 @@
<version>0.4.0</version>
<properties>
<maven.compiler.version>3.1</maven.compiler.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.dependency.version>3.1.1</maven.dependency.version>

View File

@ -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 {

View File

@ -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;
}
}

View File

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

View File

@ -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<SqlWrapperAddOn> addOn = new ArrayList<>();
public class DataAccess {
static final Logger LOGGER = LoggerFactory.getLogger(DataAccess.class);
static final List<DataAccessAddOn> 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<Long> getListOfIds(ResultSet rs, int iii, String separator) throws SQLException {
String trackString = rs.getString(iii);
public static List<Long> getListOfIds(final ResultSet rs, final int iii, final String separator) throws SQLException {
final String trackString = rs.getString(iii);
if (rs.wasNull()) {
return null;
}
List<Long> out = new ArrayList<>();
String[] elements = trackString.split("-");
for (String elem : elements) {
Long tmp = Long.parseLong(elem);
final List<Long> 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 <T> void setValuedb(final Class<?> type, final T data, int index, final Field field, final PreparedStatement ps)
throws IllegalArgumentException, IllegalAccessException, SQLException {
protected static <T> 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 <T> 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 <T> 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 <T> int update(final Class<T> clazz, final long id, final String jsonData) throws Exception {
public static <T, ID_TYPE> int updateWithJson(final Class<T> 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 <T> int updateWithJson(final Class<T> 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<String> iterator = root.fieldNames();
iterator.forEachRemaining(e -> keys.add(e));
return update(data, id, keys);
return 0;
}
public static <T> int update(final T data, final QueryItem condition) throws Exception {
return 0;
}
/**
*
* @param <T>
@ -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> T getWhere(final Class<T> clazz, final QuerryItem condition) throws Exception {
public static <T> T getWhere(final Class<T> clazz, final QueryItem condition) throws Exception {
return getWhere(clazz, condition, null);
}
public static <T> T getWhere(final Class<T> clazz, final QuerryItem condition, final QuerryOptions options) throws Exception {
public static <T> T getWhere(final Class<T> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
final List<T> 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 <T> List<T> getsWhere(final Class<T> clazz, final QuerryItem condition) throws Exception {
public static <T> List<T> getsWhere(final Class<T> clazz, final QueryItem condition) throws Exception {
return getsWhere(clazz, condition, null, null, null);
}
public static <T> List<T> getsWhere(final Class<T> clazz, final QuerryItem condition, final QuerryOptions options) throws Exception {
public static <T> List<T> getsWhere(final Class<T> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
return getsWhere(clazz, condition, null, options, null);
}
public static <T> List<T> getsWhere(final Class<T> clazz, final QuerryItem condition, final QuerryOptions options, final Integer linit) throws Exception {
public static <T> List<T> getsWhere(final Class<T> 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 <T> List<T> getsWhere(final Class<T> clazz, final QuerryItem condition, final String orderBy, final QuerryOptions options, final Integer linit) throws Exception {
public static <T> List<T> getsWhere(final Class<T> 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> T get(final Class<T> clazz, final long id, final QuerryOptions options) throws Exception {
public static <T> T get(final Class<T> 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 <T> List<T> gets(final Class<T> clazz, final QuerryOptions options) throws Exception {
public static <T> List<T> gets(final Class<T> 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<String> 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<String> preOtherTables, final List<String> 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<String> 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<String> preActionList = new ArrayList<>();
final List<String> 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<String> 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<String> 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;
}
}

View File

@ -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<String> preActionList, List<String> postActionList, boolean createIfNotExist, boolean createDrop, int fieldId)
throws Exception;
}

View File

@ -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<String> preOtherTables, final List<String> 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<String> createTable(final Class<?> clazz) throws Exception {
return createTable(clazz, true);
}
public static List<String> 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<String> preActionList = new ArrayList<>();
final List<String> 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<String> 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<String> 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;
}
}

View File

@ -1,4 +1,4 @@
package org.kar.archidata.sqlWrapper;
package org.kar.archidata.dataAccess;
// Mark as deprecated while the concept is not ready ...
@Deprecated

View File

@ -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<QuerryItem> childs;
public class QueryAnd implements QueryItem {
protected final List<QueryItem> childs;
public QuerryAnd(List<QuerryItem> childs) {
public QueryAnd(List<QueryItem> 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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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<String, Object> 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);

View File

@ -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<QuerryItem> childs;
public class QueryOr implements QueryItem {
protected final List<QueryItem> childs;
public QuerryOr(List<QuerryItem> childs) {
public QueryOr(List<QueryItem> 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;

View File

@ -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<Long> 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<Long> 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);

View File

@ -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);

View File

@ -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<Long> 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<Long>) data);
final String dataTmp = getStringOfIds((List<Long>) 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<String> preActionList, List<String> postActionList,
public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preActionList, final List<String> 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);
}
}

View File

@ -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<Long> ids) {
final List<Long> 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<Long>) 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<Long> 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<String> preActionList, final List<String> 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);
}
}

View File

@ -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;

View File

@ -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<MigrationInterface> datas;
// initialization of the migration if the DB is not present...
private MigrationInterface init;
/**
* Migration engine constructor (empty).
*/
public MigrationEngine() {
this(new ArrayList<MigrationInterface>(), null);
this(new ArrayList<>(), null);
}
/**
* Migration engine constructor (specific mode).
* @param datas All the migration ordered.
* @param init Initialization migration model.
*/
public MigrationEngine(List<MigrationInterface> datas, MigrationInterface init) {
public MigrationEngine(final List<MigrationInterface> 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<MigrationModel> data = SqlWrapper.gets(MigrationModel.class, new QuerryOptions("SQLNotRead_disable", true));
final List<MigrationModel> 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<String> 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<MigrationInterface> 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<MigrationInterface> toApply = new ArrayList<>();
public void revertTo(final DBEntry entry, final String migrationName) {
final MigrationModel currentVersion = getCurrentVersion();
final List<MigrationInterface> 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());
}
}

View File

@ -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<String> 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<Action> 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<String> tmp = SqlWrapper.createTable(clazz, false);
for (String elem : tmp) {
final List<String> tmp = DataFactory.createTable(clazz, false);
for (final String elem : tmp) {
this.actions.add(new Action(elem));
}
}
@Override
public int getNumberOfStep() {
return this.actions.size();
}
}

View File

@ -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;
*/
}

View File

@ -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<Long> ids) {
List<Long> 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<Long>) 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<Long> 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<String> preActionList, List<String> 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);
}
}

View File

@ -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();

View File

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

View File

@ -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<String> sqlCommand = SqlWrapper.createTable(SimpleTable.class);
for (String elem : sqlCommand) {
final List<String> 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);
}

View File

@ -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<String> sqlCommand = SqlWrapper.createTable(SimpleTableSoftDelete.class);
for (String elem : sqlCommand) {
final List<String> 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);

View File

@ -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<String> 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);
}
}

View File

@ -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<String> 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);
}
}

View File

@ -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<String> 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 <wkdjncvm<wk:dnxcm<lwkdnc mqs<wdn:cx,<nm wlx!k:cn<;wmlx:!c;,<wmlx!:c;n<wm ldx:;c,<nwmlx:c,;<wmlx!:c;,< w";
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.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);
}
}

View File

@ -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,
}

View File

@ -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;
}
}

View File

@ -4,4 +4,5 @@ import org.kar.archidata.model.GenericData;
public class SimpleTable extends GenericData {
public String data;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}