Compare commits

...

3 Commits

13 changed files with 330 additions and 327 deletions

View File

@ -286,11 +286,15 @@ public class AnnotationTools {
}
public static boolean isPrimaryKey(final Field element) {
final Annotation[] annotation = element.getDeclaredAnnotationsByType(Id.class);
if (annotation.length == 0) {
return false;
final Annotation[] annotationSQL = element.getDeclaredAnnotationsByType(Id.class);
if (annotationSQL.length > 0) {
return true;
}
return true;
final Annotation[] annotationMongo = element.getDeclaredAnnotationsByType(dev.morphia.annotations.Id.class);
if (annotationMongo.length > 0) {
return true;
}
return false;
}
public static boolean isUnique(final Field element) {

View File

@ -20,6 +20,7 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.UpdateTimestamp;
@ -34,6 +35,7 @@ import org.kar.archidata.dataAccess.options.DBInterfaceRoot;
import org.kar.archidata.dataAccess.options.FilterValue;
import org.kar.archidata.dataAccess.options.GroupBy;
import org.kar.archidata.dataAccess.options.Limit;
import org.kar.archidata.dataAccess.options.OptionSpecifyType;
import org.kar.archidata.dataAccess.options.OrderBy;
import org.kar.archidata.dataAccess.options.QueryOption;
import org.kar.archidata.dataAccess.options.TransmitKey;
@ -223,6 +225,20 @@ public class DBAccessSQL extends DBAccess {
return out;
}
public List<ObjectId> getListOfOIDs(final ResultSet rs, final int iii, final String separator) throws SQLException {
final String trackString = rs.getString(iii);
if (rs.wasNull()) {
return null;
}
final List<ObjectId> out = new ArrayList<>();
final String[] elements = trackString.split(separator);
for (final String elem : elements) {
final ObjectId tmp = new ObjectId(elem);
out.add(tmp);
}
return out;
}
public byte[][] splitIntoGroupsOf16Bytes(final byte[] input) {
final int inputLength = input.length;
final int numOfGroups = (inputLength + 15) / 16; // Calculate the number of groups needed
@ -251,6 +267,20 @@ public class DBAccessSQL extends DBAccess {
return out;
}
public List<ObjectId> getListOfRawOIDs(final ResultSet rs, final int iii) throws SQLException, DataAccessException {
final byte[] trackString = rs.getBytes(iii);
if (rs.wasNull()) {
return null;
}
final byte[][] elements = splitIntoGroupsOf16Bytes(trackString);
final List<ObjectId> out = new ArrayList<>();
for (final byte[] elem : elements) {
final ObjectId tmp = new ObjectId(elem);
out.add(tmp);
}
return out;
}
public UUID getListOfRawUUID(final ResultSet rs, final int iii) throws SQLException, DataAccessException {
final byte[] elem = rs.getBytes(iii);
if (rs.wasNull()) {
@ -259,13 +289,29 @@ public class DBAccessSQL extends DBAccess {
return UuidUtils.asUuid(elem);
}
protected <T> void setValuedb(
public ObjectId getListOfRawOID(final ResultSet rs, final int iii) throws SQLException, DataAccessException {
final byte[] elem = rs.getBytes(iii);
if (rs.wasNull()) {
return null;
}
return new ObjectId(elem);
}
protected <T> void setValueToDb(
final Class<?> type,
final T data,
final CountInOut iii,
final Field field,
final PreparedStatement ps) throws Exception {
if (type == UUID.class) {
if (type == ObjectId.class) {
final Object tmp = field.get(data);
if (tmp == null) {
ps.setNull(iii.value, Types.BINARY);
} else {
final String dataString = ((ObjectId) tmp).toHexString();
ps.setString(iii.value, dataString);
}
} else if (type == UUID.class) {
final Object tmp = field.get(data);
if (tmp == null) {
ps.setNull(iii.value, Types.BINARY);
@ -372,7 +418,7 @@ public class DBAccessSQL extends DBAccess {
ps.setString(iii.value, tmp.toString());
}
} else {
throw new DataAccessException("Unknown Field Type");
throw new DataAccessException("Unknown Field Type: " + type.getCanonicalName());
}
iii.inc();
}
@ -384,7 +430,17 @@ public class DBAccessSQL extends DBAccess {
final Field field,
final ResultSet rs,
final CountInOut countNotNull) throws Exception {
if (type == UUID.class) {
if (type == ObjectId.class) {
final String tmp = rs.getString(count.value);
if (rs.wasNull()) {
field.set(data, null);
} else {
// field.set(data, tmp);
final ObjectId objectId = new ObjectId(tmp);
field.set(data, objectId);
countNotNull.inc();
}
} else if (type == UUID.class) {
final byte[] tmp = rs.getBytes(count.value);
// final UUID tmp = rs.getObject(count.value, UUID.class);
if (rs.wasNull()) {
@ -556,7 +612,7 @@ public class DBAccessSQL extends DBAccess {
}
}
} else {
throw new DataAccessException("Unknown Field Type");
throw new DataAccessException("Unknown Field Type: " + type.getCanonicalName());
}
count.inc();
}
@ -564,6 +620,18 @@ public class DBAccessSQL extends DBAccess {
// TODO: this function will replace the previous one !!!
protected RetreiveFromDB createSetValueFromDbCallback(final int count, final Field field) throws Exception {
final Class<?> type = field.getType();
if (type == ObjectId.class) {
return (final ResultSet rs, final Object obj) -> {
final String tmp = rs.getString(count);
if (rs.wasNull()) {
field.set(obj, null);
} else {
// field.set(obj, tmp);
final ObjectId objectId = new ObjectId(tmp);
field.set(obj, objectId);
}
};
}
if (type == UUID.class) {
return (final ResultSet rs, final Object obj) -> {
@ -802,9 +870,12 @@ public class DBAccessSQL extends DBAccess {
final List<Field> asyncFieldUpdate = new ArrayList<>();
Long uniqueSQLID = null;
UUID uniqueSQLUUID = null;
ObjectId uniqueSQLOID = null;
final String tableName = AnnotationTools.getTableName(clazz, options);
Field primaryKeyField = null;
boolean generateUUID = false;
boolean generateOID = false;
final List<OptionSpecifyType> specificTypes = options.get(OptionSpecifyType.class);
// real add in the BDD:
try {
// boolean createIfNotExist = clazz.getDeclaredAnnotationsByType(SQLIfNotExists.class).length != 0;
@ -822,10 +893,14 @@ public class DBAccessSQL extends DBAccess {
}
if (AnnotationTools.isPrimaryKey(field)) {
primaryKeyField = field;
if (primaryKeyField.getType() != UUID.class) {
if (primaryKeyField.getType() != UUID.class && primaryKeyField.getType() != ObjectId.class) {
break;
}
generateUUID = true;
if (primaryKeyField.getType() == UUID.class) {
generateUUID = true;
} else {
generateOID = true;
}
count++;
final String name = AnnotationTools.getFieldName(field);
if (firstField) {
@ -908,6 +983,13 @@ public class DBAccessSQL extends DBAccess {
addElement(ps, uuid, iii);
iii.inc();
}
ObjectId oid = null;
if (generateOID) {
firstField = false;
oid = new ObjectId();
addElement(ps, oid, iii);
iii.inc();
}
for (final Field elem : clazz.getFields()) {
// field is only for internal global declaration ==> remove it ..
if (java.lang.reflect.Modifier.isStatic(elem.getModifiers())) {
@ -933,14 +1015,24 @@ public class DBAccessSQL extends DBAccess {
addOn.insertData(this, ps, elem, data, iii);
} else {
// Generic class insertion...
final Class<?> type = elem.getType();
Class<?> type = elem.getType();
if (!type.isPrimitive()) {
final Object tmp = elem.get(data);
if (tmp == null && elem.getDeclaredAnnotationsByType(DefaultValue.class).length != 0) {
continue;
}
}
setValuedb(type, data, iii, elem, ps);
if (type == Object.class) {
for (final OptionSpecifyType specify : specificTypes) {
if (specify.name.equals(elem.getName())) {
type = specify.clazz;
LOGGER.trace("Detect overwrite of typing ... '{}' => '{}'",
elem.getType().getCanonicalName(), specify.clazz.getCanonicalName());
break;
}
}
}
setValueToDb(type, data, iii, elem, ps);
}
count++;
}
@ -953,6 +1045,9 @@ public class DBAccessSQL extends DBAccess {
if (generateUUID) {
// we generate the UUID, otherwise we can not retrieve it
uniqueSQLUUID = uuid;
} else if (generateOID) {
// we generate the UUID, otherwise we can not retrieve it
uniqueSQLOID = oid;
} else {
try (ResultSet generatedKeys = ps.getGeneratedKeys()) {
if (generatedKeys.next()) {
@ -963,6 +1058,9 @@ public class DBAccessSQL extends DBAccess {
//final Object obj = generatedKeys.getObject(1);
final byte[] tmpid = generatedKeys.getBytes(1);
uniqueSQLUUID = UuidUtils.asUuid(tmpid);
} else if (primaryKeyField.getType() == ObjectId.class) {
final String tmpid = generatedKeys.getString(1);
uniqueSQLOID = new ObjectId(tmpid);
} else {
uniqueSQLID = generatedKeys.getLong(1);
}
@ -983,6 +1081,8 @@ public class DBAccessSQL extends DBAccess {
primaryKeyField.setLong(data, uniqueSQLID);
} else if (primaryKeyField.getType() == UUID.class) {
primaryKeyField.set(data, uniqueSQLUUID);
} else if (primaryKeyField.getType() == ObjectId.class) {
primaryKeyField.set(data, uniqueSQLOID);
} else {
LOGGER.error("Can not manage the primary filed !!!");
}
@ -1000,6 +1100,8 @@ public class DBAccessSQL extends DBAccess {
addOn.asyncInsert(this, tableName, uniqueSQLID, field, field.get(data), asyncActions);
} else if (uniqueSQLUUID != null) {
addOn.asyncInsert(this, tableName, uniqueSQLUUID, field, field.get(data), asyncActions);
} else if (uniqueSQLOID != null) {
addOn.asyncInsert(this, tableName, uniqueSQLOID, field, field.get(data), asyncActions);
}
}
for (final LazyGetter action : asyncActions) {
@ -1117,7 +1219,7 @@ public class DBAccessSQL extends DBAccess {
continue;
}
}
setValuedb(type, data, iii, field, ps);
setValueToDb(type, data, iii, field, ps);
} else {
addOn.insertData(this, ps, field, data, iii);
}
@ -1144,6 +1246,10 @@ public class DBAccessSQL extends DBAccess {
if (value instanceof final UUID tmp) {
final byte[] dataByte = UuidUtils.asBytes(tmp);
ps.setBytes(iii.value, dataByte);
} else if (value instanceof final ObjectId tmp) {
final String dataString = tmp.toHexString();
LOGGER.debug("Inject oid => {}", dataString);
ps.setString(iii.value, dataString);
} else if (value instanceof final Long tmp) {
LOGGER.debug("Inject Long => {}", tmp);
ps.setLong(iii.value, tmp);
@ -1321,6 +1427,7 @@ public class DBAccessSQL extends DBAccess {
final QueryOptions options,
final List<LazyGetter> lazyCall) throws Exception {
final boolean readAllfields = QueryOptions.readAllColomn(options);
final List<OptionSpecifyType> specificTypes = options.get(OptionSpecifyType.class);
// TODO: manage class that is defined inside a class ==> Not manage for now...
Object data = null;
for (final Constructor<?> contructor : clazz.getConstructors()) {
@ -1348,7 +1455,18 @@ public class DBAccessSQL extends DBAccess {
if (addOn != null) {
addOn.fillFromQuery(this, rs, elem, data, count, options, lazyCall);
} else {
setValueFromDb(elem.getType(), data, count, elem, rs, countNotNull);
Class<?> type = elem.getType();
if (type == Object.class) {
for (final OptionSpecifyType specify : specificTypes) {
if (specify.name.equals(elem.getName())) {
type = specify.clazz;
LOGGER.trace("Detect overwrite of typing ... '{}' => '{}'",
elem.getType().getCanonicalName(), specify.clazz.getCanonicalName());
break;
}
}
}
setValueFromDb(type, data, count, elem, rs, countNotNull);
}
}
return data;

View File

@ -10,12 +10,14 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.bson.types.ObjectId;
import org.kar.archidata.annotation.AnnotationTools;
import org.kar.archidata.annotation.CreationTimestamp;
import org.kar.archidata.annotation.DataIfNotExists;
import org.kar.archidata.annotation.UpdateTimestamp;
import org.kar.archidata.dataAccess.addOnSQL.DataAccessAddOn;
import org.kar.archidata.dataAccess.options.CreateDropTable;
import org.kar.archidata.dataAccess.options.OptionSpecifyType;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.tools.ConfigBaseVariable;
import org.slf4j.Logger;
@ -34,6 +36,10 @@ public class DataFactory {
if (type == UUID.class) {
return "binary(16)";
}
if (type == ObjectId.class) {
return "varchar(24)";
// return "binary(12)";
}
if (type == Long.class || type == long.class) {
return "bigint";
}
@ -88,6 +94,10 @@ public class DataFactory {
if (type == UUID.class) {
return "BINARY(16)";
}
if (type == ObjectId.class) {
return "text";
//return "BINARY(12)";
}
if (type == Long.class || type == long.class) {
return "INTEGER";
}
@ -387,23 +397,38 @@ public class DataFactory {
continue;
}
alreadyAdded.add(dataName);
List<OptionSpecifyType> specificTypes = new ArrayList<>();
if (options != null) {
specificTypes = options.get(OptionSpecifyType.class);
}
Class<?> basicType = elem.getType();
if (basicType == Object.class) {
for (final OptionSpecifyType specify : specificTypes) {
if (specify.name.equals(elem.getName())) {
basicType = specify.clazz;
LOGGER.trace("Detect overwrite of typing ... '{}' => '{}'",
elem.getType().getCanonicalName(), specify.clazz.getCanonicalName());
break;
}
}
}
LOGGER.trace(" + '{}'", elem.getName());
if (DBAccessSQL.isAddOnField(elem)) {
final DataAccessAddOn addOn = DBAccessSQL.findAddOnforField(elem);
LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem),
elem.getType());
LOGGER.trace("Create type for: {} ==> {} (ADD-ON)", AnnotationTools.getFieldName(elem), basicType);
if (addOn != null) {
addOn.createTables(tableName, primaryField, elem, tmpOut, preActionList, postActionList,
createIfNotExist, createDrop, fieldId);
} else {
throw new DataAccessException("Element matked as add-on but add-on does not loaded: table:"
+ tableName + " field name=" + AnnotationTools.getFieldName(elem) + " type="
+ elem.getType());
throw new DataAccessException(
"Element matked as add-on but add-on does not loaded: table:" + tableName
+ " field name=" + AnnotationTools.getFieldName(elem) + " type=" + basicType);
}
} else {
LOGGER.trace("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), elem.getType());
LOGGER.trace("Create type for: {} ==> {}", AnnotationTools.getFieldName(elem), basicType);
DataFactory.createTablesSpecificType(tableName, tablePrimaryKeyField, elem, tmpOut, preActionList,
postActionList, createIfNotExist, createDrop, fieldId, elem.getType());
postActionList, createIfNotExist, createDrop, fieldId, basicType);
}
fieldId++;
}

View File

@ -16,11 +16,9 @@ import org.kar.archidata.dataAccess.LazyGetter;
import org.kar.archidata.dataAccess.QueryAnd;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableLongLong;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableLongUUID;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableUUIDLong;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableUUIDUUID;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableGeneric;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.dataAccess.options.OptionSpecifyType;
import org.kar.archidata.dataAccess.options.OverrideTableName;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.tools.ConfigBaseVariable;
@ -315,28 +313,36 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (localKey instanceof final Long localKeyLong) {
if (objectClass == Long.class) {
actions.add(() -> {
ioDb.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)),
new OptionSpecifyType("object1Id", Long.class),
new OptionSpecifyType("object2Id", Long.class));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
} else {
actions.add(() -> {
ioDb.deleteWhere(LinkTableLongUUID.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)),
new OptionSpecifyType("object1Id", Long.class),
new OptionSpecifyType("object2Id", UUID.class));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
}
} else if (localKey instanceof final UUID localKeyUUID) {
if (objectClass == Long.class) {
actions.add(() -> {
ioDb.deleteWhere(LinkTableUUIDLong.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)),
new OptionSpecifyType("object1Id", UUID.class),
new OptionSpecifyType("object2Id", Long.class));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
} else {
actions.add(() -> {
ioDb.deleteWhere(LinkTableUUIDUUID.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)),
new OptionSpecifyType("object1Id", UUID.class),
new OptionSpecifyType("object2Id", UUID.class));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
}
@ -381,19 +387,21 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableLongLong> insertElements = new ArrayList<>();
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableLongLong(localKeyLong, remoteKey));
insertElements.add(new LinkTableGeneric(localKeyLong, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", Long.class),
new OptionSpecifyType("object2Id", Long.class));
});
} else {
// ========================================================
@ -404,19 +412,21 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableLongUUID> insertElements = new ArrayList<>();
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final UUID remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableLongUUID(localKeyLong, remoteKey));
insertElements.add(new LinkTableGeneric(localKeyLong, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", Long.class),
new OptionSpecifyType("object2Id", UUID.class));
});
}
} else if (localKey instanceof final UUID localKeyUUID) {
@ -429,19 +439,21 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableUUIDLong> insertElements = new ArrayList<>();
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableUUIDLong(localKeyUUID, remoteKey));
insertElements.add(new LinkTableGeneric(localKeyUUID, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", UUID.class),
new OptionSpecifyType("object2Id", Long.class));
});
} else {
// ========================================================
@ -452,19 +464,21 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableUUIDUUID> insertElements = new ArrayList<>();
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final UUID remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableUUIDUUID(localKeyUUID, remoteKey));
insertElements.add(new LinkTableGeneric(localKeyUUID, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", UUID.class),
new OptionSpecifyType("object2Id", UUID.class));
});
}
} else {
@ -484,7 +498,8 @@ public class AddOnManyToMany implements DataAccessAddOn {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
ioDb.drop(LinkTableLongLong.class, new OverrideTableName(linkTableName));
ioDb.drop(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", Long.class), new OptionSpecifyType("object2Id", Long.class));
}
@Override
@ -497,7 +512,8 @@ public class AddOnManyToMany implements DataAccessAddOn {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
ioDb.cleanAll(LinkTableLongLong.class, new OverrideTableName(linkTableName));
ioDb.cleanAll(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", Long.class), new OptionSpecifyType("object2Id", Long.class));
}
public static void addLink(
@ -511,8 +527,9 @@ public class AddOnManyToMany implements DataAccessAddOn {
final String linkTableName = generateLinkTableName(tableName, column);
/* final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; if (objectClass != Long.class && objectClass != UUID.class) { throw new
* DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">"); } */
final LinkTableLongLong insertElement = new LinkTableLongLong(localKey, remoteKey);
daSQL.insert(insertElement, new OverrideTableName(linkTableName));
final LinkTableGeneric insertElement = new LinkTableGeneric(localKey, remoteKey);
daSQL.insert(insertElement, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", Long.class), new OptionSpecifyType("object2Id", Long.class));
} else if (ioDb instanceof final DBAccessMorphia dam) {
} else {
@ -530,9 +547,10 @@ public class AddOnManyToMany implements DataAccessAddOn {
if (ioDb instanceof final DBAccessMorphia daSQL) {
final String tableName = AnnotationTools.getTableName(clazz);
final String linkTableName = generateLinkTableName(tableName, column);
return daSQL.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName),
return daSQL.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryAnd(new QueryCondition("object1Id", "=", localKey),
new QueryCondition("object2Id", "=", remoteKey))));
new QueryCondition("object2Id", "=", remoteKey))),
new OptionSpecifyType("object1Id", Long.class), new OptionSpecifyType("object2Id", Long.class));
} else if (ioDb instanceof final DBAccessMorphia dam) {
return 0L;
} else {
@ -568,18 +586,26 @@ public class AddOnManyToMany implements DataAccessAddOn {
final Class<?> primaryType = primaryField.getType();
if (primaryType == Long.class) {
if (objectClass == Long.class) {
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongLong.class, options);
options.add(new OptionSpecifyType("object1Id", Long.class));
options.add(new OptionSpecifyType("object2Id", Long.class));
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options);
postActionList.addAll(sqlCommand);
} else {
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongUUID.class, options);
options.add(new OptionSpecifyType("object1Id", Long.class));
options.add(new OptionSpecifyType("object2Id", UUID.class));
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options);
postActionList.addAll(sqlCommand);
}
} else if (primaryType == UUID.class) {
if (objectClass == Long.class) {
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDLong.class, options);
options.add(new OptionSpecifyType("object1Id", UUID.class));
options.add(new OptionSpecifyType("object2Id", Long.class));
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options);
postActionList.addAll(sqlCommand);
} else {
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDUUID.class, options);
options.add(new OptionSpecifyType("object1Id", UUID.class));
options.add(new OptionSpecifyType("object2Id", UUID.class));
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options);
postActionList.addAll(sqlCommand);
}
} else {

View File

@ -20,11 +20,9 @@ import org.kar.archidata.dataAccess.QueryAnd;
import org.kar.archidata.dataAccess.QueryCondition;
import org.kar.archidata.dataAccess.QueryInList;
import org.kar.archidata.dataAccess.QueryOptions;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableLongLong;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableLongUUID;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableUUIDLong;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableUUIDUUID;
import org.kar.archidata.dataAccess.addOnSQL.model.LinkTableGeneric;
import org.kar.archidata.dataAccess.options.Condition;
import org.kar.archidata.dataAccess.options.OptionSpecifyType;
import org.kar.archidata.dataAccess.options.OverrideTableName;
import org.kar.archidata.exception.DataAccessException;
import org.kar.archidata.tools.ConfigBaseVariable;
@ -316,35 +314,13 @@ public class AddOnManyToMany implements DataAccessAddOn {
final String columnName = AnnotationTools.getFieldName(field);
final String linkTableName = generateLinkTableName(tableName, columnName);
if (localKey instanceof final Long localKeyLong) {
if (objectClass == Long.class) {
actions.add(() -> {
ioDb.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
} else {
actions.add(() -> {
ioDb.deleteWhere(LinkTableLongUUID.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyLong)));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
}
} else if (localKey instanceof final UUID localKeyUUID) {
if (objectClass == Long.class) {
actions.add(() -> {
ioDb.deleteWhere(LinkTableUUIDLong.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
} else {
actions.add(() -> {
ioDb.deleteWhere(LinkTableUUIDUUID.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKeyUUID)));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
}
}
actions.add(() -> {
ioDb.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryCondition("object1Id", "=", localKey)),
new OptionSpecifyType("object1Id", localKey.getClass()),
new OptionSpecifyType("object2Id", objectClass));
});
asyncInsert(ioDb, tableName, localKey, field, data, actions);
}
@Override
@ -375,148 +351,58 @@ public class AddOnManyToMany implements DataAccessAddOn {
}
final String columnName = AnnotationTools.getFieldName(field);
final String linkTableName = generateLinkTableName(tableName, columnName);
if (localKey instanceof final Long localKeyLong) {
if (objectClass == Long.class) {
// ========================================================
// == Link a "Long" primary Key with List<Long>
// ========================================================
@SuppressWarnings("unchecked")
final List<Long> dataCasted = (List<Long>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableLongLong> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableLongLong(localKeyLong, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
});
} else {
// ========================================================
// == Link a "Long" primary Key with List<UUID>
// ========================================================
@SuppressWarnings("unchecked")
final List<UUID> dataCasted = (List<UUID>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableLongUUID> insertElements = new ArrayList<>();
for (final UUID remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableLongUUID(localKeyLong, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
});
}
} else if (localKey instanceof final UUID localKeyUUID) {
if (objectClass == Long.class) {
// ========================================================
// == Link a "UUID" primary Key with List<Long>
// ========================================================
@SuppressWarnings("unchecked")
final List<Long> dataCasted = (List<Long>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableUUIDLong> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableUUIDLong(localKeyUUID, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
});
} else {
// ========================================================
// == Link a "UUID" primary Key with List<UUID>
// ========================================================
@SuppressWarnings("unchecked")
final List<UUID> dataCasted = (List<UUID>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableUUIDUUID> insertElements = new ArrayList<>();
for (final UUID remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableUUIDUUID(localKeyUUID, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName));
});
}
} else {
throw new DataAccessException("Not manage access of remte key like ManyToMany other than Long or UUID: "
+ localKey.getClass().getCanonicalName());
@SuppressWarnings("unchecked")
final List<Long> dataCasted = (List<Long>) data;
if (dataCasted.size() == 0) {
return;
}
final List<LinkTableGeneric> insertElements = new ArrayList<>();
for (final Long remoteKey : dataCasted) {
if (remoteKey == null) {
throw new DataAccessException("Try to insert remote key with null value");
}
insertElements.add(new LinkTableGeneric(localKey, remoteKey));
}
if (insertElements.size() == 0) {
LOGGER.warn("Insert multiple link without any value (may have null in the list): {}", dataCasted);
return;
}
actions.add(() -> {
ioDb.insertMultiple(insertElements, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", localKey.getClass()),
new OptionSpecifyType("object2Id", objectClass));
});
}
@Override
public void drop(final DBAccessSQL ioDb, final String tableName, final Field field) throws Exception {
final String columnName = AnnotationTools.getFieldName(field);
final String linkTableName = generateLinkTableName(tableName, columnName);
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass != Long.class && objectClass != UUID.class) {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
ioDb.drop(LinkTableLongLong.class, new OverrideTableName(linkTableName));
ioDb.drop(LinkTableGeneric.class, new OverrideTableName(linkTableName));
}
@Override
public void cleanAll(final DBAccessSQL ioDb, final String tableName, final Field field) throws Exception {
final String columnName = AnnotationTools.getFieldName(field);
final String linkTableName = generateLinkTableName(tableName, columnName);
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass != Long.class && objectClass != UUID.class) {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
ioDb.cleanAll(LinkTableLongLong.class, new OverrideTableName(linkTableName));
ioDb.cleanAll(LinkTableGeneric.class, new OverrideTableName(linkTableName));
}
public static void addLink(
final DBAccess ioDb,
final Class<?> clazz,
final long localKey,
final Object localKey,
final String column,
final long remoteKey) throws Exception {
final Object remoteKey) throws Exception {
if (ioDb instanceof final DBAccessSQL daSQL) {
final String tableName = AnnotationTools.getTableName(clazz);
final String linkTableName = generateLinkTableName(tableName, column);
/* final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; if (objectClass != Long.class && objectClass != UUID.class) { throw new
* DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<" + objectClass.getCanonicalName() + ">"); } */
final LinkTableLongLong insertElement = new LinkTableLongLong(localKey, remoteKey);
daSQL.insert(insertElement, new OverrideTableName(linkTableName));
final LinkTableGeneric insertElement = new LinkTableGeneric(localKey, remoteKey);
daSQL.insert(insertElement, new OverrideTableName(linkTableName),
new OptionSpecifyType("object1Id", localKey.getClass()),
new OptionSpecifyType("object2Id", remoteKey.getClass()));
} else if (ioDb instanceof final DBAccessMorphia dam) {
} else {
@ -528,15 +414,17 @@ public class AddOnManyToMany implements DataAccessAddOn {
public static long removeLink(
final DBAccess ioDb,
final Class<?> clazz,
final long localKey,
final Object localKey,
final String column,
final long remoteKey) throws Exception {
final Object remoteKey) throws Exception {
if (ioDb instanceof final DBAccessSQL daSQL) {
final String tableName = AnnotationTools.getTableName(clazz);
final String linkTableName = generateLinkTableName(tableName, column);
return daSQL.deleteWhere(LinkTableLongLong.class, new OverrideTableName(linkTableName),
return daSQL.deleteWhere(LinkTableGeneric.class, new OverrideTableName(linkTableName),
new Condition(new QueryAnd(new QueryCondition("object1Id", "=", localKey),
new QueryCondition("object2Id", "=", remoteKey))));
new QueryCondition("object2Id", "=", remoteKey))),
new OptionSpecifyType("object1Id", localKey.getClass()),
new OptionSpecifyType("object2Id", remoteKey.getClass()));
} else if (ioDb instanceof final DBAccessMorphia dam) {
return 0L;
} else {
@ -555,7 +443,6 @@ public class AddOnManyToMany implements DataAccessAddOn {
final boolean createIfNotExist,
final boolean createDrop,
final int fieldId) throws Exception {
final ManyToMany manyToMany = AnnotationTools.getManyToMany(field);
if (manyToMany.mappedBy() != null && manyToMany.mappedBy().length() != 0) {
// not the reference model to create base:
@ -565,30 +452,10 @@ public class AddOnManyToMany implements DataAccessAddOn {
final QueryOptions options = new QueryOptions(new OverrideTableName(linkTableName));
final Class<?> objectClass = (Class<?>) ((ParameterizedType) field.getGenericType())
.getActualTypeArguments()[0];
if (objectClass != Long.class && objectClass != UUID.class) {
throw new DataAccessException("Can not ManyToMany with other than List<Long> or List<UUID> Model: List<"
+ objectClass.getCanonicalName() + ">");
}
final Class<?> primaryType = primaryField.getType();
if (primaryType == Long.class) {
if (objectClass == Long.class) {
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongLong.class, options);
postActionList.addAll(sqlCommand);
} else {
final List<String> sqlCommand = DataFactory.createTable(LinkTableLongUUID.class, options);
postActionList.addAll(sqlCommand);
}
} else if (primaryType == UUID.class) {
if (objectClass == Long.class) {
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDLong.class, options);
postActionList.addAll(sqlCommand);
} else {
final List<String> sqlCommand = DataFactory.createTable(LinkTableUUIDUUID.class, options);
postActionList.addAll(sqlCommand);
}
} else {
throw new DataAccessException("Can not ManyToMany with other than primary key type Long or UUID Model: "
+ primaryType.getCanonicalName());
}
options.add(new OptionSpecifyType("object1Id", primaryType));
options.add(new OptionSpecifyType("object2Id", objectClass));
final List<String> sqlCommand = DataFactory.createTable(LinkTableGeneric.class, options);
postActionList.addAll(sqlCommand);
}
}

View File

@ -1,25 +1,25 @@
package org.kar.archidata.dataAccess.addOnSQL.model;
import org.kar.archidata.model.UUIDGenericDataSoftDelete;
import org.kar.archidata.model.OIDGenericDataSoftDelete;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
public class LinkTableLongLong extends UUIDGenericDataSoftDelete {
public LinkTableLongLong() {
public class LinkTableGeneric extends OIDGenericDataSoftDelete {
public LinkTableGeneric() {
// nothing to do...
}
public LinkTableLongLong(final long object1Id, final long object2Id) {
public LinkTableGeneric(final Object object1Id, final Object object2Id) {
this.object1Id = object1Id;
this.object2Id = object2Id;
}
@Schema(description = "Object reference 1")
@Column(nullable = false)
public Long object1Id;
public Object object1Id;
@Schema(description = "Object reference 2")
@Column(nullable = false)
public Long object2Id;
public Object object2Id;
}

View File

@ -1,27 +0,0 @@
package org.kar.archidata.dataAccess.addOnSQL.model;
import java.util.UUID;
import org.kar.archidata.model.UUIDGenericDataSoftDelete;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
public class LinkTableLongUUID extends UUIDGenericDataSoftDelete {
public LinkTableLongUUID() {
// nothing to do...
}
public LinkTableLongUUID(final long object1Id, final UUID object2Id) {
this.object1Id = object1Id;
this.object2Id = object2Id;
}
@Schema(description = "Object reference 1")
@Column(nullable = false)
public Long object1Id;
@Schema(description = "Object reference 2")
@Column(nullable = false)
public UUID object2Id;
}

View File

@ -1,27 +0,0 @@
package org.kar.archidata.dataAccess.addOnSQL.model;
import java.util.UUID;
import org.kar.archidata.model.UUIDGenericDataSoftDelete;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
public class LinkTableUUIDLong extends UUIDGenericDataSoftDelete {
public LinkTableUUIDLong() {
// nothing to do...
}
public LinkTableUUIDLong(final UUID object1Id, final long object2Id) {
this.object1Id = object1Id;
this.object2Id = object2Id;
}
@Schema(description = "Object reference 1")
@Column(nullable = false)
public UUID object1Id;
@Schema(description = "Object reference 2")
@Column(nullable = false)
public Long object2Id;
}

View File

@ -1,27 +0,0 @@
package org.kar.archidata.dataAccess.addOnSQL.model;
import java.util.UUID;
import org.kar.archidata.model.UUIDGenericDataSoftDelete;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
public class LinkTableUUIDUUID extends UUIDGenericDataSoftDelete {
public LinkTableUUIDUUID() {
// nothing to do...
}
public LinkTableUUIDUUID(final UUID object1Id, final UUID object2Id) {
this.object1Id = object1Id;
this.object2Id = object2Id;
}
@Schema(description = "Object reference 1")
@Column(nullable = false)
public UUID object1Id;
@Schema(description = "Object reference 2")
@Column(nullable = false)
public UUID object2Id;
}

View File

@ -0,0 +1,12 @@
package org.kar.archidata.dataAccess.options;
public class OptionSpecifyType extends QueryOption {
public final String name;
public final Class<?> clazz;
// To specify the type of an element if the model is a Object.
public OptionSpecifyType(final String name, final Class<?> clazz) {
this.clazz = clazz;
this.name = name;
}
}

View File

@ -1,7 +1,5 @@
package org.kar.archidata.model;
import org.bson.types.ObjectId;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.persistence.GeneratedValue;
@ -9,8 +7,6 @@ import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
public class GenericData extends GenericTiming {
@dev.morphia.annotations.Id
private ObjectId _id;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false, unique = true)

View File

@ -0,0 +1,17 @@
package org.kar.archidata.model;
import org.bson.types.ObjectId;
import dev.morphia.annotations.Id;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column;
import jakarta.validation.constraints.NotNull;
public class OIDGenericData extends GenericTiming {
@Id
//@jakarta.persistence.Id
@Column(nullable = false, unique = true)
@Schema(description = "Unique ObjectID of the object", required = false, readOnly = true, example = "65161616841351")
@NotNull
public ObjectId _id = null;
}

View File

@ -0,0 +1,19 @@
package org.kar.archidata.model;
import org.kar.archidata.annotation.DataDeleted;
import org.kar.archidata.annotation.DataNotRead;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import jakarta.persistence.Column;
import jakarta.ws.rs.DefaultValue;
public class OIDGenericDataSoftDelete extends OIDGenericData {
@DataNotRead
@Column(nullable = false)
@DefaultValue("'0'")
@DataDeleted
@Schema(description = "Deleted state", hidden = true, required = false, readOnly = true)
@Nullable
public Boolean deleted = null;
}