From 3d556bfcad3eb3face9db986aa570d6e2a059448 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 4 Aug 2013 12:34:48 +0200 Subject: wip --- .../trygvis/container/compiler/EntityHandler.java | 140 +++++++++++++++------ .../trygvis/container/compiler/SqlUnitModel.java | 80 +++++++++++- .../trygvis/container/compiler/model/FieldRef.java | 3 +- .../trygvis/container/compiler/model/Imports.java | 10 +- .../trygvis/container/compiler/model/TypeRef.java | 43 +++++-- .../java/io/trygvis/persistence/EntityMirror.java | 53 ++++---- .../io/trygvis/persistence/SequenceMirror.java | 9 ++ .../trygvis/container/compiler/ProcessorTest.java | 1 + .../io/trygvis/persistence/EntityMirrorTest.java | 23 ++-- .../io/trygvis/persistence/test/Person.java | 2 + .../io/trygvis/persistence/test/package-info.java | 3 +- .../io/trygvis/container/myapp/AddressBook.java | 3 + .../java/io/trygvis/container/myapp/Person.java | 2 + 13 files changed, 278 insertions(+), 94 deletions(-) create mode 100644 container-compiler-plugin/src/main/java/io/trygvis/persistence/SequenceMirror.java diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java index d9e13ac..a25c766 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/EntityHandler.java @@ -1,10 +1,12 @@ package io.trygvis.container.compiler; import io.trygvis.container.compiler.model.ClassG; +import io.trygvis.container.compiler.model.FieldRef; import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.persistence.EntityMirror; import io.trygvis.persistence.FieldMirror; import io.trygvis.persistence.GeneratorConfiguration; +import io.trygvis.persistence.SequenceMirror; import io.trygvis.persistence.SqlEntity; import io.trygvis.persistence.TypeHandler; import io.trygvis.persistence.sql.SqlEntityDesc; @@ -12,16 +14,17 @@ import io.trygvis.persistence.sql.SqlEntityDesc; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; import javax.persistence.Id; +import javax.persistence.SequenceGenerator; import javax.tools.JavaFileObject; import java.io.IOException; import java.io.PrintWriter; -import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -32,6 +35,7 @@ import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror; import static java.lang.Character.isUpperCase; import static java.lang.reflect.Modifier.PUBLIC; import static javax.lang.model.util.ElementFilter.fieldsIn; +import static org.apache.commons.lang.StringUtils.join; import static org.apache.commons.lang.StringUtils.stripEnd; public class EntityHandler extends AbstractHandler { @@ -45,9 +49,10 @@ public class EntityHandler extends AbstractHandler { public void phase1(Set sqlEntities, Set packages) throws Exception { for (TypeElement entity : sqlEntities) { - AnnotationMirror sqlEntity = findAnnotation(SqlEntity.class, entity); + AnnotationMirror sqlEntity = getAnnotation(SqlEntity.class, entity); for (Map.Entry v : sqlEntity.getElementValues().entrySet()) { - switch (v.getKey().getSimpleName().toString()) { + String field = v.getKey().getSimpleName().toString(); + switch (field) { case "value": Class typeHandlerClass = getClass().getClassLoader().loadClass(v.getValue().getValue().toString()); @@ -56,12 +61,13 @@ public class EntityHandler extends AbstractHandler { generatorConfiguration.addTypeHandler(new TypeRef(type), typeHandler); System.out.println("Loaded TypeHandler for " + type + " through " + typeHandlerClass.getCanonicalName()); break; + default: + throw new InternalErrorException("Unknown @SqlEntity field: " + field); } } // System.out.println("sqlEntity.getElementValues() = " + sqlEntity.getElementValues()); } - System.out.println("packages = " + packages); if (packages.size() == 0) { throw new CompilerException("There has to be exactly one @SqlEntitySet annotated package."); } @@ -70,27 +76,48 @@ public class EntityHandler extends AbstractHandler { if (packages.size() != 1) { throw new CompilerException(packageElement, "There can only be one @SqlEntitySet annotated package."); } - } - - private AnnotationMirror findAnnotation(Class c, TypeElement type) { - TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType(); - for (AnnotationMirror a : type.getAnnotationMirrors()) { - if (types.isSameType(a.getAnnotationType(), annotationType)) { - return a; - } - } - - throw new CompilerException(type, "Could not find annotation " + c.getSimpleName()); + sqlUnit.setPackageName(packageElement.getQualifiedName().toString()); } public void recordEntity(TypeElement element) throws Exception { - EntityMirror entityMirror = new EntityMirror(generatorConfiguration, new TypeRef(types.getDeclaredType(element)), + EntityMirror entityMirror = new EntityMirror( + generatorConfiguration, + new TypeRef(types.getDeclaredType(element)), sqlName(element.getSimpleName().toString())); for (VariableElement f : fieldsIn(elements.getAllMembers(element))) { - entityMirror.add(fromElement(generatorConfiguration, f)); + FieldMirror field = fromElement(generatorConfiguration, f); + entityMirror.add(field); } + // ----------------------------------------------------------------------- + // Process any extra annotations + // ----------------------------------------------------------------------- + + AnnotationMirror sequenceGenerator = findAnnotation(SequenceGenerator.class, element); + + if (sequenceGenerator != null) { + String name = null; + for (Map.Entry v : sequenceGenerator.getElementValues().entrySet()) { + String field = v.getKey().getSimpleName().toString(); + switch (field) { + case "name": + name = v.getValue().getValue().toString(); + + break; + default: + throw new InternalErrorException("Unsupported field on @SequenceGenerator: " + field); + } + } + if (name != null) { + sqlUnit.add(new SequenceMirror(name)); + } + } + + // ----------------------------------------------------------------------- + // Validation + // ----------------------------------------------------------------------- + List idFields = new ArrayList<>(); for (FieldMirror field : entityMirror.fields) { if (field.id) { @@ -105,22 +132,21 @@ public class EntityHandler extends AbstractHandler { throw new CompilerException(element, "This implementation only support a single @Id annotated field."); } - sqlUnit.add(entityMirror); + sqlUnit.add(entityMirror, element); } - public void generate(EntityMirror entityMirror) throws IOException { + public ClassG phase3(EntityMirror entityMirror) throws IOException { ClassG g = new ClassG(PUBLIC, entityMirror.daoType); TypeRef stringType = g.imports.add(String.class); TypeRef sqlEntityDescType = g.imports.add(SqlEntityDesc.class); - TypeRef sqlExceptionType = g.imports.add(SQLException.class); g.addPublicStaticFinalField(stringType, "createTableSql"). value(toJavaString(entityMirror.createTableSql(sqlUnit))); g.addPublicStaticFinalField(stringType, "dropTableSql"). value(toJavaString(entityMirror.dropTableSql())); g.addPublicStaticFinalField(stringType, "insertIntoSql"). - value(toJavaString(entityMirror.insertIntoSql())); + value(toJavaString(entityMirror.insertIntoSql(sqlUnit))); g.addPublicStaticFinalField(stringType, "deleteFromSql"). value(toJavaString(entityMirror.deleteFromSql())); String desc = "new " + sqlEntityDescType + "(" + @@ -129,18 +155,13 @@ public class EntityHandler extends AbstractHandler { ")"; g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc); ClassG.InnerClassG typedQuery = g.addInnerClass(entityMirror.queryType(g.imports)); - typedQuery.inner.addMethod(entityMirror.fromResultSet(sqlUnit, g.imports)); + typedQuery.inner.addMethod(entityMirror.fromResultSet(g.imports)); g.addMethod(entityMirror.insertInto(sqlUnit, g.imports)); g.addMethod(entityMirror.delete(g.imports)); g.addMethod(entityMirror.deleteById(g.imports)); - g.addMethod(entityMirror.query(sqlUnit, g.imports)); + g.addMethod(entityMirror.query(g.imports)); - JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(entityMirror.daoType.fqName, sqlUnit.elementForEntity(entityMirror)); - try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - for (String s : g.generate()) { - w.println(stripEnd(s, " ")); - } - } + return g; } public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var) { @@ -174,12 +195,39 @@ public class EntityHandler extends AbstractHandler { public void phase3() throws Exception { for (EntityMirror entity : sqlUnit.getEntities().values()) { - generate(entity); + writeFile(phase3(entity), sqlUnit.element(entity)); + } + writeFile(generateSequences(sqlUnit), null); + writeFile(generateSession(), null); + } + + private ClassG generateSequences(SqlUnitModel unit) { + TypeRef sequences = new TypeRef(unit.getPackageName() + ".Sequences"); + ClassG g = new ClassG(PUBLIC, sequences); + List fields = new ArrayList<>(); + for (SequenceMirror sequence : unit.getSequences().values()) { + TypeRef stringType = g.imports.add(String.class); + String value = "CREATE SEQUENCE " + sequence.name + ";"; + FieldRef f = g.addPublicStaticFinalField(stringType, sequence.name).value(toJavaString(value)); + fields.add(f.name); } - generateSession(); + TypeRef stringArrayType = new TypeRef(String[].class); + System.out.println("stringArrayType = " + stringArrayType); + g.addPublicStaticFinalField(stringArrayType, "sequences"). + value("new String[]{" + join(fields, ", ") + "}"); + return g; } - private void generateSession() throws IOException { + private void writeFile(ClassG g, Element element) throws IOException { + JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(g.type.fqName, element); + try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { + for (String s : g.generate()) { + w.println(stripEnd(s, " ")); + } + } + } + + private ClassG generateSession() throws IOException { String p = packageElement.getQualifiedName().toString(); // TODO: Support a name prefix from @SqlEntitySet @@ -201,12 +249,7 @@ public class EntityHandler extends AbstractHandler { g.addConstructor(parameters, body); */ - JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(type.fqName, packageElement); - try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - for (String s : g.generate()) { - w.println(stripEnd(s, " ")); - } - } + return g; } public static String sqlName(String javaName) { @@ -220,4 +263,25 @@ public class EntityHandler extends AbstractHandler { } return builder.toString(); } + + private AnnotationMirror findAnnotation(Class c, TypeElement type) { + TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType(); + for (AnnotationMirror a : type.getAnnotationMirrors()) { + if (types.isSameType(a.getAnnotationType(), annotationType)) { + return a; + } + } + + return null; + } + + public AnnotationMirror getAnnotation(Class c, TypeElement type) { + AnnotationMirror annotation = findAnnotation(c, type); + + if (annotation != null) { + return annotation; + } + + throw new CompilerException(type, "Could not find annotation " + c.getSimpleName()); + } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java index bb6fa14..568bbe7 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/SqlUnitModel.java @@ -2,17 +2,41 @@ package io.trygvis.container.compiler; import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.persistence.EntityMirror; +import io.trygvis.persistence.SequenceMirror; import javax.lang.model.element.Element; -import java.util.Collections; import java.util.Map; import java.util.TreeMap; -import static java.util.Collections.addAll; - public class SqlUnitModel { private Map entities = new TreeMap<>(); - private Map elements = new TreeMap<>(); + private Map entityElements = new TreeMap<>(); + private Map sequences = new TreeMap<>(); + private Map sequenceElements = new TreeMap<>(); + private String packageName; + + public String getPackageName() { + if (packageName == null) { + throw new InternalErrorException("packageName is not set yet."); + } + + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + // ----------------------------------------------------------------------- + // Entity Mirrors + // ----------------------------------------------------------------------- + + public SqlUnitModel add(EntityMirror entity, Element element) { + entities.put(entity.type, entity); + entityElements.put(entity, element); + + return this; + } public SqlUnitModel add(EntityMirror... entities) { for (EntityMirror entity : entities) { @@ -34,7 +58,51 @@ public class SqlUnitModel { return entities; } - public Element elementForEntity(EntityMirror entity) { - return elements.get(entity); + public Element element(EntityMirror entity) { + return entityElements.get(entity); + } + + // ----------------------------------------------------------------------- + // Sequences + // ----------------------------------------------------------------------- + + public SqlUnitModel add(SequenceMirror sequence, Element element) { + sequences.put(sequence.name, sequence); + sequenceElements.put(sequence, element); + return this; + } + + public SqlUnitModel add(SequenceMirror... sequenceMirrors) { + for (SequenceMirror sequenceMirror : sequenceMirrors) { + this.sequences.put(sequenceMirror.name, sequenceMirror); + } + return this; + } + + public SequenceMirror getDefaultSequence() { + switch (sequences.size()) { + case 1: + return sequences.values().iterator().next(); + case 0: + throw new CompilerException("No sequenced defined"); + default: + throw new CompilerException("More than one sequence defined, the field must specify which sequence to use with @SequenceGenerator"); + } + } + + public SequenceMirror getSequence(String name) { + SequenceMirror sequence = sequences.get(name); + if (sequence == null) { + throw new CompilerException("Could not find sequence: " + name); + } + return sequence; + } + + public Map getSequences() { + return sequences; + } + + public Element element(SequenceMirror sequence) { + return sequenceElements.get(sequence); } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java index b6df4f2..1504a0b 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/FieldRef.java @@ -42,7 +42,8 @@ public class FieldRef implements Comparable { return name.compareTo(o.name); } - public void value(String value) { + public FieldRef value(String value) { this.value = value; + return this; } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Imports.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Imports.java index 9ed6097..c2e2a26 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Imports.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Imports.java @@ -18,6 +18,12 @@ public class Imports { } public TypeRef add(TypeRef klass) { + // TODO: implement properly + if (true) { + imports.add(klass); + return klass; + } + String fqName = klass.fqName; String name = klass.toString(); for (TypeRef i : imports) { @@ -32,7 +38,7 @@ public class Imports { } } - TypeRef ref = new TypeRef(fqName, name); + TypeRef ref = new TypeRef(fqName, name, klass.array, klass.args); imports.add(ref); return ref; @@ -44,7 +50,7 @@ public class Imports { if (i.isPrimitive() || i.inUnnamedPackage()) { continue; } - body.add("import " + i.fqName + ";"); + body.add("import " + i.importName() + ";"); } if (!imports.isEmpty()) { body.add(""); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java index 9c92e73..2e679a5 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/TypeRef.java @@ -37,12 +37,15 @@ public class TypeRef implements Comparable { private final boolean primitive; + public final boolean array; + public final List args; - private TypeRef(String fqName, String name, boolean primitive, List args) { + private TypeRef(String fqName, String name, boolean primitive, boolean array, List args) { this.fqName = fqName; this.plainName = name; this.primitive = primitive; + this.array = array; this.args = args; int i = this.fqName.lastIndexOf('.'); @@ -58,15 +61,28 @@ public class TypeRef implements Comparable { } public TypeRef(Class klass) { - this(klass.getCanonicalName()); + this(fqName(klass), fqName(klass), false, klass.isArray(), Collections.emptyList()); + } + + private static String fqName(Class klass) { + String name = klass.getCanonicalName(); + if (!klass.isArray()) { + return name; + } + + return name.substring(0, name.length() - 2); } public TypeRef(String fqName) { - this(fqName, fqName, false, Collections.emptyList()); + this(fqName, fqName, false, false, Collections.emptyList()); } - public TypeRef(String fqName, String name) { - this(fqName, name, false, Collections.emptyList()); + public TypeRef(String fqName, String name, boolean array, List args) { + this(fqName, name, false, array, args); + } + + public TypeRef args(List args) { + return new TypeRef(fqName, plainName, primitive, array, args); } public boolean isPrimitive() { @@ -87,8 +103,8 @@ public class TypeRef implements Comparable { return fqName.substring(0, i); } - public TypeRef args(List args) { - return new TypeRef(fqName, plainName, false, args); + public String importName() { + return fqName; } public TypeRef args(TypeRef... args) { @@ -102,7 +118,7 @@ public class TypeRef implements Comparable { TypeRef classRef = (TypeRef) o; - return fqName.equals(classRef.fqName); + return fqName.equals(classRef.fqName) && array == classRef.array; } @Override @@ -111,16 +127,19 @@ public class TypeRef implements Comparable { } @Override - public int compareTo(TypeRef o) { + public int compareTo(@SuppressWarnings("NullableProblems") TypeRef o) { return fqName.compareTo(o.fqName); } public String toString() { String s = plainName; - if(args.isEmpty()) { - return s; + if (!args.isEmpty()) { + s += "<" + join(args, ", ") + ">"; + } + if (array) { + s += "[]"; } - return s + "<" + join(args, ", ") + ">"; + return s; } public static TypeRef find(TypeKind kind) { diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java index e06855f..48f8adc 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java @@ -74,7 +74,7 @@ public class EntityMirror implements Comparable { } else if (field instanceof ReferenceFieldMirror) { ReferenceFieldMirror ref = (ReferenceFieldMirror) field; EntityMirror referenced = unit.get(ref.type); - if(referenced.idFields.size() == 1) { + if (referenced.idFields.size() == 1) { FieldMirror idField = referenced.idFields.get(0); TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); s = " " + field.sqlName + " " + typeHandler.sqlType(field); @@ -84,8 +84,7 @@ public class EntityMirror implements Comparable { } else if (field.unique) { s += " UNIQUE"; } - } - else { + } else { throw new NotImplementedException(); } } else { @@ -103,16 +102,20 @@ public class EntityMirror implements Comparable { return "DROP TABLE " + tableName + ";"; } - public String insertIntoSql() { - List names = new ArrayList<>(); - List placeholders = new ArrayList<>(); + public String insertIntoSql(SqlUnitModel unit) { + List columns = new ArrayList<>(); + List values = new ArrayList<>(); for (FieldMirror field : fields) { - names.add(field.sqlName); - placeholders.add("?"); + columns.add(field.sqlName); + if (field.id) { + values.add("nextval('" + unit.getDefaultSequence().name + "')"); + } else { + values.add("?"); + } } - return "INSERT INTO " + tableName + "(" + join(names, ", ") + ") " + - "VALUES(" + join(placeholders, ", ") + ");"; + return "INSERT INTO " + tableName + "(" + join(columns, ", ") + ") " + + "VALUES(" + join(values, ", ") + ");"; } public String deleteFromSql() { @@ -145,20 +148,26 @@ public class EntityMirror implements Comparable { List body = new ArrayList<>(); body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {"); - for (int i = 0; i < fields.size(); i++) { - FieldMirror field = fields.get(i); - if(field instanceof PrimitiveFieldMirror) { + int i = 0; + for (FieldMirror field : fields) { + // Assume all ID fields are generated for now. + if (field.id) { + continue; + } + + i++; + + if (field instanceof PrimitiveFieldMirror) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); String access = o.name + "." + field.javaName; - String setter = " stmt." + typeHandler.setter(i + 1, access) + ";"; + String setter = " stmt." + typeHandler.setter(i, access) + ";"; - if(field.notNull) { + if (field.notNull) { body.add(setter); - } - else { + } else { body.add(" " + field.type + " " + field.javaName + " = " + access + ";"); body.add(" if(" + field.javaName + " == null) {"); - body.add(" stmt.setNull(" + (i + 1) + ", " + typesType + "." + typeHandler.typeName() + ");"); + body.add(" stmt.setNull(" + i + ", " + typesType + "." + typeHandler.typeName() + ");"); body.add(" } else {"); body.add(" " + setter); body.add(" }"); @@ -168,7 +177,7 @@ public class EntityMirror implements Comparable { EntityMirror referenced = unit.get(ref.type); FieldMirror idField = referenced.getIdField(); TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); - body.add(" stmt." + typeHandler.setter(i + 1, o.name + "." + field.javaName + "." + idField.javaName) + ";"); + body.add(" stmt." + typeHandler.setter(i, o.name + "." + field.javaName + "." + idField.javaName) + ";"); } } body.add(" stmt.executeUpdate();"); @@ -231,7 +240,7 @@ public class EntityMirror implements Comparable { return typedQuery; } - public MethodRef query(SqlUnitModel sqlUnit, Imports imports) { + public MethodRef query(Imports imports) { TypeRef conType = imports.add(Connection.class); TypeRef typedQueryType = imports.add(TypedQuery.class).args(type); TypeRef entityTypedQuery = new TypeRef(type.className + "TypedQuery"); @@ -244,7 +253,7 @@ public class EntityMirror implements Comparable { return new MethodRef(PUBLIC | STATIC, typedQueryType, "query", p, body); } - public MethodRef fromResultSet(SqlUnitModel unit, Imports g) { + public MethodRef fromResultSet(Imports g) { TypeRef rsType = g.add(ResultSet.class); Parameters p = new Parameters(); ParameterRef rs = p.addParameter(rsType, "rs"); @@ -253,7 +262,7 @@ public class EntityMirror implements Comparable { List names = new ArrayList<>(); for (int i = 0; i < fields.size(); i++) { FieldMirror field = fields.get(i); - if(field instanceof PrimitiveFieldMirror) { + if (field instanceof PrimitiveFieldMirror) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); } else if (field instanceof ReferenceFieldMirror) { diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/SequenceMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/SequenceMirror.java new file mode 100644 index 0000000..9ae6781 --- /dev/null +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/SequenceMirror.java @@ -0,0 +1,9 @@ +package io.trygvis.persistence; + +public class SequenceMirror { + public final String name; + + public SequenceMirror(String name) { + this.name = name; + } +} diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java index b8d022d..c661f8b 100644 --- a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java +++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/ProcessorTest.java @@ -57,6 +57,7 @@ public class ProcessorTest { } assertThat(fileManager.codes.keySet()).containsOnly( + "io.trygvis.persistence.test.Sequences", "io.trygvis.persistence.test.Session", "io.trygvis.persistence.test.PersonDao"); assertThat(collector.getDiagnostics()).isEmpty(); diff --git a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java index 3f0f345..4eead41 100644 --- a/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java +++ b/container-compiler-plugin/src/test/java/io/trygvis/persistence/EntityMirrorTest.java @@ -28,21 +28,21 @@ public class EntityMirrorTest { return new Object[][]{ new Object[]{ new FieldMirror[]{idString}, - "INSERT INTO my_table(id) VALUES(?);", + "INSERT INTO my_table(id) VALUES(nextval('id_seq'));", "DELETE FROM my_table WHERE id=?;", format( "CREATE TABLE my_table(%n" + " id VARCHAR(1000) PRIMARY KEY%n" + ");")}, new Object[]{ new FieldMirror[]{idLong}, - "INSERT INTO my_table(id) VALUES(?);", + "INSERT INTO my_table(id) VALUES(nextval('id_seq'));", "DELETE FROM my_table WHERE id=?;", format( "CREATE TABLE my_table(%n" + " id BIGINT PRIMARY KEY%n" + ");")}, new Object[]{ new FieldMirror[]{idLong, name}, - "INSERT INTO my_table(id, name) VALUES(?, ?);", + "INSERT INTO my_table(id, name) VALUES(nextval('id_seq'), ?);", "DELETE FROM my_table WHERE id=?;", format( "CREATE TABLE my_table(%n" + " id BIGINT PRIMARY KEY,%n" + @@ -50,7 +50,7 @@ public class EntityMirrorTest { ");")}, new Object[]{ new FieldMirror[]{idLong, ref}, - "INSERT INTO my_table(id, parent) VALUES(?, ?);", + "INSERT INTO my_table(id, parent) VALUES(nextval('id_seq'), ?);", "DELETE FROM my_table WHERE id=?;", format( "CREATE TABLE my_table(%n" + " id BIGINT PRIMARY KEY,%n" + @@ -66,22 +66,22 @@ public class EntityMirrorTest { myTable.add(field); } - SqlUnitModel unit = new SqlUnitModel().add(myTable); + SqlUnitModel unit = new SqlUnitModel().add(myTable).add(new SequenceMirror("id_seq")); - assertEquals(myTable.insertIntoSql(), insert); + assertEquals(myTable.insertIntoSql(unit), insert); assertEquals(myTable.deleteFromSql(), delete); assertEquals(myTable.createTableSql(unit), create); } @Test public void testInsertIntoMethod() { - eq(insertInto(idString), + eq(insertInto(name), "try(java.sql.PreparedStatement stmt = con.prepareStatement(insertIntoSql)) {", - " java.lang.String id = o.id;", - " if(id == null) {", + " java.lang.String name = o.name;", + " if(name == null) {", " stmt.setNull(1, java.sql.Types.VARCHAR);", " } else {", - " stmt.setString(1, o.id);", + " stmt.setString(1, o.name);", " }", " stmt.executeUpdate();", "}"); @@ -110,8 +110,7 @@ public class EntityMirrorTest { private MethodRef fromResultSet(FieldMirror... fields) { EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, "my_table"); myTable.add(fields); - SqlUnitModel unit = new SqlUnitModel().add(myTable); - return myTable.fromResultSet(unit, new Imports()); + return myTable.fromResultSet(new Imports()); } private void eq(MethodRef m, String... expected) { diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java index 43a0c78..755042b 100644 --- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/Person.java @@ -3,9 +3,11 @@ package io.trygvis.persistence.test; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; import java.util.Date; @Entity +@SequenceGenerator(name = "id_seq") public class Person { @Id public Long id; diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java index 9ca5e93..b211cd3 100644 --- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/package-info.java @@ -1,3 +1,4 @@ -@SqlEntitySet package io.trygvis.persistence.test; +@SqlEntitySet +package io.trygvis.persistence.test; import io.trygvis.persistence.SqlEntitySet; diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java index ec0bffa..0120b6a 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java @@ -87,6 +87,9 @@ public class AddressBook { public void run(Connection c) throws Exception { Statement statement = c.createStatement(); statement.executeUpdate(PersonDao.createTableSql); + for (String sql : Sequences.sequences) { + statement.executeUpdate(sql); + } } } diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Person.java b/myapp/src/main/java/io/trygvis/container/myapp/Person.java index 6a7a694..be9026a 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/Person.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/Person.java @@ -2,8 +2,10 @@ package io.trygvis.container.myapp; import javax.persistence.Entity; import javax.persistence.Id; +import javax.persistence.SequenceGenerator; @Entity +@SequenceGenerator(name = "id_seq") public class Person { @Id public Long id; -- cgit v1.2.3