[DEV] continue review integration JPA
This commit is contained in:
parent
e64c70cd86
commit
9730b89b15
2
pom.xml
2
pom.xml
@ -96,7 +96,7 @@
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
||||
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
||||
<scope>test</scope>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jersey.media</groupId>
|
||||
|
@ -0,0 +1,15 @@
|
||||
package org.kar.archidata.annotation.addOn;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.kar.archidata.annotation.DataAddOn;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@DataAddOn
|
||||
public @interface DataAddOnManyToManyOrdered {
|
||||
|
||||
}
|
@ -7,12 +7,25 @@ import java.util.List;
|
||||
|
||||
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;
|
||||
|
||||
record Action(
|
||||
String action,
|
||||
List<String> filterDB) {
|
||||
public Action(String action) {
|
||||
this(action, List.of());
|
||||
}
|
||||
|
||||
public Action(String action, String filterDB) {
|
||||
this(action, List.of(filterDB));
|
||||
}
|
||||
}
|
||||
|
||||
public class MigrationSqlStep implements MigrationInterface {
|
||||
final static Logger LOGGER = LoggerFactory.getLogger(MigrationSqlStep.class);
|
||||
private final List<String> actions = new ArrayList<>();
|
||||
private final List<Action> actions = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
@ -21,8 +34,8 @@ public class MigrationSqlStep implements MigrationInterface {
|
||||
|
||||
public void display() {
|
||||
for (int iii = 0; iii < this.actions.size(); iii++) {
|
||||
final String action = this.actions.get(iii);
|
||||
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> \n{}", iii, this.actions.size(), action);
|
||||
final Action action = this.actions.get(iii);
|
||||
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> filter='{}'\n{}", iii, this.actions.size(), action.filterDB(), action.action());
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,11 +44,26 @@ public class MigrationSqlStep implements MigrationInterface {
|
||||
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 String action = this.actions.get(iii);
|
||||
LOGGER.info("SQL request: ```{}```", action);
|
||||
log.append("SQL: " + action + "\n");
|
||||
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()) {
|
||||
if (ConfigBaseVariable.getDBType().equals(elem)) {
|
||||
isValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
log.append("==> Skip (DB is not compatible: " + ConfigBaseVariable.getDBType() + ")\n");
|
||||
LOGGER.info(" >>>> SQL ACTION : {}/{} ==> SKIP", iii + 1, this.actions.size());
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
SqlWrapper.executeQuerry(action);
|
||||
SqlWrapper.executeQuerry(action.action());
|
||||
} catch (SQLException | IOException ex) {
|
||||
ex.printStackTrace();
|
||||
LOGGER.info("SQL request ERROR: ", ex.getMessage());
|
||||
@ -75,12 +103,18 @@ public class MigrationSqlStep implements MigrationInterface {
|
||||
}
|
||||
|
||||
public void addAction(final String action) {
|
||||
this.actions.add(action);
|
||||
this.actions.add(new Action(action));
|
||||
}
|
||||
|
||||
public void addAction(final String action, 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);
|
||||
this.actions.addAll(tmp);
|
||||
for (String elem : tmp) {
|
||||
this.actions.add(new Action(elem));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -169,6 +169,27 @@ public class SqlWrapper {
|
||||
throw new InternalServerErrorException("Can Not manage the DB-access");
|
||||
}
|
||||
|
||||
/**
|
||||
* extract a list of "-" separated element from a SQL input data.
|
||||
* @param rs Result Set of the BDD
|
||||
* @param iii Id in the result set
|
||||
* @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);
|
||||
if (rs.wasNull()) {
|
||||
return null;
|
||||
}
|
||||
List<Long> out = new ArrayList<>();
|
||||
String[] elements = trackString.split("-");
|
||||
for (String elem : elements) {
|
||||
Long tmp = Long.parseLong(elem);
|
||||
out.add(tmp);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public static String convertTypeInSQL(final Class<?> type) throws Exception {
|
||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||
if (type == Long.class || type == long.class) {
|
||||
@ -212,10 +233,10 @@ public class SqlWrapper {
|
||||
return "REAL";
|
||||
}
|
||||
if (type == Timestamp.class) {
|
||||
return "INTEGER";
|
||||
return "DATETIME";
|
||||
}
|
||||
if (type == Date.class) {
|
||||
return "NUMERIC";
|
||||
return "DATETIME";
|
||||
}
|
||||
if (type == String.class) {
|
||||
return "text";
|
||||
@ -369,11 +390,26 @@ public class SqlWrapper {
|
||||
field.setBoolean(data, tmp);
|
||||
}
|
||||
} else if (type == Timestamp.class) {
|
||||
final Timestamp tmp = rs.getTimestamp(index);
|
||||
if (rs.wasNull()) {
|
||||
field.set(data, null);
|
||||
} else {
|
||||
field.set(data, tmp);
|
||||
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);
|
||||
@ -853,7 +889,7 @@ public class SqlWrapper {
|
||||
continue;
|
||||
}
|
||||
final SqlWrapperAddOn addOn = findAddOnforField(elem);
|
||||
if (addOn != null) {
|
||||
if (addOn != null && addOn.isExternal()) {
|
||||
continue;
|
||||
}
|
||||
// TODO: Manage it with AddOn
|
||||
@ -872,10 +908,13 @@ public class SqlWrapper {
|
||||
querry.append(",");
|
||||
}
|
||||
querry.append(" ");
|
||||
querry.append(tableName);
|
||||
querry.append(".");
|
||||
|
||||
querry.append(name);
|
||||
if (addOn != null) {
|
||||
addOn.generateQuerry(tableName, elem, querry, name, count, options);
|
||||
} else {
|
||||
querry.append(tableName);
|
||||
querry.append(".");
|
||||
querry.append(name);
|
||||
}
|
||||
}
|
||||
querry.append(" FROM `");
|
||||
querry.append(tableName);
|
||||
@ -906,7 +945,7 @@ public class SqlWrapper {
|
||||
continue;
|
||||
}
|
||||
final SqlWrapperAddOn addOn = findAddOnforField(elem);
|
||||
if (addOn != null) {
|
||||
if (addOn != null && addOn.isExternal()) {
|
||||
continue;
|
||||
}
|
||||
// TODO: Manage it with AddOn
|
||||
@ -914,8 +953,13 @@ public class SqlWrapper {
|
||||
if (!readAllfields && notRead) {
|
||||
continue;
|
||||
}
|
||||
setValueFromDb(elem.getType(), data, count, elem, rs);
|
||||
count++;
|
||||
if (addOn != null) {
|
||||
int nbRowRead = addOn.fillFromQuerry(rs, elem, data, count, options);
|
||||
count += nbRowRead;
|
||||
} else {
|
||||
setValueFromDb(elem.getType(), data, count, elem, rs);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
final T out = (T) data;
|
||||
outs.add(out);
|
||||
@ -1063,8 +1107,8 @@ public class SqlWrapper {
|
||||
return createTable(clazz, true);
|
||||
}
|
||||
|
||||
public static void createTablesSpecificType(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> ListOtherTables, final boolean createIfNotExist,
|
||||
final boolean createDrop, final int fieldId, final Class<?> classModel) throws Exception {
|
||||
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);
|
||||
@ -1117,7 +1161,29 @@ public class SqlWrapper {
|
||||
if (!ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||
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 {
|
||||
@ -1178,7 +1244,8 @@ public class SqlWrapper {
|
||||
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> outList = new ArrayList<>();
|
||||
final List<String> preActionList = new ArrayList<>();
|
||||
final List<String> postActionList = new ArrayList<>();
|
||||
final StringBuilder out = new StringBuilder();
|
||||
// Drop Table
|
||||
if (createIfNotExist && createDrop) {
|
||||
@ -1186,7 +1253,7 @@ public class SqlWrapper {
|
||||
tableTmp.append("DROP TABLE IF EXISTS `");
|
||||
tableTmp.append(tableName);
|
||||
tableTmp.append("`;");
|
||||
outList.add(tableTmp.toString());
|
||||
postActionList.add(tableTmp.toString());
|
||||
}
|
||||
// create Table:
|
||||
out.append("CREATE TABLE `");
|
||||
@ -1212,13 +1279,13 @@ public class SqlWrapper {
|
||||
final SqlWrapperAddOn addOn = findAddOnforField(elem);
|
||||
LOGGER.info("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), elem.getType());
|
||||
if (addOn != null) {
|
||||
addOn.createTables(tableName, elem, out, outList, createIfNotExist, createDrop, fieldId);
|
||||
addOn.createTables(tableName, elem, out, 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, out, outList, createIfNotExist, createDrop, fieldId, elem.getType());
|
||||
SqlWrapper.createTablesSpecificType(tableName, elem, out, preActionList, postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
|
||||
}
|
||||
fieldId++;
|
||||
}
|
||||
@ -1237,8 +1304,9 @@ public class SqlWrapper {
|
||||
out.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci");
|
||||
}
|
||||
out.append(";");
|
||||
outList.add(out.toString());
|
||||
return outList;
|
||||
preActionList.add(out.toString());
|
||||
preActionList.addAll(postActionList);
|
||||
return preActionList;
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,8 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public interface SqlWrapperAddOn {
|
||||
/**
|
||||
* Get the Class of the declaration annotation
|
||||
@ -27,17 +29,38 @@ public interface SqlWrapperAddOn {
|
||||
*/
|
||||
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.
|
||||
* @param data The date to inject.
|
||||
* @param iii The index of injection
|
||||
* @return the new index of injection in case of multiple value management
|
||||
* @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(String tableName, Field elem, StringBuilder querry, String name, List<StateLoad> autoClasify, QuerryOptions options);
|
||||
int generateQuerry(@NotNull String tableName, @NotNull Field elem, @NotNull StringBuilder querry, @NotNull String name, @NotNull int elemCount, QuerryOptions options);
|
||||
|
||||
// Return the number of colomn read
|
||||
int fillFromQuerry(ResultSet rs, Field elem, Object data, int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException;
|
||||
|
||||
boolean canUpdate();
|
||||
|
||||
void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List<String> ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception;
|
||||
/**
|
||||
* Create associated table of the specific element.
|
||||
* @param tableName
|
||||
* @param elem
|
||||
* @param mainTableBuilder
|
||||
* @param ListOtherTables
|
||||
* @param createIfNotExist
|
||||
* @param createDrop
|
||||
* @param fieldId
|
||||
* @throws Exception
|
||||
*/
|
||||
void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List<String> preActionList, List<String> postActionList, boolean createIfNotExist, boolean createDrop, int fieldId)
|
||||
throws Exception;
|
||||
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package org.kar.archidata.sqlWrapper;
|
||||
|
||||
public enum StateLoad {
|
||||
DISABLE, NORMAL, ARRAY
|
||||
}
|
@ -5,10 +5,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.kar.archidata.GlobalConfiguration;
|
||||
import org.kar.archidata.annotation.AnnotationTools;
|
||||
@ -17,46 +14,16 @@ 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.sqlWrapper.StateLoad;
|
||||
import org.kar.archidata.util.ConfigBaseVariable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
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)
|
||||
* @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("-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* extract a list of "-" separated element from a SQL input data.
|
||||
* @param rs Result Set of the BDD
|
||||
* @param iii Id in the result set
|
||||
* @return The list of Long value
|
||||
* @throws SQLException if an error is generated in the sql request.
|
||||
*/
|
||||
protected static List<Long> getListOfIds(final ResultSet rs, final int iii) throws SQLException {
|
||||
final String trackString = rs.getString(iii);
|
||||
if (rs.wasNull()) {
|
||||
return null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
static final String SEPARATOR = "-";
|
||||
|
||||
@Override
|
||||
public Class<?> getAnnotationClass() {
|
||||
@ -76,15 +43,7 @@ public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
|
||||
@Override
|
||||
public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
|
||||
if (data == null) {
|
||||
ps.setNull(iii++, Types.BIGINT);
|
||||
} else {
|
||||
// TODO: we must check if the model of data in a list of Long ... !!!!
|
||||
@SuppressWarnings("unchecked")
|
||||
final String dataTmp = getStringOfIds((List<Long>) data);
|
||||
ps.setString(iii++, dataTmp);
|
||||
}
|
||||
return iii++;
|
||||
return iii;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -94,19 +53,26 @@ public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int generateQuerry(final String tableName, final Field elem, final StringBuilder querry, final String name, final List<StateLoad> autoClasify, QuerryOptions options) {
|
||||
|
||||
autoClasify.add(StateLoad.ARRAY);
|
||||
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) {
|
||||
String localName = name;
|
||||
if (name.endsWith("s")) {
|
||||
localName = name.substring(0, name.length() - 1);
|
||||
}
|
||||
final String tmpVariable = "tmp_" + Integer.toString(autoClasify.size());
|
||||
final String tmpVariable = "tmp_" + Integer.toString(elemCount);
|
||||
querry.append(" (SELECT GROUP_CONCAT(");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".");
|
||||
querry.append(localName);
|
||||
querry.append("_id SEPARATOR '-') FROM ");
|
||||
querry.append("_id ");
|
||||
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||
querry.append(", ");
|
||||
} else {
|
||||
querry.append("SEPARATOR ");
|
||||
}
|
||||
querry.append("'");
|
||||
querry.append(SEPARATOR);
|
||||
querry.append("') FROM ");
|
||||
querry.append(tableName);
|
||||
querry.append("_link_");
|
||||
querry.append(localName);
|
||||
@ -139,7 +105,9 @@ 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 {
|
||||
throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
|
||||
List<Long> idList = SqlWrapper.getListOfIds(rs, count, SEPARATOR);
|
||||
elem.set(data, idList);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -208,8 +176,8 @@ public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
|
||||
// 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> ListOtherTables, final boolean createIfNotExist,
|
||||
final boolean createDrop, final int fieldId) throws Exception {
|
||||
public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preActionList, List<String> postActionList,
|
||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
||||
final String name = AnnotationTools.getFieldName(elem);
|
||||
String localName = name;
|
||||
if (name.endsWith("s")) {
|
||||
@ -222,7 +190,7 @@ public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
tableTmp.append("_link_");
|
||||
tableTmp.append(localName);
|
||||
tableTmp.append("`;");
|
||||
ListOtherTables.add(tableTmp.toString());
|
||||
postActionList.add(tableTmp.toString());
|
||||
}
|
||||
final StringBuilder otherTable = new StringBuilder();
|
||||
otherTable.append("CREATE TABLE `");
|
||||
@ -263,6 +231,6 @@ public class AddOnManyToMany implements SqlWrapperAddOn {
|
||||
otherTable.append(" ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;\n\n");
|
||||
}
|
||||
otherTable.append(";");
|
||||
ListOtherTables.add(otherTable.toString());
|
||||
postActionList.add(otherTable.toString());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,235 @@
|
||||
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.Statement;
|
||||
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.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;
|
||||
|
||||
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 {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToManyOrdered.class);
|
||||
static final String SEPARATOR = "-";
|
||||
|
||||
@Override
|
||||
public Class<?> getAnnotationClass() {
|
||||
return DataAddOnManyToManyOrdered.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQLFieldType(final Field elem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatibleField(final Field elem) {
|
||||
final DataAddOnManyToManyOrdered decorators = elem.getDeclaredAnnotation(DataAddOnManyToManyOrdered.class);
|
||||
return decorators != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertData(final PreparedStatement ps, final Object data, int iii) throws SQLException {
|
||||
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) {
|
||||
String localName = name;
|
||||
if (name.endsWith("s")) {
|
||||
localName = name.substring(0, name.length() - 1);
|
||||
}
|
||||
final String tmpVariable = "tmp_" + Integer.toString(elemCount);
|
||||
querry.append(" (SELECT GROUP_CONCAT(");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".");
|
||||
querry.append(localName);
|
||||
querry.append("_id ");
|
||||
if (ConfigBaseVariable.getDBType().equals("sqlite")) {
|
||||
querry.append(", ");
|
||||
} else {
|
||||
querry.append("SEPARATOR ");
|
||||
}
|
||||
querry.append("'");
|
||||
querry.append(SEPARATOR);
|
||||
querry.append("') FROM ");
|
||||
querry.append(tableName);
|
||||
querry.append("_link_");
|
||||
querry.append(localName);
|
||||
querry.append(" ");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(" WHERE ");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".deleted = false AND ");
|
||||
querry.append(tableName);
|
||||
querry.append(".id = ");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".");
|
||||
querry.append(tableName);
|
||||
querry.append("_id ORDER BY ");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".order ASC");
|
||||
querry.append(" GROUP BY ");
|
||||
querry.append(tmpVariable);
|
||||
querry.append(".");
|
||||
querry.append(tableName);
|
||||
querry.append("_id ) AS ");
|
||||
querry.append(name);
|
||||
querry.append(" ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fillFromQuerry(final ResultSet rs, final Field elem, final Object data, final int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException {
|
||||
//throw new IllegalAccessException("This Add-on has not the capability to insert data directly in DB");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void addLink(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);
|
||||
long uniqueSQLID = -1;
|
||||
// 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 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 {
|
||||
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
|
||||
+ "_id` = ?";
|
||||
try {
|
||||
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
|
||||
public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preActionList, List<String> postActionList,
|
||||
final boolean createIfNotExist, final boolean createDrop, final int fieldId) throws Exception {
|
||||
final String name = AnnotationTools.getFieldName(elem);
|
||||
String localName = name;
|
||||
if (name.endsWith("s")) {
|
||||
localName = name.substring(0, name.length() - 1);
|
||||
}
|
||||
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`order` INTEGER NOT NULL DEFAULT 0,\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());
|
||||
}
|
||||
}
|
@ -12,11 +12,11 @@ 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.sqlWrapper.StateLoad;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class AddOnManyToOne implements SqlWrapperAddOn {
|
||||
static final Logger LOGGER = LoggerFactory.getLogger(AddOnManyToMany.class);
|
||||
@ -93,8 +93,7 @@ public class AddOnManyToOne implements SqlWrapperAddOn {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int generateQuerry(final String tableName, final Field elem, final StringBuilder querry, final String name, final List<StateLoad> autoClasify, QuerryOptions options) {
|
||||
autoClasify.add(StateLoad.NORMAL);
|
||||
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(".");
|
||||
@ -119,8 +118,8 @@ public class AddOnManyToOne implements SqlWrapperAddOn {
|
||||
|
||||
// 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> ListOtherTables, final boolean createIfNotExist,
|
||||
final boolean createDrop, final int fieldId) throws Exception {
|
||||
SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, ListOtherTables, createIfNotExist, createDrop, fieldId, Long.class);
|
||||
public void createTables(final String tableName, final Field elem, final StringBuilder mainTableBuilder, final List<String> preActionList, 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);
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ 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.kar.archidata.sqlWrapper.StateLoad;
|
||||
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
|
||||
@ -30,28 +32,7 @@ public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
|
||||
for (Long elem : ids) {
|
||||
tmp.add(elem);
|
||||
}
|
||||
return tmp.stream().map(x -> String.valueOf(x)).collect(Collectors.joining("-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* extract a list of "-" separated element from a SQL input data.
|
||||
* @param rs Result Set of the BDD
|
||||
* @param iii Id in the result set
|
||||
* @return The list of Long value
|
||||
* @throws SQLException if an error is generated in the sql request.
|
||||
*/
|
||||
protected static List<Long> getListOfIds(ResultSet rs, int iii) throws SQLException {
|
||||
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);
|
||||
out.add(tmp);
|
||||
}
|
||||
return out;
|
||||
return tmp.stream().map(x -> String.valueOf(x)).collect(Collectors.joining(SEPARATOR));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,8 +73,7 @@ public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int generateQuerry(String tableName, Field elem, StringBuilder querry, String name, List<StateLoad> autoClasify, QuerryOptions options) {
|
||||
autoClasify.add(StateLoad.ARRAY);
|
||||
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(".");
|
||||
@ -103,7 +83,7 @@ public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
|
||||
|
||||
@Override
|
||||
public int fillFromQuerry(ResultSet rs, Field elem, Object data, int count, QuerryOptions options) throws SQLException, IllegalArgumentException, IllegalAccessException {
|
||||
List<Long> idList = getListOfIds(rs, count);
|
||||
List<Long> idList = SqlWrapper.getListOfIds(rs, count, SEPARATOR);
|
||||
elem.set(data, idList);
|
||||
return 1;
|
||||
}
|
||||
@ -114,9 +94,10 @@ public class AddOnSQLTableExternalForeinKeyAsList implements SqlWrapperAddOn {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createTables(String tableName, Field elem, StringBuilder mainTableBuilder, List<String> ListOtherTables, boolean createIfNotExist, boolean createDrop, int fieldId) throws Exception {
|
||||
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, ListOtherTables, createIfNotExist, createDrop, fieldId, String.class);
|
||||
SqlWrapper.createTablesSpecificType(tableName, elem, mainTableBuilder, preActionList, postActionList, createIfNotExist, createDrop, fieldId, String.class);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user