diff --git a/README.md b/README.md index d306e7a..e914b12 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ - actually parse getter - 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 +- expose more stuff as result (e.g. accessed members/functions, ...) +- cleanup exception handling +- cleanup if else trees ## ModelBuilder - add registrable conversion types e.g. UUID, Date, Timestamp, Calendar, LocalTime, Instant,... @@ -22,6 +25,9 @@ - field length - field precision - sql type +- ignore() entity/field for db +- object inlining +- entity() with callback ## Annotations - db type diff --git a/src/main/java/jef/asm/AsmParseException.java b/src/main/java/jef/asm/AsmParseException.java index 4d7cc65..b7ba95d 100644 --- a/src/main/java/jef/asm/AsmParseException.java +++ b/src/main/java/jef/asm/AsmParseException.java @@ -1,6 +1,6 @@ package jef.asm; -public class AsmParseException extends Exception { +public class AsmParseException extends RuntimeException { public AsmParseException() { } diff --git a/src/main/java/jef/asm/AsmParseResult.java b/src/main/java/jef/asm/AsmParseResult.java new file mode 100644 index 0000000..b430100 --- /dev/null +++ b/src/main/java/jef/asm/AsmParseResult.java @@ -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 accessedFields; +} diff --git a/src/main/java/jef/asm/AsmParser.java b/src/main/java/jef/asm/AsmParser.java index 1e49fa2..e17556a 100644 --- a/src/main/java/jef/asm/AsmParser.java +++ b/src/main/java/jef/asm/AsmParser.java @@ -1,6 +1,5 @@ package jef.asm; -import jef.expressions.Expression; import jef.serializable.SerializableFunction; import jef.serializable.SerializablePredicate; import lombok.Getter; @@ -24,7 +23,7 @@ public class AsmParser { this.lambda = function; } - public Expression parse() throws AsmParseException { + public AsmParseResult parse() throws AsmParseException { try { return parseExpression(); } 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 loader = cls.getClassLoader(); InputStream is; -// System.out.println(cls); -// System.out.println(cls.getName()); if (cls.getName().contains("$$Lambda$")) { -// System.out.println(cls.getName().split("\\$\\$")[0].replace(".", "/") + ".class"); is = loader.getResourceAsStream(cls.getName().split("\\$\\$")[0].replace(".", "/") + ".class"); } else { -// System.out.println(cls.getName().replace(".", "/") + ".class"); is = loader.getResourceAsStream(cls.getName().replace(".", "/") + ".class"); } - var x = cls.getDeclaredMethod("writeReplace"); -// System.out.println(x); - x.setAccessible(true); - var serlambda = (SerializedLambda) x.invoke(lambda); + var writeReplace = cls.getDeclaredMethod("writeReplace"); + writeReplace.setAccessible(true); + var serlambda = (SerializedLambda) writeReplace.invoke(lambda); Object[] args = IntStream.range(0, serlambda.getCapturedArgCount()).mapToObj(serlambda::getCapturedArg).toArray(); -// System.out.println(serlambda); var lambdaname = serlambda.getImplMethodName(); -// System.out.println(lambdaname); - - var expr = new Expression[1]; 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); - return expr[0]; + return visiter.getResult(); } } diff --git a/src/main/java/jef/asm/FilterClassVisitor.java b/src/main/java/jef/asm/FilterClassVisitor.java index a5b5845..71d935d 100644 --- a/src/main/java/jef/asm/FilterClassVisitor.java +++ b/src/main/java/jef/asm/FilterClassVisitor.java @@ -1,23 +1,22 @@ package jef.asm; -import jef.expressions.Expression; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; -import java.util.function.Consumer; +import java.util.Optional; class FilterClassVisitor extends ClassVisitor { private final int api; private final String lambdaname; - private final Consumer queryConsumer; private final Object[] args; - protected FilterClassVisitor(int api, String lambdaname, Object[] args, Consumer queryConsumer) { + private FilterMethodVisitor mv; + + protected FilterClassVisitor(int api, String lambdaname, Object[] args) { super(api); this.api = api; this.lambdaname = lambdaname; this.args = args; - this.queryConsumer = queryConsumer; } @Override @@ -26,7 +25,23 @@ class FilterClassVisitor extends ClassVisitor { return super.visitMethod(access, name, descriptor, signature, exceptions); } - System.out.println("found method name: " + name); - return new FilterMethodVisitor(api, descriptor, args, queryConsumer); + if (mv != null) { + 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); } } diff --git a/src/main/java/jef/asm/FilterMethodVisitor.java b/src/main/java/jef/asm/FilterMethodVisitor.java index d493d21..d37adee 100644 --- a/src/main/java/jef/asm/FilterMethodVisitor.java +++ b/src/main/java/jef/asm/FilterMethodVisitor.java @@ -22,6 +22,7 @@ import org.objectweb.asm.Type; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -37,13 +38,12 @@ class FilterMethodVisitor extends MethodVisitor { private Stack varStack = new Stack<>(); private final String[] parameterClasses; private final Object[] args; - private final Consumer exprConsumer; private Expression lambdaExpr; + private final Set accessedMembers = new HashSet<>(); - protected FilterMethodVisitor(int api, String descriptor, Object[] args, Consumer exprConsumer) { + protected FilterMethodVisitor(int api, String descriptor, Object[] args) { super(api); this.args = args; - this.exprConsumer = exprConsumer; //parameters var types = Type.getMethodType(descriptor).getArgumentTypes(); @@ -53,6 +53,10 @@ class FilterMethodVisitor extends MethodVisitor { } } + public AsmParseResult getResult() { + return new AsmParseResult(lambdaExpr, accessedMembers); + } + @Override public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) { System.out.println("local var: " + name); @@ -67,6 +71,11 @@ class FilterMethodVisitor extends MethodVisitor { var v = varStack.pop(); if (v instanceof ParameterExpression p) { 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)); } else { throw new RuntimeException("field insn: unsupported GETFIELD expression"); @@ -386,7 +395,6 @@ class FilterMethodVisitor extends MethodVisitor { System.out.println("end"); super.visitEnd(); - exprConsumer.accept(lambdaExpr); } @Override diff --git a/src/main/java/jef/asm/OptimizedAsmParser.java b/src/main/java/jef/asm/OptimizedAsmParser.java index 78c21c8..349f4df 100644 --- a/src/main/java/jef/asm/OptimizedAsmParser.java +++ b/src/main/java/jef/asm/OptimizedAsmParser.java @@ -27,8 +27,9 @@ public class OptimizedAsmParser extends AsmParser{ super(function); } - public Expression parse() throws AsmParseException { - var expr = super.parse(); + public AsmParseResult parse() throws AsmParseException { + var result = super.parse(); + var expr = result.getExpression(); System.out.println(expr); expr = new TernaryRewriter().modify(expr); @@ -37,6 +38,6 @@ public class OptimizedAsmParser extends AsmParser{ System.out.println(expr); expr = new ExpressionOptimizerBottomUp().modify(expr); - return expr; + return new AsmParseResult(expr, result.getAccessedFields()); } } diff --git a/src/main/java/jef/model/DbContext.java b/src/main/java/jef/model/DbContext.java index fa31dc6..f3223b2 100644 --- a/src/main/java/jef/model/DbContext.java +++ b/src/main/java/jef/model/DbContext.java @@ -10,7 +10,7 @@ import java.util.Optional; import java.util.stream.Collectors; 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) { } @@ -44,13 +44,13 @@ public abstract class DbContext { //check for duplicate field names for (DbEntity entity : mb.getEntities()) { - var fieldNameMap = new HashMap>(); + var fieldNameMap = new HashMap>(); for (DbField field : entity.getFields()) { var name = field.getName().toLowerCase(); if (fieldNameMap.containsKey(name)) { errors.add("Duplicate DbField in entity " + entity.getTypeName() + " with name " + field.getName() + ": " + field.getName() + " and " + fieldNameMap.get(name).getName()); } else { - fieldNameMap.put(name, entity); + fieldNameMap.put(name, field); } } } diff --git a/src/main/java/jef/model/DbEntity.java b/src/main/java/jef/model/DbEntity.java index 187d9ff..45453c7 100644 --- a/src/main/java/jef/model/DbEntity.java +++ b/src/main/java/jef/model/DbEntity.java @@ -12,7 +12,6 @@ import jef.model.constraints.UniqueKeyConstraint; import jef.serializable.SerializableFunction; import jef.serializable.SerializableObject; import jef.util.Check; -import jef.util.Util; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -24,11 +23,11 @@ import java.util.List; import java.util.Objects; @Getter -@Setter +@Setter(value = AccessLevel.PACKAGE) public class DbEntity { - private final String typeName; - @Setter(value = AccessLevel.PACKAGE) - private Class type; + private String typeName; + // @Setter +// private Class type; private final List> fields; private String name; private PrimaryKeyConstraint primaryKey; @@ -39,7 +38,6 @@ public class DbEntity { //only used for migrations DbEntity(String typeName) { - this.type = (Class) Util.tryGet(() -> Class.forName(typeName)).orElse(null); this.typeName = typeName; this.fields = new ArrayList<>(); var split = typeName.split("\\."); @@ -55,7 +53,7 @@ public class DbEntity { } DbEntity(Class type, String name, List> fields) { - this.type = Check.notNull(type, "type"); +// this.type = Check.notNull(type, "type"); this.typeName = type.getName(); this.fields = Check.notNull(fields, "fields"); this.name = Check.notNull(name, "name"); @@ -107,7 +105,7 @@ public class DbEntity { var prop = getField(getter); if (prop == null) { var name = extractFieldName(getter); - var field = ReflectionUtil.getFieldsRecursive(type).stream().filter(f -> f.getName().equals(name)).findFirst().orElse(null); + var field = ReflectionUtil.getFieldsRecursive((Class) Class.forName(typeName)).stream().filter(f -> f.getName().equals(name)).findFirst().orElse(null); if (field == null) { throw new RuntimeException("Field not found: " + name); } @@ -181,6 +179,7 @@ public class DbEntity { /** * Does not validate foreign key integrity + * * @param primaryKey */ public void setPrimaryKey(PrimaryKeyConstraint primaryKey) { @@ -211,9 +210,18 @@ public class DbEntity { } } - private String extractFieldName(SerializableFunction getter) { + void addField(DbField field) { + this.fields.add(field); + } + + DbEntityBuilder builder(ModelBuilder mb) { + return new DbEntityBuilder<>(mb, this); + } + + + String extractFieldName(SerializableFunction getter) { try { - var expr = new AsmParser(getter).parse(); + var expr = new AsmParser(getter).parse().getExpression(); if (expr.getType() != Expression.Type.INTERMEDIATE_FIELD) { throw new RuntimeException(expr.getClass().getSimpleName() + " is not a field expression"); } @@ -241,13 +249,13 @@ public class DbEntity { @Override 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 public String toString() { return "DbEntity{" + - "type=" + type + + "typeName=" + typeName + ", name='" + name + '\'' + '}'; } diff --git a/src/main/java/jef/model/DbEntityBuilder.java b/src/main/java/jef/model/DbEntityBuilder.java new file mode 100644 index 0000000..f859c74 --- /dev/null +++ b/src/main/java/jef/model/DbEntityBuilder.java @@ -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 { + private final ModelBuilder modelBuilder; + private final DbEntity entity; + + public DbEntityBuilder name(String name) { + entity.setName(name); + return this; + } + + public DbFieldBuilder field(SerializableFunction 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) field.getType(), field); + entity.addField(prop); + } + return new DbFieldBuilder<>(prop); + } catch (Exception e) { + throw new RuntimeException("Invalid expression", e); + } + } + + public DbFieldBuilder field(Field field) { + var prop = (DbField) entity.getFields().stream().filter(e -> e.getField().equals(field)).findFirst().orElse(null); + if (prop == null) { + prop = new DbField<>(entity, (Class) field.getType(), field); + entity.addField(prop); + } + return new DbFieldBuilder<>(prop); + } + + public DbFieldBuilder field(String name, String typeName) { + var prop = (DbField) 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 hasOne(SerializableFunction 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 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 hasMany(SerializableFunction 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 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> fields() { + return (List) entity.getFields().stream().map(e -> new DbFieldBuilder(e)).toList(); + } + + public Optional> type() { + return Util.tryGet(() -> (Class) 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 getEntity() { //TODO make this libaray private somehow + return entity; + } + + @Override + public String toString() { + return entity.toString(); + } +} diff --git a/src/main/java/jef/model/DbField.java b/src/main/java/jef/model/DbField.java index 3dc2244..7716abe 100644 --- a/src/main/java/jef/model/DbField.java +++ b/src/main/java/jef/model/DbField.java @@ -1,8 +1,5 @@ package jef.model; -import jef.model.constraints.IndexConstraint; -import jef.model.constraints.KeyConstraint; -import jef.model.constraints.UniqueKeyConstraint; import jef.serializable.SerializableObject; import jef.util.Check; import lombok.AccessLevel; @@ -10,9 +7,7 @@ import lombok.Getter; import lombok.Setter; import java.lang.reflect.Field; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Objects; @Getter @@ -26,7 +21,7 @@ public class DbField { private Field field; private boolean isModelField; private boolean isDatabaseField; - private DbField foreignKeyModelLink; + private DbField exposingForeignKeyOf; private String name; private boolean notNull = false; @@ -62,41 +57,14 @@ public class DbField { 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() { 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() { 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 setModelField(boolean modelField) { isModelField = modelField; return this; @@ -136,14 +104,14 @@ public class DbField { && entity.getName().equals(dbField.entity.getName()) && typeName.equals(dbField.typeName) // && Objects.equals(type, dbField.type) - && Objects.equals(foreignKeyModelLink == null ? null : foreignKeyModelLink.getName(), - dbField.foreignKeyModelLink == null ? null : dbField.foreignKeyModelLink.getName()); + && Objects.equals(exposingForeignKeyOf == null ? null : exposingForeignKeyOf.getName(), + dbField.exposingForeignKeyOf == null ? null : dbField.exposingForeignKeyOf.getName()); } @Override public int hashCode() { 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); } diff --git a/src/main/java/jef/model/DbFieldBuilder.java b/src/main/java/jef/model/DbFieldBuilder.java new file mode 100644 index 0000000..4ff9ba9 --- /dev/null +++ b/src/main/java/jef/model/DbFieldBuilder.java @@ -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 { + private final DbField field; + + public DbFieldBuilder name(String name) { + field.setName(name); + return this; + } + + public DbFieldBuilder isDatabaseField(boolean isDatabase) { + field.setDatabaseField(isDatabase); + return this; + } + + public DbFieldBuilder isModelField(boolean isModel) { + field.setModelField(isModel); + return this; + } + + public DbFieldBuilder isNotNull() { + return isNotNull(true); + } + + public DbFieldBuilder 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 getField() {//TODO make this library private + return field; + } +} diff --git a/src/main/java/jef/model/EntityInitializer.java b/src/main/java/jef/model/EntityInitializer.java index 7e92edc..c39406f 100644 --- a/src/main/java/jef/model/EntityInitializer.java +++ b/src/main/java/jef/model/EntityInitializer.java @@ -4,58 +4,78 @@ import jef.DbSet; import jef.model.annotations.Clazz; import jef.model.annotations.Transient; import jef.serializable.SerializableObject; +import jef.util.Log; import java.lang.reflect.Field; import java.util.Collection; class EntityInitializer { static void initEntities(ModelBuilder mb, Class context) { - for (Field ctxfield : context.getDeclaredFields()) { - if (!DbSet.class.isAssignableFrom(ctxfield.getType())) { + for (Field ctxField : context.getDeclaredFields()) { + if (!DbSet.class.isAssignableFrom(ctxField.getType())) { continue; } - Clazz clazzAnnotation = ctxfield.getAnnotation(Clazz.class); + Clazz clazzAnnotation = ctxField.getAnnotation(Clazz.class); 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) clazzAnnotation.value(); - initEntity(mb, dbsetClazz, ctxfield.getName()); + initEntity(mb, dbSetClazz, ctxField.getName(), true); } } - static void initEntity(ModelBuilder mb, Class clazz, String name) { - var entity = mb.getOrCreateEntity(clazz); - entity.setName(name); + static void initEntity(ModelBuilder mb, Class clazz, String name, boolean overrideName) { + var existingEntity = mb.getEntity(clazz); + 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); for (var f : fields) { if (f.getAnnotationsByType(Transient.class).length > 0) { continue; } + Log.debug("Initializing field '" + f.getName() + "' with type " + f.getType().getName()); if (Collection.class.isAssignableFrom(f.getType())) { //find a Collection field with the same Model //e.g. class Entity { @Clazz(Entity2.class) List ent; @Clazz(Entity2.class) Set ent2; } - var clazzAnnotation = f.getAnnotationsByType(Clazz.class); - if (clazzAnnotation.length == 0) { + var clazzAnnotation = f.getAnnotation(Clazz.class); + if (clazzAnnotation == null) { throw new ModelException("Field " + f.getClass().getSimpleName() + "::" + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation"); } - var fClazz = clazzAnnotation[0].value(); - var foundCollection = entity.getFields().stream() - .filter(e -> Collection.class.isAssignableFrom(e.getType()) - && e.isModelField() - && e.getField().getAnnotationsByType(Clazz.class).length > 0 - && e.getField().getAnnotationsByType(Clazz.class)[0].clazz() == fClazz) + var fClazz = clazzAnnotation.value(); + if (!SerializableObject.class.isAssignableFrom(fClazz)) { + 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 + } + var foundCollection = entity.fields().stream() + .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(); 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) fClazz, fClazz.getSimpleName(), false); } else if (SerializableObject.class.isAssignableFrom(f.getType())) { - entity.getOrCreateField(f); + entity.field(f); + initEntity(mb, (Class) f.getType(), f.getType().getSimpleName(), false); } else { - var dbField = entity.getOrCreateField(f); + var dbField = entity.field(f); if (f.getType().isPrimitive()) { - dbField.setNotNull(true); + dbField.isNotNull(); } } } diff --git a/src/main/java/jef/model/ForeignKeyBuilder.java b/src/main/java/jef/model/ForeignKeyBuilder.java new file mode 100644 index 0000000..ecc34ba --- /dev/null +++ b/src/main/java/jef/model/ForeignKeyBuilder.java @@ -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 { + private final ForeignKeyConstraint foreignKey; + + public ForeignKeyBuilder onUpdate(ForeignKeyConstraint.Action onUpdate) { + foreignKey.setOnUpdate(onUpdate); + return this; + } + + public ForeignKeyBuilder onDelete(ForeignKeyConstraint.Action onDelete) { + foreignKey.setOnDelete(onDelete); + return this; + } +} diff --git a/src/main/java/jef/model/ForeignKeyExposeInitializer.java b/src/main/java/jef/model/ForeignKeyExposeInitializer.java new file mode 100644 index 0000000..ebf2214 --- /dev/null +++ b/src/main/java/jef/model/ForeignKeyExposeInitializer.java @@ -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()); + }); + } + } + } +} diff --git a/src/main/java/jef/model/ForeignKeyInitializer.java b/src/main/java/jef/model/ForeignKeyInitializer.java index c43a29b..67b9dda 100644 --- a/src/main/java/jef/model/ForeignKeyInitializer.java +++ b/src/main/java/jef/model/ForeignKeyInitializer.java @@ -3,144 +3,179 @@ package jef.model; import jef.model.annotations.Clazz; import jef.model.annotations.ForeignKey; import jef.model.annotations.Transient; -import jef.model.constraints.ForeignKeyConstraint; import jef.serializable.SerializableObject; +import jef.util.Log; import lombok.AllArgsConstructor; import lombok.Getter; +import java.lang.reflect.Field; import java.util.Collection; -import java.util.List; import java.util.Locale; class ForeignKeyInitializer { static void initForeignKeys(ModelBuilder mb) { - for (int i = 0; i < mb.getEntities().size(); i++) { - var entity = mb.getEntities().get(i); + var entities = mb.entities(); + for (int i = 0; i < entities.size(); i++) { + var entity = entities.get(i); initForeignKeys(mb, entity); } } - static void initForeignKeys(ModelBuilder mb, DbEntity entity) { - var fields = ReflectionUtil.getFieldsRecursive(entity.getType()); + static void initForeignKeys(ModelBuilder mb, DbEntityBuilder entityBuilder) { + var entity = entityBuilder.getEntity(); + var fields = ReflectionUtil.getFieldsRecursive(entityBuilder.type().orElseThrow(() -> new IllegalStateException("Class not found: " + entityBuilder.typeName()))); for (var f : fields) { if (f.getAnnotationsByType(Transient.class).length > 0) { continue; } if (Collection.class.isAssignableFrom(f.getType())) { - Clazz clazzAnnotation = f.getAnnotation(Clazz.class); - if (clazzAnnotation == null) { - throw new ModelException("Collection " + entity.getType().getSimpleName() + "." + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation"); - } - var otherEntity = mb.getEntity((Class) clazzAnnotation.value()); - if (otherEntity == null) { - EntityInitializer.initEntity(mb, (Class) clazzAnnotation.value(), f.getName()); - otherEntity = mb.getEntity((Class) clazzAnnotation.value()); - PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity); - } - var primary = entity.getPrimaryKey(); - if (primary == null) { - throw new ModelException("Entity " + entity.getType().getSimpleName() + " is missing a primary key and therefore cannot be referenced by " + otherEntity.getType().getSimpleName()); - } - var otherEntityF = otherEntity; - var otherFields = primary.getFields().stream() - .map(e -> { - //find list in other entity (N to N relation) - if (otherEntityF != entity) { //ignore on recursive models - var otherEntityListField = otherEntityF.getFields().stream() - .filter(oef -> Collection.class.isAssignableFrom(oef.getType()) - && oef.getField().getAnnotationsByType(Clazz.class).length > 0 - && oef.getField().getAnnotationsByType(Clazz.class)[0].value() == entity.getType()).findFirst(); - if (otherEntityListField.isPresent()) { - throw new ModelException("N to N relations need to explicitly defined via a mapping model (" - + otherEntityF.getType().getSimpleName() + "::" + otherEntityListField.get().getType().getName() + " and " - + entity.getType().getSimpleName() + "::" + f.getType().getName() + ")"); - } - } + do1toN(mb, entityBuilder, entity, f); + } else if (SerializableObject.class.isAssignableFrom(f.getType())) {//1 to 1 relation + do1to1(mb, entityBuilder, entity, f); + } + } + } - //find object in other entity (1 to N relation) - var otherEntityObjectField = otherEntityF.getFields().stream().filter(oef -> oef.getType() == entity.getType()).findFirst(); - if (otherEntityObjectField.isPresent()) { - return new FieldSearchResult(otherEntityObjectField.get(), false); - } + private static void do1toN(ModelBuilder mb, DbEntityBuilder entityBuilder, DbEntity entity, Field f) { + Clazz clazzAnnotation = f.getAnnotation(Clazz.class); + if (clazzAnnotation == null) { + throw new ModelException("Collection " + entityBuilder.className() + "." + f.getName() + " is missing the " + Clazz.class.getSimpleName() + " annotation"); + } + var otherEntity = mb.getEntity((Class) clazzAnnotation.value()); + if (otherEntity == null) { + //all types must be initialized by EntityInitializer + throw new IllegalStateException(ForeignKeyInitializer.class.getSimpleName() + ": Entity of type " + clazzAnnotation.value() + " does not exist"); +// EntityInitializer.initEntity(mb, (Class) clazzAnnotation.value(), f.getName()); +// otherEntity = mb.getEntity((Class) clazzAnnotation.value()); +// PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity.builder(mb)); + } + var primary = entityBuilder.getEntity().getPrimaryKey(); + if (primary == null) { + 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 otherFields = primary.getFields().stream() + .map(e -> { + //find list in other entity (N to N relation) + if (otherEntityF != entity) { //ignore on recursive models + var otherEntityListField = otherEntityF.getFields().stream() + .filter(oef -> Collection.class.isAssignableFrom(oef.getType()) + && oef.getField().getAnnotationsByType(Clazz.class).length > 0 + && oef.getField().getAnnotationsByType(Clazz.class)[0].value().getName().equals(entity.getTypeName())).findFirst(); + if (otherEntityListField.isPresent()) { + throw new ModelException("N to N relations need to explicitly defined via a mapping model (" + + otherEntityF.builder(mb).className() + "::" + otherEntityListField.get().getTypeName() + " and " + + entityBuilder.className() + "::" + f.getType().getName() + ")"); + } + } - //find objectId in other entity (1 to N relation) + //find object in other entity (1 to N relation) + var otherEntityObjectField = otherEntityF.getFields().stream().filter(oef -> oef.getTypeName().equals(entity.getTypeName())).findFirst(); + if (otherEntityObjectField.isPresent()) { + return new FieldSearchResult(otherEntityObjectField.get(), false); + } + + //find objectId in other entity (1 to N relation) // var idFieldName = entity.getType().getSimpleName().substring(0, 1).toLowerCase(Locale.ROOT) // + entity.getType().getSimpleName().substring(1) // + e.getName().substring(0, 1).toUpperCase(Locale.ROOT) // + e.getName().substring(1); - var idFieldName = f.getName() - + e.getName().substring(0, 1).toUpperCase(Locale.ROOT) - + e.getName().substring(1); - var otherEntityIdField = otherEntityF.getFields().stream().filter(oef -> oef.getName().equals(idFieldName)).findFirst(); - if (otherEntityIdField.isPresent()) { - return new FieldSearchResult(otherEntityIdField.get(), otherEntityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0); - } + var idFieldName = f.getName() + + e.getName().substring(0, 1).toUpperCase(Locale.ROOT) + + e.getName().substring(1); + var otherEntityIdField = otherEntityF.getFields().stream().filter(oef -> oef.getName().equals(idFieldName)).findFirst(); + if (otherEntityIdField.isPresent()) { + return new FieldSearchResult(otherEntityIdField.get(), otherEntityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0); + } - var field = new DbField<>(otherEntityF, e.getType(), null, idFieldName); - field = otherEntityF.addIfAbsent(field); - return new FieldSearchResult(field, true); - }) - .toList(); - if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) { - 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())) { - var otherEntity = mb.getEntity((Class) f.getType()); - if (otherEntity == null) { - EntityInitializer.initEntity(mb, (Class) f.getType(), f.getName()); - otherEntity = mb.getEntity((Class) f.getType()); - PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity); - } - var primary = otherEntity.getPrimaryKey(); - if (primary == null) { - throw new ModelException("Entity " + otherEntity.getType().getSimpleName() + " is missing a primary key and therefore cannot be referenced by " + entity.getType().getSimpleName()); - } - var otherEntityF = otherEntity; - var otherFields = primary.getFields().stream() - .map(otherPrimaryField -> { - //find list in other entity (N to 1 relation) - var entityListField = entity.getFields().stream() - .filter(oef -> Collection.class.isAssignableFrom(oef.getType()) - && oef.getField().getAnnotationsByType(Clazz.class).length > 0 - && oef.getField().getAnnotationsByType(Clazz.class)[0].value() == otherEntityF.getType()).toList(); -// if (entityListField.size() == 1) { -// return new FieldSearchResult(entityListField.get(0), true); -// } +// //add shadow field +// var entityField = new DbField<>(otherEntityF, f.getDeclaringClass(), null, f.getName()); +// entityField.setNotNull(true); +// entityField = otherEntityF.addIfAbsent(entityField); - //find object in other entity (1 to 1 relation) - var entityObjectFields = entity.getFields().stream().filter(oef -> oef.getType() == otherEntityF.getType()).toList(); + //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(); + if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) { + otherEntity.builder(mb) + .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)); + } + } + + 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) f.getType()); + if (otherEntity == null) { + //all types must be initialized by EntityInitializer + throw new IllegalStateException(ForeignKeyInitializer.class.getSimpleName() + ": Entity of type " + f.getType().getName() + " does not exist"); +// EntityInitializer.initEntity(mb, (Class) f.getType(), f.getName()); +// otherEntity = mb.getEntity((Class) f.getType()); +// PrimaryKeyInitializer.initPrimaryKeys(mb, otherEntity.builder(mb)); + } + var primary = otherEntity.getPrimaryKey(); + if (primary == null) { + 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 otherFields = primary.getFields().stream() + .map(otherPrimaryField -> { +// //find list in other entity (N to 1 relation) +// var entityListField = entity.getFields().stream() +// .filter(oef -> Collection.class.isAssignableFrom(oef.getType()) +// && oef.getField().getAnnotationsByType(Clazz.class).length > 0 +// && oef.getField().getAnnotationsByType(Clazz.class)[0].value().getName().equals(otherEntityF.getTypeName())).toList(); +//// if (entityListField.size() == 1) { +//// return new FieldSearchResult(entityListField.get(0), true); +//// } + + //find object in other entity (1 to 1 relation) +// var entityObjectFields = entity.getFields().stream().filter(oef -> oef.getTypeName().equals(otherEntityF.getTypeName())).toList(); // if (entityObjectField.isPresent()) { // return new FieldSearchResult(entityObjectField.get(), false); // } - //find objectId in other entity (1 to 1 relation) - var idFieldName = f.getName() - + otherPrimaryField.getName().substring(0, 1).toUpperCase(Locale.ROOT) - + otherPrimaryField.getName().substring(1); - var entityIdField = entity.getFields().stream().filter(oef -> oef.getName().equals(idFieldName)).findFirst(); - if (entityIdField.isPresent()) { - return new FieldSearchResult(entityIdField.get(), entityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0); - } + //find objectId in other entity (1 to 1 relation) + var idFieldName = f.getName() + + otherPrimaryField.getName().substring(0, 1).toUpperCase(Locale.ROOT) + + otherPrimaryField.getName().substring(1); + var entityIdField = entity.getFields().stream().filter(oef -> oef.getName().equals(idFieldName)).findFirst(); + if (entityIdField.isPresent()) { + return new FieldSearchResult(entityIdField.get(), entityIdField.get().getField().getAnnotationsByType(ForeignKey.class).length == 0); + } - var field = new DbField<>(entity, otherPrimaryField.getType(), null, idFieldName); - field = entity.addIfAbsent(field); - if (entityListField.size() == 1) { - field.setForeignKeyModelLink(entityListField.get(0)); - entityListField.get(0).setForeignKeyModelLink(field); - } else if (entityObjectFields.size() == 1) { - field.setForeignKeyModelLink(entityObjectFields.get(0)); - entityObjectFields.get(0).setForeignKeyModelLink(field); - } - return new FieldSearchResult(field, true); + var field = new DbField<>(entity, otherPrimaryField.getType(), null, idFieldName); + field.setExposingForeignKeyOf(entity.getField(f.getName())); + field = entity.addIfAbsent(field); +// if (entityListField.size() == 1) { +//// field.setForeignKeyObjectField(entityListField.get(0)); +//// entityListField.get(0).setForeignKeyObjectField(field); +// } else +// if (entityObjectFields.size() == 1) { +// field.setExposingForeignKeyOf(entityObjectFields.get(0)); +// entityObjectFields.get(0).setForeignKeyObjectField(field); +// } + 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)) - }) - .toList(); - if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) { - entity.addForeignKey(new ForeignKeyConstraint(entity, (List) otherFields.stream().map(FieldSearchResult::getField).toList(), - otherEntity, primary.getFields(), ForeignKeyConstraint.Action.RESTRICT, ForeignKeyConstraint.Action.CASCADE)); - } - } + }) + .toList(); + if (otherFields.stream().anyMatch(FieldSearchResult::isCreateForeignKey)) { + entityBuilder + .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)); } } diff --git a/src/main/java/jef/model/KeyBuilder.java b/src/main/java/jef/model/KeyBuilder.java new file mode 100644 index 0000000..3f46a02 --- /dev/null +++ b/src/main/java/jef/model/KeyBuilder.java @@ -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 { + private final ModelBuilder modelBuilder; + private final DbEntity entity; + private final List> fields; + + public ForeignKeyBuilder withOne(SerializableFunction 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 ForeignKeyBuilder 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 ForeignKeyBuilder withMany(SerializableFunction 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 ForeignKeyBuilder 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) 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 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); + } + } +} diff --git a/src/main/java/jef/model/ModelBuilder.java b/src/main/java/jef/model/ModelBuilder.java index 1aec282..f79588e 100644 --- a/src/main/java/jef/model/ModelBuilder.java +++ b/src/main/java/jef/model/ModelBuilder.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; public class ModelBuilder { private static final List annotationProcessors = new ArrayList<>(); @@ -48,6 +49,7 @@ public class ModelBuilder { var mb = new ModelBuilder(new ArrayList<>()); EntityInitializer.initEntities(mb, context); PrimaryKeyInitializer.initPrimaryKeys(mb); + ForeignKeyExposeInitializer.initForeignKeyExposures(mb); ForeignKeyInitializer.initForeignKeys(mb); for (AnnotationProcessor processor : annotationProcessors) { @@ -86,6 +88,10 @@ public class ModelBuilder { return Collections.unmodifiableList(entities); } + public List> 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. * @@ -117,9 +123,9 @@ public class ModelBuilder { * @param the type of model class * @return the DbEntity for the requested class or the newly created empty DbEntity if none existed. */ - public DbEntity getOrCreateEntity(Class clazz) { + public DbEntityBuilder entity(Class clazz) { Check.notNull(clazz, "clazz"); - return getOrCreateEntity(clazz.getName()); + return entity(clazz.getName()); } /** @@ -129,14 +135,14 @@ public class ModelBuilder { * @param the type of model class * @return the DbEntity for the requested class or the newly created empty DbEntity if none existed. */ - public DbEntity getOrCreateEntity(String typeName) { + public DbEntityBuilder entity(String typeName) { Check.notNull(typeName, "typeName"); var entity = (DbEntity) getEntity(typeName); if (entity == null) { entity = new DbEntity<>(typeName); entities.add(entity); } - return entity; + return new DbEntityBuilder<>(this, entity); } /** @@ -168,7 +174,7 @@ public class ModelBuilder { var old = this.entities.get(i); var entity = (DbEntity) new DbEntity(old.getTypeName()); entity.setName(old.getName()); - entity.setType((Class) old.getType()); + entity.setTypeName(old.getTypeName()); //add fields old.getFields().stream().map(e -> { @@ -183,9 +189,9 @@ public class ModelBuilder { .forEach(entity::addIfAbsent); //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 - 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()); diff --git a/src/main/java/jef/model/PrimaryKeyInitializer.java b/src/main/java/jef/model/PrimaryKeyInitializer.java index ad2c391..6cd40aa 100644 --- a/src/main/java/jef/model/PrimaryKeyInitializer.java +++ b/src/main/java/jef/model/PrimaryKeyInitializer.java @@ -2,22 +2,21 @@ package jef.model; import jef.model.annotations.Id; import jef.model.annotations.Transient; -import jef.model.constraints.PrimaryKeyConstraint; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.List; class PrimaryKeyInitializer { static void initPrimaryKeys(ModelBuilder mb) { - for (int i = 0; i < mb.getEntities().size(); i++) { - var entity = mb.getEntities().get(i); + var entities = mb.entities(); + for (int i = 0; i < entities.size(); i++) { + var entity = entities.get(i); initPrimaryKeys(mb, entity); } } - static void initPrimaryKeys(ModelBuilder mb, DbEntity entity) { - var fields = ReflectionUtil.getFieldsRecursive(entity.getType()); + static void initPrimaryKeys(ModelBuilder mb, DbEntityBuilder entity) { + var fields = ReflectionUtil.getFieldsRecursive(entity.type().get()); var idFields = new ArrayList(); //search for fields with @Id annotation @@ -56,8 +55,8 @@ class PrimaryKeyInitializer { } if (!idFields.isEmpty()) { - var dbfields = idFields.stream().map(entity::getField).toList(); - entity.setPrimaryKey(new PrimaryKeyConstraint(entity, (List) dbfields)); + var dbfields = idFields.stream().map(e -> entity.field(e).getField().getName()).toList(); + entity.hasOne(dbfields.toArray(String[]::new)).isPrimaryKey(true); } } } diff --git a/src/main/java/jef/model/annotations/processors/ForeignKeyProcessor.java b/src/main/java/jef/model/annotations/processors/ForeignKeyProcessor.java index ea2a67c..536736e 100644 --- a/src/main/java/jef/model/annotations/processors/ForeignKeyProcessor.java +++ b/src/main/java/jef/model/annotations/processors/ForeignKeyProcessor.java @@ -1,7 +1,6 @@ package jef.model.annotations.processors; -import jef.model.DbEntity; -import jef.model.DbField; +import jef.model.DbEntityBuilder; import jef.model.ModelBuilder; import jef.model.ModelException; import jef.model.annotations.ForeignKey; @@ -22,61 +21,62 @@ public class ForeignKeyProcessor implements AnnotationProcessor { @Override public void apply(ModelBuilder mb) { - for (DbEntity entity : mb.getEntities()) { + for (var entity : mb.entities()) { //annotation on fields - for (DbField field : entity.getFields()) { - if (field.isModelField() && field.getField().getAnnotationsByType(ForeignKey.class).length > 0) { - var anno = field.getField().getAnnotationsByType(ForeignKey.class)[0]; + for (var field : entity.fields()) { + if (field.getField().isModelField() && field.getField().getField().getAnnotationsByType(ForeignKey.class).length > 0) { + var anno = field.getField().getField().getAnnotationsByType(ForeignKey.class)[0]; // var dbfield = entity.getField(field.getField()); // if (dbfield == null) { // throw new ModelException("DbField with field " + field.getName() + " not found in " + entity.getType().getSimpleName()); // } 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) { 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; try { - refClassField = getField(refEntity, anno.getterOrField()); + refClassField = getField(refEntityBuilder, anno.getterOrField()); } catch (ModelException e) { 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); if (exposeForeignKey) { - field.setForeignKeyModelLink(refField); - refField.setForeignKeyModelLink(field); +// field.getField().setExposingForeignKeyOf(refField); + refField.setExposingForeignKeyOf(field.getField()); continue; } //check for primary key 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() - + " 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 if (!refEntity.getPrimaryKey().getFields().equals(List.of(refField))) { - throw new ModelException(refEntity.getType().getSimpleName() + "::" + refField.getField().getName() - + " is not equal to the primary key of entity " + refEntity.getType().getSimpleName() + throw new ModelException(refEntityBuilder.className() + "::" + refField.getField().getName() + + " is not equal to the primary key of entity " + refEntityBuilder.className() + " (" + refEntity.getPrimaryKey().getFields().stream().map(e -> e.getField().getName()).collect(Collectors.joining(", ")) + ")" + " 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 entity, String fieldOrGetter) { + private Field getField(DbEntityBuilder entity, String fieldOrGetter) { Method getter = null; try { - getter = entity.getType().getDeclaredMethod(fieldOrGetter); + getter = entity.type().get().getDeclaredMethod(fieldOrGetter); } catch (NoSuchMethodException e) { } @@ -84,15 +84,15 @@ public class ForeignKeyProcessor implements AnnotationProcessor { try { 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 - field = entity.getType().getDeclaredField(name); + field = entity.type().get().getDeclaredField(name); } else { - field = entity.getType().getDeclaredField(fieldOrGetter); + field = entity.type().get().getDeclaredField(fieldOrGetter); } } catch (NoSuchFieldException e) { } 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; } diff --git a/src/main/java/jef/model/annotations/processors/IndexProcessor.java b/src/main/java/jef/model/annotations/processors/IndexProcessor.java index a6ae043..b487bc4 100644 --- a/src/main/java/jef/model/annotations/processors/IndexProcessor.java +++ b/src/main/java/jef/model/annotations/processors/IndexProcessor.java @@ -1,7 +1,9 @@ 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.Index; import jef.model.constraints.IndexConstraint; import jef.serializable.SerializableObject; @@ -17,8 +19,8 @@ public class IndexProcessor extends KeyProcessorBase { } @Override - protected IndexConstraint initConstraint(DbEntity entity, List> fields) { - return new IndexConstraint(entity, fields); + protected IndexConstraint initConstraint(DbEntityBuilder entity, List> fields) { + return new IndexConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList()); } @Override diff --git a/src/main/java/jef/model/annotations/processors/KeyProcessor.java b/src/main/java/jef/model/annotations/processors/KeyProcessor.java index f207535..83c00ef 100644 --- a/src/main/java/jef/model/annotations/processors/KeyProcessor.java +++ b/src/main/java/jef/model/annotations/processors/KeyProcessor.java @@ -1,7 +1,9 @@ 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.Key; import jef.model.constraints.KeyConstraint; import jef.serializable.SerializableObject; @@ -17,8 +19,8 @@ public class KeyProcessor extends KeyProcessorBase { } @Override - protected KeyConstraint initConstraint(DbEntity entity, List> fields) { - return new KeyConstraint(entity, fields); + protected KeyConstraint initConstraint(DbEntityBuilder entity, List> fields) { + return new KeyConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList()); } @Override diff --git a/src/main/java/jef/model/annotations/processors/KeyProcessorBase.java b/src/main/java/jef/model/annotations/processors/KeyProcessorBase.java index 1d26114..d1dcc43 100644 --- a/src/main/java/jef/model/annotations/processors/KeyProcessorBase.java +++ b/src/main/java/jef/model/annotations/processors/KeyProcessorBase.java @@ -1,7 +1,8 @@ package jef.model.annotations.processors; -import jef.model.DbEntity; +import jef.model.DbEntityBuilder; import jef.model.DbField; +import jef.model.DbFieldBuilder; import jef.model.ModelBuilder; import jef.model.ModelException; import jef.serializable.SerializableObject; @@ -21,7 +22,7 @@ abstract class KeyProcessorBase implements AnnotationPr this.annotationClass = annotationClass; } - protected abstract K initConstraint(DbEntity entity, List> fields); + protected abstract K initConstraint(DbEntityBuilder entity, List> fields); protected abstract void addConstraint(K constr); @@ -29,16 +30,16 @@ abstract class KeyProcessorBase implements AnnotationPr @Override public void apply(ModelBuilder mb) { - for (DbEntity entity : mb.getEntities()) { + for (DbEntityBuilder entity : mb.entities()) { //class annotation - var classAnno = entity.getType().getAnnotationsByType(annotationClass); + var classAnno = entity.type().get().getAnnotationsByType(annotationClass); for (T t : classAnno) { var classFields = Arrays.stream(getGettersOrFields(t)) .map(name -> getField(entity, name)) .map(field -> { - var dbfield = (DbField) entity.getField(field); + var dbfield = (DbFieldBuilder) entity.field(field); 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; }).toList(); @@ -46,11 +47,11 @@ abstract class KeyProcessorBase implements AnnotationPr } //annotation on fields - for (DbField field : entity.getFields()) { - if (field.getField() != null && field.getField().getAnnotationsByType(annotationClass).length > 0) { - var dbfield = entity.getField(field.getField()); + for (DbFieldBuilder field : entity.fields()) { + if (field.getField().getField() != null && field.getField().getField().getAnnotationsByType(annotationClass).length > 0) { + var dbfield = entity.field(field.getField().getField()); 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))); } @@ -58,26 +59,26 @@ abstract class KeyProcessorBase implements AnnotationPr } } - private Field getField(DbEntity entity, String fieldOrGetter) { + private Field getField(DbEntityBuilder entity, String fieldOrGetter) { Method getter = null; try { - getter = entity.getType().getDeclaredMethod(fieldOrGetter); + getter = entity.type().get().getDeclaredMethod(fieldOrGetter); } catch (NoSuchMethodException e) { } Field field = null; try { 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 - field = entity.getType().getDeclaredField(name); + var name = getter.getName().substring(3, 4).toLowerCase(Locale.ROOT) + getter.getName().substring(4); //TODO HACK + field = entity.type().get().getDeclaredField(name); } else { - field = entity.getType().getDeclaredField(fieldOrGetter); + field = entity.type().get().getDeclaredField(fieldOrGetter); } } catch (NoSuchFieldException e) { } 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; } diff --git a/src/main/java/jef/model/annotations/processors/UniqueProcessor.java b/src/main/java/jef/model/annotations/processors/UniqueProcessor.java index 20a4bf4..95757ef 100644 --- a/src/main/java/jef/model/annotations/processors/UniqueProcessor.java +++ b/src/main/java/jef/model/annotations/processors/UniqueProcessor.java @@ -1,13 +1,14 @@ package jef.model.annotations.processors; -import jef.model.DbEntity; -import jef.model.DbField; +import jef.model.DbEntityBuilder; +import jef.model.DbFieldBuilder; import jef.model.annotations.Unique; import jef.model.constraints.UniqueKeyConstraint; import jef.serializable.SerializableObject; import java.lang.annotation.Annotation; import java.util.List; +import java.util.stream.Collectors; public class UniqueProcessor extends KeyProcessorBase { public static final UniqueProcessor INSTANCE = new UniqueProcessor(); @@ -17,8 +18,8 @@ public class UniqueProcessor extends KeyProcessorBase entity, List> fields) { - return new UniqueKeyConstraint(entity, fields); + protected UniqueKeyConstraint initConstraint(DbEntityBuilder entity, List> fields) { + return new UniqueKeyConstraint(entity.getEntity(), (List)fields.stream().map(DbFieldBuilder::getField).toList()); } @Override diff --git a/src/main/java/jef/model/constraints/ForeignKeyConstraint.java b/src/main/java/jef/model/constraints/ForeignKeyConstraint.java index 3b38922..566737b 100644 --- a/src/main/java/jef/model/constraints/ForeignKeyConstraint.java +++ b/src/main/java/jef/model/constraints/ForeignKeyConstraint.java @@ -2,25 +2,28 @@ package jef.model.constraints; import jef.model.DbEntity; import jef.model.DbField; +import jef.util.Check; import lombok.Getter; +import lombok.Setter; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @Getter +@Setter public class ForeignKeyConstraint extends ConstraintBase { private final DbEntity referencedEntity; private final List> referencedFields; - private final Action onUpdate; - private final Action onDelete; + private Action onUpdate; + private Action onDelete; public ForeignKeyConstraint(DbEntity entity, List> fields, DbEntity referencedEntity, List> referencedFields, Action onUpdate, Action onDelete) { super(entity, fields); - this.referencedEntity = referencedEntity; - this.referencedFields = referencedFields; - this.onUpdate = onUpdate; - this.onDelete = onDelete; + this.referencedEntity = Check.notNull(referencedEntity, "referencedEntity"); + this.referencedFields = Check.notNull(referencedFields, "referencedFields"); + this.onUpdate = Check.notNull(onUpdate, "onUpdate"); + this.onDelete = Check.notNull(onDelete, "onDelete"); } @Override diff --git a/src/main/java/jef/model/migration/creator/ModelBuilderGenerator.java b/src/main/java/jef/model/migration/creator/ModelBuilderGenerator.java index 342e0e6..d9a7875 100644 --- a/src/main/java/jef/model/migration/creator/ModelBuilderGenerator.java +++ b/src/main/java/jef/model/migration/creator/ModelBuilderGenerator.java @@ -2,6 +2,7 @@ package jef.model.migration.creator; import jef.model.DbContext; import jef.model.DbEntity; +import jef.model.DbEntityBuilder; import jef.model.DbField; import jef.model.ModelBuilder; import jef.model.constraints.ForeignKeyConstraint; @@ -40,29 +41,29 @@ public class ModelBuilderGenerator { var indent = " "; imports.add(DbContext.class); imports.add(ModelBuilder.class); - imports.add(DbEntity.class); + imports.add(DbEntityBuilder.class); var java = "" + "public class " + name + "Snapshot extends DbContext {\n" + " @Override\n" + " public void onModelCreate(ModelBuilder mb) {\n" - + indent + "DbEntity entity;\n" - + indent + "DbEntity referencedEntity;\n"; + + indent + "DbEntityBuilder entity;\n" + + indent + "DbEntityBuilder referencedEntity;\n"; for (DbEntity entity : mb.getEntities()) { - java += indent + "entity = mb.getOrCreateEntity(\"" + entity.getTypeName() + "\");\n" - + indent + "entity.setName(\"" + entity.getName() + "\");\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .name(\"" + entity.getName() + "\");\n"; for (DbField field : entity.getFields()) { - java += indent + "entity.getOrCreateField(\"" + field.getName() + "\", \"" + field.getTypeName() + "\")" - + (field.isNotNull() ? "\n" + indent + " .setNotNull(true)" : "") - + "\n" + indent + " .setDatabaseField(" + field.isDatabaseField() + ")" - + "\n" + indent + " .setModelField(" + field.isModelField() + ")" - + ";\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .field(\"" + field.getName() + "\", \"" + field.getTypeName() + "\")" + + (field.isNotNull() ? "\n" + indent + " .isNotNull()" : "") + + "\n" + indent + " .isDatabaseField(" + field.isDatabaseField() + ")" + + "\n" + indent + " .isModelField(" + field.isModelField() + ");"; } if (entity.getPrimaryKey() != null) { imports.add(List.class); imports.add(PrimaryKeyConstraint.class); - java += indent + "entity.setPrimaryKey(new PrimaryKeyConstraint(entity, List.of(\n" - + indent + " " + entity.getPrimaryKey().getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n ")) + "\n" - + indent + " )));\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .hasOne(" + entity.getPrimaryKey().getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n" + + indent + " .isPrimaryKey();\n"; } java += "\n"; } @@ -71,40 +72,29 @@ public class ModelBuilderGenerator { continue; } - java += indent + "entity = mb.getOrCreateEntity(\"" + entity.getTypeName() + "\");\n"; for (ForeignKeyConstraint foreignKey : entity.getForeignKeys()) { - imports.add(List.class); imports.add(ForeignKeyConstraint.class); - imports.add(ForeignKeyConstraint.Action.class); - java += indent + "referencedEntity = mb.getEntity(\"" + foreignKey.getReferencedEntity().getTypeName() + "\");\n" - + indent + "entity.addForeignKey(new ForeignKeyConstraint(entity, List.of(\n" - + indent + " " + foreignKey.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n" - + indent + " ),\n" - + indent + " referencedEntity, List.of(\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"; + //TODO hasOne/hasMany/withOne/WithMany + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .hasOne(" + foreignKey.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", " + indent)) + ")\n" + + indent + " .withOne(\"" + foreignKey.getReferencedEntity().getTypeName() + "\", " + foreignKey.getReferencedFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n" + + indent + " .onUpdate(ForeignKeyConstraint.Action." + foreignKey.getOnUpdate().name() + ")\n" + + indent + " .onDelete(ForeignKeyConstraint.Action." + foreignKey.getOnDelete().name() + ");\n"; } for (UniqueKeyConstraint uniqueKey : entity.getUniqueKeys()) { - imports.add(List.class); - imports.add(UniqueKeyConstraint.class); - java += indent + "entity.addUniqueKey(new UniqueKeyConstraint(entity, List.of(\n" - + indent + " " + uniqueKey.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n" - + indent + " )));\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .hasOne(" + uniqueKey.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n" + + indent + " .isUnique();\n"; } for (KeyConstraint key : entity.getKeys()) { - imports.add(List.class); - imports.add(KeyConstraint.class); - java += indent + "entity.addKey(new KeyConstraint(entity, List.of(\n" - + indent + " " + key.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n" - + indent + " )));\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .hasOne(" + key.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n" + + indent + " .isKey();\n"; } for (IndexConstraint index : entity.getIndexes()) { - imports.add(List.class); - imports.add(IndexConstraint.class); - java += indent + "entity.addIndex(new IndexConstraint(entity, List.of(\n" - + indent + " " + index.getFields().stream().map(f -> "entity.getField(\"" + f.getName() + "\")").collect(Collectors.joining(",\n " + indent)) + "\n" - + indent + " )));\n"; + java += indent + "mb.entity(\"" + entity.getTypeName() + "\")\n" + + indent + " .hasOne(" + index.getFields().stream().map(f -> "\"" + f.getName() + "\"").collect(Collectors.joining(", ")) + ")\n" + + indent + " .isIndex();\n"; } } java += " }\n" diff --git a/src/main/java/jef/operations/FilterOp.java b/src/main/java/jef/operations/FilterOp.java index e7c61ab..6abc68b 100644 --- a/src/main/java/jef/operations/FilterOp.java +++ b/src/main/java/jef/operations/FilterOp.java @@ -2,15 +2,11 @@ package jef.operations; import jef.Queryable; import jef.asm.AsmParseException; -import jef.asm.AsmParser; import jef.asm.OptimizedAsmParser; import jef.expressions.Expression; import jef.expressions.SelectExpression; import jef.expressions.WhereExpression; -import jef.expressions.modifier.ExpressionOptimizerBottomUp; -import jef.expressions.modifier.IConst0Fixer; import jef.expressions.modifier.TableAliasInjector; -import jef.expressions.modifier.TernaryRewriter; import jef.expressions.selectable.DatabaseSelectAllExpression; import jef.serializable.SerializablePredicate; @@ -31,18 +27,13 @@ public class FilterOp implements Queryable, Operation var parser = new OptimizedAsmParser(predicate); Expression expr; try { - expr = parser.parse(); + expr = parser.parse().getExpression(); } catch (AsmParseException e) { throw new RuntimeException(e); } expr = new TableAliasInjector(getTableAlias()).modify(expr);//TODO this does not work together with expression optimization 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 diff --git a/src/main/java/jef/operations/SortOp.java b/src/main/java/jef/operations/SortOp.java index 2eddab7..0bf7f54 100644 --- a/src/main/java/jef/operations/SortOp.java +++ b/src/main/java/jef/operations/SortOp.java @@ -61,7 +61,7 @@ public class SortOp implements Queryable { var parser = new AsmParser(fieldSelector); Expression expr; try { - expr = parser.parse(); + expr = parser.parse().getExpression(); } catch (AsmParseException e) { throw new RuntimeException(e); } diff --git a/src/main/java/jef/util/Log.java b/src/main/java/jef/util/Log.java new file mode 100644 index 0000000..c807565 --- /dev/null +++ b/src/main/java/jef/util/Log.java @@ -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() { + + } +} diff --git a/src/test/java/jef/asm/OptimizedAsmParserTest.java b/src/test/java/jef/asm/OptimizedAsmParserTest.java index 8b513d6..eb20944 100644 --- a/src/test/java/jef/asm/OptimizedAsmParserTest.java +++ b/src/test/java/jef/asm/OptimizedAsmParserTest.java @@ -15,38 +15,38 @@ public class OptimizedAsmParserTest { public void testTrue() throws AsmParseException { 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); } @Test public void testCompareWithEntityMember() throws AsmParseException { 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); - 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); - 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); - 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); - 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); - 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); - 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); } @@ -54,12 +54,12 @@ public class OptimizedAsmParserTest { public void testContainsWithEntityMember() throws AsmParseException { var s = List.of(1, 3); 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); //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); } @@ -67,23 +67,23 @@ public class OptimizedAsmParserTest { public void testComplexExpression() throws AsmParseException { String act; 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); - 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); - 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); - 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); - 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); } @@ -91,7 +91,7 @@ public class OptimizedAsmParserTest { public void testComplexExpressionMixedAndOr() throws AsmParseException { String act; 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); @@ -105,15 +105,15 @@ public class OptimizedAsmParserTest { public void testObject() throws AsmParseException { String act; 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); - 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); - 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); } @@ -121,41 +121,41 @@ public class OptimizedAsmParserTest { public void testFloatingPoint() throws AsmParseException { String act; 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); - 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); - 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); } @Test public void testIDFLConst() throws AsmParseException { 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); - 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); - 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); - 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); } @Test public void testMemberViaGetter() throws AsmParseException { 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); } diff --git a/src/test/java/jef/model/DbContextSimpleTest.java b/src/test/java/jef/model/DbContextSimpleTest.java index 2716b46..7554d54 100644 --- a/src/test/java/jef/model/DbContextSimpleTest.java +++ b/src/test/java/jef/model/DbContextSimpleTest.java @@ -38,6 +38,14 @@ class DbContextSimpleTest { @Clazz(TestClass.class) private DbSet objects1; + + @Override + public void onModelCreate(ModelBuilder mb) { + super.onModelCreate(mb); + mb.entity(TestClass.class) + .hasOne(e -> e.i) + .isUnique(true); + } } @Getter diff --git a/src/test/java/jef/model/EntityInitializerMultiple1ToNRelationTest.java b/src/test/java/jef/model/EntityInitializerMultiple1ToNRelationTest.java index 7cb286a..3f53eba 100644 --- a/src/test/java/jef/model/EntityInitializerMultiple1ToNRelationTest.java +++ b/src/test/java/jef/model/EntityInitializerMultiple1ToNRelationTest.java @@ -16,7 +16,7 @@ import static org.junit.jupiter.api.Assertions.assertThrowsExactly; class EntityInitializerMultiple1ToNRelationTest { @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()); } diff --git a/src/test/java/jef/model/ForeignKeyInitializerNestedList2LayerTest.java b/src/test/java/jef/model/ForeignKeyInitializerNestedList2LayerTest.java index 9c89bae..cd41091 100644 --- a/src/test/java/jef/model/ForeignKeyInitializerNestedList2LayerTest.java +++ b/src/test/java/jef/model/ForeignKeyInitializerNestedList2LayerTest.java @@ -19,8 +19,8 @@ class ForeignKeyInitializerNestedList2LayerTest { assertEquals(3, mb.getEntities().size()); assertEquals("objects1", mb.getEntity(TestClass3.class).getName()); - assertEquals("nested2", mb.getEntity(TestClass2.class).getName()); - assertEquals("nested", mb.getEntity(TestClass.class).getName()); + assertEquals("TestClass2", mb.getEntity(TestClass2.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(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))); diff --git a/src/test/java/jef/model/ForeignKeyInitializerNestedListSimpleTest.java b/src/test/java/jef/model/ForeignKeyInitializerNestedListSimpleTest.java index 05a594e..ed1b07e 100644 --- a/src/test/java/jef/model/ForeignKeyInitializerNestedListSimpleTest.java +++ b/src/test/java/jef/model/ForeignKeyInitializerNestedListSimpleTest.java @@ -19,7 +19,7 @@ class ForeignKeyInitializerNestedListSimpleTest { assertEquals(2, mb.getEntities().size()); 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(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))); diff --git a/src/test/java/jef/model/ForeignKeyInitializerNestedObject2LayerTest.java b/src/test/java/jef/model/ForeignKeyInitializerNestedObject2LayerTest.java index f52db24..1ad7cb3 100644 --- a/src/test/java/jef/model/ForeignKeyInitializerNestedObject2LayerTest.java +++ b/src/test/java/jef/model/ForeignKeyInitializerNestedObject2LayerTest.java @@ -17,8 +17,8 @@ class ForeignKeyInitializerNestedObject2LayerTest { assertEquals(3, mb.getEntities().size()); assertEquals("objects1", mb.getEntity(TestClass3.class).getName()); - assertEquals("nested2", mb.getEntity(TestClass2.class).getName()); - assertEquals("nested", mb.getEntity(TestClass.class).getName()); + assertEquals("TestClass2", mb.getEntity(TestClass2.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(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))); diff --git a/src/test/java/jef/model/ForeignKeyInitializerNestedObjectSimpleTest.java b/src/test/java/jef/model/ForeignKeyInitializerNestedObjectSimpleTest.java index e3a6af2..043670a 100644 --- a/src/test/java/jef/model/ForeignKeyInitializerNestedObjectSimpleTest.java +++ b/src/test/java/jef/model/ForeignKeyInitializerNestedObjectSimpleTest.java @@ -17,7 +17,7 @@ class ForeignKeyInitializerNestedObjectSimpleTest { assertEquals(2, mb.getEntities().size()); 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(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))); diff --git a/src/test/java/jef/model/ModelBuilderCloneTest.java b/src/test/java/jef/model/ModelBuilderCloneTest.java index 510dc7e..a2c02c0 100644 --- a/src/test/java/jef/model/ModelBuilderCloneTest.java +++ b/src/test/java/jef/model/ModelBuilderCloneTest.java @@ -102,11 +102,6 @@ public class ModelBuilderCloneTest { System.out.println("ex: " + o.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())) { System.out.println("names differ: entity " + o.getName()); System.out.println("ex: " + o.getName()); @@ -202,11 +197,11 @@ public class ModelBuilderCloneTest { System.out.println("ex: " + of.getField()); System.out.println("ac: " + cf.getField()); } - if (!Objects.equals(of.getForeignKeyModelLink() == null ? null : of.getForeignKeyModelLink().getName(), - cf.getForeignKeyModelLink() == null ? null : cf.getForeignKeyModelLink().getName())) { + if (!Objects.equals(of.getExposingForeignKeyOf() == null ? null : of.getExposingForeignKeyOf().getName(), + cf.getExposingForeignKeyOf() == null ? null : cf.getExposingForeignKeyOf().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("ac: " + (cf.getForeignKeyModelLink() == null ? null : cf.getForeignKeyModelLink().getName())); + System.out.println("ex: " + (of.getExposingForeignKeyOf() == null ? null : of.getExposingForeignKeyOf().getName())); + System.out.println("ac: " + (cf.getExposingForeignKeyOf() == null ? null : cf.getExposingForeignKeyOf().getName())); } if (!of.getName().equals(cf.getName())) { System.out.println("names differ: entity " + o.getName() + ", field " + of.getName()); diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java index 4c05485..466ede0 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorAddEntityTest.java @@ -26,10 +26,10 @@ public class MigrationCreatorAddEntityTest extends MigrationCreatorTestBase { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); var ent = to.entity("AddedEntity"); - ent.getOrCreateField("id", int.class.getName()); - ent.getOrCreateField("addedField", int.class.getName()); - ent.setPrimaryKey(new PrimaryKeyConstraint(ent, List.of(ent.getField("id")))); - ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("addedField")), ent, List.of(ent.getField("id")), ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE)); + ent.field("id", int.class.getName()); + ent.field("addedField", int.class.getName()); + to.getEntity("AddedEntity").setPrimaryKey(new PrimaryKeyConstraint(to.getEntity("AddedEntity"), List.of(to.getEntity("AddedEntity").getField("id")))); + 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 res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorAddForeignKeyTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorAddForeignKeyTest.java index ff47bf1..9b96948 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorAddForeignKeyTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorAddForeignKeyTest.java @@ -16,7 +16,7 @@ import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase{ +public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase { @Test public void test() { var from = ModelBuilder.from(Ctx.class); @@ -39,8 +39,8 @@ public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase assertEquals(1, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddForeignKeyOperation o - && o.getTable().equals("nested") - && o.getReferencedTable().equals("nested") + && o.getTable().equals("TestClass") + && o.getReferencedTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i2") && o.getReferencedFields().size() == 1 @@ -52,8 +52,8 @@ public class MigrationCreatorAddForeignKeyTest extends MigrationCreatorTestBase assertEquals(1, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("FK_nested_nested_i2")) + && o.getTable().equals("TestClass") + && o.getName().equals("FK_TestClass_TestClass_i2")) .count()); } diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorAddIndexTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorAddIndexTest.java index 91955e0..f77a59b 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorAddIndexTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorAddIndexTest.java @@ -20,8 +20,8 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{ public void test() { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); - var ent = to.getEntity(TestClass.class); - ent.getField("d").setIndex(true); + var ent = to.entity(TestClass.class); + ent.field("d", double.class.getName()).isIndex(true); var mc = new MigrationCreator(); var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { @@ -38,7 +38,7 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddIndexOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("d")) .count()); @@ -48,8 +48,8 @@ public class MigrationCreatorAddIndexTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("I_nested_d")) + && o.getTable().equals("TestClass") + && o.getName().equals("I_TestClass_d")) .count()); } diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorAddKeyTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorAddKeyTest.java index c163ff0..d251c9e 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorAddKeyTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorAddKeyTest.java @@ -20,8 +20,8 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{ public void test() { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); - var ent = to.getEntity(TestClass.class); - ent.getField("d").setKey(true); + var ent = to.entity(TestClass.class); + ent.field("d", double.class.getName()).isKey(true); var mc = new MigrationCreator(); var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { @@ -38,7 +38,7 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("d")) .count()); @@ -48,8 +48,8 @@ public class MigrationCreatorAddKeyTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("K_nested_d")) + && o.getTable().equals("TestClass") + && o.getName().equals("K_TestClass_d")) .count()); } diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorAddUniqueTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorAddUniqueTest.java index 8e7f0b3..0c3ddbb 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorAddUniqueTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorAddUniqueTest.java @@ -20,8 +20,8 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{ public void test() { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); - var ent = to.getEntity(TestClass.class); - ent.getField("d").setUnique(true); + var ent = to.entity(TestClass.class); + ent.field("d", double.class.getName()).isUnique(true); var mc = new MigrationCreator(); var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { @@ -38,7 +38,7 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddUniqueKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("d")) .count()); @@ -48,8 +48,8 @@ public class MigrationCreatorAddUniqueTest extends MigrationCreatorTestBase{ assertEquals(1, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("U_nested_d")) + && o.getTable().equals("TestClass") + && o.getName().equals("U_TestClass_d")) .count()); } diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java index 2baa042..5affeb4 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorInitialMigrationTest.java @@ -45,7 +45,7 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddTableOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && 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("f")).count() == 1 @@ -62,13 +62,13 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddForeignKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getReferencedTable().equals("objects1") && o.getFields().size() == 1 && o.getFields().get(0).equals("nestedI") @@ -81,12 +81,12 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa assertEquals(5, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("FK_nested_objects1_nestedI")) + && o.getTable().equals("TestClass") + && o.getName().equals("FK_TestClass_objects1_nestedI")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getName().equals("PRIMARY")) .count()); assertEquals(1, res.getStepsDown().stream() @@ -97,7 +97,7 @@ public class MigrationCreatorInitialMigrationTest extends MigrationCreatorTestBa assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropTableOperation o - && o.getTable().equals("nested")) + && o.getTable().equals("TestClass")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropTableOperation o diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameEntityTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameEntityTest.java index b9af916..c3e0a98 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameEntityTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameEntityTest.java @@ -22,8 +22,8 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase { public void test() { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); - var ent = to.getEntity(TestClass.class); - ent.setName("d2"); + var ent = to.entity(TestClass.class); + ent.name("d2"); var mc = new MigrationCreator(); var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { @@ -40,17 +40,17 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase { assertEquals(5, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("FK_nested_objects1_nestedI")) + && o.getTable().equals("TestClass") + && o.getName().equals("FK_TestClass_objects1_nestedI")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getName().equals("PRIMARY")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof RenameTableOperation o - && o.getOldName().equals("nested") + && o.getOldName().equals("TestClass") && o.getNewName().equals("d2")) .count()); assertEquals(1, res.getStepsUp().stream() @@ -85,17 +85,17 @@ public class MigrationCreatorRenameEntityTest extends MigrationCreatorTestBase { assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof RenameTableOperation o && o.getOldName().equals("d2") - && o.getNewName().equals("nested")) + && o.getNewName().equals("TestClass")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddForeignKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getReferencedTable().equals("objects1") && o.getFields().size() == 1 && o.getFields().get(0).equals("nestedI") diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldConstraintsTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldConstraintsTest.java index a30c9f4..3b55355 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldConstraintsTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldConstraintsTest.java @@ -46,45 +46,45 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator assertEquals(11, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("FK_nested_nested_iFk")) + && o.getTable().equals("TestClass") + && o.getName().equals("FK_TestClass_TestClass_iFk")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getName().equals("PRIMARY")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("U_nested_i")) + && o.getTable().equals("TestClass") + && o.getName().equals("U_TestClass_i")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("K_nested_i")) + && o.getTable().equals("TestClass") + && o.getName().equals("K_TestClass_i")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("I_nested_i")) + && o.getTable().equals("TestClass") + && o.getName().equals("I_TestClass_i")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof RenameFieldOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getOldName().equals("i") && o.getNewName().equals("i2")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i2")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddForeignKeyOperation o - && o.getTable().equals("nested") - && o.getReferencedTable().equals("nested") + && o.getTable().equals("TestClass") + && o.getReferencedTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("iFk") && o.getReferencedFields().size() == 1 @@ -92,19 +92,19 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddUniqueKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i2")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i2")) .count()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof AddIndexOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i2")) .count()); @@ -114,45 +114,45 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator assertEquals(11, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("FK_nested_nested_iFk")) + && o.getTable().equals("TestClass") + && o.getName().equals("FK_TestClass_TestClass_iFk")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getName().equals("PRIMARY")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("U_nested_i2")) + && o.getTable().equals("TestClass") + && o.getName().equals("U_TestClass_i2")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("K_nested_i2")) + && o.getTable().equals("TestClass") + && o.getName().equals("K_TestClass_i2")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof DropConstraintOperation o - && o.getTable().equals("nested") - && o.getName().equals("I_nested_i2")) + && o.getTable().equals("TestClass") + && o.getName().equals("I_TestClass_i2")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof RenameFieldOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getOldName().equals("i2") && o.getNewName().equals("i")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddPrimaryKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddForeignKeyOperation o - && o.getTable().equals("nested") - && o.getReferencedTable().equals("nested") + && o.getTable().equals("TestClass") + && o.getReferencedTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("iFk") && o.getReferencedFields().size() == 1 @@ -160,19 +160,19 @@ public class MigrationCreatorRenameFieldConstraintsTest extends MigrationCreator .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddUniqueKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddKeyOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof AddIndexOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getFields().size() == 1 && o.getFields().get(0).equals("i")) .count()); diff --git a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldTest.java b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldTest.java index 48f8bea..db8abde 100644 --- a/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldTest.java +++ b/src/test/java/jef/model/migration/creator/MigrationCreatorRenameFieldTest.java @@ -19,8 +19,8 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase { public void test() { var from = ModelBuilder.from(Ctx.class); var to = ModelBuilder.from(Ctx.class); - var ent = to.getEntity(TestClass.class); - ent.getField("d").setName("d2"); + var ent = to.entity(TestClass.class); + ent.field("d", double.class.getName()).name("d2"); var mc = new MigrationCreator(); var res = mc.createMigration(from, to, "SomeMigration", "test", new ModelBuilderGenerator(from, "Current", "test").generate().getJava()); try { @@ -37,7 +37,7 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase { assertEquals(1, res.getStepsUp().size()); assertEquals(1, res.getStepsUp().stream() .filter(e -> e instanceof RenameFieldOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getOldName().equals("d") && o.getNewName().equals("d2")) .count()); @@ -47,7 +47,7 @@ public class MigrationCreatorRenameFieldTest extends MigrationCreatorTestBase { assertEquals(1, res.getStepsDown().size()); assertEquals(1, res.getStepsDown().stream() .filter(e -> e instanceof RenameFieldOperation o - && o.getTable().equals("nested") + && o.getTable().equals("TestClass") && o.getOldName().equals("d2") && o.getNewName().equals("d")) .count()); diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddEntityTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddEntityTest.java index 439e064..72a38d0 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddEntityTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddEntityTest.java @@ -24,22 +24,22 @@ class ModelChangeDetectorAddEntityTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); mb.entity("TestClass2"); - mb.entity("TestClass2").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass2").field("i2", int.class.getName()) + .isNotNull(true); mb.entity("TestClass3"); - mb.entity("TestClass3").getOrCreateField("i3", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass3").field("i3", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddFieldTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddFieldTest.java index 4674068..88ac220 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddFieldTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddFieldTest.java @@ -24,20 +24,20 @@ class ModelChangeDetectorAddFieldTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i3", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i3", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddForeignKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddForeignKeyTest.java index cbb8a3f..49d76ee 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddForeignKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddForeignKeyTest.java @@ -26,23 +26,23 @@ class ModelChangeDetectorAddForeignKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); var ent = mb.entity("TestClass"); - ent.getOrCreateField("i", int.class.getName()) - .setNotNull(true); - ent.getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("i2")), - ent, List.of(ent.getField("i")), - ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE)); + ent.field("i", int.class.getName()) + .isNotNull(true); + ent.field("i2", int.class.getName()) + .isNotNull(true); + mb.getEntity("TestClass").addForeignKey(new ForeignKeyConstraint(mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i2")), + mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i")), + ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE)); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddIndexTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddIndexTest.java index 1ebbd7e..c522f62 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddIndexTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddIndexTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorAddIndexTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setIndex(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isIndex(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddKeyTest.java index ac1ded6..aacce43 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddKeyTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorAddKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setKey(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isKey(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddPrimaryKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddPrimaryKeyTest.java index 47f3b11..77dbafb 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddPrimaryKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddPrimaryKeyTest.java @@ -27,22 +27,22 @@ class ModelChangeDetectorAddPrimaryKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.entity("TestClass"), - List.of(mb.entity("TestClass").getField("i")))); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.getEntity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.getEntity("TestClass"), + List.of(mb.getEntity("TestClass").getField("i")))); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddUniqueTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddUniqueTest.java index 30eadec..d7130dd 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddUniqueTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorAddUniqueTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorAddUniqueTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setUnique(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isUnique(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropEntityTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropEntityTest.java index 733fde0..a2a328f 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropEntityTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropEntityTest.java @@ -24,22 +24,22 @@ class ModelChangeDetectorDropEntityTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); mb.entity("TestClass2"); - mb.entity("TestClass2").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass2").field("i2", int.class.getName()) + .isNotNull(true); mb.entity("TestClass3"); - mb.entity("TestClass3").getOrCreateField("i3", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass3").field("i3", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropFieldTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropFieldTest.java index 3e84738..8d7a9c2 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropFieldTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropFieldTest.java @@ -24,20 +24,20 @@ class ModelChangeDetectorDropFieldTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i3", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i3", int.class.getName()) + .isNotNull(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropForeignKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropForeignKeyTest.java index 60a4e98..07ef75f 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropForeignKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropForeignKeyTest.java @@ -26,23 +26,23 @@ class ModelChangeDetectorDropForeignKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); var ent = mb.entity("TestClass"); - ent.getOrCreateField("i", int.class.getName()) - .setNotNull(true); - ent.getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - ent.addForeignKey(new ForeignKeyConstraint(ent, List.of(ent.getField("i2")), - ent, List.of(ent.getField("i")), - ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE)); + ent.field("i", int.class.getName()) + .isNotNull(true); + ent.field("i2", int.class.getName()) + .isNotNull(true); + mb.getEntity("TestClass").addForeignKey(new ForeignKeyConstraint(mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i2")), + mb.getEntity("TestClass"), List.of(mb.getEntity("TestClass").getField("i")), + ForeignKeyConstraint.Action.CASCADE, ForeignKeyConstraint.Action.CASCADE)); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropIndexTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropIndexTest.java index 2556a8b..d72136e 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropIndexTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropIndexTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorDropIndexTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setIndex(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isIndex(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropKeyTest.java index 692bca0..c2cb3dc 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropKeyTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorDropKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setKey(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isKey(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropPrimaryKeyTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropPrimaryKeyTest.java index e588257..d8e2244 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropPrimaryKeyTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropPrimaryKeyTest.java @@ -27,22 +27,22 @@ class ModelChangeDetectorDropPrimaryKeyTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.entity("TestClass"), - List.of(mb.entity("TestClass").getField("i")))); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.getEntity("TestClass").setPrimaryKey(new PrimaryKeyConstraint(mb.getEntity("TestClass"), + List.of(mb.getEntity("TestClass").getField("i")))); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropUniqueTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropUniqueTest.java index bf0c7a3..57d233d 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropUniqueTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorDropUniqueTest.java @@ -23,21 +23,21 @@ class ModelChangeDetectorDropUniqueTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()).setUnique(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()).isUnique(true); return mb; } private ModelBuilder createTo() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass").field("i2", int.class.getName()) + .isNotNull(true); return mb; } } \ No newline at end of file diff --git a/src/test/java/jef/model/migration/creator/ModelChangeDetectorNoChangeTest.java b/src/test/java/jef/model/migration/creator/ModelChangeDetectorNoChangeTest.java index 3bedbf8..6087dae 100644 --- a/src/test/java/jef/model/migration/creator/ModelChangeDetectorNoChangeTest.java +++ b/src/test/java/jef/model/migration/creator/ModelChangeDetectorNoChangeTest.java @@ -18,13 +18,13 @@ class ModelChangeDetectorNoChangeTest { private ModelBuilder createFrom() { var mb = new ModelBuilder(); mb.entity("TestClass"); - mb.entity("TestClass").getOrCreateField("i", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass").field("i", int.class.getName()) + .isNotNull(true); mb.entity("TestClass2"); - mb.entity("TestClass2").getOrCreateField("i", int.class.getName()) - .setNotNull(true); - mb.entity("TestClass2").getOrCreateField("i2", int.class.getName()) - .setNotNull(true); + mb.entity("TestClass2").field("i", int.class.getName()) + .isNotNull(true); + mb.entity("TestClass2").field("i2", int.class.getName()) + .isNotNull(true); return mb; }