added database value generation with identity generation

This commit is contained in:
wea_ondara
2022-11-27 08:10:52 +01:00
parent 3e581a9e4a
commit 195f3d0148
14 changed files with 118 additions and 15 deletions

View File

@@ -1,5 +1,6 @@
package jef.model;
import jef.model.annotations.Generated;
import jef.serializable.SerializableObject;
import jef.util.Check;
import lombok.AccessLevel;
@@ -19,12 +20,13 @@ public class DbField<T> {
private Class<T> type;
@Setter(value = AccessLevel.PACKAGE)
private Field field;
private boolean isModelField;
private boolean isDatabaseField;
private boolean isModelField;//TODO get rid of this field
private boolean isDatabaseField;//TODO get rid of this field
private DbField<?> exposingForeignKeyOf;
private String name;
private boolean notNull = false;
private String sqlType;
private Generated.Type generated = Generated.Type.NONE;
DbField(DbEntity<? extends SerializableObject> entity, String name, String typeName) {
this.entity = Check.notNull(entity, "entity");
@@ -85,6 +87,11 @@ public class DbField<T> {
this.sqlType = sqlType;
}
public void setGenerated(Generated.Type generated) {
Check.notNull(generated, "generated");
this.generated = generated;
}
@Override
public boolean equals(Object o) {
if (!equalsCommon(o)) {
@@ -108,6 +115,7 @@ public class DbField<T> {
&& notNull == dbField.notNull
&& entity.getName().equals(dbField.entity.getName())
&& typeName.equals(dbField.typeName)
&& generated == dbField.generated
// && Objects.equals(type, dbField.type)
&& Objects.equals(exposingForeignKeyOf == null ? null : exposingForeignKeyOf.getName(),
dbField.exposingForeignKeyOf == null ? null : dbField.exposingForeignKeyOf.getName());
@@ -117,7 +125,7 @@ public class DbField<T> {
public int hashCode() {
return Objects.hash(entity.getName(), typeName, type, field == null ? null : field.getName(), isModelField, isDatabaseField,
exposingForeignKeyOf == null ? null : exposingForeignKeyOf.getName(),
name, notNull);
name, notNull, generated);
}
@Override

View File

@@ -1,5 +1,6 @@
package jef.model;
import jef.model.annotations.Generated;
import jef.model.constraints.IndexConstraint;
import jef.model.constraints.KeyConstraint;
import jef.model.constraints.UniqueKeyConstraint;
@@ -41,6 +42,11 @@ public class DbFieldBuilder<T> {
return this;
}
public DbFieldBuilder<T> generated(Generated.Type type) {
field.setGenerated(type);
return this;
}
public void isUnique() {
isUnique(true);
}

View File

@@ -196,6 +196,7 @@ public class ModelBuilder {
nf.setType(e.getType());
nf.setSqlType(e.getSqlType());
nf.setNotNull(e.isNotNull());
nf.setGenerated(e.getGenerated());
nf.setModelField(e.isModelField());
nf.setDatabaseField(e.isDatabaseField());
return nf;

View File

@@ -2,6 +2,7 @@ package jef.model;
import jef.model.annotations.processors.AnnotationProcessor;
import jef.model.annotations.processors.ForeignKeyProcessor;
import jef.model.annotations.processors.GeneratedProcessor;
import jef.model.annotations.processors.IndexProcessor;
import jef.model.annotations.processors.KeyProcessor;
import jef.model.annotations.processors.NotNullProcessor;
@@ -28,7 +29,8 @@ public class ModelBuilderOptions {
UniqueProcessor.INSTANCE,
IndexProcessor.INSTANCE,
KeyProcessor.INSTANCE,
ForeignKeyProcessor.INSTANCE
ForeignKeyProcessor.INSTANCE,
GeneratedProcessor.INSTANCE
));
this.contextOptions = new DbContextOptions(null);//TODO
}

View File

@@ -1,5 +1,6 @@
package jef.model;
import jef.model.annotations.Generated;
import jef.model.annotations.Id;
import jef.model.annotations.Transient;
@@ -58,5 +59,9 @@ class PrimaryKeyInitializer {
var dbfields = idFields.stream().map(e -> entity.field(e).getField().getName()).toList();
entity.hasOne(dbfields.toArray(String[]::new)).isPrimaryKey(true);
}
if (idFields.size() == 1) {//auto enable identity generation for primary key
entity.field(idFields.get(0)).generated(Generated.Type.IDENTITY);
}
}
}

View File

@@ -0,0 +1,21 @@
package jef.model.annotations;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Generated {
Type value() default Type.IDENTITY;
enum Type {
NONE,//no value is generated
IDENTITY,//value is generated on insert
// COMPUTED,//value is generated on insert and update
;
}
}

View File

@@ -0,0 +1,27 @@
package jef.model.annotations.processors;
import jef.model.DbEntityBuilder;
import jef.model.DbFieldBuilder;
import jef.model.ModelBuilder;
import jef.model.annotations.Generated;
import jef.serializable.SerializableObject;
public class GeneratedProcessor implements AnnotationProcessor {
public static final GeneratedProcessor INSTANCE = new GeneratedProcessor();
@Override
public void apply(ModelBuilder mb) {
for (DbEntityBuilder<? extends SerializableObject> entity : mb.entities()) {
for (DbFieldBuilder<?> field : entity.fields()) {
if (field.getField().getField() == null) {
continue;
}
var annotation = field.getField().getField().getAnnotation(Generated.class);
if (annotation == null) {
continue;
}
field.generated(annotation.value());
}
}
}
}

View File

@@ -1,5 +1,7 @@
package jef.model.migration.operation;
import jef.model.annotations.Generated;
import jef.util.Check;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -14,6 +16,7 @@ public class AddFieldOperation implements MigrationOperation {
protected final String field;
protected final String sqlType;
protected final boolean notNull;
protected final Generated.Type generated;
@EqualsAndHashCode
@ToString
@@ -22,6 +25,7 @@ public class AddFieldOperation implements MigrationOperation {
protected final String field;
protected String sqlType;
protected boolean notNull;
protected Generated.Type generated;
public Builder(String table, String field) {
this.table = table;
@@ -38,8 +42,14 @@ public class AddFieldOperation implements MigrationOperation {
return this;
}
public Builder generated(Generated.Type generated) {
Check.notNull(generated, "generated");
this.generated = generated;
return this;
}
public AddFieldOperation build() {
return new AddFieldOperation(table, field, sqlType, notNull);
return new AddFieldOperation(table, field, sqlType, notNull, generated);
}
}
}

View File

@@ -1,5 +1,6 @@
package jef.model.migration.operation;
import jef.model.annotations.Generated;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
@@ -10,8 +11,8 @@ import lombok.ToString;
public class UpdateFieldOperation extends AddFieldOperation {
private final String newName;
public UpdateFieldOperation(String table, String field, String newName, String sqlType, boolean notNull) {
super(table, field, sqlType, notNull);
public UpdateFieldOperation(String table, String field, String newName, String sqlType, boolean notNull, Generated.Type generated) {
super(table, field, sqlType, notNull, generated);
this.newName = newName;
}
@@ -30,7 +31,7 @@ public class UpdateFieldOperation extends AddFieldOperation {
}
public UpdateFieldOperation build() {
return new UpdateFieldOperation(table, field, newName, sqlType, notNull);
return new UpdateFieldOperation(table, field, newName, sqlType, notNull, generated);
}
}
}

View File

@@ -158,7 +158,7 @@ public class ModelBuilderCloneTest {
}
assertEquals(o.getFields().size(), c.getFields().size());
for (int j = 0; j < o.getIndexes().size(); j++) {
for (int j = 0; j < o.getFields().size(); j++) {
var of = o.getFields().get(j);
var cf = c.getFields().get(j);
@@ -177,6 +177,11 @@ public class ModelBuilderCloneTest {
System.out.println("ex: " + of.isNotNull());
System.out.println("ac: " + cf.isNotNull());
}
if (of.getGenerated() != cf.getGenerated()) {
System.out.println("is generated differ: entity " + o.getName() + ", field " + of.getName());
System.out.println("ex: " + of.getGenerated());
System.out.println("ac: " + cf.getGenerated());
}
if (!of.getEntity().getName().equals(cf.getEntity().getName())) {
System.out.println("entities differ: entity " + o.getName() + ", field " + of.getName());
System.out.println("ex: " + of.getEntity().getName());