[DEV] refacto dataAccess and ManyToMany interface (get Long)
This commit is contained in:
parent
81cfe8a713
commit
8d271601be
@ -27,6 +27,7 @@
|
|||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
10
.project
10
.project
@ -10,16 +10,6 @@
|
|||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
|
|
||||||
<triggers>full,incremental,</triggers>
|
|
||||||
<arguments>
|
|
||||||
<dictionary>
|
|
||||||
<key>LaunchConfigHandle</key>
|
|
||||||
<value><project>/.externalToolBuilders/org.eclipse.jdt.core.javabuilder.launch</value>
|
|
||||||
</dictionary>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
<buildCommand>
|
<buildCommand>
|
||||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||||
<arguments>
|
<arguments>
|
||||||
|
@ -2,7 +2,10 @@ package org.kar.archidata.annotation;
|
|||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -15,6 +18,18 @@ import jakarta.persistence.Table;
|
|||||||
public class AnnotationTools {
|
public class AnnotationTools {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(AnnotationTools.class);
|
||||||
|
|
||||||
|
public static String getTableName(final Class<?> clazz, final QueryOptions options) throws Exception {
|
||||||
|
if (options != null) {
|
||||||
|
final Object data = options.get(QueryOptions.OVERRIDE_TABLE_NAME);
|
||||||
|
if (data instanceof final String optionString) {
|
||||||
|
return optionString;
|
||||||
|
} else if (data != null) {
|
||||||
|
LOGGER.error("'{}' ==> has not a String value: {}", QueryOptions.SQL_DELETED_DISABLE, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AnnotationTools.getTableName(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
public static String getTableName(final Class<?> element) throws Exception {
|
public static String getTableName(final Class<?> element) throws Exception {
|
||||||
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
|
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Table.class);
|
||||||
if (annotation.length == 0) {
|
if (annotation.length == 0) {
|
||||||
@ -206,4 +221,31 @@ public class AnnotationTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<String> getFieldsNames(final Class<?> clazz) throws Exception {
|
||||||
|
return getFieldsNamesFilter(clazz, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getAllFieldsNames(final Class<?> clazz) throws Exception {
|
||||||
|
return getFieldsNamesFilter(clazz, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String> getFieldsNamesFilter(final Class<?> clazz, final boolean full) throws Exception {
|
||||||
|
final List<String> out = new ArrayList<>();
|
||||||
|
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 (!full && AnnotationTools.isGenericField(elem)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
out.add(AnnotationTools.getFieldName(elem));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isGenericField(final Field elem) throws Exception {
|
||||||
|
return AnnotationTools.isPrimaryKey(elem) || AnnotationTools.isCreatedAtField(elem) || AnnotationTools.isUpdateAtField(elem);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package org.kar.archidata.dataAccess;
|
package org.kar.archidata.dataAccess;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -11,9 +14,8 @@ import java.time.LocalTime;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.aopalliance.reflect.Class;
|
|
||||||
import org.glassfish.jaxb.runtime.v2.schemagen.xmlschema.List;
|
|
||||||
import org.kar.archidata.GlobalConfiguration;
|
import org.kar.archidata.GlobalConfiguration;
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.annotation.CreationTimestamp;
|
import org.kar.archidata.annotation.CreationTimestamp;
|
||||||
@ -30,14 +32,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
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.ManyToMany;
|
import jakarta.persistence.ManyToMany;
|
||||||
import jakarta.persistence.ManyToOne;
|
import jakarta.persistence.ManyToOne;
|
||||||
import jakarta.ws.rs.InternalServerErrorException;
|
import jakarta.ws.rs.InternalServerErrorException;
|
||||||
import javassist.bytecode.Descriptor.Iterator;
|
|
||||||
|
|
||||||
public class DataAccess {
|
public class DataAccess {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(DataAccess.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(DataAccess.class);
|
||||||
@ -362,11 +360,22 @@ public class DataAccess {
|
|||||||
field.set(data, tmp);
|
field.set(data, tmp);
|
||||||
}
|
}
|
||||||
} else if (type == Date.class) {
|
} else if (type == Date.class) {
|
||||||
final Timestamp tmp = rs.getTimestamp(index);
|
try {
|
||||||
if (rs.wasNull()) {
|
final Timestamp tmp = rs.getTimestamp(index);
|
||||||
field.set(data, null);
|
if (rs.wasNull()) {
|
||||||
} else {
|
field.set(data, null);
|
||||||
field.set(data, Date.from(tmp.toInstant()));
|
} else {
|
||||||
|
field.set(data, Date.from(tmp.toInstant()));
|
||||||
|
}
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
final String tmp = rs.getString(index);
|
||||||
|
LOGGER.error("Fail to parse the SQL time !!! {}", tmp);
|
||||||
|
LOGGER.error("Fail to parse the SQL time !!! {}", Date.parse(tmp));
|
||||||
|
if (rs.wasNull()) {
|
||||||
|
field.set(data, null);
|
||||||
|
} else {
|
||||||
|
field.set(data, Date.parse(tmp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (type == LocalDate.class) {
|
} else if (type == LocalDate.class) {
|
||||||
final java.sql.Date tmp = rs.getDate(index);
|
final java.sql.Date tmp = rs.getDate(index);
|
||||||
@ -433,13 +442,16 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T insert(final T data) throws Exception {
|
public static <T> T insert(final T data) throws Exception {
|
||||||
|
return insert(data, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T insert(final T data, final QueryOptions options) throws Exception {
|
||||||
final Class<?> clazz = data.getClass();
|
final Class<?> clazz = data.getClass();
|
||||||
//public static NodeSmall createNode(String typeInNode, String name, String descrition, Long parentId) {
|
|
||||||
|
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
||||||
// real add in the BDD:
|
// real add in the BDD:
|
||||||
try {
|
try {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
final StringBuilder querry = new StringBuilder();
|
final StringBuilder querry = new StringBuilder();
|
||||||
querry.append("INSERT INTO `");
|
querry.append("INSERT INTO `");
|
||||||
@ -457,7 +469,7 @@ public class DataAccess {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && addOn.isExternal()) {
|
if (addOn != null && !addOn.canInsert()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
||||||
@ -496,7 +508,7 @@ public class DataAccess {
|
|||||||
querry.append("?");
|
querry.append("?");
|
||||||
}
|
}
|
||||||
querry.append(")");
|
querry.append(")");
|
||||||
//LOGGER.warn("generate the querry: '{}'", querry.toString());
|
LOGGER.warn("generate the querry: '{}'", querry.toString());
|
||||||
// prepare the request:
|
// prepare the request:
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
||||||
Field primaryKeyField = null;
|
Field primaryKeyField = null;
|
||||||
@ -511,7 +523,7 @@ public class DataAccess {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && addOn.isExternal()) {
|
if (addOn != null && !addOn.canInsert()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
||||||
@ -585,6 +597,17 @@ public class DataAccess {
|
|||||||
return insert(data);
|
return insert(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update an object with the inserted json data
|
||||||
|
*
|
||||||
|
* @param <T> Type of the object to insert
|
||||||
|
* @param <ID_TYPE> Master key on the object manage with @Id
|
||||||
|
* @param clazz Class reference of the insertion model
|
||||||
|
* @param id Key to insert data
|
||||||
|
* @param jsonData Json data (partial) values to update
|
||||||
|
* @return the number of object updated
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public static <T, ID_TYPE> int updateWithJson(final Class<T> clazz, final ID_TYPE 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 ....
|
// Find the ID field type ....
|
||||||
final Field idField = AnnotationTools.getIdField(clazz);
|
final Field idField = AnnotationTools.getIdField(clazz);
|
||||||
@ -592,12 +615,12 @@ public class DataAccess {
|
|||||||
throw new Exception("The class have no annotation @Id ==> can not determine the default type searching");
|
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
|
// check the compatibility of the id and the declared ID
|
||||||
if (id instanceof idField.getType()) {
|
final Class<?> typeClass = idField.getType();
|
||||||
|
if (id == typeClass) {
|
||||||
throw new Exception("Request update with the wriong type ...");
|
throw new Exception("Request update with the wriong type ...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Udpade Json Value
|
// Udpade Json Value
|
||||||
return updateWithJson(clazz, QueryCondition(AnnotationTools.getFieldName(idField), "=", id), jsonData);
|
return updateWithJson(clazz, new QueryCondition(AnnotationTools.getFieldName(idField), "=", id), jsonData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> int updateWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData) throws Exception {
|
public static <T> int updateWithJson(final Class<T> clazz, final QueryItem condition, final String jsonData) throws Exception {
|
||||||
@ -607,15 +630,17 @@ public class DataAccess {
|
|||||||
// Read the tree to filter injection of data:
|
// Read the tree to filter injection of data:
|
||||||
final JsonNode root = mapper.readTree(jsonData);
|
final JsonNode root = mapper.readTree(jsonData);
|
||||||
final List<String> keys = new ArrayList<>();
|
final List<String> keys = new ArrayList<>();
|
||||||
final Iterator<String> iterator = root.fieldNames();
|
final var iterator = root.fieldNames();
|
||||||
iterator.forEachRemaining(e -> keys.add(e));
|
iterator.forEachRemaining(e -> keys.add(e));
|
||||||
return update(data, id, keys);
|
return update(data, condition, keys);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
public static <T, ID_TYPE> int update(final T data, final ID_TYPE id) throws Exception {
|
||||||
|
return update(data, id, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> int update(final T data, final QueryItem condition) throws Exception {
|
public static <T> int update(final T data, final QueryItem condition) throws Exception {
|
||||||
|
return update(data, condition, null);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -627,14 +652,28 @@ public class DataAccess {
|
|||||||
* @return the affected rows.
|
* @return the affected rows.
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static <T> int update(final T data, final long id, final List<String> filterValue) throws Exception {
|
public static <T, ID_TYPE> int update(final T data, final ID_TYPE id, final List<String> filterValue) throws Exception {
|
||||||
|
// Find the ID field type ....
|
||||||
|
final Field idField = AnnotationTools.getIdField(data.getClass());
|
||||||
|
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
|
||||||
|
final Class<?> typeClass = idField.getType();
|
||||||
|
if (id == typeClass) {
|
||||||
|
throw new Exception("Request update with the wriong type ...");
|
||||||
|
}
|
||||||
|
return update(data, new QueryCondition(AnnotationTools.getFieldName(idField), "=", id), filterValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> int update(final T data, final QueryItem condition, final QueryOptions options, final List<String> filterValue) throws Exception {
|
||||||
final Class<?> clazz = data.getClass();
|
final Class<?> clazz = data.getClass();
|
||||||
//public static NodeSmall createNode(String typeInNode, String name, String description, Long parentId) {
|
//public static NodeSmall createNode(String typeInNode, String name, String description, Long parentId) {
|
||||||
|
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
||||||
// real add in the BDD:
|
// real add in the BDD:
|
||||||
try {
|
try {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
final StringBuilder querry = new StringBuilder();
|
final StringBuilder querry = new StringBuilder();
|
||||||
querry.append("UPDATE `");
|
querry.append("UPDATE `");
|
||||||
@ -642,27 +681,21 @@ public class DataAccess {
|
|||||||
querry.append("` SET ");
|
querry.append("` SET ");
|
||||||
|
|
||||||
boolean firstField = true;
|
boolean firstField = true;
|
||||||
Field primaryKeyField = null;
|
|
||||||
for (final Field elem : clazz.getFields()) {
|
for (final Field elem : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (AnnotationTools.isPrimaryKey(elem)) {
|
final String name = AnnotationTools.getFieldName(elem);
|
||||||
primaryKeyField = elem;
|
if (filterValue != null) {
|
||||||
|
if (!filterValue.contains(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (AnnotationTools.isGenericField(elem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && addOn.isExternal()) {
|
if (addOn != null && !addOn.canUpdate()) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final boolean createTime = AnnotationTools.isCreatedAtField(elem);
|
|
||||||
if (createTime) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final String name = AnnotationTools.getFieldName(elem);
|
|
||||||
final boolean updateTime = AnnotationTools.isUpdateAtField(elem);
|
|
||||||
if (!updateTime && !filterValue.contains(name)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!elem.getClass().isPrimitive()) {
|
if (!elem.getClass().isPrimitive()) {
|
||||||
@ -678,19 +711,13 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
querry.append(" `");
|
querry.append(" `");
|
||||||
querry.append(name);
|
querry.append(name);
|
||||||
querry.append("` = ");
|
querry.append("` = ? ");
|
||||||
if (updateTime) {
|
|
||||||
querry.append(getDBNow());
|
|
||||||
querry.append(" ");
|
|
||||||
} else {
|
|
||||||
querry.append("? ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
querry.append(" WHERE `");
|
querry.append(" ");
|
||||||
querry.append(AnnotationTools.getFieldName(primaryKeyField));
|
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
querry.append("` = ?");
|
whereAppendQuery(querry, tableName, condition, null, deletedFieldName);
|
||||||
firstField = true;
|
firstField = true;
|
||||||
// logger.debug("generate the querry: '{}'", querry.toString());
|
LOGGER.debug("generate the querry: '{}'", querry.toString());
|
||||||
// prepare the request:
|
// prepare the request:
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
||||||
int iii = 1;
|
int iii = 1;
|
||||||
@ -699,22 +726,18 @@ public class DataAccess {
|
|||||||
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (AnnotationTools.isPrimaryKey(elem)) {
|
final String name = AnnotationTools.getFieldName(elem);
|
||||||
|
if (filterValue != null) {
|
||||||
|
if (!filterValue.contains(name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (AnnotationTools.isGenericField(elem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && !addOn.canUpdate()) {
|
if (addOn != null && !addOn.canUpdate()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final boolean createTime = elem.getDeclaredAnnotationsByType(CreationTimestamp.class).length != 0;
|
|
||||||
if (createTime) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final String name = AnnotationTools.getFieldName(elem);
|
|
||||||
final boolean updateTime = elem.getDeclaredAnnotationsByType(UpdateTimestamp.class).length != 0;
|
|
||||||
if (updateTime || !filterValue.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (addOn == null) {
|
if (addOn == null) {
|
||||||
final Class<?> type = elem.getType();
|
final Class<?> type = elem.getType();
|
||||||
if (!type.isPrimitive()) {
|
if (!type.isPrimitive()) {
|
||||||
@ -728,7 +751,8 @@ public class DataAccess {
|
|||||||
iii = addOn.insertData(ps, data, iii);
|
iii = addOn.insertData(ps, data, iii);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ps.setLong(iii++, id);
|
iii = whereInjectValue(ps, condition, iii);
|
||||||
|
|
||||||
return ps.executeUpdate();
|
return ps.executeUpdate();
|
||||||
} catch (final SQLException ex) {
|
} catch (final SQLException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@ -808,13 +832,13 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void whereInjectValue(final PreparedStatement ps, final QueryItem condition) throws Exception {
|
public static int whereInjectValue(final PreparedStatement ps, final QueryItem condition, int iii) throws Exception {
|
||||||
// Check if we have a condition to generate
|
// Check if we have a condition to generate
|
||||||
if (condition == null) {
|
if (condition == null) {
|
||||||
return;
|
return iii;
|
||||||
}
|
}
|
||||||
int iii = 1;
|
|
||||||
iii = condition.injectQuerry(ps, iii);
|
iii = condition.injectQuerry(ps, iii);
|
||||||
|
return iii;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int executeSimpleQuerry(final String querry, final boolean root) throws SQLException, IOException {
|
public static int executeSimpleQuerry(final String querry, final boolean root) throws SQLException, IOException {
|
||||||
@ -861,7 +885,7 @@ public class DataAccess {
|
|||||||
return getsWhere(clazz, condition, null, options, linit);
|
return getsWhere(clazz, condition, null, options, linit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: set limit as an querry Option...
|
// TODO: set limit as an query Option...
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> List<T> getsWhere(final Class<T> clazz, final QueryItem condition, final String orderBy, final QueryOptions 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 {
|
||||||
|
|
||||||
@ -879,7 +903,7 @@ public class DataAccess {
|
|||||||
final List<T> outs = new ArrayList<>();
|
final List<T> outs = new ArrayList<>();
|
||||||
// real add in the BDD:
|
// real add in the BDD:
|
||||||
try {
|
try {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
//boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
final StringBuilder querry = new StringBuilder();
|
final StringBuilder querry = new StringBuilder();
|
||||||
querry.append("SELECT ");
|
querry.append("SELECT ");
|
||||||
@ -895,7 +919,7 @@ public class DataAccess {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && addOn.isExternal()) {
|
if (addOn != null && !addOn.canRetrieve(elem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO: Manage it with AddOn
|
// TODO: Manage it with AddOn
|
||||||
@ -936,7 +960,7 @@ public class DataAccess {
|
|||||||
LOGGER.debug("generate the querry: '{}'", querry.toString());
|
LOGGER.debug("generate the querry: '{}'", querry.toString());
|
||||||
// prepare the request:
|
// prepare the request:
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString(), Statement.RETURN_GENERATED_KEYS);
|
||||||
whereInjectValue(ps, condition);
|
whereInjectValue(ps, condition, 1);
|
||||||
// execute the request
|
// execute the request
|
||||||
final ResultSet rs = ps.executeQuery();
|
final ResultSet rs = ps.executeQuery();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
@ -949,7 +973,7 @@ public class DataAccess {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final DataAccessAddOn addOn = findAddOnforField(elem);
|
final DataAccessAddOn addOn = findAddOnforField(elem);
|
||||||
if (addOn != null && addOn.isExternal()) {
|
if (addOn != null && !addOn.canRetrieve(elem)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO: Manage it with AddOn
|
// TODO: Manage it with AddOn
|
||||||
@ -1017,29 +1041,33 @@ public class DataAccess {
|
|||||||
|
|
||||||
// TODO : detect the @Id
|
// TODO : detect the @Id
|
||||||
public static int delete(final Class<?> clazz, final long id) throws Exception {
|
public static int delete(final Class<?> clazz, final long id) throws Exception {
|
||||||
|
return delete(clazz, id, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int delete(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
|
||||||
final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
if (hasDeletedFieldName != null) {
|
if (hasDeletedFieldName != null) {
|
||||||
return deleteSoft(clazz, id);
|
return deleteSoft(clazz, id, options);
|
||||||
} else {
|
} else {
|
||||||
return deleteHard(clazz, id);
|
return deleteHard(clazz, id, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int deleteWhere(final Class<?> clazz, final QueryItem condition) throws Exception {
|
public static int deleteWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
|
||||||
final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
final String hasDeletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
if (hasDeletedFieldName != null) {
|
if (hasDeletedFieldName != null) {
|
||||||
return deleteSoftWhere(clazz, condition);
|
return deleteSoftWhere(clazz, condition, options);
|
||||||
} else {
|
} else {
|
||||||
return deleteHardWhere(clazz, condition);
|
return deleteHardWhere(clazz, condition, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int deleteHard(final Class<?> clazz, final long id) throws Exception {
|
public static int deleteHard(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
|
||||||
return deleteHardWhere(clazz, new QueryCondition("id", "=", id));
|
return deleteHardWhere(clazz, new QueryCondition("id", "=", id), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int deleteHardWhere(final Class<?> clazz, final QueryItem condition) throws Exception {
|
public static int deleteHardWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
// find the deleted field
|
// find the deleted field
|
||||||
|
|
||||||
@ -1052,7 +1080,7 @@ public class DataAccess {
|
|||||||
try {
|
try {
|
||||||
LOGGER.debug("APPLY: {}", querry.toString());
|
LOGGER.debug("APPLY: {}", querry.toString());
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
||||||
whereInjectValue(ps, condition);
|
whereInjectValue(ps, condition, 1);
|
||||||
return ps.executeUpdate();
|
return ps.executeUpdate();
|
||||||
} finally {
|
} finally {
|
||||||
entry.close();
|
entry.close();
|
||||||
@ -1060,8 +1088,8 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int deleteSoft(final Class<?> clazz, final long id) throws Exception {
|
private static int deleteSoft(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
|
||||||
return deleteSoftWhere(clazz, new QueryCondition("id", "=", id));
|
return deleteSoftWhere(clazz, new QueryCondition("id", "=", id), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDBNow() {
|
public static String getDBNow() {
|
||||||
@ -1071,8 +1099,8 @@ public class DataAccess {
|
|||||||
return "DATE()";
|
return "DATE()";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int deleteSoftWhere(final Class<?> clazz, final QueryItem condition) throws Exception {
|
public static int deleteSoftWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
/*
|
/*
|
||||||
String updateFieldName = null;
|
String updateFieldName = null;
|
||||||
@ -1102,7 +1130,7 @@ public class DataAccess {
|
|||||||
try {
|
try {
|
||||||
LOGGER.debug("APPLY UPDATE: {}", querry.toString());
|
LOGGER.debug("APPLY UPDATE: {}", querry.toString());
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
||||||
whereInjectValue(ps, condition);
|
whereInjectValue(ps, condition, 1);
|
||||||
return ps.executeUpdate();
|
return ps.executeUpdate();
|
||||||
} finally {
|
} finally {
|
||||||
entry.close();
|
entry.close();
|
||||||
@ -1111,11 +1139,15 @@ public class DataAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int unsetDelete(final Class<?> clazz, final long id) throws Exception {
|
public static int unsetDelete(final Class<?> clazz, final long id) throws Exception {
|
||||||
return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id));
|
return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int unsetDeleteWhere(final Class<?> clazz, final QueryItem condition) throws Exception {
|
public static int unsetDelete(final Class<?> clazz, final long id, final QueryOptions options) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
return unsetDeleteWhere(clazz, new QueryCondition("id", "=", id), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int unsetDeleteWhere(final Class<?> clazz, final QueryItem condition, final QueryOptions options) throws Exception {
|
||||||
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
final String deletedFieldName = AnnotationTools.getDeletedFieldName(clazz);
|
||||||
if (deletedFieldName == null) {
|
if (deletedFieldName == null) {
|
||||||
throw new Exception("The class " + clazz.getCanonicalName() + " has no deleted field");
|
throw new Exception("The class " + clazz.getCanonicalName() + " has no deleted field");
|
||||||
@ -1134,11 +1166,11 @@ public class DataAccess {
|
|||||||
querry.append(", ");
|
querry.append(", ");
|
||||||
*/
|
*/
|
||||||
// need to disable the deleted false because the model must be unselected to be updated.
|
// need to disable the deleted false because the model must be unselected to be updated.
|
||||||
final QueryOptions options = new QueryOptions(QueryOptions.SQL_DELETED_DISABLE, true);
|
options.put(QueryOptions.SQL_DELETED_DISABLE, true);
|
||||||
whereAppendQuery(querry, tableName, condition, options, deletedFieldName);
|
whereAppendQuery(querry, tableName, condition, options, deletedFieldName);
|
||||||
try {
|
try {
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
final PreparedStatement ps = entry.connection.prepareStatement(querry.toString());
|
||||||
whereInjectValue(ps, condition);
|
whereInjectValue(ps, condition, 1);
|
||||||
return ps.executeUpdate();
|
return ps.executeUpdate();
|
||||||
} finally {
|
} finally {
|
||||||
entry.close();
|
entry.close();
|
||||||
|
@ -39,8 +39,11 @@ public interface DataAccessAddOn {
|
|||||||
*/
|
*/
|
||||||
int insertData(PreparedStatement ps, Object data, int iii) throws SQLException;
|
int insertData(PreparedStatement ps, Object data, int iii) throws SQLException;
|
||||||
|
|
||||||
// External mean that the type of the object is absolutely not obvious...
|
// Element can insert in the single request
|
||||||
boolean isExternal();
|
boolean canInsert();
|
||||||
|
|
||||||
|
// Element can be retrieve with the specific mode
|
||||||
|
boolean canRetrieve(final Field field);
|
||||||
|
|
||||||
int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QueryOptions options);
|
int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QueryOptions options);
|
||||||
|
|
||||||
|
@ -273,11 +273,22 @@ public class DataFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> createTable(final Class<?> clazz) throws Exception {
|
public static List<String> createTable(final Class<?> clazz) throws Exception {
|
||||||
return createTable(clazz, true);
|
return createTable(clazz, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> createTable(final Class<?> clazz, final boolean createDrop) throws Exception {
|
public static List<String> createTable(final Class<?> clazz, final QueryOptions options) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz, options);
|
||||||
|
|
||||||
|
boolean createDrop = false;
|
||||||
|
if (options != null) {
|
||||||
|
final Object data = options.get(QueryOptions.CREATE_DROP_TABLE);
|
||||||
|
if (data instanceof final Boolean optionBoolean) {
|
||||||
|
createDrop = optionBoolean;
|
||||||
|
} else if (data != null) {
|
||||||
|
LOGGER.error("'{}' ==> has not a Boolean value: {}", QueryOptions.CREATE_DROP_TABLE, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
final boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
|
||||||
final List<String> preActionList = new ArrayList<>();
|
final List<String> preActionList = new ArrayList<>();
|
||||||
final List<String> postActionList = new ArrayList<>();
|
final List<String> postActionList = new ArrayList<>();
|
||||||
@ -311,7 +322,7 @@ public class DataFactory {
|
|||||||
Class<?> currentClazz = clazz;
|
Class<?> currentClazz = clazz;
|
||||||
while (currentClazz != null) {
|
while (currentClazz != null) {
|
||||||
fieldId = 0;
|
fieldId = 0;
|
||||||
LOGGER.info("parse class: '{}'", currentClazz.getCanonicalName());
|
LOGGER.trace("parse class: '{}'", currentClazz.getCanonicalName());
|
||||||
for (final Field elem : clazz.getFields()) {
|
for (final Field elem : clazz.getFields()) {
|
||||||
// static field is only for internal global declaration ==> remove it ..
|
// static field is only for internal global declaration ==> remove it ..
|
||||||
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
|
||||||
@ -327,10 +338,10 @@ public class DataFactory {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
alreadyAdded.add(dataName);
|
alreadyAdded.add(dataName);
|
||||||
LOGGER.info(" + '{}'", elem.getName());
|
LOGGER.trace(" + '{}'", elem.getName());
|
||||||
if (DataAccess.isAddOnField(elem)) {
|
if (DataAccess.isAddOnField(elem)) {
|
||||||
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
|
final DataAccessAddOn addOn = DataAccess.findAddOnforField(elem);
|
||||||
LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
|
LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
|
||||||
if (addOn != null) {
|
if (addOn != null) {
|
||||||
addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
|
addOn.createTables(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId);
|
||||||
} else {
|
} else {
|
||||||
@ -338,7 +349,7 @@ public class DataFactory {
|
|||||||
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
|
"Element matked as add-on but add-on does not loaded: table:" + tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type=" + elem.getType());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGGER.info("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
|
LOGGER.trace("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
|
||||||
DataFactory.createTablesSpecificType(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
|
DataFactory.createTablesSpecificType(tableName, elem, tmpOut, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
|
||||||
}
|
}
|
||||||
fieldId++;
|
fieldId++;
|
||||||
|
@ -6,6 +6,8 @@ import java.util.Map;
|
|||||||
public class QueryOptions {
|
public class QueryOptions {
|
||||||
public static final String SQL_NOT_READ_DISABLE = "SQLNotRead_disable";
|
public static final String SQL_NOT_READ_DISABLE = "SQLNotRead_disable";
|
||||||
public static final String SQL_DELETED_DISABLE = "SQLDeleted_disable";
|
public static final String SQL_DELETED_DISABLE = "SQLDeleted_disable";
|
||||||
|
public static final String OVERRIDE_TABLE_NAME = "SQL_OVERRIDE_TABLE_NAME";
|
||||||
|
public static final String CREATE_DROP_TABLE = "CREATE_DROP_TABLE";
|
||||||
|
|
||||||
private final Map<String, Object> options = new HashMap<>();
|
private final Map<String, Object> options = new HashMap<>();
|
||||||
|
|
||||||
@ -13,26 +15,26 @@ public class QueryOptions {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryOptions(String key, Object value) {
|
public QueryOptions(final String key, final Object value) {
|
||||||
this.options.put(key, value);
|
this.options.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryOptions(String key, Object value, String key2, Object value2) {
|
public QueryOptions(final String key, final Object value, final String key2, final Object value2) {
|
||||||
this.options.put(key, value);
|
this.options.put(key, value);
|
||||||
this.options.put(key2, value2);
|
this.options.put(key2, value2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryOptions(String key, Object value, String key2, Object value2, String key3, Object value3) {
|
public QueryOptions(final String key, final Object value, final String key2, final Object value2, final String key3, final Object value3) {
|
||||||
this.options.put(key, value);
|
this.options.put(key, value);
|
||||||
this.options.put(key2, value2);
|
this.options.put(key2, value2);
|
||||||
this.options.put(key3, value3);
|
this.options.put(key3, value3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void put(String key, Object value) {
|
public void put(final String key, final Object value) {
|
||||||
this.options.put(key, value);
|
this.options.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(String value) {
|
public Object get(final String value) {
|
||||||
return this.options.get(value);
|
return this.options.get(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,16 +4,16 @@ import java.lang.reflect.Field;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.kar.archidata.GlobalConfiguration;
|
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccessAddOn;
|
import org.kar.archidata.dataAccess.DataAccessAddOn;
|
||||||
import org.kar.archidata.dataAccess.DataAccess.ExceptionDBInterface;
|
import org.kar.archidata.dataAccess.DataFactory;
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.dataAccess.QueryAnd;
|
||||||
|
import org.kar.archidata.dataAccess.QueryCondition;
|
||||||
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
|
import org.kar.archidata.dataAccess.addOn.model.LinkTable;
|
||||||
import org.kar.archidata.util.ConfigBaseVariable;
|
import org.kar.archidata.util.ConfigBaseVariable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -42,29 +42,42 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
|
public int insertData(final PreparedStatement ps, final Object data, final int iii) throws SQLException {
|
||||||
return iii;
|
return iii;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExternal() {
|
public boolean canInsert() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int generateQuerry(@NotNull final String tableName, @NotNull final Field elem, @NotNull final StringBuilder querry, @NotNull final String name, @NotNull final int elemCount,
|
public boolean canRetrieve(final Field field) {
|
||||||
QueryOptions options) {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateLinkTableNameField(final String tableName, final Field field) throws Exception {
|
||||||
|
final String name = AnnotationTools.getFieldName(field);
|
||||||
|
return generateLinkTableName(tableName, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateLinkTableName(final String tableName, final String name) {
|
||||||
String localName = name;
|
String localName = name;
|
||||||
if (name.endsWith("s")) {
|
if (name.endsWith("s")) {
|
||||||
localName = name.substring(0, name.length() - 1);
|
localName = name.substring(0, name.length() - 1);
|
||||||
}
|
}
|
||||||
|
return tableName + "_link_" + localName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
final String linkTableName = generateLinkTableName(tableName, name);
|
||||||
|
|
||||||
final String tmpVariable = "tmp_" + Integer.toString(elemCount);
|
final String tmpVariable = "tmp_" + Integer.toString(elemCount);
|
||||||
querry.append(" (SELECT GROUP_CONCAT(");
|
querry.append(" (SELECT GROUP_CONCAT(");
|
||||||
querry.append(tmpVariable);
|
querry.append(tmpVariable);
|
||||||
querry.append(".");
|
querry.append(".object2Id");
|
||||||
querry.append(localName);
|
|
||||||
querry.append("_id ");
|
|
||||||
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
querry.append(", ");
|
querry.append(", ");
|
||||||
} else {
|
} else {
|
||||||
@ -73,9 +86,7 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
querry.append("'");
|
querry.append("'");
|
||||||
querry.append(SEPARATOR);
|
querry.append(SEPARATOR);
|
||||||
querry.append("') FROM ");
|
querry.append("') FROM ");
|
||||||
querry.append(tableName);
|
querry.append(linkTableName);
|
||||||
querry.append("_link_");
|
|
||||||
querry.append(localName);
|
|
||||||
querry.append(" ");
|
querry.append(" ");
|
||||||
querry.append(tmpVariable);
|
querry.append(tmpVariable);
|
||||||
querry.append(" WHERE ");
|
querry.append(" WHERE ");
|
||||||
@ -85,12 +96,13 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
querry.append(".id = ");
|
querry.append(".id = ");
|
||||||
querry.append(tmpVariable);
|
querry.append(tmpVariable);
|
||||||
querry.append(".");
|
querry.append(".");
|
||||||
querry.append(tableName);
|
querry.append("object1Id ");
|
||||||
querry.append("_id GROUP BY ");
|
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||||
querry.append(tmpVariable);
|
querry.append(" GROUP BY ");
|
||||||
querry.append(".");
|
querry.append(tmpVariable);
|
||||||
querry.append(tableName);
|
querry.append(".object2Id");
|
||||||
querry.append("_id ) AS ");
|
}
|
||||||
|
querry.append(") AS ");
|
||||||
querry.append(name);
|
querry.append(name);
|
||||||
querry.append(" ");
|
querry.append(" ");
|
||||||
/*
|
/*
|
||||||
@ -104,8 +116,9 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QueryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException {
|
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, final QueryOptions options)
|
||||||
List<Long> idList = DataAccess.getListOfIds(rs, count, SEPARATOR);
|
throws SQLException, IllegalArgumentException, IllegalAccessException {
|
||||||
|
final List<Long> idList = DataAccess.getListOfIds(rs, count, SEPARATOR);
|
||||||
elem.set(data, idList);
|
elem.set(data, idList);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -115,122 +128,29 @@ public class AddOnManyToMany implements DataAccessAddOn {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addLink(final Class<?> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
|
public static void addLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
final String linkTableName = generateLinkTableName(tableName, column);
|
||||||
long uniqueSQLID = -1;
|
final LinkTable insertElement = new LinkTable(localKey, remoteKey);
|
||||||
// real add in the BDD:
|
final QueryOptions options = new QueryOptions(QueryOptions.OVERRIDE_TABLE_NAME, linkTableName);
|
||||||
try {
|
DataAccess.insert(insertElement, options);
|
||||||
// prepare the request:
|
|
||||||
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);
|
|
||||||
ps.setLong(iii++, remoteKey);
|
|
||||||
// execute the request
|
|
||||||
final int affectedRows = ps.executeUpdate();
|
|
||||||
if (affectedRows == 0) {
|
|
||||||
throw new SQLException("Creating data failed, no rows affected.");
|
|
||||||
}
|
|
||||||
// retrieve uid inserted
|
|
||||||
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
|
|
||||||
if (generatedKeys.next()) {
|
|
||||||
uniqueSQLID = generatedKeys.getLong(1);
|
|
||||||
} else {
|
|
||||||
throw new SQLException("Creating user failed, no ID obtained (1).");
|
|
||||||
}
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
LOGGER.debug("Can not get the UID key inserted ... ");
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new SQLException("Creating user failed, no ID obtained (2).");
|
|
||||||
}
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
|
|
||||||
} finally {
|
|
||||||
entry.close();
|
|
||||||
entry = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeLink(final Class<?> clazz, final long localKey, final String table, final long remoteKey) throws Exception {
|
public static int removeLink(final Class<?> clazz, final long localKey, final String column, final long remoteKey) throws Exception {
|
||||||
final String tableName = AnnotationTools.getTableName(clazz);
|
final String tableName = AnnotationTools.getTableName(clazz);
|
||||||
DBEntry entry = DBEntry.createInterface(GlobalConfiguration.dbConfig);
|
final String linkTableName = generateLinkTableName(tableName, column);
|
||||||
final String querry = "UPDATE `" + tableName + "_link_" + table + "` SET `modify_date`=" + DataAccess.getDBNow() + ", `deleted`=true WHERE `" + tableName + "_id` = ? AND `" + table
|
final QueryOptions options = new QueryOptions(QueryOptions.OVERRIDE_TABLE_NAME, linkTableName);
|
||||||
+ "_id` = ?";
|
final QueryAnd condition = new QueryAnd(new QueryCondition("object1Id", "=", localKey), new QueryCondition("object2Id", "=", remoteKey));
|
||||||
try {
|
return DataAccess.deleteWhere(LinkTable.class, condition, options);
|
||||||
final PreparedStatement ps = entry.connection.prepareStatement(querry);
|
|
||||||
int iii = 1;
|
|
||||||
ps.setLong(iii++, localKey);
|
|
||||||
ps.setLong(iii++, remoteKey);
|
|
||||||
ps.executeUpdate();
|
|
||||||
} catch (final SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
throw new ExceptionDBInterface(500, "SQL error: " + ex.getMessage());
|
|
||||||
} finally {
|
|
||||||
entry.close();
|
|
||||||
entry = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system
|
|
||||||
@Override
|
@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 {
|
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
||||||
final String name = AnnotationTools.getFieldName(elem);
|
final String linkTableName = generateLinkTableNameField(tableName, elem);
|
||||||
String localName = name;
|
final QueryOptions options = new QueryOptions(QueryOptions.OVERRIDE_TABLE_NAME, linkTableName);
|
||||||
if (name.endsWith("s")) {
|
final List<String> sqlCommand = DataFactory.createTable(LinkTable.class, options);
|
||||||
localName = name.substring(0, name.length() - 1);
|
postActionList.addAll(sqlCommand);
|
||||||
}
|
|
||||||
if (createIfNotExist && createDrop) {
|
|
||||||
final StringBuilder tableTmp = new StringBuilder();
|
|
||||||
tableTmp.append("DROP TABLE IF EXISTS `");
|
|
||||||
tableTmp.append(tableName);
|
|
||||||
tableTmp.append("_link_");
|
|
||||||
tableTmp.append(localName);
|
|
||||||
tableTmp.append("`;");
|
|
||||||
postActionList.add(tableTmp.toString());
|
|
||||||
}
|
|
||||||
final StringBuilder otherTable = new StringBuilder();
|
|
||||||
otherTable.append("CREATE TABLE `");
|
|
||||||
otherTable.append(tableName);
|
|
||||||
otherTable.append("_link_");
|
|
||||||
otherTable.append(localName);
|
|
||||||
otherTable.append("`(\n");
|
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
|
||||||
otherTable.append("\t\t`id` bigint NOT NULL AUTO_INCREMENT,\n");
|
|
||||||
otherTable.append("\t\t`deleted` tinyint(1) NOT NULL DEFAULT '0',\n");
|
|
||||||
otherTable.append("\t\t`createdAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
|
|
||||||
otherTable.append("\t\t`updatedAt` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),\n");
|
|
||||||
} else {
|
|
||||||
otherTable.append("\t\t`id` INTEGER PRIMARY KEY AUTOINCREMENT,\n");
|
|
||||||
otherTable.append("\t\t`deleted` INTEGER NOT NULL DEFAULT '0',\n");
|
|
||||||
otherTable.append("\t\t`createdAt` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
|
|
||||||
otherTable.append("\t\t`updatedAt` INTEGER NOT NULL DEFAULT CURRENT_TIMESTAMP,\n");
|
|
||||||
}
|
|
||||||
otherTable.append("\t\t`");
|
|
||||||
otherTable.append(tableName);
|
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
|
||||||
otherTable.append("_id` bigint NOT NULL,\n");
|
|
||||||
} else {
|
|
||||||
otherTable.append("_id` INTEGER NOT NULL,\n");
|
|
||||||
}
|
|
||||||
otherTable.append("\t\t`");
|
|
||||||
otherTable.append(localName);
|
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
|
||||||
otherTable.append("_id` bigint NOT NULL\n");
|
|
||||||
} else {
|
|
||||||
otherTable.append("_id` INTEGER NOT NULL\n");
|
|
||||||
}
|
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
|
||||||
otherTable.append("\t, PRIMARY KEY (`id`)\n");
|
|
||||||
}
|
|
||||||
otherTable.append("\t)");
|
|
||||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
|
||||||
otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
|
|
||||||
}
|
|
||||||
otherTable.append(";");
|
|
||||||
postActionList.add(otherTable.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import java.util.List;
|
|||||||
import org.kar.archidata.GlobalConfiguration;
|
import org.kar.archidata.GlobalConfiguration;
|
||||||
import org.kar.archidata.annotation.AnnotationTools;
|
import org.kar.archidata.annotation.AnnotationTools;
|
||||||
import org.kar.archidata.annotation.addOn.DataAddOnManyToManyOrdered;
|
import org.kar.archidata.annotation.addOn.DataAddOnManyToManyOrdered;
|
||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.DataAccessAddOn;
|
|
||||||
import org.kar.archidata.dataAccess.DataAccess.ExceptionDBInterface;
|
import org.kar.archidata.dataAccess.DataAccess.ExceptionDBInterface;
|
||||||
|
import org.kar.archidata.dataAccess.DataAccessAddOn;
|
||||||
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.db.DBEntry;
|
||||||
import org.kar.archidata.util.ConfigBaseVariable;
|
import org.kar.archidata.util.ConfigBaseVariable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -46,18 +46,23 @@ public class AddOnManyToManyOrdered implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
|
public int insertData(final PreparedStatement ps, final Object data, final int iii) throws SQLException {
|
||||||
return iii;
|
return iii;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExternal() {
|
public boolean canInsert() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QueryOptions options) {
|
public boolean canRetrieve(final Field field) {
|
||||||
|
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) {
|
||||||
String localName = name;
|
String localName = name;
|
||||||
if (name.endsWith("s")) {
|
if (name.endsWith("s")) {
|
||||||
localName = name.substring(0, name.length() - 1);
|
localName = name.substring(0, name.length() - 1);
|
||||||
@ -103,7 +108,8 @@ public class AddOnManyToManyOrdered implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QueryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException {
|
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, final QueryOptions options)
|
||||||
|
throws SQLException, IllegalArgumentException, IllegalAccessException {
|
||||||
//throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
|
//throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -174,7 +180,7 @@ public class AddOnManyToManyOrdered implements DataAccessAddOn {
|
|||||||
|
|
||||||
// TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system
|
// TODO : refacto this table to manage a generic table with dynamic name to be serializable with the default system
|
||||||
@Override
|
@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 {
|
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
||||||
final String name = AnnotationTools.getFieldName(elem);
|
final String name = AnnotationTools.getFieldName(elem);
|
||||||
String localName = name;
|
String localName = name;
|
||||||
|
@ -89,8 +89,12 @@ public class AddOnManyToOne implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExternal() {
|
public boolean canInsert() {
|
||||||
// TODO Auto-generated method stub
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRetrieve(final Field field) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,12 @@ public class AddOnSQLTableExternalForeinKeyAsList implements DataAccessAddOn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExternal() {
|
public boolean canInsert() {
|
||||||
// TODO Auto-generated method stub
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRetrieve(final Field field) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
25
src/org/kar/archidata/dataAccess/addOn/model/LinkTable.java
Normal file
25
src/org/kar/archidata/dataAccess/addOn/model/LinkTable.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package org.kar.archidata.dataAccess.addOn.model;
|
||||||
|
|
||||||
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
|
import org.kar.archidata.model.GenericDataSoftDelete;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
|
||||||
|
public class LinkTable extends GenericDataSoftDelete {
|
||||||
|
public LinkTable() {
|
||||||
|
// nothing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkTable(final long object1Id, final long object2Id) {
|
||||||
|
this.object1Id = object1Id;
|
||||||
|
this.object2Id = object2Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SQLComment("Object reference 1")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public Long object1Id;
|
||||||
|
@SQLComment("Object reference 2")
|
||||||
|
@Column(nullable = false)
|
||||||
|
public Long object2Id;
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,7 @@ import org.kar.archidata.dataAccess.DataFactory;
|
|||||||
import org.kar.archidata.dataAccess.QueryOptions;
|
import org.kar.archidata.dataAccess.QueryOptions;
|
||||||
import org.kar.archidata.db.DBConfig;
|
import org.kar.archidata.db.DBConfig;
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.db.DBEntry;
|
||||||
|
import org.kar.archidata.migration.model.Migration;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -58,12 +59,12 @@ public class MigrationEngine {
|
|||||||
* Get the current version/migration name
|
* Get the current version/migration name
|
||||||
* @return Model represent the last migration. If null then no migration has been done.
|
* @return Model represent the last migration. If null then no migration has been done.
|
||||||
*/
|
*/
|
||||||
public MigrationModel getCurrentVersion() {
|
public Migration getCurrentVersion() {
|
||||||
if (!DataAccess.isTableExist("KAR_migration")) {
|
if (!DataAccess.isTableExist("KAR_migration")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final List<MigrationModel> data = DataAccess.gets(MigrationModel.class, new QueryOptions("SQLNotRead_disable", true));
|
final List<Migration> data = DataAccess.gets(Migration.class, new QueryOptions("SQLNotRead_disable", true));
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
LOGGER.error("Can not collect the migration table in the DB:{}");
|
LOGGER.error("Can not collect the migration table in the DB:{}");
|
||||||
return null;
|
return null;
|
||||||
@ -73,7 +74,7 @@ public class MigrationEngine {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
LOGGER.debug("List of migrations:");
|
LOGGER.debug("List of migrations:");
|
||||||
for (final MigrationModel elem : data) {
|
for (final Migration elem : data) {
|
||||||
LOGGER.debug(" - date={} name={} end={}", elem.updatedAt, elem.name, elem.terminated);
|
LOGGER.debug(" - date={} name={} end={}", elem.updatedAt, elem.name, elem.terminated);
|
||||||
}
|
}
|
||||||
return data.get(data.size() - 1);
|
return data.get(data.size() - 1);
|
||||||
@ -117,7 +118,7 @@ public class MigrationEngine {
|
|||||||
// create the table:
|
// create the table:
|
||||||
List<String> sqlQuery;
|
List<String> sqlQuery;
|
||||||
try {
|
try {
|
||||||
sqlQuery = DataFactory.createTable(MigrationModel.class, false);
|
sqlQuery = DataFactory.createTable(Migration.class);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -136,7 +137,7 @@ public class MigrationEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final MigrationModel currentVersion = getCurrentVersion();
|
final Migration currentVersion = getCurrentVersion();
|
||||||
List<MigrationInterface> toApply = new ArrayList<>();
|
List<MigrationInterface> toApply = new ArrayList<>();
|
||||||
if (currentVersion == null) {
|
if (currentVersion == null) {
|
||||||
//This is a first migration
|
//This is a first migration
|
||||||
@ -151,7 +152,8 @@ public class MigrationEngine {
|
|||||||
} else {
|
} else {
|
||||||
// we insert a placeholder to simulate all migration is well done.
|
// we insert a placeholder to simulate all migration is well done.
|
||||||
final 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();
|
Migration migrationResult = new Migration();
|
||||||
|
migrationResult.id = 1000L;
|
||||||
migrationResult.name = placeholderName;
|
migrationResult.name = placeholderName;
|
||||||
migrationResult.stepId = 0;
|
migrationResult.stepId = 0;
|
||||||
migrationResult.terminated = true;
|
migrationResult.terminated = true;
|
||||||
@ -197,10 +199,12 @@ public class MigrationEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void migrateSingle(final DBEntry entry, final MigrationInterface elem, final int id, final 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());
|
LOGGER.info("---------------------------------------------------------");
|
||||||
|
LOGGER.info("-- Migrate: [{}/{}] {} [BEGIN]", id, count, elem.getName());
|
||||||
|
LOGGER.info("---------------------------------------------------------");
|
||||||
final StringBuilder log = new StringBuilder();
|
final StringBuilder log = new StringBuilder();
|
||||||
log.append("Start migration");
|
log.append("Start migration\n");
|
||||||
MigrationModel migrationResult = new MigrationModel();
|
Migration migrationResult = new Migration();
|
||||||
migrationResult.name = elem.getName();
|
migrationResult.name = elem.getName();
|
||||||
migrationResult.stepId = 0;
|
migrationResult.stepId = 0;
|
||||||
migrationResult.terminated = false;
|
migrationResult.terminated = false;
|
||||||
@ -243,7 +247,7 @@ public class MigrationEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void revertTo(final DBEntry entry, final String migrationName) {
|
public void revertTo(final DBEntry entry, final String migrationName) {
|
||||||
final MigrationModel currentVersion = getCurrentVersion();
|
final Migration currentVersion = getCurrentVersion();
|
||||||
final List<MigrationInterface> toApply = new ArrayList<>();
|
final List<MigrationInterface> toApply = new ArrayList<>();
|
||||||
boolean find = false;
|
boolean find = false;
|
||||||
for (int iii = this.datas.size() - 1; iii >= 0; iii--) {
|
for (int iii = this.datas.size() - 1; iii >= 0; iii--) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.kar.archidata.migration;
|
package org.kar.archidata.migration;
|
||||||
|
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.db.DBEntry;
|
||||||
|
import org.kar.archidata.migration.model.Migration;
|
||||||
|
|
||||||
public interface MigrationInterface {
|
public interface MigrationInterface {
|
||||||
/**
|
/**
|
||||||
@ -16,7 +17,7 @@ public interface MigrationInterface {
|
|||||||
* @param migration Migration post data on each step...
|
* @param migration Migration post data on each step...
|
||||||
* @return true if migration is finished.
|
* @return true if migration is finished.
|
||||||
*/
|
*/
|
||||||
boolean applyMigration(DBEntry entry, StringBuilder log, MigrationModel model);
|
boolean applyMigration(DBEntry entry, StringBuilder log, Migration model);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a migration the system to the previous version.
|
* Remove a migration the system to the previous version.
|
||||||
|
@ -8,6 +8,7 @@ import java.util.List;
|
|||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
import org.kar.archidata.dataAccess.DataFactory;
|
import org.kar.archidata.dataAccess.DataFactory;
|
||||||
import org.kar.archidata.db.DBEntry;
|
import org.kar.archidata.db.DBEntry;
|
||||||
|
import org.kar.archidata.migration.model.Migration;
|
||||||
import org.kar.archidata.util.ConfigBaseVariable;
|
import org.kar.archidata.util.ConfigBaseVariable;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -41,7 +42,7 @@ public class MigrationSqlStep implements MigrationInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean applyMigration(final DBEntry entry, final StringBuilder log, final MigrationModel model) {
|
public boolean applyMigration(final DBEntry entry, final StringBuilder log, final Migration model) {
|
||||||
for (int iii = 0; iii < this.actions.size(); iii++) {
|
for (int iii = 0; iii < this.actions.size(); iii++) {
|
||||||
log.append("action [" + (iii + 1) + "/" + this.actions.size() + "]\n");
|
log.append("action [" + (iii + 1) + "/" + this.actions.size() + "]\n");
|
||||||
LOGGER.info(" >>>> SQL ACTION : {}/{}", iii + 1, this.actions.size());
|
LOGGER.info(" >>>> SQL ACTION : {}/{}", iii + 1, this.actions.size());
|
||||||
@ -112,7 +113,7 @@ public class MigrationSqlStep implements MigrationInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addClass(final Class<?> clazz) throws Exception {
|
public void addClass(final Class<?> clazz) throws Exception {
|
||||||
final List<String> tmp = DataFactory.createTable(clazz, false);
|
final List<String> tmp = DataFactory.createTable(clazz);
|
||||||
for (final String elem : tmp) {
|
for (final String elem : tmp) {
|
||||||
this.actions.add(new Action(elem));
|
this.actions.add(new Action(elem));
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package org.kar.archidata.migration;
|
package org.kar.archidata.migration.model;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.SQLComment;
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
import org.kar.archidata.annotation.SQLDefault;
|
import org.kar.archidata.annotation.SQLDefault;
|
||||||
@ -16,7 +16,7 @@ import jakarta.persistence.Table;
|
|||||||
@Table(name = "KAR_migration")
|
@Table(name = "KAR_migration")
|
||||||
@SQLIfNotExists
|
@SQLIfNotExists
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class MigrationModel extends GenericDataSoftDelete {
|
public class Migration extends GenericDataSoftDelete {
|
||||||
@SQLComment("Name of the migration")
|
@SQLComment("Name of the migration")
|
||||||
@Column(length = 256)
|
@Column(length = 256)
|
||||||
public String name;
|
public String name;
|
165
test/src/test/kar/archidata/TestManyToMany.java
Normal file
165
test/src/test/kar/archidata/TestManyToMany.java
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
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.dataAccess.addOn.AddOnManyToMany;
|
||||||
|
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.TypeManyToManyRemote;
|
||||||
|
import test.kar.archidata.model.TypeManyToManyRoot;
|
||||||
|
|
||||||
|
@ExtendWith(StepwiseExtension.class)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class TestManyToMany {
|
||||||
|
final static private Logger LOGGER = LoggerFactory.getLogger(TestManyToMany.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> sqlCommand2 = DataFactory.createTable(TypeManyToManyRoot.class);
|
||||||
|
final List<String> sqlCommand = DataFactory.createTable(TypeManyToManyRemote.class);
|
||||||
|
sqlCommand.addAll(sqlCommand2);
|
||||||
|
for (final String elem : sqlCommand) {
|
||||||
|
LOGGER.debug("request: '{}'", elem);
|
||||||
|
DataAccess.executeSimpleQuerry(elem, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(2)
|
||||||
|
@Test
|
||||||
|
public void testSimpleInsertAndRetieve() throws Exception {
|
||||||
|
final TypeManyToManyRoot test = new TypeManyToManyRoot();
|
||||||
|
test.otherData = "kjhlkjlkj";
|
||||||
|
final TypeManyToManyRoot insertedData = DataAccess.insert(test);
|
||||||
|
Assertions.assertNotNull(insertedData);
|
||||||
|
Assertions.assertNotNull(insertedData.id);
|
||||||
|
Assertions.assertTrue(insertedData.id >= 0);
|
||||||
|
Assertions.assertNull(insertedData.remote);
|
||||||
|
|
||||||
|
// Try to retrieve all the data:
|
||||||
|
final TypeManyToManyRoot retrieve = DataAccess.get(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
|
||||||
|
Assertions.assertNotNull(retrieve);
|
||||||
|
Assertions.assertNotNull(retrieve.id);
|
||||||
|
Assertions.assertEquals(insertedData.id, retrieve.id);
|
||||||
|
Assertions.assertNotNull(retrieve.otherData);
|
||||||
|
Assertions.assertEquals(insertedData.otherData, retrieve.otherData);
|
||||||
|
Assertions.assertNull(retrieve.remote);
|
||||||
|
|
||||||
|
DataAccess.delete(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Order(3)
|
||||||
|
@Test
|
||||||
|
public void testSimpleInsertAndRetieveZZZ() throws Exception {
|
||||||
|
|
||||||
|
TypeManyToManyRemote remote = new TypeManyToManyRemote();
|
||||||
|
remote.data = "remote1";
|
||||||
|
final TypeManyToManyRemote insertedRemote1 = DataAccess.insert(remote);
|
||||||
|
Assertions.assertEquals(insertedRemote1.data, remote.data);
|
||||||
|
|
||||||
|
remote = new TypeManyToManyRemote();
|
||||||
|
remote.data = "remote2";
|
||||||
|
final TypeManyToManyRemote insertedRemote2 = DataAccess.insert(remote);
|
||||||
|
Assertions.assertEquals(insertedRemote2.data, remote.data);
|
||||||
|
|
||||||
|
final TypeManyToManyRoot test = new TypeManyToManyRoot();
|
||||||
|
test.otherData = "kjhlkjlkj";
|
||||||
|
final TypeManyToManyRoot insertedData = DataAccess.insert(test);
|
||||||
|
Assertions.assertNotNull(insertedData);
|
||||||
|
Assertions.assertNotNull(insertedData.id);
|
||||||
|
Assertions.assertTrue(insertedData.id >= 0);
|
||||||
|
Assertions.assertNull(insertedData.remote);
|
||||||
|
|
||||||
|
// Try to retrieve all the data:
|
||||||
|
TypeManyToManyRoot retrieve = DataAccess.get(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
|
||||||
|
Assertions.assertNotNull(retrieve);
|
||||||
|
Assertions.assertNotNull(retrieve.id);
|
||||||
|
Assertions.assertEquals(insertedData.id, retrieve.id);
|
||||||
|
Assertions.assertNotNull(retrieve.otherData);
|
||||||
|
Assertions.assertEquals(insertedData.otherData, retrieve.otherData);
|
||||||
|
Assertions.assertNull(retrieve.remote);
|
||||||
|
|
||||||
|
// Add remote elements
|
||||||
|
AddOnManyToMany.addLink(TypeManyToManyRoot.class, retrieve.id, "remote", insertedRemote1.id);
|
||||||
|
AddOnManyToMany.addLink(TypeManyToManyRoot.class, retrieve.id, "remote", insertedRemote2.id);
|
||||||
|
|
||||||
|
retrieve = DataAccess.get(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
|
||||||
|
Assertions.assertNotNull(retrieve);
|
||||||
|
Assertions.assertNotNull(retrieve.id);
|
||||||
|
Assertions.assertEquals(insertedData.id, retrieve.id);
|
||||||
|
Assertions.assertNotNull(retrieve.otherData);
|
||||||
|
Assertions.assertEquals(insertedData.otherData, retrieve.otherData);
|
||||||
|
Assertions.assertNotNull(retrieve.remote);
|
||||||
|
Assertions.assertEquals(retrieve.remote.size(), 2);
|
||||||
|
Assertions.assertEquals(retrieve.remote.get(0), insertedRemote1.id);
|
||||||
|
Assertions.assertEquals(retrieve.remote.get(1), insertedRemote2.id);
|
||||||
|
|
||||||
|
// Remove an element
|
||||||
|
int count = AddOnManyToMany.removeLink(TypeManyToManyRoot.class, retrieve.id, "remote", insertedRemote1.id);
|
||||||
|
Assertions.assertEquals(1, count);
|
||||||
|
|
||||||
|
retrieve = DataAccess.get(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
|
||||||
|
Assertions.assertNotNull(retrieve);
|
||||||
|
Assertions.assertNotNull(retrieve.id);
|
||||||
|
Assertions.assertEquals(insertedData.id, retrieve.id);
|
||||||
|
Assertions.assertNotNull(retrieve.otherData);
|
||||||
|
Assertions.assertEquals(insertedData.otherData, retrieve.otherData);
|
||||||
|
Assertions.assertNotNull(retrieve.remote);
|
||||||
|
Assertions.assertEquals(retrieve.remote.size(), 1);
|
||||||
|
Assertions.assertEquals(retrieve.remote.get(0), insertedRemote2.id);
|
||||||
|
|
||||||
|
// Remove the second element
|
||||||
|
count = AddOnManyToMany.removeLink(TypeManyToManyRoot.class, retrieve.id, "remote", insertedRemote2.id);
|
||||||
|
Assertions.assertEquals(1, count);
|
||||||
|
|
||||||
|
retrieve = DataAccess.get(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
|
||||||
|
Assertions.assertNotNull(retrieve);
|
||||||
|
Assertions.assertNotNull(retrieve.id);
|
||||||
|
Assertions.assertEquals(insertedData.id, retrieve.id);
|
||||||
|
Assertions.assertNotNull(retrieve.otherData);
|
||||||
|
Assertions.assertEquals(insertedData.otherData, retrieve.otherData);
|
||||||
|
Assertions.assertNull(retrieve.remote);
|
||||||
|
|
||||||
|
DataAccess.delete(TypeManyToManyRoot.class, insertedData.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
test/src/test/kar/archidata/model/TypeManyToManyRemote.java
Normal file
15
test/src/test/kar/archidata/model/TypeManyToManyRemote.java
Normal 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 TypeManyToManyRemote {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
public Long id = null;
|
||||||
|
|
||||||
|
public String data;
|
||||||
|
}
|
22
test/src/test/kar/archidata/model/TypeManyToManyRoot.java
Normal file
22
test/src/test/kar/archidata/model/TypeManyToManyRoot.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package test.kar.archidata.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.ManyToMany;
|
||||||
|
|
||||||
|
public class TypeManyToManyRoot {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(nullable = false, unique = true)
|
||||||
|
public Long id = null;
|
||||||
|
|
||||||
|
public String otherData;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY, targetEntity = TypeManyToManyRemote.class)
|
||||||
|
public List<Long> remote;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user