From 8cca2127e0e11486cc45ae1a8198bd778301f935 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Mon, 19 Aug 2013 19:45:28 +0200 Subject: o Dropping the Sequences class. Moving more stuff into SqlUnit to make it easier available in a generic form. o Fixing the complicated cases where the generation got confused with both setter and constructor injection. --- container-compiler-plugin/pom.xml | 11 -- .../trygvis/container/compiler/EntityHandler.java | 135 +++++++++++++++------ .../io/trygvis/container/compiler/MyProcessor.java | 2 - .../java/io/trygvis/persistence/EntityMirror.java | 19 ++- .../java/io/trygvis/persistence/FieldMirror.java | 27 ++--- .../persistence/generators/DaoGenerator.java | 20 +-- .../persistence/generators/DaoUtilsGenerator.java | 4 +- .../persistence/generators/SequencesGenerator.java | 41 ------- .../generators/SqlSessionFactoryGenerator.java | 38 ++++-- .../generators/SqlSessionGenerator.java | 25 +++- .../services/javax.annotation.processing.Processor | 1 + .../trygvis/container/compiler/ProcessorTest.java | 5 +- .../io/trygvis/persistence/EntityMirrorTest.java | 31 +++-- .../persistence/test/basic/ChildEntity.java | 3 + .../io/trygvis/persistence/test/basic/Person.java | 3 +- myapp/pom.xml | 4 +- .../trygvis/container/myapp/AddressBookDirect.java | 13 +- .../trygvis/container/myapp/AddressBookTest.java | 26 ++++ pom.xml | 22 ++-- .../io/trygvis/persistence/sql/SqlConstructor.java | 11 ++ .../java/io/trygvis/persistence/sql/SqlDao.java | 2 + .../trygvis/persistence/sql/SqlSequenceMeta.java | 13 ++ .../io/trygvis/persistence/sql/SqlSession.java | 2 +- .../trygvis/persistence/sql/SqlSessionFactory.java | 4 + .../java/io/trygvis/persistence/sql/SqlUnit.java | 31 ++++- 25 files changed, 322 insertions(+), 171 deletions(-) delete mode 100644 container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java create mode 100644 container-compiler-plugin/src/main/resources/META-INF/services/javax.annotation.processing.Processor create mode 100644 myapp/src/test/java/io/trygvis/container/myapp/AddressBookTest.java create mode 100644 sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlConstructor.java create mode 100644 sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSequenceMeta.java diff --git a/container-compiler-plugin/pom.xml b/container-compiler-plugin/pom.xml index d451ee3..9b10129 100644 --- a/container-compiler-plugin/pom.xml +++ b/container-compiler-plugin/pom.xml @@ -20,17 +20,6 @@ sql-persistence ${project.version} - - org.easytesting - fest-assert - 1.4 - - - org.testng - testng - 6.8.5 - test - commons-lang commons-lang 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 ba9f100..5eb404b 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 @@ -9,6 +9,7 @@ import io.trygvis.persistence.SqlEntity; import io.trygvis.persistence.SqlEntitySet; import io.trygvis.persistence.TypeHandler; import io.trygvis.persistence.generators.DaoGenerator; +import io.trygvis.persistence.sql.SqlConstructor; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; @@ -22,6 +23,7 @@ import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.persistence.AccessType; import javax.persistence.Id; import javax.persistence.SequenceGenerator; import java.util.ArrayList; @@ -37,13 +39,12 @@ import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.Utils.writeFile; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.FieldMirror.GetterType; -import static io.trygvis.persistence.FieldMirror.SetterType; import static io.trygvis.persistence.TypeHandler.StringEnumTypeHandler; import static java.lang.Character.isUpperCase; import static java.lang.String.format; -import static javax.lang.model.util.ElementFilter.fieldsIn; -import static javax.lang.model.util.ElementFilter.methodsIn; +import static javax.lang.model.util.ElementFilter.*; +import static javax.persistence.AccessType.FIELD; +import static javax.persistence.AccessType.PROPERTY; import static org.apache.commons.lang.StringUtils.join; public class EntityHandler extends AbstractHandler { @@ -116,6 +117,10 @@ public class EntityHandler extends AbstractHandler { } public EntityMirror buildMirror(TypeElement element, boolean concrete) throws Exception { + // ----------------------------------------------------------------------- + // Figure out inheritage and ancestry + // ----------------------------------------------------------------------- + EntityMirror superEntity = null; Set ancestry = new TreeSet<>(new TypeMirrorComparator()); @@ -135,11 +140,48 @@ public class EntityHandler extends AbstractHandler { superType = superTypeMirror.getSuperclass(); } + // ----------------------------------------------------------------------- + // Find constructor + // ----------------------------------------------------------------------- + + ExecutableElement constructor = null; + List constructors = constructorsIn(elements.getAllMembers(element)); + if (constructors.size() == 1) { + constructor = constructors.get(0); + } else { + for (ExecutableElement c : constructors) { + AnnotationMirror sqlConstructor = findAnnotation(SqlConstructor.class, c); + if (sqlConstructor == null) { + continue; + } + + if (constructor != null) { + throw new CompilerException(c, "There can only be one @SqlConstructor annotated constructor."); + } + + constructor = c; + } + } + + System.out.println("element = " + element); + System.out.println("constructor = " + constructor); + + List constructorParameters = new ArrayList<>(); + for (VariableElement p : constructor.getParameters()) { + String name = p.getSimpleName().toString(); + constructorParameters.add(name); + } + + // ----------------------------------------------------------------------- + // + // ----------------------------------------------------------------------- + EntityMirror entity = new EntityMirror( generatorConfiguration, new TypeRef(types.getDeclaredType(element)), concrete, superEntity, + constructor, constructorParameters, concrete ? Utils.sqlName(element.getSimpleName().toString()) : null); Map getters = new TreeMap<>(); @@ -166,7 +208,6 @@ public class EntityHandler extends AbstractHandler { } for (VariableElement f : fieldsIn(elements.getAllMembers(element))) { - System.out.println("f.getEnclosingElement() = " + f.getEnclosingElement()); if (!ancestry.contains(f.getEnclosingElement().asType())) { continue; } @@ -174,7 +215,7 @@ public class EntityHandler extends AbstractHandler { String name = f.getSimpleName().toString(); ExecutableElement getter = getters.remove(name); ExecutableElement setter = setters.remove(name); - FieldMirror field = fromElement(generatorConfiguration, f, getter, setter); + FieldMirror field = fromElement(generatorConfiguration, entity, f, getter, setter); if (field == null) { continue; } @@ -191,7 +232,7 @@ public class EntityHandler extends AbstractHandler { continue; } - FieldMirror field = fromElement(generatorConfiguration, null, getter, setter); + FieldMirror field = fromElement(generatorConfiguration, entity, null, getter, setter); if (field == null) { continue; } @@ -221,25 +262,40 @@ public class EntityHandler extends AbstractHandler { } public void validate(Element element, EntityMirror entity) { - if (!entity.concrete) { - return; - } + if (entity.concrete) { + List idFields = new ArrayList<>(); + List constructorFields = new ArrayList<>(); + for (FieldMirror field : entity.getFields()) { + if (field.id) { + idFields.add(field); + } + if (field.constructorParam) { + constructorFields.add(field); + } + } - List idFields = new ArrayList<>(); - for (FieldMirror field : entity.getFields()) { - if (field.id) { - idFields.add(field); + if (idFields.size() == 0) { + throw new CompilerException(element, "An @Entity is required to have at least one @Id field."); + } + if (idFields.size() != 1) { + throw new CompilerException(element, "This implementation only support a single @Id annotated field."); } - } - if (idFields.size() == 0) { - throw new CompilerException(element, "An @Entity is required to have at least one @Id field."); - } - if (idFields.size() != 1) { - throw new CompilerException(element, "This implementation only support a single @Id annotated field."); - } + entity.setIdType(idFields.get(0).type); - entity.setIdType(idFields.get(0).type); + System.out.println("constructorFields = " + constructorFields); + System.out.println("entity.getConstructorParameters() = " + entity.getConstructorParameters()); + List constructorParameters = new ArrayList<>(entity.getConstructorParameters()); + for (FieldMirror f : constructorFields) { + if (!constructorParameters.remove(f.javaName)) { + throw new CompilerException(entity.constructor, "Unknown field used in constructor: " + f.javaName); + } + } + + if (!constructorParameters.isEmpty()) { + throw new CompilerException(entity.constructor, "Unknown field used in constructor: " + join(constructorParameters, ", ")); + } + } } private void processSequenceGenerators(Element element) { @@ -278,12 +334,13 @@ public class EntityHandler extends AbstractHandler { } } - public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, VariableElement var, - ExecutableElement getter, ExecutableElement setter) { + public FieldMirror fromElement(GeneratorConfiguration generatorConfiguration, EntityMirror entity, + VariableElement var, ExecutableElement getter, ExecutableElement setter) { // TODO: check the setter for annotations too // TODO: check for transient and @Transient - final SetterType setterType; - final GetterType getterType; + boolean isConstructorParameter; + final AccessType setterType; + final AccessType getterType; TypeRef type; Element element; String javaName; @@ -294,16 +351,19 @@ public class EntityHandler extends AbstractHandler { if (var.getModifiers().contains(Modifier.STATIC)) { return null; } + javaName = var.getSimpleName().toString(); + isConstructorParameter = entity.hasConstructorParameter(javaName); + boolean isFinal = var.getModifiers().contains(Modifier.FINAL); if (isFinal) { - setterType = SetterType.CONSTRUCTOR; - } else { - setterType = setter != null ? SetterType.METHOD : SetterType.FIELD; + if (!isConstructorParameter) { + throw new CompilerException(var, "The field " + javaName + " is final, but not a constructor parameter. Constructor parameters: " + join(entity.getConstructorParameters(), ", ")); + } } - getterType = getter != null ? GetterType.METHOD : GetterType.FIELD; + setterType = setter != null ? PROPERTY : FIELD; + getterType = getter != null ? PROPERTY : FIELD; type = new TypeRef(var.asType()); element = types.asElement(var.asType()); - javaName = var.getSimpleName().toString(); id = isId(var); processSequenceGenerators(var); } else { @@ -314,8 +374,9 @@ public class EntityHandler extends AbstractHandler { // Skipping fields is closer to what hibernate does. return null; } - setterType = SetterType.METHOD; - getterType = GetterType.METHOD; + isConstructorParameter = false; + setterType = PROPERTY; + getterType = PROPERTY; type = new TypeRef(getter.getReturnType()); element = types.asElement(getter.getReturnType()); id = isId(getter); @@ -348,11 +409,11 @@ public class EntityHandler extends AbstractHandler { TypeHandler typeHandler = generatorConfiguration.typeHandler(type); // TODO: check for configuration conflict notNull = !typeHandler.nullable; - field = new FieldMirror(PRIMITIVE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(PRIMITIVE, isConstructorParameter, setterType, getterType, type, javaName, sqlName, id, notNull, unique); } else if (generatorConfiguration.hasTypeHandler(type)) { throw new CompilerException(var, "Missing type handler for type: " + type.fqName); } else { - field = new FieldMirror(REFERENCE, setterType, getterType, type, javaName, sqlName, id, notNull, unique); + field = new FieldMirror(REFERENCE, isConstructorParameter, setterType, getterType, type, javaName, sqlName, id, notNull, unique); } return field; } @@ -378,7 +439,6 @@ public class EntityHandler extends AbstractHandler { continue; } - System.out.println("entity.type = " + entity.type); DaoGenerator daoGenerator = new DaoGenerator(generatorConfiguration, sqlUnit, entity); writeFile(processingEnv, daoGenerator.generate(), sqlUnit.element(entity)); writeFile(processingEnv, daoGenerator.generateRow(), sqlUnit.element(entity)); @@ -392,6 +452,9 @@ public class EntityHandler extends AbstractHandler { } } + /** + * @return Returns null if the annotation could not be found. + */ private AnnotationMirror findAnnotation(Class c, Element type) { TypeMirror annotationType = elements.getTypeElement(c.getCanonicalName()).asType(); for (AnnotationMirror a : type.getAnnotationMirrors()) { diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java index 80b7283..e9029c7 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/MyProcessor.java @@ -27,7 +27,6 @@ import java.util.HashSet; import java.util.Set; import static io.trygvis.container.compiler.Utils.writeFile; -import static io.trygvis.persistence.generators.SequencesGenerator.generateSequences; import static io.trygvis.persistence.generators.SqlSessionFactoryGenerator.generateSqlSessionFactory; import static io.trygvis.persistence.generators.SqlSessionGenerator.generateSqlSession; import static java.util.Arrays.asList; @@ -145,7 +144,6 @@ public class MyProcessor implements Processor { } entityHandler.phase3(hadErrors); - writeFile(processingEnv, generateSequences(unit), null); // writeFile(processingEnv, generateEntityManagerFactory(unit), null); // writeFile(processingEnv, generateEntityManager(unit), null); writeFile(processingEnv, generateSqlSession(unit), null); 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 3f6816d..e3d0ec8 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 @@ -3,10 +3,12 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.CompilerException; import io.trygvis.container.compiler.model.TypeRef; +import javax.lang.model.element.ExecutableElement; import java.util.ArrayList; import java.util.List; import static java.util.Collections.addAll; +import static java.util.Collections.unmodifiableList; public class EntityMirror implements Comparable { public final GeneratorConfiguration generatorConfiguration; @@ -21,14 +23,19 @@ public class EntityMirror implements Comparable { /** * The nearest @MappedSuperclass */ - public EntityMirror superEntity; + public final EntityMirror superEntity; + private final List constructorParameters; + public ExecutableElement constructor; public EntityMirror(GeneratorConfiguration generatorConfiguration, TypeRef type, boolean concrete, - EntityMirror superEntity, String tableName) { + EntityMirror superEntity, ExecutableElement constructor, List constructorParameters, + String tableName) { this.generatorConfiguration = generatorConfiguration; this.type = type; this.concrete = concrete; this.superEntity = superEntity; + this.constructor = constructor; + this.constructorParameters = unmodifiableList(constructorParameters); if (concrete) { this.tableName = tableName; @@ -67,6 +74,14 @@ public class EntityMirror implements Comparable { return fields; } + public List getConstructorParameters() { + return constructorParameters; + } + + public boolean hasConstructorParameter(String parameter) { + return constructorParameters.contains(parameter); + } + // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java index dd759ef..c235c77 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java @@ -2,16 +2,20 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.model.TypeRef; +import javax.persistence.AccessType; + import static io.trygvis.container.compiler.Utils.toGetterName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; +import static javax.persistence.AccessType.FIELD; /** * TODO: a single field might have to be mapped to multiple sql columns. */ public class FieldMirror { public final FieldType fieldType; - public final SetterType setterType; - public final GetterType getterType; + public final boolean constructorParam; + public final AccessType setterType; + public final AccessType getterType; public final TypeRef type; public final String javaName; public final String sqlName; @@ -24,20 +28,10 @@ public class FieldMirror { REFERENCE, } - public enum SetterType { - CONSTRUCTOR, - FIELD, - METHOD, - } - - public enum GetterType { - FIELD, - METHOD, - } - - public FieldMirror(FieldType fieldType, SetterType setterType, GetterType getterType, TypeRef type, String javaName, - String sqlName, boolean id, boolean notNull, boolean unique) { + public FieldMirror(FieldType fieldType, boolean constructorParam, AccessType setterType, AccessType getterType, + TypeRef type, String javaName, String sqlName, boolean id, boolean notNull, boolean unique) { this.fieldType = fieldType; + this.constructorParam = constructorParam; this.setterType = setterType; this.getterType = getterType; this.type = type; @@ -57,7 +51,7 @@ public class FieldMirror { } private String fieldAccessor(String o) { - if (getterType == GetterType.FIELD) { + if (getterType == FIELD) { return o + "." + javaName; } return o + "." + toGetterName(javaName) + "()"; @@ -67,6 +61,7 @@ public class FieldMirror { public String toString() { return "FieldMirror{" + "fieldType=" + fieldType + + ", constructorParam=" + constructorParam + ", setterType=" + setterType + ", getterType=" + getterType + ", type=" + type + diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java index 7cd3f59..b9b65a5 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java @@ -26,9 +26,10 @@ import static io.trygvis.container.compiler.Utils.*; import static io.trygvis.container.compiler.model.TypeRef.VOID; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.FieldMirror.SetterType; import static java.lang.String.format; import static java.lang.reflect.Modifier.PUBLIC; +import static javax.persistence.AccessType.FIELD; +import static javax.persistence.AccessType.PROPERTY; import static org.apache.commons.lang.StringUtils.join; public class DaoGenerator { @@ -51,16 +52,17 @@ public class DaoGenerator { g.add(new Constructor(p, "super(" + session.name + ");")); TypeRef stringType = g.imports.add(String.class); + TypeRef stringArrayType = g.imports.add(String[].class); TypeRef sqlEntityDescType = g.imports.add(SqlEntityMeta.class); TypeRef sqlException = g.imports.add(SQLException.class); // TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type); FieldRef createTableSql = g.addPublicStaticFinalField(stringType, "createTableSql"). value(toJavaString(createTableSql())); - g.add(new MethodRef(PUBLIC, stringType, "createTableSql", "return createTableSql;")); + g.add(new MethodRef(PUBLIC, stringArrayType, "createTableSql", "return new String[]{createTableSql};")); FieldRef dropTableSql = g.addPublicStaticFinalField(stringType, "dropTableSql"). value(toJavaString(dropTableSql())); - g.add(new MethodRef(PUBLIC, stringType, "dropTableSql", "return dropTableSql;")); + g.add(new MethodRef(PUBLIC, stringArrayType, "dropTableSql", "return new String[]{dropTableSql};")); g.addPublicStaticFinalField(stringType, "insertIntoSql"). value(toJavaString(insertIntoSql())); g.addPublicStaticFinalField(stringType, "deleteFromSql"). @@ -277,7 +279,7 @@ public class DaoGenerator { Parameters.ParameterRef row = p.addParameter(this.entity.rowType, "row"); List body = new ArrayList<>(); - List cArgs = new ArrayList<>(); + String[] cArgs = new String[entity.getConstructorParameters().size()]; List method = new ArrayList<>(); for (int i = 0; i < entity.getFields().size(); i++) { FieldMirror field = this.entity.getFields().get(i); @@ -292,11 +294,13 @@ public class DaoGenerator { // body.add(x); } - if (field.setterType == SetterType.CONSTRUCTOR) { - cArgs.add(value); - } else if (field.setterType == SetterType.METHOD) { + if (field.constructorParam) { + System.out.println("entity.getConstructorParameters() = " + entity.getConstructorParameters()); + System.out.println("field.javaName = " + field.javaName); + cArgs[entity.getConstructorParameters().indexOf(field.javaName)] = value; + } else if (field.setterType == PROPERTY) { method.add("_entity." + toSetterName(field.javaName) + "(" + value + ");"); - } else if (field.setterType == SetterType.FIELD) { + } else if (field.setterType == FIELD) { method.add("_entity." + field.javaName + " = " + value + ";"); } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java index 08a7f45..3ca191f 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java @@ -22,10 +22,10 @@ import java.util.List; import static io.trygvis.container.compiler.Utils.toGetterName; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; -import static io.trygvis.persistence.FieldMirror.GetterType; import static java.lang.reflect.Modifier.PUBLIC; import static java.lang.reflect.Modifier.STATIC; import static java.util.Collections.singletonList; +import static javax.persistence.AccessType.FIELD; import static org.apache.commons.lang.StringUtils.join; public class DaoUtilsGenerator { @@ -134,7 +134,7 @@ public class DaoUtilsGenerator { List arguments = new ArrayList<>(); arguments.add(con.name); FieldMirror field = entity.getIdField(); - if (field.getterType == GetterType.FIELD) { + if (field.getterType == FIELD) { arguments.add(o.name + "." + field.javaName); } else { arguments.add(o.name + "." + toGetterName(field.javaName) + "()"); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java deleted file mode 100644 index 07823af..0000000 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SequencesGenerator.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.trygvis.persistence.generators; - -import io.trygvis.container.compiler.SqlUnitModel; -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.SequenceMirror; - -import java.util.ArrayList; -import java.util.List; - -import static io.trygvis.container.compiler.Utils.toJavaString; -import static java.lang.reflect.Modifier.PUBLIC; -import static org.apache.commons.lang.StringUtils.capitalize; -import static org.apache.commons.lang.StringUtils.join; - -public class SequencesGenerator { - public static ClassG generateSequences(SqlUnitModel unit) { - TypeRef sequences = new TypeRef(unit.getPackageName() + ".Sequences"); - ClassG g = new ClassG(PUBLIC, sequences); - List creates = new ArrayList<>(); - List drops = new ArrayList<>(); - for (SequenceMirror sequence : unit.getSequences().values()) { - TypeRef stringType = g.imports.add(String.class); - String value = "CREATE SEQUENCE " + sequence.sequenceName + ";"; - FieldRef f = g.addPublicStaticFinalField(stringType, "create" + capitalize(sequence.name)). - value(toJavaString(value)); - creates.add(f.name); - - f = g.addPublicStaticFinalField(stringType, "drop" + capitalize(sequence.name)). - value(toJavaString("DROP SEQUENCE " + sequence.sequenceName) + ";"); - drops.add(f.name); - - } - g.addPublicStaticFinalField(new TypeRef(String[].class), "createSequences"). - value("new String[]{" + join(creates, ", ") + "}"); - g.addPublicStaticFinalField(new TypeRef(String[].class), "dropSequences"). - value("new String[]{" + join(drops, ", ") + "}"); - return g; - } -} diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java index 7b6f667..697b262 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionFactoryGenerator.java @@ -9,7 +9,9 @@ import io.trygvis.container.compiler.model.MethodRef; import io.trygvis.container.compiler.model.Parameters; import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.persistence.EntityMirror; +import io.trygvis.persistence.SequenceMirror; import io.trygvis.persistence.sql.SqlEntityMeta; +import io.trygvis.persistence.sql.SqlSequenceMeta; import io.trygvis.persistence.sql.SqlSessionFactory; import io.trygvis.persistence.sql.SqlUnit; @@ -20,6 +22,8 @@ import java.util.ArrayList; import java.util.List; import static io.trygvis.container.compiler.Utils.toClassName; +import static io.trygvis.container.compiler.Utils.toJavaString; +import static java.lang.String.format; import static java.lang.reflect.Modifier.*; import static org.apache.commons.lang.StringUtils.join; @@ -32,30 +36,50 @@ public class SqlSessionFactoryGenerator { ClassG g = new ClassG(PUBLIC, ssfType). extendsType(new TypeRef(SqlSessionFactory.class).args(ssType)); - List s = new ArrayList<>(); + List es = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { if (!entity.concrete) { continue; } - s.add(entity.daoType.plainName + ".desc"); + es.add(entity.daoType.plainName + ".desc"); } TypeRef sqlEntityMetaArrayType = new TypeRef(SqlEntityMeta[].class); - FieldRef entities = g.addField(PUBLIC | STATIC, sqlEntityMetaArrayType, "entities"). - value("new " + sqlEntityMetaArrayType + "{" + join(s, ", ") + "}"); + FieldRef entities = g.addField(PRIVATE | STATIC, sqlEntityMetaArrayType, "entities"). + value(format("new " + sqlEntityMetaArrayType + "{%n" + join(es, ", %n") + "%n}")); - g.add(constructor(entities, g.imports)); + TypeRef sqlSequenceMetaArrayType = new TypeRef(SqlSequenceMeta[].class); + List ss = generateSequences(unit, g.imports); + FieldRef sequences = g.addField(PRIVATE | STATIC, sqlSequenceMetaArrayType, "sequences"). + value(format("new " + sqlSequenceMetaArrayType + "{%n" + join(ss, ", %n") + "%n}")); + + g.add(constructor(entities, sequences, g.imports)); g.add(newSession(unit, ssType, g.imports)); return g; } - private static Constructor constructor(FieldRef entities, Imports imports) { + public static List generateSequences(SqlUnitModel unit, Imports imports) { + TypeRef sqlSequenceMetaType = imports.add(SqlSequenceMeta.class); + List fields = new ArrayList<>(); + for (SequenceMirror sequence : unit.getSequences().values()) { + String create = "CREATE SEQUENCE " + sequence.sequenceName; + String drop = "DROP SEQUENCE " + sequence.sequenceName; + + fields.add(format("new " + sqlSequenceMetaType.plainName + "(" + toJavaString(sequence.sequenceName) + ",%n" + + toJavaString(create) + ",%n" + + toJavaString(drop) + ")")); + } + + return fields; + } + + private static Constructor constructor(FieldRef entities, FieldRef sequences, Imports imports) { TypeRef dataSourceType = imports.add(DataSource.class); TypeRef sqlUnitType = imports.add(SqlUnit.class); Parameters p = new Parameters(); Parameters.ParameterRef ds = p.addParameter(dataSourceType, "ds"); ArrayList body = new ArrayList<>(); - body.add("super(new " + sqlUnitType.plainName + "(" + entities.name + "), " + ds.name + ");"); + body.add("super(new " + sqlUnitType.plainName + "(" + entities.name + "," + sequences.name + "), " + ds.name + ");"); return new Constructor(p, body); } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java index 8e32cfe..90309e4 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/SqlSessionGenerator.java @@ -16,13 +16,17 @@ import io.trygvis.persistence.sql.SqlSession; import java.io.IOException; import java.sql.Connection; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import static io.trygvis.container.compiler.Utils.toFieldName; import static io.trygvis.container.compiler.model.Parameters.ParameterRef; +import static java.lang.String.format; +import static java.lang.reflect.Modifier.FINAL; import static java.lang.reflect.Modifier.PUBLIC; +import static org.apache.commons.lang.StringUtils.join; public class SqlSessionGenerator { public static ClassG generateSqlSession(SqlUnitModel unit) throws IOException { @@ -41,18 +45,33 @@ public class SqlSessionGenerator { daoFields.put(entity, f); } - g.add(constructor(unit, g.imports, daoFields)); + TypeRef sqlDaoType = new TypeRef(SqlDao.class); + TypeRef listOfDaos = g.imports.add(new TypeRef(List.class).args(sqlDaoType)); + FieldRef daos = new FieldRef(PUBLIC | FINAL, listOfDaos, "daos"); + + g.add(daos); + g.add(constructor(unit, g.imports, daoFields, daos)); g.add(getSqlDao(unit, g.imports, daoFields)); + g.add(getDaos(g.imports, daos)); return g; } - private static Constructor constructor(SqlUnitModel unit, Imports imports, Map daoFields) { + private static MethodRef getDaos(Imports imports, FieldRef daos) { + TypeRef sqlDaoType = new TypeRef(SqlDao.class); + TypeRef listOfDaos = imports.add(new TypeRef(List.class).args(sqlDaoType)); + return new MethodRef(PUBLIC, listOfDaos, "getDaos", "return " + daos.name + ";"); + } + + private static Constructor constructor(SqlUnitModel unit, Imports imports, Map daoFields, FieldRef daos) { + TypeRef arraysType = imports.add(Arrays.class); + Parameters p = new Parameters(); ParameterRef c = p.addParameter(imports.add(Connection.class), "c"); List body = new ArrayList<>(); body.add("super(" + c.name + ");"); + List daoNames = new ArrayList<>(); for (EntityMirror entity : unit.getEntities().values()) { if (!entity.concrete) { continue; @@ -60,7 +79,9 @@ public class SqlSessionGenerator { FieldRef f = daoFields.get(entity); body.add("this." + f.name + " = new " + entity.daoType.plainName + "(this);"); + daoNames.add(f.name); } + body.add(format("this." + daos.name + " = " + arraysType.plainName + ".asList(new SqlDao[]{%n" + join(daoNames, ", %n") + "%n});")); return new Constructor(p, body); } diff --git a/container-compiler-plugin/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/container-compiler-plugin/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000..d8aa899 --- /dev/null +++ b/container-compiler-plugin/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +io.trygvis.container.compiler.MyProcessor 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 4fa9e87..e7affa3 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 @@ -41,7 +41,6 @@ public class ProcessorTest { "io.trygvis.persistence.test.basic.ChildEntity", }, new String[]{ - "io.trygvis.persistence.test.basic.Sequences", "io.trygvis.persistence.test.basic.BasicSqlSession", "io.trygvis.persistence.test.basic.BasicSqlSessionFactory", "io.trygvis.persistence.test.basic.PersonDao", @@ -52,9 +51,9 @@ public class ProcessorTest { }, new Object[]{ new String[]{ "io.trygvis.persistence.test.inheritance.package-info", - "io.trygvis.persistence.test.inheritance.A",}, + "io.trygvis.persistence.test.inheritance.A", + }, new String[]{ - "io.trygvis.persistence.test.inheritance.Sequences", "io.trygvis.persistence.test.inheritance.InheritanceSqlSession", "io.trygvis.persistence.test.inheritance.InheritanceSqlSessionFactory", "io.trygvis.persistence.test.inheritance.DDao", 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 c978ec9..a76c640 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 @@ -11,13 +11,14 @@ import org.testng.annotations.Test; import java.io.CharArrayWriter; import java.io.PrintWriter; +import java.util.Collections; import static io.trygvis.container.compiler.Utils.EOL; import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE; import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE; -import static io.trygvis.persistence.FieldMirror.GetterType; -import static io.trygvis.persistence.FieldMirror.SetterType; import static java.lang.String.format; +import static javax.persistence.AccessType.FIELD; +import static javax.persistence.AccessType.PROPERTY; import static org.testng.Assert.assertEquals; public class EntityMirrorTest { @@ -25,19 +26,19 @@ public class EntityMirrorTest { GeneratorConfiguration generatorConfiguration = new GeneratorConfiguration(); static TypeRef entityType = new TypeRef("Wat"); - static FieldMirror idLong = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + static FieldMirror idLong = new FieldMirror(PRIMITIVE, true, FIELD, FIELD, new TypeRef(Long.class), "id", "id", true, false, true); - static FieldMirror idString = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + static FieldMirror idString = new FieldMirror(PRIMITIVE, true, FIELD, FIELD, new TypeRef(String.class), "id", "id", true, false, true); - static FieldMirror idMethod = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.METHOD, + static FieldMirror idMethod = new FieldMirror(PRIMITIVE, true, PROPERTY, PROPERTY, new TypeRef(Long.class), "id", "id", true, false, true); - static FieldMirror name = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + static FieldMirror name = new FieldMirror(PRIMITIVE, true, FIELD, FIELD, new TypeRef(String.class), "name", "name", false, false, false); - static FieldMirror age = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.FIELD, + static FieldMirror age = new FieldMirror(PRIMITIVE, true, FIELD, FIELD, new TypeRef(Integer.class), "age", "age", false, true, false); - static FieldMirror year = new FieldMirror(PRIMITIVE, SetterType.CONSTRUCTOR, GetterType.METHOD, + static FieldMirror year = new FieldMirror(PRIMITIVE, true, PROPERTY, PROPERTY, new TypeRef(Integer.class), "year", "year", false, true, false); - static FieldMirror ref = new FieldMirror(REFERENCE, SetterType.CONSTRUCTOR, GetterType.FIELD, + static FieldMirror ref = new FieldMirror(REFERENCE, true, FIELD, FIELD, entityType, "parent", "parent", false, false, false); @DataProvider(name = "insertIntoSql", parallel = true) @@ -78,7 +79,8 @@ public class EntityMirrorTest { @Test(dataProvider = "insertIntoSql") public void testInsertIntoSql(FieldMirror[] fields, String insert, String delete, String create) throws Exception { - EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table"); + EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, null, + Collections.emptyList(), "my_table"); for (FieldMirror field : fields) { myTable.add(field); } @@ -127,7 +129,8 @@ public class EntityMirrorTest { } private MethodRef insertInto(FieldMirror... fields) { - EntityMirror myTable = new EntityMirror(generatorConfiguration, entityType, true, null, "my_table"); + EntityMirror myTable = new EntityMirror(generatorConfiguration, entityType, true, null, null, + Collections.emptyList(), "my_table"); myTable.add(fields); SqlUnitModel unit = new SqlUnitModel().add(myTable); return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).insertInto(new Imports()); @@ -151,7 +154,8 @@ public class EntityMirrorTest { } private MethodRef delete(FieldMirror... fields) { - EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table"); + EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, null, + Collections.emptyList(), "my_table"); myTable.add(fields); SqlUnitModel unit = new SqlUnitModel().add(myTable); return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).delete(new Imports()); @@ -181,7 +185,8 @@ public class EntityMirrorTest { } private MethodRef deleteById(FieldMirror... fields) { - EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, "my_table"); + EntityMirror myTable = new EntityMirror(new GeneratorConfiguration(), entityType, true, null, null, + Collections.emptyList(), "my_table"); myTable.add(fields); SqlUnitModel unit = new SqlUnitModel().add(myTable); return new DaoUtilsGenerator(unit, generatorConfiguration, myTable).deleteById(new Imports()); diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java index 208ee9a..29ce1b2 100644 --- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/ChildEntity.java @@ -1,5 +1,7 @@ package io.trygvis.persistence.test.basic; +import io.trygvis.persistence.sql.SqlConstructor; + import javax.persistence.Entity; @Entity @@ -8,6 +10,7 @@ public class ChildEntity extends ParentEntity { public final int favoriteNumber; + @SqlConstructor public ChildEntity(Long id, String name, int favoriteNumber) { super(id); this.name = name; diff --git a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java index 3cbdb84..6b1efb5 100644 --- a/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java +++ b/container-compiler-plugin/src/test/resources/io/trygvis/persistence/test/basic/Person.java @@ -30,7 +30,8 @@ public class Person { // @OrderBy("birthDate asc") // private List children = new ArrayList<>(); - public Person(Long id, Date birthDate, Person mother, Gender gender) { + // The parameters is not in the same order as the fields. + public Person(Long id, Person mother, Date birthDate, Gender gender) { this.id = id; this.birthDate = birthDate; this.mother = mother; diff --git a/myapp/pom.xml b/myapp/pom.xml index 8084e3e..b8024cb 100644 --- a/myapp/pom.xml +++ b/myapp/pom.xml @@ -31,9 +31,9 @@ maven-compiler-plugin - + io.trygvis.container.compiler.MyProcessor - + diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java index 7cb6b54..cd76c84 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBookDirect.java @@ -23,6 +23,7 @@ public class AddressBookDirect { sessionFactory = new MyAppSqlSessionFactory(new DriverManagerDataSource(jdbcUrl)); new AddressBookDirect().work(); } catch (EOFException ignore) { + // Happens when the user closes stdin. } } @@ -89,19 +90,15 @@ public class AddressBookDirect { } public void create() throws SQLException { - session.executeUpdate(CompanyDao.createTableSql); - session.executeUpdate(ContactDao.createTableSql); - for (String sql : Sequences.createSequences) { - session.executeUpdate(sql); + for (String s : sessionFactory.getUnit().create()) { + session.executeUpdate(s); } } public void drop() throws SQLException { - for (String sql : Sequences.dropSequences) { - session.executeUpdate(sql); + for (String s : sessionFactory.getUnit().drop()) { + session.executeUpdate(s); } - session.executeUpdate(ContactDao.dropTableSql); - session.executeUpdate(CompanyDao.dropTableSql); } // ----------------------------------------------------------------------- diff --git a/myapp/src/test/java/io/trygvis/container/myapp/AddressBookTest.java b/myapp/src/test/java/io/trygvis/container/myapp/AddressBookTest.java new file mode 100644 index 0000000..4757b54 --- /dev/null +++ b/myapp/src/test/java/io/trygvis/container/myapp/AddressBookTest.java @@ -0,0 +1,26 @@ +package io.trygvis.container.myapp; + +import org.testng.annotations.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class AddressBookTest { + @Test + public void testBasic() throws Exception { + String jdbcUrl = "jdbc:h2:mem:address-book;DB_CLOSE_DELAY=-1"; + MyAppSqlSessionFactory sessionFactory = new MyAppSqlSessionFactory(new DriverManagerDataSource(jdbcUrl)); + + MyAppSqlSession session = sessionFactory.newSession(); + + for (String s : sessionFactory.getUnit().create()) { + session.executeUpdate(s); + } + session.close(); + + session = sessionFactory.newSession(); + session.company.insert(new Company("My Company")); + + Company company = session.company.selectById(1l); + assertThat(company.name).isEqualTo("My Company"); + } +} diff --git a/pom.xml b/pom.xml index 907c9b6..90b2b43 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,18 @@ io.trygvis.container container-playground 1.0-SNAPSHOT + + + org.easytesting + fest-assert + 1.4 + + + org.testng + testng + 6.8.5 + + @@ -22,16 +34,6 @@ - container-compiler-plugin diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlConstructor.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlConstructor.java new file mode 100644 index 0000000..35511e6 --- /dev/null +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlConstructor.java @@ -0,0 +1,11 @@ +package io.trygvis.persistence.sql; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.CONSTRUCTOR) +@Retention(RetentionPolicy.CLASS) +public @interface SqlConstructor { +} diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java index 361fd95..6d3ed67 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlDao.java @@ -27,6 +27,8 @@ public abstract class SqlDao { public abstract List selectWhere(String where) throws SQLException; + public abstract String[] createTableSql(); + // ----------------------------------------------------------------------- // Protected // ----------------------------------------------------------------------- diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSequenceMeta.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSequenceMeta.java new file mode 100644 index 0000000..a3917bf --- /dev/null +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSequenceMeta.java @@ -0,0 +1,13 @@ +package io.trygvis.persistence.sql; + +public class SqlSequenceMeta { + public final String sequenceName; + public final String createSql; + public final String dropSql; + + public SqlSequenceMeta(String sequenceName, String createSql, String dropSql) { + this.sequenceName = sequenceName; + this.createSql = createSql; + this.dropSql = dropSql; + } +} diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java index 43f1206..fc2407d 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSession.java @@ -5,7 +5,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.util.List; -public class SqlSession { +public abstract class SqlSession { // TODO: Make private public final Connection c; diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSessionFactory.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSessionFactory.java index adf36d3..acd0882 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSessionFactory.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlSessionFactory.java @@ -13,6 +13,10 @@ public abstract class SqlSessionFactory { this.ds = ds; } + public SqlUnit getUnit() { + return unit; + } + public T newSession() throws SQLException { Connection c = ds.getConnection(); diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlUnit.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlUnit.java index 2879f5d..8eb6f98 100644 --- a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlUnit.java +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlUnit.java @@ -1,18 +1,37 @@ package io.trygvis.persistence.sql; +import java.util.ArrayList; import java.util.List; -import static java.util.Arrays.asList; +import static java.util.Collections.addAll; +import static java.util.Collections.emptyList; public class SqlUnit { - private final List entities; + private final SqlEntityMeta[] entities; + private final SqlSequenceMeta[] sequences; - public SqlUnit(SqlEntityMeta... entities) { - this.entities = asList(entities); + public SqlUnit(SqlEntityMeta[] entities, SqlSequenceMeta[] sequences) { + this.entities = entities; + this.sequences = sequences; } - public List getEntities() { - return entities; + public List create() { + List strings = new ArrayList<>(); + + for (SqlSequenceMeta meta : sequences) { + addAll(strings, meta.createSql); + } + + for (SqlEntityMeta meta : entities) { + addAll(strings, meta.createTableSql); + } + + return strings; + } + + public List drop() { + // TODO: implement + return emptyList(); } } -- cgit v1.2.3