added migrations
This commit is contained in:
@@ -15,6 +15,9 @@
|
|||||||
- actually parse getter
|
- actually parse getter
|
||||||
- resolve Predicate functions (not, and, or)
|
- resolve Predicate functions (not, and, or)
|
||||||
- don't bind external vars in lambdas, instead make information (parameter and intercepted values) available in a context object
|
- don't bind external vars in lambdas, instead make information (parameter and intercepted values) available in a context object
|
||||||
|
- expose more stuff as result (e.g. accessed members/functions, ...)
|
||||||
|
- cleanup exception handling
|
||||||
|
- cleanup if else trees
|
||||||
|
|
||||||
## ModelBuilder
|
## ModelBuilder
|
||||||
- add registrable conversion types e.g. UUID, Date, Timestamp, Calendar, LocalTime, Instant,...
|
- add registrable conversion types e.g. UUID, Date, Timestamp, Calendar, LocalTime, Instant,...
|
||||||
@@ -22,6 +25,9 @@
|
|||||||
- field length
|
- field length
|
||||||
- field precision
|
- field precision
|
||||||
- sql type
|
- sql type
|
||||||
|
- ignore() entity/field for db
|
||||||
|
- object inlining
|
||||||
|
- entity() with callback
|
||||||
|
|
||||||
## Annotations
|
## Annotations
|
||||||
- db type
|
- db type
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package jef.asm;
|
package jef.asm;
|
||||||
|
|
||||||
public class AsmParseException extends Exception {
|
public class AsmParseException extends RuntimeException {
|
||||||
public AsmParseException() {
|
public AsmParseException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
src/main/java/jef/asm/AsmParseResult.java
Normal file
16
src/main/java/jef/asm/AsmParseResult.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package jef.asm;
|
||||||
|
|
||||||
|
import jef.expressions.Expression;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class AsmParseResult {
|
||||||
|
private final Expression expression;
|
||||||
|
private final Set<Field> accessedFields;
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package jef.asm;
|
package jef.asm;
|
||||||
|
|
||||||
import jef.expressions.Expression;
|
|
||||||
import jef.serializable.SerializableFunction;
|
import jef.serializable.SerializableFunction;
|
||||||
import jef.serializable.SerializablePredicate;
|
import jef.serializable.SerializablePredicate;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -24,7 +23,7 @@ public class AsmParser {
|
|||||||
this.lambda = function;
|
this.lambda = function;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression parse() throws AsmParseException {
|
public AsmParseResult parse() throws AsmParseException {
|
||||||
try {
|
try {
|
||||||
return parseExpression();
|
return parseExpression();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -32,35 +31,26 @@ public class AsmParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression parseExpression() throws Exception {
|
private AsmParseResult parseExpression() throws Exception {
|
||||||
var cls = lambda.getClass();
|
var cls = lambda.getClass();
|
||||||
var loader = cls.getClassLoader();
|
var loader = cls.getClassLoader();
|
||||||
InputStream is;
|
InputStream is;
|
||||||
// System.out.println(cls);
|
|
||||||
// System.out.println(cls.getName());
|
|
||||||
if (cls.getName().contains("$$Lambda$")) {
|
if (cls.getName().contains("$$Lambda$")) {
|
||||||
// System.out.println(cls.getName().split("\\$\\$")[0].replace(".", "/") + ".class");
|
|
||||||
is = loader.getResourceAsStream(cls.getName().split("\\$\\$")[0].replace(".", "/") + ".class");
|
is = loader.getResourceAsStream(cls.getName().split("\\$\\$")[0].replace(".", "/") + ".class");
|
||||||
} else {
|
} else {
|
||||||
// System.out.println(cls.getName().replace(".", "/") + ".class");
|
|
||||||
is = loader.getResourceAsStream(cls.getName().replace(".", "/") + ".class");
|
is = loader.getResourceAsStream(cls.getName().replace(".", "/") + ".class");
|
||||||
}
|
}
|
||||||
var x = cls.getDeclaredMethod("writeReplace");
|
var writeReplace = cls.getDeclaredMethod("writeReplace");
|
||||||
// System.out.println(x);
|
writeReplace.setAccessible(true);
|
||||||
x.setAccessible(true);
|
var serlambda = (SerializedLambda) writeReplace.invoke(lambda);
|
||||||
var serlambda = (SerializedLambda) x.invoke(lambda);
|
|
||||||
Object[] args = IntStream.range(0, serlambda.getCapturedArgCount()).mapToObj(serlambda::getCapturedArg).toArray();
|
Object[] args = IntStream.range(0, serlambda.getCapturedArgCount()).mapToObj(serlambda::getCapturedArg).toArray();
|
||||||
// System.out.println(serlambda);
|
|
||||||
|
|
||||||
var lambdaname = serlambda.getImplMethodName();
|
var lambdaname = serlambda.getImplMethodName();
|
||||||
// System.out.println(lambdaname);
|
|
||||||
|
|
||||||
var expr = new Expression[1];
|
|
||||||
|
|
||||||
var cr = new ClassReader(is);
|
var cr = new ClassReader(is);
|
||||||
var visiter = new FilterClassVisitor(Opcodes.ASM9, lambdaname, args, e -> expr[0] = e);
|
var visiter = new FilterClassVisitor(Opcodes.ASM9, lambdaname, args);
|
||||||
cr.accept(visiter, 0);
|
cr.accept(visiter, 0);
|
||||||
|
|
||||||
return expr[0];
|
return visiter.getResult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
package jef.asm;
|
package jef.asm;
|
||||||
|
|
||||||
import jef.expressions.Expression;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.Optional;
|
||||||
|
|
||||||
class FilterClassVisitor extends ClassVisitor {
|
class FilterClassVisitor extends ClassVisitor {
|
||||||
private final int api;
|
private final int api;
|
||||||
private final String lambdaname;
|
private final String lambdaname;
|
||||||
private final Consumer<Expression> queryConsumer;
|
|
||||||
private final Object[] args;
|
private final Object[] args;
|
||||||
|
|
||||||
protected FilterClassVisitor(int api, String lambdaname, Object[] args, Consumer<Expression> queryConsumer) {
|
private FilterMethodVisitor mv;
|
||||||
|
|
||||||
|
protected FilterClassVisitor(int api, String lambdaname, Object[] args) {
|
||||||
super(api);
|
super(api);
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.lambdaname = lambdaname;
|
this.lambdaname = lambdaname;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
this.queryConsumer = queryConsumer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -26,7 +25,23 @@ class FilterClassVisitor extends ClassVisitor {
|
|||||||
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
return super.visitMethod(access, name, descriptor, signature, exceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("found method name: " + name);
|
if (mv != null) {
|
||||||
return new FilterMethodVisitor(api, descriptor, args, queryConsumer);
|
throw new IllegalStateException("multiple lambda with same name found: " + lambdaname);
|
||||||
|
}
|
||||||
|
return mv = new FilterMethodVisitor(api, descriptor, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
super.visitEnd();
|
||||||
|
|
||||||
|
//finish
|
||||||
|
if (mv == null) {
|
||||||
|
throw new IllegalStateException("lambda not found: " + lambdaname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsmParseResult getResult() {
|
||||||
|
return Optional.ofNullable(mv).map(e -> e.getResult()).orElse(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.objectweb.asm.Type;
|
|||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -37,13 +38,12 @@ class FilterMethodVisitor extends MethodVisitor {
|
|||||||
private Stack<Expression> varStack = new Stack<>();
|
private Stack<Expression> varStack = new Stack<>();
|
||||||
private final String[] parameterClasses;
|
private final String[] parameterClasses;
|
||||||
private final Object[] args;
|
private final Object[] args;
|
||||||
private final Consumer<Expression> exprConsumer;
|
|
||||||
private Expression lambdaExpr;
|
private Expression lambdaExpr;
|
||||||
|
private final Set<Field> accessedMembers = new HashSet<>();
|
||||||
|
|
||||||
protected FilterMethodVisitor(int api, String descriptor, Object[] args, Consumer<Expression> exprConsumer) {
|
protected FilterMethodVisitor(int api, String descriptor, Object[] args) {
|
||||||
super(api);
|
super(api);
|
||||||
this.args = args;
|
this.args = args;
|
||||||
this.exprConsumer = exprConsumer;
|
|
||||||
|
|
||||||
//parameters
|
//parameters
|
||||||
var types = Type.getMethodType(descriptor).getArgumentTypes();
|
var types = Type.getMethodType(descriptor).getArgumentTypes();
|
||||||
@@ -53,6 +53,10 @@ class FilterMethodVisitor extends MethodVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AsmParseResult getResult() {
|
||||||
|
return new AsmParseResult(lambdaExpr, accessedMembers);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
|
public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
|
||||||
System.out.println("local var: " + name);
|
System.out.println("local var: " + name);
|
||||||
@@ -67,6 +71,11 @@ class FilterMethodVisitor extends MethodVisitor {
|
|||||||
var v = varStack.pop();
|
var v = varStack.pop();
|
||||||
if (v instanceof ParameterExpression p) {
|
if (v instanceof ParameterExpression p) {
|
||||||
if (p.isInput()) {
|
if (p.isInput()) {
|
||||||
|
try {
|
||||||
|
accessedMembers.add(Class.forName(owner.replace("/", ".")).getDeclaredField(name));
|
||||||
|
} catch (NoSuchFieldException | ClassNotFoundException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
varStack.push(new IntermediateFieldExpression(name, descriptor));
|
varStack.push(new IntermediateFieldExpression(name, descriptor));
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("field insn: unsupported GETFIELD expression");
|
throw new RuntimeException("field insn: unsupported GETFIELD expression");
|
||||||
@@ -386,7 +395,6 @@ class FilterMethodVisitor extends MethodVisitor {
|
|||||||
System.out.println("end");
|
System.out.println("end");
|
||||||
|
|
||||||
super.visitEnd();
|
super.visitEnd();
|
||||||
exprConsumer.accept(lambdaExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ public class OptimizedAsmParser extends AsmParser{
|
|||||||
super(function);
|
super(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression parse() throws AsmParseException {
|
public AsmParseResult parse() throws AsmParseException {
|
||||||
var expr = super.parse();
|
var result = super.parse();
|
||||||
|
var expr = result.getExpression();
|
||||||
|
|
||||||
System.out.println(expr);
|
System.out.println(expr);
|
||||||
expr = new TernaryRewriter().modify(expr);
|
expr = new TernaryRewriter().modify(expr);
|
||||||
@@ -37,6 +38,6 @@ public class OptimizedAsmParser extends AsmParser{
|
|||||||
System.out.println(expr);
|
System.out.println(expr);
|
||||||
expr = new ExpressionOptimizerBottomUp().modify(expr);
|
expr = new ExpressionOptimizerBottomUp().modify(expr);
|
||||||
|
|
||||||
return expr;
|
return new AsmParseResult(expr, result.getAccessedFields());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import java.util.Optional;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class DbContext {
|
public abstract class DbContext {
|
||||||
private static final String ILLEGAL_CHARACTERS = "\"'`,.";//TODO also validate this in modelbuilder/dbentity/dbfield
|
private static final String ILLEGAL_CHARACTERS = "\"'`,.";
|
||||||
|
|
||||||
public void onModelCreate(ModelBuilder mb) {
|
public void onModelCreate(ModelBuilder mb) {
|
||||||
}
|
}
|
||||||
@@ -44,13 +44,13 @@ public abstract class DbContext {
|
|||||||
|
|
||||||
//check for duplicate field names
|
//check for duplicate field names
|
||||||
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
||||||
var fieldNameMap = new HashMap<String, DbEntity<?>>();
|
var fieldNameMap = new HashMap<String, DbField<?>>();
|
||||||
for (DbField<?> field : entity.getFields()) {
|
for (DbField<?> field : entity.getFields()) {
|
||||||
var name = field.getName().toLowerCase();
|
var name = field.getName().toLowerCase();
|
||||||
if (fieldNameMap.containsKey(name)) {
|
if (fieldNameMap.containsKey(name)) {
|
||||||
errors.add("Duplicate DbField in entity " + entity.getTypeName() + " with name " + field.getName() + ": " + field.getName() + " and " + fieldNameMap.get(name).getName());
|
errors.add("Duplicate DbField in entity " + entity.getTypeName() + " with name " + field.getName() + ": " + field.getName() + " and " + fieldNameMap.get(name).getName());
|
||||||
} else {
|
} else {
|
||||||
fieldNameMap.put(name, entity);
|
fieldNameMap.put(name, field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import jef.model.constraints.UniqueKeyConstraint;
|
|||||||
import jef.serializable.SerializableFunction;
|
import jef.serializable.SerializableFunction;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
import jef.util.Check;
|
import jef.util.Check;
|
||||||
import jef.util.Util;
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -24,11 +23,11 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter(value = AccessLevel.PACKAGE)
|
||||||
public class DbEntity<T extends SerializableObject> {
|
public class DbEntity<T extends SerializableObject> {
|
||||||
private final String typeName;
|
private String typeName;
|
||||||
@Setter(value = AccessLevel.PACKAGE)
|
// @Setter
|
||||||
private Class<T> type;
|
// private Class<T> type;
|
||||||
private final List<DbField<?>> fields;
|
private final List<DbField<?>> fields;
|
||||||
private String name;
|
private String name;
|
||||||
private PrimaryKeyConstraint primaryKey;
|
private PrimaryKeyConstraint primaryKey;
|
||||||
@@ -39,7 +38,6 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
|
|
||||||
//only used for migrations
|
//only used for migrations
|
||||||
DbEntity(String typeName) {
|
DbEntity(String typeName) {
|
||||||
this.type = (Class) Util.tryGet(() -> Class.forName(typeName)).orElse(null);
|
|
||||||
this.typeName = typeName;
|
this.typeName = typeName;
|
||||||
this.fields = new ArrayList<>();
|
this.fields = new ArrayList<>();
|
||||||
var split = typeName.split("\\.");
|
var split = typeName.split("\\.");
|
||||||
@@ -55,7 +53,7 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DbEntity(Class<T> type, String name, List<DbField<?>> fields) {
|
DbEntity(Class<T> type, String name, List<DbField<?>> fields) {
|
||||||
this.type = Check.notNull(type, "type");
|
// this.type = Check.notNull(type, "type");
|
||||||
this.typeName = type.getName();
|
this.typeName = type.getName();
|
||||||
this.fields = Check.notNull(fields, "fields");
|
this.fields = Check.notNull(fields, "fields");
|
||||||
this.name = Check.notNull(name, "name");
|
this.name = Check.notNull(name, "name");
|
||||||
@@ -107,7 +105,7 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
var prop = getField(getter);
|
var prop = getField(getter);
|
||||||
if (prop == null) {
|
if (prop == null) {
|
||||||
var name = extractFieldName(getter);
|
var name = extractFieldName(getter);
|
||||||
var field = ReflectionUtil.getFieldsRecursive(type).stream().filter(f -> f.getName().equals(name)).findFirst().orElse(null);
|
var field = ReflectionUtil.getFieldsRecursive((Class<SerializableObject>) Class.forName(typeName)).stream().filter(f -> f.getName().equals(name)).findFirst().orElse(null);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new RuntimeException("Field not found: " + name);
|
throw new RuntimeException("Field not found: " + name);
|
||||||
}
|
}
|
||||||
@@ -181,6 +179,7 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Does not validate foreign key integrity
|
* Does not validate foreign key integrity
|
||||||
|
*
|
||||||
* @param primaryKey
|
* @param primaryKey
|
||||||
*/
|
*/
|
||||||
public void setPrimaryKey(PrimaryKeyConstraint primaryKey) {
|
public void setPrimaryKey(PrimaryKeyConstraint primaryKey) {
|
||||||
@@ -211,9 +210,18 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <R> String extractFieldName(SerializableFunction<T, R> getter) {
|
void addField(DbField<?> field) {
|
||||||
|
this.fields.add(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
DbEntityBuilder<T> builder(ModelBuilder mb) {
|
||||||
|
return new DbEntityBuilder<>(mb, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
<R> String extractFieldName(SerializableFunction<T, R> getter) {
|
||||||
try {
|
try {
|
||||||
var expr = new AsmParser(getter).parse();
|
var expr = new AsmParser(getter).parse().getExpression();
|
||||||
if (expr.getType() != Expression.Type.INTERMEDIATE_FIELD) {
|
if (expr.getType() != Expression.Type.INTERMEDIATE_FIELD) {
|
||||||
throw new RuntimeException(expr.getClass().getSimpleName() + " is not a field expression");
|
throw new RuntimeException(expr.getClass().getSimpleName() + " is not a field expression");
|
||||||
}
|
}
|
||||||
@@ -241,13 +249,13 @@ public class DbEntity<T extends SerializableObject> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(typeName, type, fields, name, primaryKey, foreignKeys, uniqueKeys, keys, indexes);
|
return Objects.hash(typeName, fields, name, primaryKey, foreignKeys, uniqueKeys, keys, indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DbEntity{" +
|
return "DbEntity{" +
|
||||||
"type=" + type +
|
"typeName=" + typeName +
|
||||||
", name='" + name + '\'' +
|
", name='" + name + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|||||||
121
src/main/java/jef/model/DbEntityBuilder.java
Normal file
121
src/main/java/jef/model/DbEntityBuilder.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package jef.model;
|
||||||
|
|
||||||
|
import jef.asm.AsmParser;
|
||||||
|
import jef.serializable.SerializableFunction;
|
||||||
|
import jef.serializable.SerializableObject;
|
||||||
|
import jef.util.Check;
|
||||||
|
import jef.util.Util;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class DbEntityBuilder<T extends SerializableObject> {
|
||||||
|
private final ModelBuilder modelBuilder;
|
||||||
|
private final DbEntity<T> entity;
|
||||||
|
|
||||||
|
public DbEntityBuilder<T> name(String name) {
|
||||||
|
entity.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R> DbFieldBuilder<R> field(SerializableFunction<T, R> getter) {
|
||||||
|
try {
|
||||||
|
var prop = entity.getField(getter);
|
||||||
|
if (prop == null) {
|
||||||
|
var name = entity.extractFieldName(getter);
|
||||||
|
var field = ReflectionUtil.getFieldsRecursive(type().get()).stream().filter(f -> f.getName().equals(name)).findFirst().orElse(null);
|
||||||
|
if (field == null) {
|
||||||
|
throw new RuntimeException("Field not found: " + name);
|
||||||
|
}
|
||||||
|
prop = new DbField<>(entity, (Class<R>) field.getType(), field);
|
||||||
|
entity.addField(prop);
|
||||||
|
}
|
||||||
|
return new DbFieldBuilder<>(prop);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Invalid expression", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R> DbFieldBuilder<R> field(Field field) {
|
||||||
|
var prop = (DbField<R>) entity.getFields().stream().filter(e -> e.getField().equals(field)).findFirst().orElse(null);
|
||||||
|
if (prop == null) {
|
||||||
|
prop = new DbField<>(entity, (Class<R>) field.getType(), field);
|
||||||
|
entity.addField(prop);
|
||||||
|
}
|
||||||
|
return new DbFieldBuilder<>(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R> DbFieldBuilder<R> field(String name, String typeName) {
|
||||||
|
var prop = (DbField<R>) entity.getFields().stream().filter(e -> e.getName().equals(name)).findFirst().orElse(null);
|
||||||
|
if (prop == null) {
|
||||||
|
prop = new DbField<>(entity, name, typeName);
|
||||||
|
entity.addField(prop);
|
||||||
|
}
|
||||||
|
return new DbFieldBuilder<>(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
//keys
|
||||||
|
public KeyBuilder<T> hasOne(SerializableFunction<T, ?> getter) {
|
||||||
|
Check.notNull(getter, "getter");
|
||||||
|
var set = new AsmParser(getter).parse().getAccessedFields();
|
||||||
|
var fields = entity.getFields().stream().filter(e -> set.contains(e.getField())).toList();
|
||||||
|
return new KeyBuilder<>(modelBuilder, entity, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBuilder<T> hasOne(String... getterOrFieldNames) {
|
||||||
|
Check.notNull(getterOrFieldNames, "getterOrFieldNames");
|
||||||
|
var set = new HashSet<>(Arrays.asList(getterOrFieldNames));
|
||||||
|
var fields = entity.getFields().stream().filter(e -> set.contains(e.getName())).toList();
|
||||||
|
return new KeyBuilder<>(modelBuilder, entity, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBuilder<T> hasMany(SerializableFunction<T, ?> getter) {
|
||||||
|
Check.notNull(getter, "getter");
|
||||||
|
var set = new AsmParser(getter).parse().getAccessedFields();
|
||||||
|
var fields = entity.getFields().stream().filter(e -> set.contains(e.getField())).toList();
|
||||||
|
return new KeyBuilder<>(modelBuilder, entity, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBuilder<T> hasMany(String... getterOrFieldNames) {
|
||||||
|
Check.notNull(getterOrFieldNames, "getterOrFieldNames");
|
||||||
|
var set = new HashSet<>(Arrays.asList(getterOrFieldNames));
|
||||||
|
var fields = entity.getFields().stream().filter(e -> set.contains(e.getName())).toList();
|
||||||
|
return new KeyBuilder<>(modelBuilder, entity, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
//getters
|
||||||
|
public String name() {
|
||||||
|
return entity.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DbFieldBuilder<?>> fields() {
|
||||||
|
return (List) entity.getFields().stream().map(e -> new DbFieldBuilder(e)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Class<T>> type() {
|
||||||
|
return Util.tryGet(() -> (Class<T>) Class.forName(typeName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String typeName() {
|
||||||
|
return entity.getTypeName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String className() {
|
||||||
|
var s = entity.getTypeName().replace("$", ".").split("\\.");
|
||||||
|
return s[s.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbEntity<T> getEntity() { //TODO make this libaray private somehow
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return entity.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
package jef.model;
|
package jef.model;
|
||||||
|
|
||||||
import jef.model.constraints.IndexConstraint;
|
|
||||||
import jef.model.constraints.KeyConstraint;
|
|
||||||
import jef.model.constraints.UniqueKeyConstraint;
|
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
import jef.util.Check;
|
import jef.util.Check;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
@@ -10,9 +7,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -26,7 +21,7 @@ public class DbField<T> {
|
|||||||
private Field field;
|
private Field field;
|
||||||
private boolean isModelField;
|
private boolean isModelField;
|
||||||
private boolean isDatabaseField;
|
private boolean isDatabaseField;
|
||||||
private DbField<?> foreignKeyModelLink;
|
private DbField<?> exposingForeignKeyOf;
|
||||||
private String name;
|
private String name;
|
||||||
private boolean notNull = false;
|
private boolean notNull = false;
|
||||||
|
|
||||||
@@ -62,41 +57,14 @@ public class DbField<T> {
|
|||||||
return entity.getUniqueKeys().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
return entity.getUniqueKeys().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnique(boolean unique) {
|
|
||||||
var constr = entity.getUniqueKeys().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == this).findFirst();
|
|
||||||
if (!constr.isPresent() && unique) {
|
|
||||||
entity.addUniqueKey(new UniqueKeyConstraint(entity, new ArrayList<>(List.of(this))));
|
|
||||||
} else if (constr.isPresent() && !unique) {
|
|
||||||
entity.dropUniqueKey(constr.get());
|
|
||||||
} //else do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIndex() {
|
public boolean isIndex() {
|
||||||
return entity.getIndexes().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
return entity.getIndexes().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIndex(boolean indexed) {
|
|
||||||
var constr = entity.getIndexes().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == this).findFirst();
|
|
||||||
if (!constr.isPresent() && indexed) {
|
|
||||||
entity.addIndex(new IndexConstraint(entity, new ArrayList<>(List.of(this))));
|
|
||||||
} else if (constr.isPresent() && !indexed) {
|
|
||||||
entity.dropIndex(constr.get());
|
|
||||||
} //else do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isKey() {
|
public boolean isKey() {
|
||||||
return entity.getKeys().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
return entity.getKeys().stream().anyMatch(u -> u.getFields().size() == 1 && u.getFields().get(0) == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(boolean keyed) {
|
|
||||||
var constr = entity.getKeys().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == this).findFirst();
|
|
||||||
if (!constr.isPresent() && keyed) {
|
|
||||||
entity.addKey(new KeyConstraint(entity, new ArrayList<>(List.of(this))));
|
|
||||||
} else if (constr.isPresent() && !keyed) {
|
|
||||||
entity.dropKey(constr.get());
|
|
||||||
} //else do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
public DbField<T> setModelField(boolean modelField) {
|
public DbField<T> setModelField(boolean modelField) {
|
||||||
isModelField = modelField;
|
isModelField = modelField;
|
||||||
return this;
|
return this;
|
||||||
@@ -136,14 +104,14 @@ public class DbField<T> {
|
|||||||
&& entity.getName().equals(dbField.entity.getName())
|
&& entity.getName().equals(dbField.entity.getName())
|
||||||
&& typeName.equals(dbField.typeName)
|
&& typeName.equals(dbField.typeName)
|
||||||
// && Objects.equals(type, dbField.type)
|
// && Objects.equals(type, dbField.type)
|
||||||
&& Objects.equals(foreignKeyModelLink == null ? null : foreignKeyModelLink.getName(),
|
&& Objects.equals(exposingForeignKeyOf == null ? null : exposingForeignKeyOf.getName(),
|
||||||
dbField.foreignKeyModelLink == null ? null : dbField.foreignKeyModelLink.getName());
|
dbField.exposingForeignKeyOf == null ? null : dbField.exposingForeignKeyOf.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(entity.getName(), typeName, type, field == null ? null : field.getName(), isModelField, isDatabaseField,
|
return Objects.hash(entity.getName(), typeName, type, field == null ? null : field.getName(), isModelField, isDatabaseField,
|
||||||
foreignKeyModelLink == null ? null : foreignKeyModelLink.getName(),
|
exposingForeignKeyOf == null ? null : exposingForeignKeyOf.getName(),
|
||||||
name, notNull);
|
name, notNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
85
src/main/java/jef/model/DbFieldBuilder.java
Normal file
85
src/main/java/jef/model/DbFieldBuilder.java
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package jef.model;
|
||||||
|
|
||||||
|
import jef.model.constraints.IndexConstraint;
|
||||||
|
import jef.model.constraints.KeyConstraint;
|
||||||
|
import jef.model.constraints.UniqueKeyConstraint;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DbFieldBuilder<T> {
|
||||||
|
private final DbField<T> field;
|
||||||
|
|
||||||
|
public DbFieldBuilder<T> name(String name) {
|
||||||
|
field.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbFieldBuilder<T> isDatabaseField(boolean isDatabase) {
|
||||||
|
field.setDatabaseField(isDatabase);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbFieldBuilder<T> isModelField(boolean isModel) {
|
||||||
|
field.setModelField(isModel);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbFieldBuilder<T> isNotNull() {
|
||||||
|
return isNotNull(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbFieldBuilder<T> isNotNull(boolean notnull) {
|
||||||
|
field.setNotNull(notnull);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isUnique() {
|
||||||
|
isUnique(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isUnique(boolean unique) {
|
||||||
|
var entity = field.getEntity();
|
||||||
|
var constr = entity.getUniqueKeys().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == field).findFirst();
|
||||||
|
if (!constr.isPresent() && unique) {
|
||||||
|
entity.addUniqueKey(new UniqueKeyConstraint(entity, new ArrayList<>(List.of(field))));
|
||||||
|
} else if (constr.isPresent() && !unique) {
|
||||||
|
entity.dropUniqueKey(constr.get());
|
||||||
|
} //else do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isKey() {
|
||||||
|
isKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isKey(boolean key) {
|
||||||
|
var entity = field.getEntity();
|
||||||
|
var constr = entity.getKeys().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == field).findFirst();
|
||||||
|
if (!constr.isPresent() && key) {
|
||||||
|
entity.addKey(new KeyConstraint(entity, new ArrayList<>(List.of(field))));
|
||||||
|
} else if (constr.isPresent() && !key) {
|
||||||
|
entity.dropKey(constr.get());
|
||||||
|
} //else do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isIndex() {
|
||||||
|
isIndex(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isIndex(boolean index) {
|
||||||
|
var entity = field.getEntity();
|
||||||
|
var constr = entity.getIndexes().stream().filter(u -> u.getFields().size() == 1 && u.getFields().get(0) == field).findFirst();
|
||||||
|
if (!constr.isPresent() && index) {
|
||||||
|
entity.addIndex(new IndexConstraint(entity, new ArrayList<>(List.of(field))));
|
||||||
|
} else if (constr.isPresent() && !index) {
|
||||||
|
entity.dropIndex(constr.get());
|
||||||
|
} //else do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public DbField<T> getField() {//TODO make this library private
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,58 +4,78 @@ import jef.DbSet;
|
|||||||
import jef.model.annotations.Clazz;
|
import jef.model.annotations.Clazz;
|
||||||
import jef.model.annotations.Transient;
|
import jef.model.annotations.Transient;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
|
import jef.util.Log;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
class EntityInitializer {
|
class EntityInitializer {
|
||||||
static void initEntities(ModelBuilder mb, Class<? extends DbContext> context) {
|
static void initEntities(ModelBuilder mb, Class<? extends DbContext> context) {
|
||||||
for (Field ctxfield : context.getDeclaredFields()) {
|
for (Field ctxField : context.getDeclaredFields()) {
|
||||||
if (!DbSet.class.isAssignableFrom(ctxfield.getType())) {
|
if (!DbSet.class.isAssignableFrom(ctxField.getType())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Clazz clazzAnnotation = ctxfield.getAnnotation(Clazz.class);
|
Clazz clazzAnnotation = ctxField.getAnnotation(Clazz.class);
|
||||||
if (clazzAnnotation == null) {
|
if (clazzAnnotation == null) {
|
||||||
throw new ModelException("DbSet " + ctxfield.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
throw new ModelException("DbSet " + ctxField.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
||||||
|
}
|
||||||
|
if (!SerializableObject.class.isAssignableFrom(clazzAnnotation.value())) {
|
||||||
|
throw new ModelException("DbSet " + ctxField.getName() + " has a class in its " + Clazz.class.getSimpleName() + " annotation that does not inherit from " + SerializableObject.class.getSimpleName() + ": " + clazzAnnotation.value().getSimpleName()); //TODO testcase for this
|
||||||
}
|
}
|
||||||
var dbSetClazz = (Class<? extends SerializableObject>) clazzAnnotation.value();
|
var dbSetClazz = (Class<? extends SerializableObject>) clazzAnnotation.value();
|
||||||
initEntity(mb, dbsetClazz, ctxfield.getName());
|
initEntity(mb, dbSetClazz, ctxField.getName(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initEntity(ModelBuilder mb, Class<? extends SerializableObject> clazz, String name) {
|
static void initEntity(ModelBuilder mb, Class<? extends SerializableObject> clazz, String name, boolean overrideName) {
|
||||||
var entity = mb.getOrCreateEntity(clazz);
|
var existingEntity = mb.getEntity(clazz);
|
||||||
entity.setName(name);
|
if (existingEntity != null) {
|
||||||
|
//allow DbSets to override the name
|
||||||
|
if (overrideName) {
|
||||||
|
existingEntity.setName(name);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.debug("Initializing entity '" + name + "' of type " + clazz.getName());
|
||||||
|
var entity = mb.entity(clazz);
|
||||||
|
entity.name(name);
|
||||||
|
|
||||||
var fields = ReflectionUtil.getFieldsRecursive(clazz);
|
var fields = ReflectionUtil.getFieldsRecursive(clazz);
|
||||||
for (var f : fields) {
|
for (var f : fields) {
|
||||||
if (f.getAnnotationsByType(Transient.class).length > 0) {
|
if (f.getAnnotationsByType(Transient.class).length > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Log.debug("Initializing field '" + f.getName() + "' with type " + f.getType().getName());
|
||||||
if (Collection.class.isAssignableFrom(f.getType())) {
|
if (Collection.class.isAssignableFrom(f.getType())) {
|
||||||
//find a Collection field with the same Model
|
//find a Collection field with the same Model
|
||||||
//e.g. class Entity { @Clazz(Entity2.class) List<Entity2> ent; @Clazz(Entity2.class) Set<Entity2> ent2; }
|
//e.g. class Entity { @Clazz(Entity2.class) List<Entity2> ent; @Clazz(Entity2.class) Set<Entity2> ent2; }
|
||||||
var clazzAnnotation = f.getAnnotationsByType(Clazz.class);
|
var clazzAnnotation = f.getAnnotation(Clazz.class);
|
||||||
if (clazzAnnotation.length == 0) {
|
if (clazzAnnotation == null) {
|
||||||
throw new ModelException("Field " + f.getClass().getSimpleName() + "::" + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
throw new ModelException("Field " + f.getClass().getSimpleName() + "::" + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
||||||
}
|
}
|
||||||
var fClazz = clazzAnnotation[0].value();
|
var fClazz = clazzAnnotation.value();
|
||||||
var foundCollection = entity.getFields().stream()
|
if (!SerializableObject.class.isAssignableFrom(fClazz)) {
|
||||||
.filter(e -> Collection.class.isAssignableFrom(e.getType())
|
throw new ModelException("Field " + f.getClass().getSimpleName() + "::" + f.getName() + " has a class in its " + Clazz.class.getSimpleName() + " annotation that does not inherit from " + SerializableObject.class.getSimpleName() + ": " + fClazz.getSimpleName()); //TODO testcase for this
|
||||||
&& e.isModelField()
|
}
|
||||||
&& e.getField().getAnnotationsByType(Clazz.class).length > 0
|
var foundCollection = entity.fields().stream()
|
||||||
&& e.getField().getAnnotationsByType(Clazz.class)[0].clazz() == fClazz)
|
.filter(e -> Collection.class.isAssignableFrom(e.getField().getType())
|
||||||
|
&& e.getField().isModelField()
|
||||||
|
&& e.getField().getField().getAnnotationsByType(Clazz.class).length > 0
|
||||||
|
&& e.getField().getField().getAnnotationsByType(Clazz.class)[0].value() == fClazz)
|
||||||
.findFirst();
|
.findFirst();
|
||||||
if (foundCollection.isPresent()) {
|
if (foundCollection.isPresent()) {
|
||||||
throw new ModelException("Model " + entity.getType().getSimpleName() + " multiple contains a 1 to N relation with type " + fClazz.getSimpleName());
|
throw new ModelException("Model " + entity.className() + " contains multiple 1 to N relations with type " + fClazz.getSimpleName());
|
||||||
}
|
}
|
||||||
entity.getOrCreateField(f);
|
entity.field(f);
|
||||||
|
initEntity(mb, (Class<? extends SerializableObject>) fClazz, fClazz.getSimpleName(), false);
|
||||||
} else if (SerializableObject.class.isAssignableFrom(f.getType())) {
|
} else if (SerializableObject.class.isAssignableFrom(f.getType())) {
|
||||||
entity.getOrCreateField(f);
|
entity.field(f);
|
||||||
|
initEntity(mb, (Class<? extends SerializableObject>) f.getType(), f.getType().getSimpleName(), false);
|
||||||
} else {
|
} else {
|
||||||
var dbField = entity.getOrCreateField(f);
|
var dbField = entity.field(f);
|
||||||
if (f.getType().isPrimitive()) {
|
if (f.getType().isPrimitive()) {
|
||||||
dbField.setNotNull(true);
|
dbField.isNotNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/main/java/jef/model/ForeignKeyBuilder.java
Normal file
22
src/main/java/jef/model/ForeignKeyBuilder.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package jef.model;
|
||||||
|
|
||||||
|
import jef.model.constraints.ForeignKeyConstraint;
|
||||||
|
import jef.serializable.SerializableObject;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class ForeignKeyBuilder<T extends SerializableObject, R extends SerializableObject> {
|
||||||
|
private final ForeignKeyConstraint foreignKey;
|
||||||
|
|
||||||
|
public ForeignKeyBuilder<T, R> onUpdate(ForeignKeyConstraint.Action onUpdate) {
|
||||||
|
foreignKey.setOnUpdate(onUpdate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForeignKeyBuilder<T, R> onDelete(ForeignKeyConstraint.Action onDelete) {
|
||||||
|
foreignKey.setOnDelete(onDelete);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
63
src/main/java/jef/model/ForeignKeyExposeInitializer.java
Normal file
63
src/main/java/jef/model/ForeignKeyExposeInitializer.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package jef.model;
|
||||||
|
|
||||||
|
import jef.model.annotations.ForeignKey;
|
||||||
|
import jef.serializable.SerializableObject;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
class ForeignKeyExposeInitializer {//TODO testcases for this class
|
||||||
|
|
||||||
|
static void initForeignKeyExposures(ModelBuilder mb) {
|
||||||
|
var entities = mb.entities();
|
||||||
|
for (int i = 0; i < entities.size(); i++) {
|
||||||
|
var entity = entities.get(i);
|
||||||
|
initForeignKeyExposures(mb, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void initForeignKeyExposures(ModelBuilder mb, DbEntityBuilder<?> entityBuilder) {
|
||||||
|
var fields = entityBuilder.fields();
|
||||||
|
for (var f : fields) {
|
||||||
|
if (SerializableObject.class.isAssignableFrom(f.getField().getType())) {
|
||||||
|
var idFields = fields.stream()
|
||||||
|
.filter(e -> {
|
||||||
|
//ignore self
|
||||||
|
if (e.getField().getName().equals(f.getField().getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//match with name in annotation
|
||||||
|
var anno = e.getField().getField().getAnnotation(ForeignKey.class);
|
||||||
|
if (anno != null) {
|
||||||
|
if (anno.entity() != SerializableObject.class) { // not a foreign key exposure
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return f.getField().getName().equals(anno.getterOrField());//TODO support getters
|
||||||
|
}
|
||||||
|
//only allow fields with same prefix
|
||||||
|
if (!e.getField().getName().startsWith(f.getField().getName())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//match id field which ends in Id or Fk
|
||||||
|
if (e.getField().getName().equals(f.getField().getName() + "Id")
|
||||||
|
|| e.getField().getName().equals(f.getField().getName() + "ID")
|
||||||
|
|| e.getField().getName().equals(f.getField().getName() + "Fk")
|
||||||
|
|| e.getField().getName().equals(f.getField().getName() + "FK")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//match id field which ends in the name of the primary key field of the referenced entity
|
||||||
|
var other = mb.getEntity(f.getField().getTypeName());
|
||||||
|
if (other == null || other.getPrimaryKey() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//assumption: initializing from models only has primary keys with 1 field (no composite keys)
|
||||||
|
var x = other.getPrimaryKey().getFields().get(0).getName();
|
||||||
|
x = x.substring(0, 1).toUpperCase(Locale.ROOT) + x.substring(1);
|
||||||
|
return e.getField().getName().equals(f.getField().getName() + x);
|
||||||
|
}).toList();
|
||||||
|
idFields.forEach(e -> {
|
||||||
|
e.getField().setExposingForeignKeyOf(f.getField());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,43 +3,55 @@ package jef.model;
|
|||||||
import jef.model.annotations.Clazz;
|
import jef.model.annotations.Clazz;
|
||||||
import jef.model.annotations.ForeignKey;
|
import jef.model.annotations.ForeignKey;
|
||||||
import jef.model.annotations.Transient;
|
import jef.model.annotations.Transient;
|
||||||
import jef.model.constraints.ForeignKeyConstraint;
|
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
|
import jef.util.Log;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
class ForeignKeyInitializer {
|
class ForeignKeyInitializer {
|
||||||
static void initForeignKeys(ModelBuilder mb) {
|
static void initForeignKeys(ModelBuilder mb) {
|
||||||
for (int i = 0; i < mb.getEntities().size(); i++) {
|
var entities = mb.entities();
|
||||||
var entity = mb.getEntities().get(i);
|
for (int i = 0; i < entities.size(); i++) {
|
||||||
|
var entity = entities.get(i);
|
||||||
initForeignKeys(mb, entity);
|
initForeignKeys(mb, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initForeignKeys(ModelBuilder mb, DbEntity<?> entity) {
|
static void initForeignKeys(ModelBuilder mb, DbEntityBuilder<?> entityBuilder) {
|
||||||
var fields = ReflectionUtil.getFieldsRecursive(entity.getType());
|
var entity = entityBuilder.getEntity();
|
||||||
|
var fields = ReflectionUtil.getFieldsRecursive(entityBuilder.type().orElseThrow(() -> new IllegalStateException("Class not found: " + entityBuilder.typeName())));
|
||||||
for (var f : fields) {
|
for (var f : fields) {
|
||||||
if (f.getAnnotationsByType(Transient.class).length > 0) {
|
if (f.getAnnotationsByType(Transient.class).length > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (Collection.class.isAssignableFrom(f.getType())) {
|
if (Collection.class.isAssignableFrom(f.getType())) {
|
||||||
|
do1toN(mb, entityBuilder, entity, f);
|
||||||
|
} else if (SerializableObject.class.isAssignableFrom(f.getType())) {//1 to 1 relation
|
||||||
|
do1to1(mb, entityBuilder, entity, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void do1toN(ModelBuilder mb, DbEntityBuilder<?> entityBuilder, DbEntity<?> entity, Field f) {
|
||||||
Clazz clazzAnnotation = f.getAnnotation(Clazz.class);
|
Clazz clazzAnnotation = f.getAnnotation(Clazz.class);
|
||||||
if (clazzAnnotation == null) {
|
if (clazzAnnotation == null) {
|
||||||
throw new ModelException("Collection " + entity.getType().getSimpleName() + "." + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
throw new ModelException("Collection " + entityBuilder.className() + "." + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation");
|
||||||
}
|
}
|
||||||
var otherEntity = mb.getEntity((Class<? extends SerializableObject>) clazzAnnotation.value());
|
var otherEntity = mb.getEntity((Class<? extends SerializableObject>) clazzAnnotation.value());
|
||||||
if (otherEntity == null) {
|
if (otherEntity == null) {
|
||||||
EntityInitializer.initEntity(mb, (Class<? extends SerializableObject>) clazzAnnotation.value(), f.getName());
|
//all types must be initialized by EntityInitializer
|
||||||
otherEntity = mb.getEntity((Class<? extends SerializableObject>) clazzAnnotation.value());
|
throw new IllegalStateException(ForeignKeyInitializer.class.getSimpleName() + ": Entity of type " + clazzAnnotation.value() + " does not exist");
|
||||||
PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity);
|
// EntityInitializer.initEntity(mb, (Class<? extends SerializableObject>) clazzAnnotation.value(), f.getName());
|
||||||
|
// otherEntity = mb.getEntity((Class<? extends SerializableObject>) clazzAnnotation.value());
|
||||||
|
// PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity.builder(mb));
|
||||||
}
|
}
|
||||||
var primary = entity.getPrimaryKey();
|
var primary = entityBuilder.getEntity().getPrimaryKey();
|
||||||
if (primary == null) {
|
if (primary == null) {
|
||||||
throw new ModelException("Entity " + entity.getType().getSimpleName() + " is missing a primary key and therefore cannot be referenced by " + otherEntity.getType().getSimpleName());
|
throw new ModelException("Entity " + entityBuilder.className() + " is missing a primary key and therefore cannot be referenced by " + otherEntity.builder(mb).className());
|
||||||
}
|
}
|
||||||
var otherEntityF = otherEntity;
|
var otherEntityF = otherEntity;
|
||||||
var otherFields = primary.getFields().stream()
|
var otherFields = primary.getFields().stream()
|
||||||
@@ -49,16 +61,16 @@ class ForeignKeyInitializer {
|
|||||||
var otherEntityListField = otherEntityF.getFields().stream()
|
var otherEntityListField = otherEntityF.getFields().stream()
|
||||||
.filter(oef -> Collection.class.isAssignableFrom(oef.getType())
|
.filter(oef -> Collection.class.isAssignableFrom(oef.getType())
|
||||||
&& oef.getField().getAnnotationsByType(Clazz.class).length > 0
|
&& oef.getField().getAnnotationsByType(Clazz.class).length > 0
|
||||||
&& oef.getField().getAnnotationsByType(Clazz.class)[0].value() == entity.getType()).findFirst();
|
&& oef.getField().getAnnotationsByType(Clazz.class)[0].value().getName().equals(entity.getTypeName())).findFirst();
|
||||||
if (otherEntityListField.isPresent()) {
|
if (otherEntityListField.isPresent()) {
|
||||||
throw new ModelException("N to N relations need to explicitly defined via a mapping model ("
|
throw new ModelException("N to N relations need to explicitly defined via a mapping model ("
|
||||||
+ otherEntityF.getType().getSimpleName() + "::" + otherEntityListField.get().getType().getName() + " and "
|
+ otherEntityF.builder(mb).className() + "::" + otherEntityListField.get().getTypeName() + " and "
|
||||||
+ entity.getType().getSimpleName() + "::" + f.getType().getName() + ")");
|
+ entityBuilder.className() + "::" + f.getType().getName() + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find object in other entity (1 to N relation)
|
//find object in other entity (1 to N relation)
|
||||||
var otherEntityObjectField = otherEntityF.getFields().stream().filter(oef -> oef.getType() == entity.getType()).findFirst();
|
var otherEntityObjectField = otherEntityF.getFields().stream().filter(oef -> oef.getTypeName().equals(entity.getTypeName())).findFirst();
|
||||||
if (otherEntityObjectField.isPresent()) {
|
if (otherEntityObjectField.isPresent()) {
|
||||||
return new FieldSearchResult(otherEntityObjectField.get(), false);
|
return new FieldSearchResult(otherEntityObjectField.get(), false);
|
||||||
}
|
}
|
||||||
@@ -76,40 +88,60 @@ class ForeignKeyInitializer {
|
|||||||
return new FieldSearchResult(otherEntityIdField.get(), otherEntityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0);
|
return new FieldSearchResult(otherEntityIdField.get(), otherEntityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var field = new DbField<>(otherEntityF, e.getType(), null, idFieldName);
|
// //add shadow field
|
||||||
field = otherEntityF.addIfAbsent(field);
|
// var entityField = new DbField<>(otherEntityF, f.getDeclaringClass(), null, f.getName());
|
||||||
return new FieldSearchResult(field, true);
|
// entityField.setNotNull(true);
|
||||||
|
// entityField = otherEntityF.addIfAbsent(entityField);
|
||||||
|
|
||||||
|
//add shadow id field
|
||||||
|
var entityIdField = new DbField<>(otherEntityF, entityBuilder.type().orElseThrow(), null, idFieldName);
|
||||||
|
entityIdField.setNotNull(true);
|
||||||
|
entityIdField.setDatabaseField(true);
|
||||||
|
entityIdField = otherEntityF.addIfAbsent(entityIdField);
|
||||||
|
// if (entityIdField.getExposingForeignKeyOf() == null) {
|
||||||
|
// entityIdField.setExposingForeignKeyOf(entityField);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return new FieldSearchResult(entityIdField, true);
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) {
|
if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) {
|
||||||
otherEntity.addForeignKey(new ForeignKeyConstraint(otherEntity, (List) otherFields.stream().map(FieldSearchResult::getField).toList(),
|
otherEntity.builder(mb)
|
||||||
entity, primary.getFields(), ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE));
|
.hasOne(otherFields.stream().map(e -> e.getField().getName()).toArray(String[]::new))
|
||||||
|
.withMany(entity.getTypeName(), primary.getFields().stream().map(DbField::getName).toArray(String[]::new));
|
||||||
|
// otherEntity.addForeignKey(new ForeignKeyConstraint(otherEntity, (List) otherFields.stream().map(FieldSearchResult::getField).toList(),
|
||||||
|
// entity, primary.getFields(), ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE));
|
||||||
}
|
}
|
||||||
} else if (SerializableObject.class.isAssignableFrom(f.getType())) {
|
}
|
||||||
|
|
||||||
|
private static void do1to1(ModelBuilder mb, DbEntityBuilder<?> entityBuilder, DbEntity<?> entity, Field f) {
|
||||||
|
Log.debug("Initializing foreign key for " + entityBuilder.className() + "::" + f.getName());
|
||||||
var otherEntity = mb.getEntity((Class<? extends SerializableObject>) f.getType());
|
var otherEntity = mb.getEntity((Class<? extends SerializableObject>) f.getType());
|
||||||
if (otherEntity == null) {
|
if (otherEntity == null) {
|
||||||
EntityInitializer.initEntity(mb, (Class<? extends SerializableObject>) f.getType(), f.getName());
|
//all types must be initialized by EntityInitializer
|
||||||
otherEntity = mb.getEntity((Class<? extends SerializableObject>) f.getType());
|
throw new IllegalStateException(ForeignKeyInitializer.class.getSimpleName() + ": Entity of type " + f.getType().getName() + " does not exist");
|
||||||
PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity);
|
// EntityInitializer.initEntity(mb, (Class<? extends SerializableObject>) f.getType(), f.getName());
|
||||||
|
// otherEntity = mb.getEntity((Class<? extends SerializableObject>) f.getType());
|
||||||
|
// PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity.builder(mb));
|
||||||
}
|
}
|
||||||
var primary = otherEntity.getPrimaryKey();
|
var primary = otherEntity.getPrimaryKey();
|
||||||
if (primary == null) {
|
if (primary == null) {
|
||||||
throw new ModelException("Entity " + otherEntity.getType().getSimpleName() + " is missing a primary key and therefore cannot be referenced by " + entity.getType().getSimpleName());
|
throw new ModelException("Entity " + otherEntity.builder(mb).className() + " is missing a primary key and therefore cannot be referenced by " + entityBuilder.className());
|
||||||
}
|
}
|
||||||
var otherEntityF = otherEntity;
|
var otherEntityF = otherEntity;
|
||||||
var otherFields = primary.getFields().stream()
|
var otherFields = primary.getFields().stream()
|
||||||
.map(otherPrimaryField -> {
|
.map(otherPrimaryField -> {
|
||||||
//find list<object> in other entity (N to 1 relation)
|
// //find list<object> in other entity (N to 1 relation)
|
||||||
var entityListField = entity.getFields().stream()
|
// var entityListField = entity.getFields().stream()
|
||||||
.filter(oef -> Collection.class.isAssignableFrom(oef.getType())
|
// .filter(oef -> Collection.class.isAssignableFrom(oef.getType())
|
||||||
&& oef.getField().getAnnotationsByType(Clazz.class).length > 0
|
// && oef.getField().getAnnotationsByType(Clazz.class).length > 0
|
||||||
&& oef.getField().getAnnotationsByType(Clazz.class)[0].value() == otherEntityF.getType()).toList();
|
// && oef.getField().getAnnotationsByType(Clazz.class)[0].value().getName().equals(otherEntityF.getTypeName())).toList();
|
||||||
// if (entityListField.size() == 1) {
|
//// if (entityListField.size() == 1) {
|
||||||
// return new FieldSearchResult(entityListField.get(0), true);
|
//// return new FieldSearchResult(entityListField.get(0), true);
|
||||||
// }
|
//// }
|
||||||
|
|
||||||
//find object in other entity (1 to 1 relation)
|
//find object in other entity (1 to 1 relation)
|
||||||
var entityObjectFields = entity.getFields().stream().filter(oef -> oef.getType() == otherEntityF.getType()).toList();
|
// var entityObjectFields = entity.getFields().stream().filter(oef -> oef.getTypeName().equals(otherEntityF.getTypeName())).toList();
|
||||||
// if (entityObjectField.isPresent()) {
|
// if (entityObjectField.isPresent()) {
|
||||||
// return new FieldSearchResult(entityObjectField.get(), false);
|
// return new FieldSearchResult(entityObjectField.get(), false);
|
||||||
// }
|
// }
|
||||||
@@ -124,23 +156,26 @@ class ForeignKeyInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var field = new DbField<>(entity, otherPrimaryField.getType(), null, idFieldName);
|
var field = new DbField<>(entity, otherPrimaryField.getType(), null, idFieldName);
|
||||||
|
field.setExposingForeignKeyOf(entity.getField(f.getName()));
|
||||||
field = entity.addIfAbsent(field);
|
field = entity.addIfAbsent(field);
|
||||||
if (entityListField.size() == 1) {
|
// if (entityListField.size() == 1) {
|
||||||
field.setForeignKeyModelLink(entityListField.get(0));
|
//// field.setForeignKeyObjectField(entityListField.get(0));
|
||||||
entityListField.get(0).setForeignKeyModelLink(field);
|
//// entityListField.get(0).setForeignKeyObjectField(field);
|
||||||
} else if (entityObjectFields.size() == 1) {
|
// } else
|
||||||
field.setForeignKeyModelLink(entityObjectFields.get(0));
|
// if (entityObjectFields.size() == 1) {
|
||||||
entityObjectFields.get(0).setForeignKeyModelLink(field);
|
// field.setExposingForeignKeyOf(entityObjectFields.get(0));
|
||||||
}
|
// entityObjectFields.get(0).setForeignKeyObjectField(field);
|
||||||
|
// }
|
||||||
return new FieldSearchResult(field, true);
|
return new FieldSearchResult(field, true);
|
||||||
// return new DbField<>(entity, e.getType(), null, f.getName() + e.getName().substring(0, 1).toUpperCase(Locale.ROOT) + e.getName().substring(1))
|
// return new DbField<>(entity, e.getType(), null, f.getName() + e.getName().substring(0, 1).toUpperCase(Locale.ROOT) + e.getName().substring(1))
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) {
|
if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) {
|
||||||
entity.addForeignKey(new ForeignKeyConstraint(entity, (List) otherFields.stream().map(FieldSearchResult::getField).toList(),
|
entityBuilder
|
||||||
otherEntity, primary.getFields(), ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE));
|
.hasOne(otherFields.stream().map(e -> e.getField().getName()).toArray(String[]::new))
|
||||||
}
|
.withOne(otherEntity.getTypeName(), primary.getFields().stream().map(DbField::getName).toArray(String[]::new));
|
||||||
}
|
// entity.addForeignKey(new ForeignKeyConstraint(entity, (List) otherFields.stream().map(FieldSearchResult::getField).toList(),
|
||||||
|
// otherEntity, primary.getFields(), ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
180
src/main/java/jef/model/KeyBuilder.java
Normal file
180
src/main/java/jef/model/KeyBuilder.java
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
package jef.model;
|
||||||
|
|
||||||
|
import jef.asm.AsmParser;
|
||||||
|
import jef.model.constraints.ForeignKeyConstraint;
|
||||||
|
import jef.model.constraints.IndexConstraint;
|
||||||
|
import jef.model.constraints.KeyConstraint;
|
||||||
|
import jef.model.constraints.PrimaryKeyConstraint;
|
||||||
|
import jef.model.constraints.UniqueKeyConstraint;
|
||||||
|
import jef.serializable.SerializableFunction;
|
||||||
|
import jef.serializable.SerializableObject;
|
||||||
|
import jef.util.Check;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class KeyBuilder<T extends SerializableObject> {
|
||||||
|
private final ModelBuilder modelBuilder;
|
||||||
|
private final DbEntity<T> entity;
|
||||||
|
private final List<DbField<?>> fields;
|
||||||
|
|
||||||
|
public <R extends SerializableObject> ForeignKeyBuilder<T, R> withOne(SerializableFunction<T, R> getter) {
|
||||||
|
Check.notNull(getter, "getter");
|
||||||
|
var set = new AsmParser(getter).parse().getAccessedFields();
|
||||||
|
// if (set.isEmpty()) throw new IllegalArgumentException("no fields found");
|
||||||
|
// else if (set.size() > 1) throw new IllegalArgumentException("more than 1 field found");
|
||||||
|
// var refFields = entity.getFields().stream().filter(e -> set.contains(e.getField())).toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> modelBuilder.getEntity(e.getTypeName())).toList();
|
||||||
|
// var existingFk = entity.getForeignKeys().stream().filter(fk -> fk.getEntity() == this.entity
|
||||||
|
// && fk.getFields().equals(this.fields)
|
||||||
|
// && fk.getReferencedEntity() == refEntities.get(0)
|
||||||
|
// && fk.getReferencedFields().equals(refFields))
|
||||||
|
// .findFirst().orElse(null);
|
||||||
|
// if (existingFk == null) {
|
||||||
|
// existingFk = new ForeignKeyConstraint(this.entity, this.fields, refEntities.get(0), refFields, ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE);
|
||||||
|
// this.entity.addForeignKey(existingFk);
|
||||||
|
// }
|
||||||
|
// return new ForeignKeyBuilder<>(existingFk);
|
||||||
|
// var rClassName = getter.getClass().
|
||||||
|
return withOne("", set.stream().map(Field::getName).toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R extends SerializableObject> ForeignKeyBuilder<T, R> withOne(String referencedClass, String... getterOrFieldNames) {
|
||||||
|
Check.notNull(getterOrFieldNames, "getterOrFieldNames");
|
||||||
|
// var set = new HashSet<>(Arrays.asList(getterOrFieldNames));
|
||||||
|
// if (set.isEmpty()) throw new IllegalArgumentException("no fields found");
|
||||||
|
// else if (set.size() > 1) throw new IllegalArgumentException("more than 1 field found");
|
||||||
|
// var refFields = entity.getFields().stream().filter(e -> set.contains(e.getName())).toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> modelBuilder.getEntity(e.getTypeName())).toList();
|
||||||
|
var refEntities = List.of(modelBuilder.getEntity(referencedClass));
|
||||||
|
var refFields = IntStream.range(0, getterOrFieldNames.length)
|
||||||
|
.mapToObj(i -> {
|
||||||
|
// var field = fields.get(i);
|
||||||
|
// if (field.getExposingForeignKeyOf() != null) {
|
||||||
|
// field = field.getExposingForeignKeyOf();
|
||||||
|
// }
|
||||||
|
return refEntities.get(0).getField(getterOrFieldNames[i]);
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> e.getEntity()).toList();
|
||||||
|
var existingFk = entity.getForeignKeys().stream().filter(fk -> fk.getEntity() == this.entity
|
||||||
|
&& fk.getFields().equals(this.fields)
|
||||||
|
&& fk.getReferencedEntity() == refEntities.get(0)
|
||||||
|
&& fk.getReferencedFields().equals(refFields))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
if (existingFk == null) {
|
||||||
|
existingFk = new ForeignKeyConstraint(this.entity, this.fields, refEntities.get(0), (List) refFields, ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE);
|
||||||
|
this.entity.addForeignKey(existingFk);
|
||||||
|
}
|
||||||
|
return new ForeignKeyBuilder<>(existingFk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R extends SerializableObject> ForeignKeyBuilder<T, R> withMany(SerializableFunction<T, R> getter) {
|
||||||
|
Check.notNull(getter, "getter");
|
||||||
|
var set = new AsmParser(getter).parse().getAccessedFields();
|
||||||
|
// if (set.isEmpty()) throw new IllegalArgumentException("no fields found");
|
||||||
|
// else if (set.size() > 1) throw new IllegalArgumentException("more than 1 field found");
|
||||||
|
// var refFields = entity.getFields().stream().filter(e -> set.contains(e.getField())).toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> modelBuilder.getEntity(e.getTypeName())).toList();
|
||||||
|
// var existingFk = entity.getForeignKeys().stream().filter(fk -> fk.getEntity() == this.entity
|
||||||
|
// && fk.getFields().equals(this.fields)
|
||||||
|
// && fk.getReferencedEntity() == refEntities.get(0)
|
||||||
|
// && fk.getReferencedFields().equals(refFields))
|
||||||
|
// .findFirst().orElse(null);
|
||||||
|
// if (existingFk == null) {
|
||||||
|
// existingFk = new ForeignKeyConstraint(this.entity, this.fields, refEntities.get(0), refFields, ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE);
|
||||||
|
// this.entity.addForeignKey(existingFk);
|
||||||
|
// }
|
||||||
|
// return new ForeignKeyBuilder<>(existingFk);
|
||||||
|
return withMany("", set.stream().map(Field::getName).toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <R extends SerializableObject> ForeignKeyBuilder<T, R> withMany(String referencedClass, String... getterOrFieldNames) {
|
||||||
|
Check.notNull(getterOrFieldNames, "getterOrFieldNames");
|
||||||
|
// var set = new HashSet<>(Arrays.asList(getterOrFieldNames));
|
||||||
|
// var refFields = entity.getFields().stream().filter(e -> set.contains(e.getName())).toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> modelBuilder.getEntity(e.getTypeName())).toList();
|
||||||
|
var refEntities = List.of(modelBuilder.getEntity(referencedClass));
|
||||||
|
var refFields = IntStream.range(0, getterOrFieldNames.length)
|
||||||
|
.mapToObj(i -> {
|
||||||
|
// var field = fields.get(i);
|
||||||
|
// if (field.getExposingForeignKeyOf() != null) {
|
||||||
|
// field = field.getExposingForeignKeyOf();
|
||||||
|
// }
|
||||||
|
// var type = (Class<? extends SerializableObject>) field.getType();
|
||||||
|
// return modelBuilder.getEntity(type).getField(getterOrFieldNames[i]);
|
||||||
|
return refEntities.get(0).getField(getterOrFieldNames[i]);
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
// var refEntities = refFields.stream().map(e -> e.getEntity()).toList();
|
||||||
|
var existingFk = entity.getForeignKeys().stream().filter(fk -> fk.getEntity() == this.entity
|
||||||
|
&& fk.getFields().equals(this.fields)
|
||||||
|
&& fk.getReferencedEntity() == refEntities.get(0)
|
||||||
|
&& fk.getReferencedFields().equals(refFields))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
if (existingFk == null) {
|
||||||
|
existingFk = new ForeignKeyConstraint(this.entity, this.fields, refEntities.get(0), (List) refFields, ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE);
|
||||||
|
this.entity.addForeignKey(existingFk);
|
||||||
|
}
|
||||||
|
return new ForeignKeyBuilder<>(existingFk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyBuilder<T> notNull(boolean notNull) {
|
||||||
|
//TODO
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isUnique() {
|
||||||
|
isUnique(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isUnique(boolean unique) {
|
||||||
|
var key = new UniqueKeyConstraint(entity, fields);
|
||||||
|
if (unique) {
|
||||||
|
entity.addUniqueKey(key);
|
||||||
|
} else {
|
||||||
|
entity.dropUniqueKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isPrimaryKey() {
|
||||||
|
isPrimaryKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isPrimaryKey(boolean primary) {//TODO foreign key integrity
|
||||||
|
if (primary) {
|
||||||
|
entity.setPrimaryKey(new PrimaryKeyConstraint(entity, fields));
|
||||||
|
} else {
|
||||||
|
entity.setPrimaryKey(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isKey() {
|
||||||
|
isKey(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isKey(boolean key) {
|
||||||
|
var k = new KeyConstraint(entity, fields);
|
||||||
|
if (key) {
|
||||||
|
entity.addKey(k);
|
||||||
|
} else {
|
||||||
|
entity.dropKey(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isIndex() {
|
||||||
|
isIndex(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isIndex(boolean index) {
|
||||||
|
var i = new IndexConstraint(entity, fields);
|
||||||
|
if (index) {
|
||||||
|
entity.addIndex(i);
|
||||||
|
} else {
|
||||||
|
entity.dropIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ModelBuilder {
|
public class ModelBuilder {
|
||||||
private static final List<AnnotationProcessor> annotationProcessors = new ArrayList<>();
|
private static final List<AnnotationProcessor> annotationProcessors = new ArrayList<>();
|
||||||
@@ -48,6 +49,7 @@ public class ModelBuilder {
|
|||||||
var mb = new ModelBuilder(new ArrayList<>());
|
var mb = new ModelBuilder(new ArrayList<>());
|
||||||
EntityInitializer.initEntities(mb, context);
|
EntityInitializer.initEntities(mb, context);
|
||||||
PrimaryKeyInitializer.initPrimaryKeys(mb);
|
PrimaryKeyInitializer.initPrimaryKeys(mb);
|
||||||
|
ForeignKeyExposeInitializer.initForeignKeyExposures(mb);
|
||||||
ForeignKeyInitializer.initForeignKeys(mb);
|
ForeignKeyInitializer.initForeignKeys(mb);
|
||||||
|
|
||||||
for (AnnotationProcessor processor : annotationProcessors) {
|
for (AnnotationProcessor processor : annotationProcessors) {
|
||||||
@@ -86,6 +88,10 @@ public class ModelBuilder {
|
|||||||
return Collections.unmodifiableList(entities);
|
return Collections.unmodifiableList(entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<DbEntityBuilder<? extends SerializableObject>> entities() {
|
||||||
|
return entities.stream().map(e -> new DbEntityBuilder<>(this, e)).collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the database model for the requested class or null if not present.
|
* Returns the database model for the requested class or null if not present.
|
||||||
*
|
*
|
||||||
@@ -117,9 +123,9 @@ public class ModelBuilder {
|
|||||||
* @param <T> the type of model class
|
* @param <T> the type of model class
|
||||||
* @return the DbEntity for the requested class or the newly created empty DbEntity if none existed.
|
* @return the DbEntity for the requested class or the newly created empty DbEntity if none existed.
|
||||||
*/
|
*/
|
||||||
public <T extends SerializableObject> DbEntity<T> getOrCreateEntity(Class<T> clazz) {
|
public <T extends SerializableObject> DbEntityBuilder<T> entity(Class<T> clazz) {
|
||||||
Check.notNull(clazz, "clazz");
|
Check.notNull(clazz, "clazz");
|
||||||
return getOrCreateEntity(clazz.getName());
|
return entity(clazz.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,14 +135,14 @@ public class ModelBuilder {
|
|||||||
* @param <T> the type of model class
|
* @param <T> the type of model class
|
||||||
* @return the DbEntity for the requested class or the newly created empty DbEntity if none existed.
|
* @return the DbEntity for the requested class or the newly created empty DbEntity if none existed.
|
||||||
*/
|
*/
|
||||||
public <T extends SerializableObject> DbEntity<T> getOrCreateEntity(String typeName) {
|
public <T extends SerializableObject> DbEntityBuilder<T> entity(String typeName) {
|
||||||
Check.notNull(typeName, "typeName");
|
Check.notNull(typeName, "typeName");
|
||||||
var entity = (DbEntity<T>) getEntity(typeName);
|
var entity = (DbEntity<T>) getEntity(typeName);
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
entity = new DbEntity<>(typeName);
|
entity = new DbEntity<>(typeName);
|
||||||
entities.add(entity);
|
entities.add(entity);
|
||||||
}
|
}
|
||||||
return entity;
|
return new DbEntityBuilder<>(this, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,7 +174,7 @@ public class ModelBuilder {
|
|||||||
var old = this.entities.get(i);
|
var old = this.entities.get(i);
|
||||||
var entity = (DbEntity<?>) new DbEntity(old.getTypeName());
|
var entity = (DbEntity<?>) new DbEntity(old.getTypeName());
|
||||||
entity.setName(old.getName());
|
entity.setName(old.getName());
|
||||||
entity.setType((Class) old.getType());
|
entity.setTypeName(old.getTypeName());
|
||||||
|
|
||||||
//add fields
|
//add fields
|
||||||
old.getFields().stream().map(e -> {
|
old.getFields().stream().map(e -> {
|
||||||
@@ -183,9 +189,9 @@ public class ModelBuilder {
|
|||||||
.forEach(entity::addIfAbsent);
|
.forEach(entity::addIfAbsent);
|
||||||
|
|
||||||
//apply exposed foreign keys
|
//apply exposed foreign keys
|
||||||
old.getFields().stream().filter(e -> e.getForeignKeyModelLink() != null).forEach(e -> {
|
old.getFields().stream().filter(e -> e.getExposingForeignKeyOf() != null).forEach(e -> {
|
||||||
var nf = entity.getFields().stream().filter(f -> f.getName().equals(e.getName())).findFirst().get(); //get(): should always be there
|
var nf = entity.getFields().stream().filter(f -> f.getName().equals(e.getName())).findFirst().get(); //get(): should always be there
|
||||||
nf.setForeignKeyModelLink(old.getFields().stream().filter(f -> f.getName().equals(e.getForeignKeyModelLink().getName())).findFirst().get()); //get(): should always be there
|
nf.setExposingForeignKeyOf(old.getFields().stream().filter(f -> f.getName().equals(e.getExposingForeignKeyOf().getName())).findFirst().get()); //get(): should always be there
|
||||||
});
|
});
|
||||||
|
|
||||||
entity.setName(old.getName());
|
entity.setName(old.getName());
|
||||||
|
|||||||
@@ -2,22 +2,21 @@ package jef.model;
|
|||||||
|
|
||||||
import jef.model.annotations.Id;
|
import jef.model.annotations.Id;
|
||||||
import jef.model.annotations.Transient;
|
import jef.model.annotations.Transient;
|
||||||
import jef.model.constraints.PrimaryKeyConstraint;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class PrimaryKeyInitializer {
|
class PrimaryKeyInitializer {
|
||||||
static void initPrimaryKeys(ModelBuilder mb) {
|
static void initPrimaryKeys(ModelBuilder mb) {
|
||||||
for (int i = 0; i < mb.getEntities().size(); i++) {
|
var entities = mb.entities();
|
||||||
var entity = mb.getEntities().get(i);
|
for (int i = 0; i < entities.size(); i++) {
|
||||||
|
var entity = entities.get(i);
|
||||||
initPrimaryKeys(mb, entity);
|
initPrimaryKeys(mb, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initPrimaryKeys(ModelBuilder mb, DbEntity<?> entity) {
|
static void initPrimaryKeys(ModelBuilder mb, DbEntityBuilder<?> entity) {
|
||||||
var fields = ReflectionUtil.getFieldsRecursive(entity.getType());
|
var fields = ReflectionUtil.getFieldsRecursive(entity.type().get());
|
||||||
var idFields = new ArrayList<Field>();
|
var idFields = new ArrayList<Field>();
|
||||||
|
|
||||||
//search for fields with @Id annotation
|
//search for fields with @Id annotation
|
||||||
@@ -56,8 +55,8 @@ class PrimaryKeyInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!idFields.isEmpty()) {
|
if (!idFields.isEmpty()) {
|
||||||
var dbfields = idFields.stream().map(entity::getField).toList();
|
var dbfields = idFields.stream().map(e -> entity.field(e).getField().getName()).toList();
|
||||||
entity.setPrimaryKey(new PrimaryKeyConstraint(entity, (List) dbfields));
|
entity.hasOne(dbfields.toArray(String[]::new)).isPrimaryKey(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package jef.model.annotations.processors;
|
package jef.model.annotations.processors;
|
||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
|
||||||
import jef.model.ModelBuilder;
|
import jef.model.ModelBuilder;
|
||||||
import jef.model.ModelException;
|
import jef.model.ModelException;
|
||||||
import jef.model.annotations.ForeignKey;
|
import jef.model.annotations.ForeignKey;
|
||||||
@@ -22,61 +21,62 @@ public class ForeignKeyProcessor implements AnnotationProcessor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(ModelBuilder mb) {
|
public void apply(ModelBuilder mb) {
|
||||||
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
for (var entity : mb.entities()) {
|
||||||
//annotation on fields
|
//annotation on fields
|
||||||
for (DbField<?> field : entity.getFields()) {
|
for (var field : entity.fields()) {
|
||||||
if (field.isModelField() && field.getField().getAnnotationsByType(ForeignKey.class).length > 0) {
|
if (field.getField().isModelField() && field.getField().getField().getAnnotationsByType(ForeignKey.class).length > 0) {
|
||||||
var anno = field.getField().getAnnotationsByType(ForeignKey.class)[0];
|
var anno = field.getField().getField().getAnnotationsByType(ForeignKey.class)[0];
|
||||||
// var dbfield = entity.getField(field.getField());
|
// var dbfield = entity.getField(field.getField());
|
||||||
// if (dbfield == null) {
|
// if (dbfield == null) {
|
||||||
// throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.getType().getSimpleName());
|
// throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.getType().getSimpleName());
|
||||||
// }
|
// }
|
||||||
var exposeForeignKey = anno.entity() == SerializableObject.class;
|
var exposeForeignKey = anno.entity() == SerializableObject.class;
|
||||||
var refEntity = exposeForeignKey ? entity : mb.getEntity(anno.entity());
|
var refEntity = exposeForeignKey ? entity.getEntity() : mb.getEntity(anno.entity());
|
||||||
if (!exposeForeignKey && refEntity == null) {
|
if (!exposeForeignKey && refEntity == null) {
|
||||||
throw new ModelException("Could not find referenced entity " + anno.entity().getSimpleName() + " (via @" + ForeignKey.class.getSimpleName()
|
throw new ModelException("Could not find referenced entity " + anno.entity().getSimpleName() + " (via @" + ForeignKey.class.getSimpleName()
|
||||||
+ " in " + entity.getType().getSimpleName() + "::" + field.getField().getName() + ")");
|
+ " in " + entity.className() + "::" + field.getField().getName() + ")");
|
||||||
}
|
}
|
||||||
|
var refEntityBuilder = mb.entity(refEntity.getTypeName());
|
||||||
Field refClassField;
|
Field refClassField;
|
||||||
try {
|
try {
|
||||||
refClassField = getField(refEntity, anno.getterOrField());
|
refClassField = getField(refEntityBuilder, anno.getterOrField());
|
||||||
} catch (ModelException e) {
|
} catch (ModelException e) {
|
||||||
throw new ModelException(e.getMessage() + " (via @" + ForeignKey.class.getSimpleName()
|
throw new ModelException(e.getMessage() + " (via @" + ForeignKey.class.getSimpleName()
|
||||||
+ " in " + entity.getType().getSimpleName() + "::" + field.getField().getName() + ")");
|
+ " in " + entity.className() + "::" + field.getField().getName() + ")");
|
||||||
}
|
}
|
||||||
var refField = refEntity.getField(refClassField);
|
var refField = refEntity.getField(refClassField);
|
||||||
|
|
||||||
if (exposeForeignKey) {
|
if (exposeForeignKey) {
|
||||||
field.setForeignKeyModelLink(refField);
|
// field.getField().setExposingForeignKeyOf(refField);
|
||||||
refField.setForeignKeyModelLink(field);
|
refField.setExposingForeignKeyOf(field.getField());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for primary key
|
//check for primary key
|
||||||
if (refEntity.getPrimaryKey() == null) {
|
if (refEntity.getPrimaryKey() == null) {
|
||||||
throw new ModelException("Entity " + refEntity.getType().getSimpleName() + " does not have a primary key and can "
|
throw new ModelException("Entity " + refEntityBuilder.className() + " does not have a primary key and can "
|
||||||
+ "therefore not be referenced (via @" + ForeignKey.class.getSimpleName()
|
+ "therefore not be referenced (via @" + ForeignKey.class.getSimpleName()
|
||||||
+ " in " + entity.getType().getSimpleName() + "::" + field.getField().getName() + ")");
|
+ " in " + entity.className() + "::" + field.getField().getName() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if references field is the primary key of the refeneced entity
|
//check if references field is the primary key of the refeneced entity
|
||||||
if (!refEntity.getPrimaryKey().getFields().equals(List.of(refField))) {
|
if (!refEntity.getPrimaryKey().getFields().equals(List.of(refField))) {
|
||||||
throw new ModelException(refEntity.getType().getSimpleName() + "::" + refField.getField().getName()
|
throw new ModelException(refEntityBuilder.className() + "::" + refField.getField().getName()
|
||||||
+ " is not equal to the primary key of entity " + refEntity.getType().getSimpleName()
|
+ " is not equal to the primary key of entity " + refEntityBuilder.className()
|
||||||
+ " (" + refEntity.getPrimaryKey().getFields().stream().map(e -> e.getField().getName()).collect(Collectors.joining(", ")) + ")"
|
+ " (" + refEntity.getPrimaryKey().getFields().stream().map(e -> e.getField().getName()).collect(Collectors.joining(", ")) + ")"
|
||||||
+ " and can therefore not be referenced (via @" + ForeignKey.class.getSimpleName()
|
+ " and can therefore not be referenced (via @" + ForeignKey.class.getSimpleName()
|
||||||
+ " in " + entity.getType().getSimpleName() + "::" + field.getField().getName() + ")");
|
+ " in " + entity.className() + "::" + field.getField().getName() + ")");
|
||||||
}
|
}
|
||||||
entity.addForeignKey(new ForeignKeyConstraint(entity, List.of(field), refEntity, List.of(refField), anno.onUpdate(), anno.onDelete()));
|
entity.getEntity().addForeignKey(new ForeignKeyConstraint(entity.getEntity(), List.of(field.getField()), refEntity, List.of(refField), anno.onUpdate(), anno.onDelete()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Field getField(DbEntity<? extends SerializableObject> entity, String fieldOrGetter) {
|
private Field getField(DbEntityBuilder<? extends SerializableObject> entity, String fieldOrGetter) {
|
||||||
Method getter = null;
|
Method getter = null;
|
||||||
try {
|
try {
|
||||||
getter = entity.getType().getDeclaredMethod(fieldOrGetter);
|
getter = entity.type().get().getDeclaredMethod(fieldOrGetter);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,15 +84,15 @@ public class ForeignKeyProcessor implements AnnotationProcessor {
|
|||||||
try {
|
try {
|
||||||
if (getter != null && getter.getName().length() > 3 && getter.getName().startsWith("get")) {
|
if (getter != null && getter.getName().length() > 3 && getter.getName().startsWith("get")) {
|
||||||
var name = getter.getName().substring(3, 4).toLowerCase(Locale.ROOT) + getter.getName().substring(4); //HACK
|
var name = getter.getName().substring(3, 4).toLowerCase(Locale.ROOT) + getter.getName().substring(4); //HACK
|
||||||
field = entity.getType().getDeclaredField(name);
|
field = entity.type().get().getDeclaredField(name);
|
||||||
} else {
|
} else {
|
||||||
field = entity.getType().getDeclaredField(fieldOrGetter);
|
field = entity.type().get().getDeclaredField(fieldOrGetter);
|
||||||
}
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new ModelException("Cannot find getter/field " + entity.getType().getSimpleName() + "::" + fieldOrGetter);
|
throw new ModelException("Cannot find getter/field " + entity.className() + "::" + fieldOrGetter);
|
||||||
}
|
}
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package jef.model.annotations.processors;
|
package jef.model.annotations.processors;
|
||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntity;
|
||||||
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
import jef.model.DbField;
|
||||||
|
import jef.model.DbFieldBuilder;
|
||||||
import jef.model.annotations.Index;
|
import jef.model.annotations.Index;
|
||||||
import jef.model.constraints.IndexConstraint;
|
import jef.model.constraints.IndexConstraint;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
@@ -17,8 +19,8 @@ public class IndexProcessor extends KeyProcessorBase<IndexConstraint, Index> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IndexConstraint initConstraint(DbEntity<? extends SerializableObject> entity, List<DbField<?>> fields) {
|
protected IndexConstraint initConstraint(DbEntityBuilder<? extends SerializableObject> entity, List<DbFieldBuilder<?>> fields) {
|
||||||
return new IndexConstraint(entity, fields);
|
return new IndexConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package jef.model.annotations.processors;
|
package jef.model.annotations.processors;
|
||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntity;
|
||||||
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
import jef.model.DbField;
|
||||||
|
import jef.model.DbFieldBuilder;
|
||||||
import jef.model.annotations.Key;
|
import jef.model.annotations.Key;
|
||||||
import jef.model.constraints.KeyConstraint;
|
import jef.model.constraints.KeyConstraint;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
@@ -17,8 +19,8 @@ public class KeyProcessor extends KeyProcessorBase<KeyConstraint, Key> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected KeyConstraint initConstraint(DbEntity<? extends SerializableObject> entity, List<DbField<?>> fields) {
|
protected KeyConstraint initConstraint(DbEntityBuilder<? extends SerializableObject> entity, List<DbFieldBuilder<?>> fields) {
|
||||||
return new KeyConstraint(entity, fields);
|
return new KeyConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package jef.model.annotations.processors;
|
package jef.model.annotations.processors;
|
||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
import jef.model.DbField;
|
||||||
|
import jef.model.DbFieldBuilder;
|
||||||
import jef.model.ModelBuilder;
|
import jef.model.ModelBuilder;
|
||||||
import jef.model.ModelException;
|
import jef.model.ModelException;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
@@ -21,7 +22,7 @@ abstract class KeyProcessorBase<K, T extends Annotation> implements AnnotationPr
|
|||||||
this.annotationClass = annotationClass;
|
this.annotationClass = annotationClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract K initConstraint(DbEntity<? extends SerializableObject> entity, List<DbField<?>> fields);
|
protected abstract K initConstraint(DbEntityBuilder<? extends SerializableObject> entity, List<DbFieldBuilder<?>> fields);
|
||||||
|
|
||||||
protected abstract void addConstraint(K constr);
|
protected abstract void addConstraint(K constr);
|
||||||
|
|
||||||
@@ -29,16 +30,16 @@ abstract class KeyProcessorBase<K, T extends Annotation> implements AnnotationPr
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void apply(ModelBuilder mb) {
|
public void apply(ModelBuilder mb) {
|
||||||
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
for (DbEntityBuilder<? extends SerializableObject> entity : mb.entities()) {
|
||||||
//class annotation
|
//class annotation
|
||||||
var classAnno = entity.getType().getAnnotationsByType(annotationClass);
|
var classAnno = entity.type().get().getAnnotationsByType(annotationClass);
|
||||||
for (T t : classAnno) {
|
for (T t : classAnno) {
|
||||||
var classFields = Arrays.stream(getGettersOrFields(t))
|
var classFields = Arrays.stream(getGettersOrFields(t))
|
||||||
.map(name -> getField(entity, name))
|
.map(name -> getField(entity, name))
|
||||||
.map(field -> {
|
.map(field -> {
|
||||||
var dbfield = (DbField<?>) entity.getField(field);
|
var dbfield = (DbFieldBuilder<?>) entity.field(field);
|
||||||
if (dbfield == null) {
|
if (dbfield == null) {
|
||||||
throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.getType().getSimpleName());
|
throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.className());
|
||||||
}
|
}
|
||||||
return dbfield;
|
return dbfield;
|
||||||
}).toList();
|
}).toList();
|
||||||
@@ -46,11 +47,11 @@ abstract class KeyProcessorBase<K, T extends Annotation> implements AnnotationPr
|
|||||||
}
|
}
|
||||||
|
|
||||||
//annotation on fields
|
//annotation on fields
|
||||||
for (DbField<?> field : entity.getFields()) {
|
for (DbFieldBuilder<?> field : entity.fields()) {
|
||||||
if (field.getField() != null && field.getField().getAnnotationsByType(annotationClass).length > 0) {
|
if (field.getField().getField() != null && field.getField().getField().getAnnotationsByType(annotationClass).length > 0) {
|
||||||
var dbfield = entity.getField(field.getField());
|
var dbfield = entity.field(field.getField().getField());
|
||||||
if (dbfield == null) {
|
if (dbfield == null) {
|
||||||
throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.getType().getSimpleName());
|
throw new ModelException("DbField with field " + field.getField().getName() + " not found in " + entity.className());
|
||||||
}
|
}
|
||||||
addConstraint(initConstraint(entity, List.of(dbfield)));
|
addConstraint(initConstraint(entity, List.of(dbfield)));
|
||||||
}
|
}
|
||||||
@@ -58,26 +59,26 @@ abstract class KeyProcessorBase<K, T extends Annotation> implements AnnotationPr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Field getField(DbEntity<? extends SerializableObject> entity, String fieldOrGetter) {
|
private Field getField(DbEntityBuilder<? extends SerializableObject> entity, String fieldOrGetter) {
|
||||||
Method getter = null;
|
Method getter = null;
|
||||||
try {
|
try {
|
||||||
getter = entity.getType().getDeclaredMethod(fieldOrGetter);
|
getter = entity.type().get().getDeclaredMethod(fieldOrGetter);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Field field = null;
|
Field field = null;
|
||||||
try {
|
try {
|
||||||
if (getter != null && getter.getName().length() > 3 && getter.getName().startsWith("get")) {
|
if (getter != null && getter.getName().length() > 3 && getter.getName().startsWith("get")) {
|
||||||
var name = getter.getName().substring(3, 4).toLowerCase(Locale.ROOT) + getter.getName().substring(4); //HACK
|
var name = getter.getName().substring(3, 4).toLowerCase(Locale.ROOT) + getter.getName().substring(4); //TODO HACK
|
||||||
field = entity.getType().getDeclaredField(name);
|
field = entity.type().get().getDeclaredField(name);
|
||||||
} else {
|
} else {
|
||||||
field = entity.getType().getDeclaredField(fieldOrGetter);
|
field = entity.type().get().getDeclaredField(fieldOrGetter);
|
||||||
}
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
throw new ModelException("Cannot find getter/field '" + fieldOrGetter + "' in " + entity.getType().getSimpleName());
|
throw new ModelException("Cannot find getter/field '" + fieldOrGetter + "' in " + entity.className());
|
||||||
}
|
}
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package jef.model.annotations.processors;
|
package jef.model.annotations.processors;
|
||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
import jef.model.DbFieldBuilder;
|
||||||
import jef.model.annotations.Unique;
|
import jef.model.annotations.Unique;
|
||||||
import jef.model.constraints.UniqueKeyConstraint;
|
import jef.model.constraints.UniqueKeyConstraint;
|
||||||
import jef.serializable.SerializableObject;
|
import jef.serializable.SerializableObject;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class UniqueProcessor extends KeyProcessorBase<UniqueKeyConstraint, Unique> {
|
public class UniqueProcessor extends KeyProcessorBase<UniqueKeyConstraint, Unique> {
|
||||||
public static final UniqueProcessor INSTANCE = new UniqueProcessor();
|
public static final UniqueProcessor INSTANCE = new UniqueProcessor();
|
||||||
@@ -17,8 +18,8 @@ public class UniqueProcessor extends KeyProcessorBase<UniqueKeyConstraint, Uniqu
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected UniqueKeyConstraint initConstraint(DbEntity<? extends SerializableObject> entity, List<DbField<?>> fields) {
|
protected UniqueKeyConstraint initConstraint(DbEntityBuilder<? extends SerializableObject> entity, List<DbFieldBuilder<?>> fields) {
|
||||||
return new UniqueKeyConstraint(entity, fields);
|
return new UniqueKeyConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,25 +2,28 @@ package jef.model.constraints;
|
|||||||
|
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntity;
|
||||||
import jef.model.DbField;
|
import jef.model.DbField;
|
||||||
|
import jef.util.Check;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
@Setter
|
||||||
public class ForeignKeyConstraint extends ConstraintBase {
|
public class ForeignKeyConstraint extends ConstraintBase {
|
||||||
private final DbEntity<?> referencedEntity;
|
private final DbEntity<?> referencedEntity;
|
||||||
private final List<DbField<?>> referencedFields;
|
private final List<DbField<?>> referencedFields;
|
||||||
private final Action onUpdate;
|
private Action onUpdate;
|
||||||
private final Action onDelete;
|
private Action onDelete;
|
||||||
|
|
||||||
public ForeignKeyConstraint(DbEntity<?> entity, List<DbField<?>> fields, DbEntity<?> referencedEntity, List<DbField<?>> referencedFields, Action onUpdate, Action onDelete) {
|
public ForeignKeyConstraint(DbEntity<?> entity, List<DbField<?>> fields, DbEntity<?> referencedEntity, List<DbField<?>> referencedFields, Action onUpdate, Action onDelete) {
|
||||||
super(entity, fields);
|
super(entity, fields);
|
||||||
this.referencedEntity = referencedEntity;
|
this.referencedEntity = Check.notNull(referencedEntity, "referencedEntity");
|
||||||
this.referencedFields = referencedFields;
|
this.referencedFields = Check.notNull(referencedFields, "referencedFields");
|
||||||
this.onUpdate = onUpdate;
|
this.onUpdate = Check.notNull(onUpdate, "onUpdate");
|
||||||
this.onDelete = onDelete;
|
this.onDelete = Check.notNull(onDelete, "onDelete");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package jef.model.migration.creator;
|
|||||||
|
|
||||||
import jef.model.DbContext;
|
import jef.model.DbContext;
|
||||||
import jef.model.DbEntity;
|
import jef.model.DbEntity;
|
||||||
|
import jef.model.DbEntityBuilder;
|
||||||
import jef.model.DbField;
|
import jef.model.DbField;
|
||||||
import jef.model.ModelBuilder;
|
import jef.model.ModelBuilder;
|
||||||
import jef.model.constraints.ForeignKeyConstraint;
|
import jef.model.constraints.ForeignKeyConstraint;
|
||||||
@@ -40,29 +41,29 @@ public class ModelBuilderGenerator {
|
|||||||
var indent = " ";
|
var indent = " ";
|
||||||
imports.add(DbContext.class);
|
imports.add(DbContext.class);
|
||||||
imports.add(ModelBuilder.class);
|
imports.add(ModelBuilder.class);
|
||||||
imports.add(DbEntity.class);
|
imports.add(DbEntityBuilder.class);
|
||||||
var java = ""
|
var java = ""
|
||||||
+ "public class " + name + "Snapshot extends DbContext {\n"
|
+ "public class " + name + "Snapshot extends DbContext {\n"
|
||||||
+ " @Override\n"
|
+ " @Override\n"
|
||||||
+ " public void onModelCreate(ModelBuilder mb) {\n"
|
+ " public void onModelCreate(ModelBuilder mb) {\n"
|
||||||
+ indent + "DbEntity entity;\n"
|
+ indent + "DbEntityBuilder entity;\n"
|
||||||
+ indent + "DbEntity referencedEntity;\n";
|
+ indent + "DbEntityBuilder referencedEntity;\n";
|
||||||
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
for (DbEntity<? extends SerializableObject> entity : mb.getEntities()) {
|
||||||
java += indent + "entity = mb.getOrCreateEntity(\"" + entity.getTypeName() + "\");\n"
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
+ indent + "entity.setName(\"" + entity.getName() + "\");\n";
|
+ indent + " .name(\"" + entity.getName() + "\");\n";
|
||||||
for (DbField<?> field : entity.getFields()) {
|
for (DbField<?> field : entity.getFields()) {
|
||||||
java += indent + "entity.getOrCreateField(\"" + field.getName() + "\", \"" + field.getTypeName() + "\")"
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
+ (field.isNotNull() ? "\n" + indent + " .setNotNull(true)" : "")
|
+ indent + " .field(\"" + field.getName() + "\", \"" + field.getTypeName() + "\")"
|
||||||
+ "\n" + indent + " .setDatabaseField(" + field.isDatabaseField() + ")"
|
+ (field.isNotNull() ? "\n" + indent + " .isNotNull()" : "")
|
||||||
+ "\n" + indent + " .setModelField(" + field.isModelField() + ")"
|
+ "\n" + indent + " .isDatabaseField(" + field.isDatabaseField() + ")"
|
||||||
+ ";\n";
|
+ "\n" + indent + " .isModelField(" + field.isModelField() + ");";
|
||||||
}
|
}
|
||||||
if (entity.getPrimaryKey() != null) {
|
if (entity.getPrimaryKey() != null) {
|
||||||
imports.add(List.class);
|
imports.add(List.class);
|
||||||
imports.add(PrimaryKeyConstraint.class);
|
imports.add(PrimaryKeyConstraint.class);
|
||||||
java += indent + "entity.setPrimaryKey(new PrimaryKeyConstraint(entity, List.of(\n"
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
+ indent + " " + entity.getPrimaryKey().getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n ")) + "\n"
|
+ indent + " .hasOne(" + entity.getPrimaryKey().getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n"
|
||||||
+ indent + " )));\n";
|
+ indent + " .isPrimaryKey();\n";
|
||||||
}
|
}
|
||||||
java += "\n";
|
java += "\n";
|
||||||
}
|
}
|
||||||
@@ -71,40 +72,29 @@ public class ModelBuilderGenerator {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
java += indent + "entity = mb.getOrCreateEntity(\"" + entity.getTypeName() + "\");\n";
|
|
||||||
for (ForeignKeyConstraint foreignKey : entity.getForeignKeys()) {
|
for (ForeignKeyConstraint foreignKey : entity.getForeignKeys()) {
|
||||||
imports.add(List.class);
|
|
||||||
imports.add(ForeignKeyConstraint.class);
|
imports.add(ForeignKeyConstraint.class);
|
||||||
imports.add(ForeignKeyConstraint.Action.class);
|
//TODO hasOne/hasMany/withOne/WithMany
|
||||||
java += indent + "referencedEntity = mb.getEntity(\"" + foreignKey.getReferencedEntity().getTypeName() + "\");\n"
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
+ indent + "entity.addForeignKey(new ForeignKeyConstraint(entity, List.of(\n"
|
+ indent + " .hasOne(" + foreignKey.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", " + indent)) + ")\n"
|
||||||
+ indent + " " + foreignKey.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n"
|
+ indent + " .withOne(\"" + foreignKey.getReferencedEntity().getTypeName() + "\", " + foreignKey.getReferencedFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n"
|
||||||
+ indent + " ),\n"
|
+ indent + " .onUpdate(ForeignKeyConstraint.Action." + foreignKey.getOnUpdate().name() + ")\n"
|
||||||
+ indent + " referencedEntity, List.of(\n"
|
+ indent + " .onDelete(ForeignKeyConstraint.Action." + foreignKey.getOnDelete().name() + ");\n";
|
||||||
+ indent + " " + foreignKey.getReferencedFields().stream().map(f -> "referencedEntity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n"
|
|
||||||
+ indent + " ),\n"
|
|
||||||
+ indent + " ForeignKeyConstraint.Action." + foreignKey.getOnUpdate().name() + ", ForeignKeyConstraint.Action." + foreignKey.getOnDelete().name() + "));\n";
|
|
||||||
}
|
}
|
||||||
for (UniqueKeyConstraint uniqueKey : entity.getUniqueKeys()) {
|
for (UniqueKeyConstraint uniqueKey : entity.getUniqueKeys()) {
|
||||||
imports.add(List.class);
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
imports.add(UniqueKeyConstraint.class);
|
+ indent + " .hasOne(" + uniqueKey.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n"
|
||||||
java += indent + "entity.addUniqueKey(new UniqueKeyConstraint(entity, List.of(\n"
|
+ indent + " .isUnique();\n";
|
||||||
+ indent + " " + uniqueKey.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n"
|
|
||||||
+ indent + " )));\n";
|
|
||||||
}
|
}
|
||||||
for (KeyConstraint key : entity.getKeys()) {
|
for (KeyConstraint key : entity.getKeys()) {
|
||||||
imports.add(List.class);
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
imports.add(KeyConstraint.class);
|
+ indent + " .hasOne(" + key.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n"
|
||||||
java += indent + "entity.addKey(new KeyConstraint(entity, List.of(\n"
|
+ indent + " .isKey();\n";
|
||||||
+ indent + " " + key.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n"
|
|
||||||
+ indent + " )));\n";
|
|
||||||
}
|
}
|
||||||
for (IndexConstraint index : entity.getIndexes()) {
|
for (IndexConstraint index : entity.getIndexes()) {
|
||||||
imports.add(List.class);
|
java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n"
|
||||||
imports.add(IndexConstraint.class);
|
+ indent + " .hasOne(" + index.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n"
|
||||||
java += indent + "entity.addIndex(new IndexConstraint(entity, List.of(\n"
|
+ indent + " .isIndex();\n";
|
||||||
+ indent + " " + index.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n"
|
|
||||||
+ indent + " )));\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
java += " }\n"
|
java += " }\n"
|
||||||
|
|||||||
@@ -2,15 +2,11 @@ package jef.operations;
|
|||||||
|
|
||||||
import jef.Queryable;
|
import jef.Queryable;
|
||||||
import jef.asm.AsmParseException;
|
import jef.asm.AsmParseException;
|
||||||
import jef.asm.AsmParser;
|
|
||||||
import jef.asm.OptimizedAsmParser;
|
import jef.asm.OptimizedAsmParser;
|
||||||
import jef.expressions.Expression;
|
import jef.expressions.Expression;
|
||||||
import jef.expressions.SelectExpression;
|
import jef.expressions.SelectExpression;
|
||||||
import jef.expressions.WhereExpression;
|
import jef.expressions.WhereExpression;
|
||||||
import jef.expressions.modifier.ExpressionOptimizerBottomUp;
|
|
||||||
import jef.expressions.modifier.IConst0Fixer;
|
|
||||||
import jef.expressions.modifier.TableAliasInjector;
|
import jef.expressions.modifier.TableAliasInjector;
|
||||||
import jef.expressions.modifier.TernaryRewriter;
|
|
||||||
import jef.expressions.selectable.DatabaseSelectAllExpression;
|
import jef.expressions.selectable.DatabaseSelectAllExpression;
|
||||||
import jef.serializable.SerializablePredicate;
|
import jef.serializable.SerializablePredicate;
|
||||||
|
|
||||||
@@ -31,18 +27,13 @@ public class FilterOp<T extends Serializable> implements Queryable<T>, Operation
|
|||||||
var parser = new OptimizedAsmParser(predicate);
|
var parser = new OptimizedAsmParser(predicate);
|
||||||
Expression expr;
|
Expression expr;
|
||||||
try {
|
try {
|
||||||
expr = parser.parse();
|
expr = parser.parse().getExpression();
|
||||||
} catch (AsmParseException e) {
|
} catch (AsmParseException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = new TableAliasInjector(getTableAlias()).modify(expr);//TODO this does not work together with expression optimization
|
expr = new TableAliasInjector(getTableAlias()).modify(expr);//TODO this does not work together with expression optimization
|
||||||
this.predicateExpr = expr;
|
this.predicateExpr = expr;
|
||||||
//TODO optimize whole expression
|
|
||||||
// this.finalExpr = new ExpressionOptimizerBottomUp().modify(
|
|
||||||
// new WhereExpression(
|
|
||||||
// new SelectExpression(List.of(DatabaseSelectAllExpression.INSTANCE), queryable.getExpression(), getTableAlias()),
|
|
||||||
// predicateExpr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class SortOp<T extends Serializable> implements Queryable<T> {
|
|||||||
var parser = new AsmParser(fieldSelector);
|
var parser = new AsmParser(fieldSelector);
|
||||||
Expression expr;
|
Expression expr;
|
||||||
try {
|
try {
|
||||||
expr = parser.parse();
|
expr = parser.parse().getExpression();
|
||||||
} catch (AsmParseException e) {
|
} catch (AsmParseException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/main/java/jef/util/Log.java
Normal file
13
src/main/java/jef/util/Log.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package jef.util;
|
||||||
|
|
||||||
|
public class Log {
|
||||||
|
// private static Log INSTANCE = new Log();
|
||||||
|
|
||||||
|
public static void debug(String s) {
|
||||||
|
System.out.println(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Log() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,38 +15,38 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testTrue() throws AsmParseException {
|
public void testTrue() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> true).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> true).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("1", act);
|
Assertions.assertEquals("1", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCompareWithEntityMember() throws AsmParseException {
|
public void testCompareWithEntityMember() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1", act);
|
Assertions.assertEquals("`i` = 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i != 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i != 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` <> 1", act);
|
Assertions.assertEquals("`i` <> 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i < 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i < 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` < 1", act);
|
Assertions.assertEquals("`i` < 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i > 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i > 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` > 1", act);
|
Assertions.assertEquals("`i` > 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i <= 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i <= 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` <= 1", act);
|
Assertions.assertEquals("`i` <= 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i >= 1).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i >= 1).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` >= 1", act);
|
Assertions.assertEquals("`i` >= 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1337", act);
|
Assertions.assertEquals("`i` = 1337", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,12 +54,12 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testContainsWithEntityMember() throws AsmParseException {
|
public void testContainsWithEntityMember() throws AsmParseException {
|
||||||
var s = List.of(1, 3);
|
var s = List.of(1, 3);
|
||||||
String act;
|
String act;
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` IN (1, 3)", act);
|
Assertions.assertEquals("`i` IN (1, 3)", act);
|
||||||
|
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
// act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> List.of(1, 3).contains(e.i)).parse().toString();
|
// act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> List.of(1, 3).contains(e.i)).parse().getExpression().toString();
|
||||||
// Assertions.assertEquals("`i` IN (1, 3)", act);
|
// Assertions.assertEquals("`i` IN (1, 3)", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,23 +67,23 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testComplexExpression() throws AsmParseException {
|
public void testComplexExpression() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
var s = List.of(1, 3);
|
var s = List.of(1, 3);
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && e.i == 1337).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && e.i == 1337).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` IN (1, 3) AND `i` = 1337", act);
|
Assertions.assertEquals("`i` IN (1, 3) AND `i` = 1337", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && e.i == 1337 && e.i == 420).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && e.i == 1337 && e.i == 420).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` IN (1, 3) AND `i` = 1337 AND `i` = 420", act);
|
Assertions.assertEquals("`i` IN (1, 3) AND `i` = 1337 AND `i` = 420", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || e.i != 420 || s.contains(e.i)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || e.i != 420 || s.contains(e.i)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1337 OR `i` <> 420 OR `i` IN (1, 3)", act);
|
Assertions.assertEquals("`i` = 1337 OR `i` <> 420 OR `i` IN (1, 3)", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || e.i == 420 || s.contains(e.i)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || e.i == 420 || s.contains(e.i)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1337 OR `i` = 420 OR `i` IN (1, 3)", act);
|
Assertions.assertEquals("`i` = 1337 OR `i` = 420 OR `i` IN (1, 3)", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || s.contains(e.i) || e.i == 420).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 1337 || s.contains(e.i) || e.i == 420).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1337 OR `i` IN (1, 3) OR `i` = 420", act);
|
Assertions.assertEquals("`i` = 1337 OR `i` IN (1, 3) OR `i` = 420", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testComplexExpressionMixedAndOr() throws AsmParseException {
|
public void testComplexExpressionMixedAndOr() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
var s = List.of(1, 3);
|
var s = List.of(1, 3);
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && (e.i == 1337 || e.i == 420)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> s.contains(e.i) && (e.i == 1337 || e.i == 420)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` IN (1, 3) AND (`i` = 1337 OR `i` = 420)", act);
|
Assertions.assertEquals("`i` IN (1, 3) AND (`i` = 1337 OR `i` = 420)", act);
|
||||||
|
|
||||||
|
|
||||||
@@ -105,15 +105,15 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testObject() throws AsmParseException {
|
public void testObject() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
var s = Arrays.asList(null, 4);
|
var s = Arrays.asList(null, 4);
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o == null).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o == null).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`o` IS NULL", act);
|
Assertions.assertEquals("`o` IS NULL", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o != null).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o != null).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`o` IS NOT NULL", act);
|
Assertions.assertEquals("`o` IS NOT NULL", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o != null || s.contains(e.o)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.o != null || s.contains(e.o)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`o` IS NOT NULL OR `o` IN (NULL, 4)", act);
|
Assertions.assertEquals("`o` IS NOT NULL OR `o` IN (NULL, 4)", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,41 +121,41 @@ public class OptimizedAsmParserTest {
|
|||||||
public void testFloatingPoint() throws AsmParseException {
|
public void testFloatingPoint() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
var s = Arrays.asList(null, 2);
|
var s = Arrays.asList(null, 2);
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d == 3.14d).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d == 3.14d).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`d` = 3.14", act);
|
Assertions.assertEquals("`d` = 3.14", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.f == 3.14f).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.f == 3.14f).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`f` = 3.14", act);
|
Assertions.assertEquals("`f` = 3.14", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d != 1d || e.f != 1 || s.contains(e.d)).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d != 1d || e.f != 1 || s.contains(e.d)).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`d` <> 1 OR `f` <> 1 OR `d` IN (NULL, 2)", act);
|
Assertions.assertEquals("`d` <> 1 OR `f` <> 1 OR `d` IN (NULL, 2)", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIDFLConst() throws AsmParseException {
|
public void testIDFLConst() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 0 || e.i == 1 || e.i == 2 || e.i == 3 || e.i == 4 || e.i == 5).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.i == 0 || e.i == 1 || e.i == 2 || e.i == 3 || e.i == 4 || e.i == 5).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 0 OR `i` = 1 OR `i` = 2 OR `i` = 3 OR `i` = 4 OR `i` = 5", act);
|
Assertions.assertEquals("`i` = 0 OR `i` = 1 OR `i` = 2 OR `i` = 3 OR `i` = 4 OR `i` = 5", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d == 0D || e.d == 1D).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.d == 0D || e.d == 1D).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`d` = 0 OR `d` = 1", act);
|
Assertions.assertEquals("`d` = 0 OR `d` = 1", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.f == 0F || e.f == 1F || e.f == 2F).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.f == 0F || e.f == 1F || e.f == 2F).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`f` = 0 OR `f` = 1 OR `f` = 2", act);
|
Assertions.assertEquals("`f` = 0 OR `f` = 1 OR `f` = 2", act);
|
||||||
|
|
||||||
|
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.l == 0L || e.l == 1L).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.l == 0L || e.l == 1L).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`l` = 0 OR `l` = 1", act);
|
Assertions.assertEquals("`l` = 0 OR `l` = 1", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMemberViaGetter() throws AsmParseException {
|
public void testMemberViaGetter() throws AsmParseException {
|
||||||
String act;
|
String act;
|
||||||
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.getI() == 1337).parse().toString();
|
act = new OptimizedAsmParser((SerializablePredicate<?>) (TestClass e) -> e.getI() == 1337).parse().getExpression().toString();
|
||||||
Assertions.assertEquals("`i` = 1337", act);
|
Assertions.assertEquals("`i` = 1337", act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ class DbContextSimpleTest {
|
|||||||
|
|
||||||
@Clazz(TestClass.class)
|
@Clazz(TestClass.class)
|
||||||
private DbSet<TestClass> objects1;
|
private DbSet<TestClass> objects1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelCreate(ModelBuilder mb) {
|
||||||
|
super.onModelCreate(mb);
|
||||||
|
mb.entity(TestClass.class)
|
||||||
|
.hasOne(e -> e.i)
|
||||||
|
.isUnique(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
|
|||||||
class EntityInitializerMultiple1ToNRelationTest {
|
class EntityInitializerMultiple1ToNRelationTest {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
assertEquals("Model TestClass2 multiple contains a 1 to N relation with type TestClass",
|
assertEquals("Model TestClass2 contains multiple 1 to N relations with type TestClass",
|
||||||
assertThrowsExactly(ModelException.class, () -> ModelBuilder.from(Ctx.class)).getMessage());
|
assertThrowsExactly(ModelException.class, () -> ModelBuilder.from(Ctx.class)).getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ class ForeignKeyInitializerNestedList2LayerTest {
|
|||||||
|
|
||||||
assertEquals(3, mb.getEntities().size());
|
assertEquals(3, mb.getEntities().size());
|
||||||
assertEquals("objects1", mb.getEntity(TestClass3.class).getName());
|
assertEquals("objects1", mb.getEntity(TestClass3.class).getName());
|
||||||
assertEquals("nested2", mb.getEntity(TestClass2.class).getName());
|
assertEquals("TestClass2", mb.getEntity(TestClass2.class).getName());
|
||||||
assertEquals("nested", mb.getEntity(TestClass.class).getName());
|
assertEquals("TestClass", mb.getEntity(TestClass.class).getName());
|
||||||
assertTrue(mb.getEntity(TestClass3.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass3.class)));
|
assertTrue(mb.getEntity(TestClass3.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass3.class)));
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
assertTrue(mb.getEntity(TestClass.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
assertTrue(mb.getEntity(TestClass.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ForeignKeyInitializerNestedListSimpleTest {
|
|||||||
|
|
||||||
assertEquals(2, mb.getEntities().size());
|
assertEquals(2, mb.getEntities().size());
|
||||||
assertEquals("objects1", mb.getEntity(TestClass2.class).getName());
|
assertEquals("objects1", mb.getEntity(TestClass2.class).getName());
|
||||||
assertEquals("nested", mb.getEntity(TestClass.class).getName());
|
assertEquals("TestClass", mb.getEntity(TestClass.class).getName());
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ class ForeignKeyInitializerNestedObject2LayerTest {
|
|||||||
|
|
||||||
assertEquals(3, mb.getEntities().size());
|
assertEquals(3, mb.getEntities().size());
|
||||||
assertEquals("objects1", mb.getEntity(TestClass3.class).getName());
|
assertEquals("objects1", mb.getEntity(TestClass3.class).getName());
|
||||||
assertEquals("nested2", mb.getEntity(TestClass2.class).getName());
|
assertEquals("TestClass2", mb.getEntity(TestClass2.class).getName());
|
||||||
assertEquals("nested", mb.getEntity(TestClass.class).getName());
|
assertEquals("TestClass", mb.getEntity(TestClass.class).getName());
|
||||||
assertTrue(mb.getEntity(TestClass3.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass3.class)));
|
assertTrue(mb.getEntity(TestClass3.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass3.class)));
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class ForeignKeyInitializerNestedObjectSimpleTest {
|
|||||||
|
|
||||||
assertEquals(2, mb.getEntities().size());
|
assertEquals(2, mb.getEntities().size());
|
||||||
assertEquals("objects1", mb.getEntity(TestClass2.class).getName());
|
assertEquals("objects1", mb.getEntity(TestClass2.class).getName());
|
||||||
assertEquals("nested", mb.getEntity(TestClass.class).getName());
|
assertEquals("TestClass", mb.getEntity(TestClass.class).getName());
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
assertTrue(mb.getEntity(TestClass.class).getFields().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass.class)));
|
||||||
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
assertTrue(mb.getEntity(TestClass2.class).getForeignKeys().stream().allMatch(e -> e.getEntity() == mb.getEntity(TestClass2.class)));
|
||||||
|
|||||||
@@ -102,11 +102,6 @@ public class ModelBuilderCloneTest {
|
|||||||
System.out.println("ex: " + o.getTypeName());
|
System.out.println("ex: " + o.getTypeName());
|
||||||
System.out.println("ac: " + c.getTypeName());
|
System.out.println("ac: " + c.getTypeName());
|
||||||
}
|
}
|
||||||
if (!Objects.equals(o.getType(), c.getType())) {
|
|
||||||
System.out.println("types differ: entity " + o.getName());
|
|
||||||
System.out.println("ex: " + o.getType());
|
|
||||||
System.out.println("ac: " + c.getType());
|
|
||||||
}
|
|
||||||
if (!o.getName().equals(c.getName())) {
|
if (!o.getName().equals(c.getName())) {
|
||||||
System.out.println("names differ: entity " + o.getName());
|
System.out.println("names differ: entity " + o.getName());
|
||||||
System.out.println("ex: " + o.getName());
|
System.out.println("ex: " + o.getName());
|
||||||
@@ -202,11 +197,11 @@ public class ModelBuilderCloneTest {
|
|||||||
System.out.println("ex: " + of.getField());
|
System.out.println("ex: " + of.getField());
|
||||||
System.out.println("ac: " + cf.getField());
|
System.out.println("ac: " + cf.getField());
|
||||||
}
|
}
|
||||||
if (!Objects.equals(of.getForeignKeyModelLink() == null ? null : of.getForeignKeyModelLink().getName(),
|
if (!Objects.equals(of.getExposingForeignKeyOf() == null ? null : of.getExposingForeignKeyOf().getName(),
|
||||||
cf.getForeignKeyModelLink() == null ? null : cf.getForeignKeyModelLink().getName())) {
|
cf.getExposingForeignKeyOf() == null ? null : cf.getExposingForeignKeyOf().getName())) {
|
||||||
System.out.println("fk model links differ: entity " + o.getName() + ", field " + of.getName());
|
System.out.println("fk model links differ: entity " + o.getName() + ", field " + of.getName());
|
||||||
System.out.println("ex: " + (of.getForeignKeyModelLink() == null ? null : of.getForeignKeyModelLink().getName()));
|
System.out.println("ex: " + (of.getExposingForeignKeyOf() == null ? null : of.getExposingForeignKeyOf().getName()));
|
||||||
System.out.println("ac: " + (cf.getForeignKeyModelLink() == null ? null : cf.getForeignKeyModelLink().getName()));
|
System.out.println("ac: " + (cf.getExposingForeignKeyOf() == null ? null : cf.getExposingForeignKeyOf().getName()));
|
||||||
}
|
}
|
||||||
if (!of.getName().equals(cf.getName())) {
|
if (!of.getName().equals(cf.getName())) {
|
||||||
System.out.println("names differ: entity " + o.getName() + ", field " + of.getName());
|
System.out.println("names differ: entity " + o.getName() + ", field " + of.getName());
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase {
|
|||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.entity("AddedEntity");
|
var ent = to.entity("AddedEntity");
|
||||||
ent.getOrCreateField("id", int.class.getName());
|
ent.field("id", int.class.getName());
|
||||||
ent.getOrCreateField("addedField", int.class.getName());
|
ent.field("addedField", int.class.getName());
|
||||||
ent.setPrimaryKey(new PrimaryKeyConstraint(ent, List.of(ent.getField("id"))));
|
to.getEntity("AddedEntity").setPrimaryKey(new PrimaryKeyConstraint(to.getEntity("AddedEntity"), List.of(to.getEntity("AddedEntity").getField("id"))));
|
||||||
ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("addedField")), ent, List.of(ent.getField("id")), ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
to.getEntity("AddedEntity").addForeignKey(new ForeignKeyConstraint(to.getEntity("AddedEntity"), List.of(to.getEntity("AddedEntity").getField("addedField")), to.getEntity("AddedEntity"), List.of(to.getEntity("AddedEntity").getField("id")), ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase{
|
public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
@@ -39,8 +39,8 @@ public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase
|
|||||||
assertEquals(1, res.getStepsUp().size());
|
assertEquals(1, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getReferencedTable().equals("nested")
|
&& o.getReferencedTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i2")
|
&& o.getFields().get(0).equals("i2")
|
||||||
&& o.getReferencedFields().size() == 1
|
&& o.getReferencedFields().size() == 1
|
||||||
@@ -52,8 +52,8 @@ public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase
|
|||||||
assertEquals(1, res.getStepsDown().size());
|
assertEquals(1, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_nested_nested_i2"))
|
&& o.getName().equals("FK_TestClass_TestClass_i2"))
|
||||||
.count());
|
.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{
|
|||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.getEntity(TestClass.class);
|
var ent = to.entity(TestClass.class);
|
||||||
ent.getField("d").setIndex(true);
|
ent.field("d", double.class.getName()).isIndex(true);
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
@@ -38,7 +38,7 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsUp().size());
|
assertEquals(1, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddIndexOperation o
|
.filter(e -> e instanceof AddIndexOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("d"))
|
&& o.getFields().get(0).equals("d"))
|
||||||
.count());
|
.count());
|
||||||
@@ -48,8 +48,8 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsDown().size());
|
assertEquals(1, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("I_nested_d"))
|
&& o.getName().equals("I_TestClass_d"))
|
||||||
.count());
|
.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{
|
|||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.getEntity(TestClass.class);
|
var ent = to.entity(TestClass.class);
|
||||||
ent.getField("d").setKey(true);
|
ent.field("d", double.class.getName()).isKey(true);
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
@@ -38,7 +38,7 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsUp().size());
|
assertEquals(1, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddKeyOperation o
|
.filter(e -> e instanceof AddKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("d"))
|
&& o.getFields().get(0).equals("d"))
|
||||||
.count());
|
.count());
|
||||||
@@ -48,8 +48,8 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsDown().size());
|
assertEquals(1, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("K_nested_d"))
|
&& o.getName().equals("K_TestClass_d"))
|
||||||
.count());
|
.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{
|
|||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.getEntity(TestClass.class);
|
var ent = to.entity(TestClass.class);
|
||||||
ent.getField("d").setUnique(true);
|
ent.field("d", double.class.getName()).isUnique(true);
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
@@ -38,7 +38,7 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsUp().size());
|
assertEquals(1, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddUniqueKeyOperation o
|
.filter(e -> e instanceof AddUniqueKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("d"))
|
&& o.getFields().get(0).equals("d"))
|
||||||
.count());
|
.count());
|
||||||
@@ -48,8 +48,8 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{
|
|||||||
assertEquals(1, res.getStepsDown().size());
|
assertEquals(1, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("U_nested_d"))
|
&& o.getName().equals("U_TestClass_d"))
|
||||||
.count());
|
.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddTableOperation o
|
.filter(e -> e instanceof AddTableOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 6
|
&& o.getFields().size() == 6
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("d")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("d")).count() == 1
|
||||||
&& o.getFields().stream().filter(f -> f.build().getField().equals("f")).count() == 1
|
&& o.getFields().stream().filter(f -> f.build().getField().equals("f")).count() == 1
|
||||||
@@ -62,13 +62,13 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getReferencedTable().equals("objects1")
|
&& o.getReferencedTable().equals("objects1")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("nestedI")
|
&& o.getFields().get(0).equals("nestedI")
|
||||||
@@ -81,12 +81,12 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
assertEquals(5, res.getStepsDown().size());
|
assertEquals(5, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_nested_objects1_nestedI"))
|
&& o.getName().equals("FK_TestClass_objects1_nestedI"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("PRIMARY"))
|
&& o.getName().equals("PRIMARY"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
@@ -97,7 +97,7 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa
|
|||||||
|
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropTableOperation o
|
.filter(e -> e instanceof DropTableOperation o
|
||||||
&& o.getTable().equals("nested"))
|
&& o.getTable().equals("TestClass"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropTableOperation o
|
.filter(e -> e instanceof DropTableOperation o
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase {
|
|||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.getEntity(TestClass.class);
|
var ent = to.entity(TestClass.class);
|
||||||
ent.setName("d2");
|
ent.name("d2");
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
@@ -40,17 +40,17 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase {
|
|||||||
assertEquals(5, res.getStepsUp().size());
|
assertEquals(5, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_nested_objects1_nestedI"))
|
&& o.getName().equals("FK_TestClass_objects1_nestedI"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("PRIMARY"))
|
&& o.getName().equals("PRIMARY"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof RenameTableOperation o
|
.filter(e -> e instanceof RenameTableOperation o
|
||||||
&& o.getOldName().equals("nested")
|
&& o.getOldName().equals("TestClass")
|
||||||
&& o.getNewName().equals("d2"))
|
&& o.getNewName().equals("d2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
@@ -85,17 +85,17 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase {
|
|||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof RenameTableOperation o
|
.filter(e -> e instanceof RenameTableOperation o
|
||||||
&& o.getOldName().equals("d2")
|
&& o.getOldName().equals("d2")
|
||||||
&& o.getNewName().equals("nested"))
|
&& o.getNewName().equals("TestClass"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getReferencedTable().equals("objects1")
|
&& o.getReferencedTable().equals("objects1")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("nestedI")
|
&& o.getFields().get(0).equals("nestedI")
|
||||||
|
|||||||
@@ -46,45 +46,45 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator
|
|||||||
assertEquals(11, res.getStepsUp().size());
|
assertEquals(11, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_nested_nested_iFk"))
|
&& o.getName().equals("FK_TestClass_TestClass_iFk"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("PRIMARY"))
|
&& o.getName().equals("PRIMARY"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("U_nested_i"))
|
&& o.getName().equals("U_TestClass_i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("K_nested_i"))
|
&& o.getName().equals("K_TestClass_i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("I_nested_i"))
|
&& o.getName().equals("I_TestClass_i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof RenameFieldOperation o
|
.filter(e -> e instanceof RenameFieldOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getOldName().equals("i")
|
&& o.getOldName().equals("i")
|
||||||
&& o.getNewName().equals("i2"))
|
&& o.getNewName().equals("i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i2"))
|
&& o.getFields().get(0).equals("i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getReferencedTable().equals("nested")
|
&& o.getReferencedTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("iFk")
|
&& o.getFields().get(0).equals("iFk")
|
||||||
&& o.getReferencedFields().size() == 1
|
&& o.getReferencedFields().size() == 1
|
||||||
@@ -92,19 +92,19 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator
|
|||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddUniqueKeyOperation o
|
.filter(e -> e instanceof AddUniqueKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i2"))
|
&& o.getFields().get(0).equals("i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddKeyOperation o
|
.filter(e -> e instanceof AddKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i2"))
|
&& o.getFields().get(0).equals("i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof AddIndexOperation o
|
.filter(e -> e instanceof AddIndexOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i2"))
|
&& o.getFields().get(0).equals("i2"))
|
||||||
.count());
|
.count());
|
||||||
@@ -114,45 +114,45 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator
|
|||||||
assertEquals(11, res.getStepsDown().size());
|
assertEquals(11, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("FK_nested_nested_iFk"))
|
&& o.getName().equals("FK_TestClass_TestClass_iFk"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("PRIMARY"))
|
&& o.getName().equals("PRIMARY"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("U_nested_i2"))
|
&& o.getName().equals("U_TestClass_i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("K_nested_i2"))
|
&& o.getName().equals("K_TestClass_i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof DropConstraintOperation o
|
.filter(e -> e instanceof DropConstraintOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getName().equals("I_nested_i2"))
|
&& o.getName().equals("I_TestClass_i2"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof RenameFieldOperation o
|
.filter(e -> e instanceof RenameFieldOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getOldName().equals("i2")
|
&& o.getOldName().equals("i2")
|
||||||
&& o.getNewName().equals("i"))
|
&& o.getNewName().equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
.filter(e -> e instanceof AddPrimaryKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddForeignKeyOperation o
|
.filter(e -> e instanceof AddForeignKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getReferencedTable().equals("nested")
|
&& o.getReferencedTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("iFk")
|
&& o.getFields().get(0).equals("iFk")
|
||||||
&& o.getReferencedFields().size() == 1
|
&& o.getReferencedFields().size() == 1
|
||||||
@@ -160,19 +160,19 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator
|
|||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddUniqueKeyOperation o
|
.filter(e -> e instanceof AddUniqueKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddKeyOperation o
|
.filter(e -> e instanceof AddKeyOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof AddIndexOperation o
|
.filter(e -> e instanceof AddIndexOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getFields().size() == 1
|
&& o.getFields().size() == 1
|
||||||
&& o.getFields().get(0).equals("i"))
|
&& o.getFields().get(0).equals("i"))
|
||||||
.count());
|
.count());
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase {
|
|||||||
public void test() {
|
public void test() {
|
||||||
var from = ModelBuilder.from(Ctx.class);
|
var from = ModelBuilder.from(Ctx.class);
|
||||||
var to = ModelBuilder.from(Ctx.class);
|
var to = ModelBuilder.from(Ctx.class);
|
||||||
var ent = to.getEntity(TestClass.class);
|
var ent = to.entity(TestClass.class);
|
||||||
ent.getField("d").setName("d2");
|
ent.field("d", double.class.getName()).name("d2");
|
||||||
var mc = new MigrationCreator();
|
var mc = new MigrationCreator();
|
||||||
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava());
|
||||||
try {
|
try {
|
||||||
@@ -37,7 +37,7 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase {
|
|||||||
assertEquals(1, res.getStepsUp().size());
|
assertEquals(1, res.getStepsUp().size());
|
||||||
assertEquals(1, res.getStepsUp().stream()
|
assertEquals(1, res.getStepsUp().stream()
|
||||||
.filter(e -> e instanceof RenameFieldOperation o
|
.filter(e -> e instanceof RenameFieldOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getOldName().equals("d")
|
&& o.getOldName().equals("d")
|
||||||
&& o.getNewName().equals("d2"))
|
&& o.getNewName().equals("d2"))
|
||||||
.count());
|
.count());
|
||||||
@@ -47,7 +47,7 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase {
|
|||||||
assertEquals(1, res.getStepsDown().size());
|
assertEquals(1, res.getStepsDown().size());
|
||||||
assertEquals(1, res.getStepsDown().stream()
|
assertEquals(1, res.getStepsDown().stream()
|
||||||
.filter(e -> e instanceof RenameFieldOperation o
|
.filter(e -> e instanceof RenameFieldOperation o
|
||||||
&& o.getTable().equals("nested")
|
&& o.getTable().equals("TestClass")
|
||||||
&& o.getOldName().equals("d2")
|
&& o.getOldName().equals("d2")
|
||||||
&& o.getNewName().equals("d"))
|
&& o.getNewName().equals("d"))
|
||||||
.count());
|
.count());
|
||||||
|
|||||||
@@ -24,22 +24,22 @@ class ModelChangeDetectorAddEntityTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass2");
|
mb.entity("TestClass2");
|
||||||
mb.entity("TestClass2").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass2").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass3");
|
mb.entity("TestClass3");
|
||||||
mb.entity("TestClass3").getOrCreateField("i3", int.class.getName())
|
mb.entity("TestClass3").field("i3", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,20 +24,20 @@ class ModelChangeDetectorAddFieldTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i3", int.class.getName())
|
mb.entity("TestClass").field("i3", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,22 +26,22 @@ class ModelChangeDetectorAddForeignKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
var ent = mb.entity("TestClass");
|
var ent = mb.entity("TestClass");
|
||||||
ent.getOrCreateField("i", int.class.getName())
|
ent.field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
ent.getOrCreateField("i2", int.class.getName())
|
ent.field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("i2")),
|
mb.getEntity("TestClass").addForeignKey(new ForeignKeyConstraint(mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i2")),
|
||||||
ent, List.of(ent.getField("i")),
|
mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i")),
|
||||||
ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorAddIndexTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setIndex(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isIndex(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorAddKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setKey(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isKey(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,22 +27,22 @@ class ModelChangeDetectorAddPrimaryKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.entity("TestClass"),
|
mb.getEntity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.getEntity("TestClass"),
|
||||||
List.of(mb.entity("TestClass").getField("i"))));
|
List.of(mb.getEntity("TestClass").getField("i"))));
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorAddUniqueTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setUnique(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isUnique(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,22 +24,22 @@ class ModelChangeDetectorDropEntityTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass2");
|
mb.entity("TestClass2");
|
||||||
mb.entity("TestClass2").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass2").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass3");
|
mb.entity("TestClass3");
|
||||||
mb.entity("TestClass3").getOrCreateField("i3", int.class.getName())
|
mb.entity("TestClass3").field("i3", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,20 +24,20 @@ class ModelChangeDetectorDropFieldTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i3", int.class.getName())
|
mb.entity("TestClass").field("i3", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,12 +26,12 @@ class ModelChangeDetectorDropForeignKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
var ent = mb.entity("TestClass");
|
var ent = mb.entity("TestClass");
|
||||||
ent.getOrCreateField("i", int.class.getName())
|
ent.field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
ent.getOrCreateField("i2", int.class.getName())
|
ent.field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("i2")),
|
mb.getEntity("TestClass").addForeignKey(new ForeignKeyConstraint(mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i2")),
|
||||||
ent, List.of(ent.getField("i")),
|
mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i")),
|
||||||
ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE));
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
@@ -39,10 +39,10 @@ class ModelChangeDetectorDropForeignKeyTest {
|
|||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorDropIndexTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setIndex(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isIndex(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorDropKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setKey(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isKey(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,22 +27,22 @@ class ModelChangeDetectorDropPrimaryKeyTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.entity("TestClass"),
|
mb.getEntity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.getEntity("TestClass"),
|
||||||
List.of(mb.entity("TestClass").getField("i"))));
|
List.of(mb.getEntity("TestClass").getField("i"))));
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,21 +23,21 @@ class ModelChangeDetectorDropUniqueTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setUnique(true);
|
mb.entity("TestClass").field("i", int.class.getName()).isUnique(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelBuilder createTo() {
|
private ModelBuilder createTo() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,13 +18,13 @@ class ModelChangeDetectorNoChangeTest {
|
|||||||
private ModelBuilder createFrom() {
|
private ModelBuilder createFrom() {
|
||||||
var mb = new ModelBuilder();
|
var mb = new ModelBuilder();
|
||||||
mb.entity("TestClass");
|
mb.entity("TestClass");
|
||||||
mb.entity("TestClass").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass2");
|
mb.entity("TestClass2");
|
||||||
mb.entity("TestClass2").getOrCreateField("i", int.class.getName())
|
mb.entity("TestClass2").field("i", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
mb.entity("TestClass2").getOrCreateField("i2", int.class.getName())
|
mb.entity("TestClass2").field("i2", int.class.getName())
|
||||||
.setNotNull(true);
|
.isNotNull(true);
|
||||||
return mb;
|
return mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user