added database value generation with identity generation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
core/src/main/java/jef/model/annotations/Generated.java
Normal file
21
core/src/main/java/jef/model/annotations/Generated.java
Normal 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
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user