From 2b1c32590db960be2b5f62897e65bb10d434cae0 Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 3 Aug 2013 23:13:32 +0200 Subject: wip --- container-compiler-plugin/pom.xml | 11 +- .../trygvis/container/compiler/EntityHandler.java | 38 +++- .../io/trygvis/container/compiler/MyProcessor.java | 8 +- .../container/compiler/TransactionalHandler.java | 18 +- .../trygvis/container/compiler/model/ClassG.java | 186 +++++++++++------ .../container/compiler/model/Constructor.java | 20 +- .../trygvis/container/compiler/model/FieldRef.java | 8 +- .../container/compiler/model/MethodRef.java | 4 +- .../container/compiler/model/ParameterRef.java | 11 - .../container/compiler/model/Parameters.java | 31 ++- .../trygvis/container/compiler/model/TypeRef.java | 69 +++++-- .../java/io/trygvis/persistence/EntityMirror.java | 104 ++++++++-- .../java/io/trygvis/persistence/TypeHandler.java | 40 +++- .../container/compiler/model/TypeRefTest.java | 19 ++ .../io/trygvis/persistence/test/Person.java | 9 +- container-core/pom.xml | 5 - .../io/trygvis/container/myapp/AddressBook.java | 11 +- .../java/io/trygvis/container/myapp/Person.java | 5 + pom.xml | 1 + sql-persistence/pom.xml | 19 ++ .../persistence/sql/AbstractTypedQuery.java | 227 +++++++++++++++++++++ .../io/trygvis/persistence/sql/SqlEntityDesc.java | 11 + 22 files changed, 680 insertions(+), 175 deletions(-) delete mode 100644 container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java create mode 100644 container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java create mode 100644 sql-persistence/pom.xml create mode 100644 sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java create mode 100644 sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java diff --git a/container-compiler-plugin/pom.xml b/container-compiler-plugin/pom.xml index 2e9fff9..d451ee3 100644 --- a/container-compiler-plugin/pom.xml +++ b/container-compiler-plugin/pom.xml @@ -17,7 +17,7 @@ io.trygvis.container - persistence-compile-time + sql-persistence ${project.version} @@ -31,14 +31,11 @@ 6.8.5 test - commons-io commons-io 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 c623af7..19205b1 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 @@ -7,6 +7,7 @@ import io.trygvis.persistence.FieldMirror; import io.trygvis.persistence.GeneratorConfiguration; import io.trygvis.persistence.SqlEntity; import io.trygvis.persistence.TypeHandler; +import io.trygvis.persistence.sql.SqlEntityDesc; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; @@ -28,7 +29,9 @@ import java.util.Set; import static io.trygvis.container.compiler.Utils.toJavaString; 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.stripEnd; public class EntityHandler extends AbstractHandler { private GeneratorConfiguration generatorConfiguration = new GeneratorConfiguration(); @@ -49,7 +52,7 @@ public class EntityHandler extends AbstractHandler { TypeHandler typeHandler = (TypeHandler) typeHandlerClass.newInstance(); String type = entity.asType().toString(); - generatorConfiguration.addTypeHandler(new TypeRef(type, type), typeHandler); + generatorConfiguration.addTypeHandler(new TypeRef(type), typeHandler); System.out.println("Loaded TypeHandler for " + type + " through " + typeHandlerClass.getCanonicalName()); break; } @@ -105,18 +108,33 @@ public class EntityHandler extends AbstractHandler { } public void generate(EntityMirror entityMirror) throws IOException { - ClassG g = new ClassG(entityMirror.daoType); - g.addPublicStaticFinalField(String.class, "createTableSql").value(toJavaString(entityMirror.createTableSql(sqlUnit))); - g.addPublicStaticFinalField(String.class, "dropTableSql").value(toJavaString(entityMirror.dropTableSql())); - g.addPublicStaticFinalField(String.class, "insertIntoSql").value(toJavaString(entityMirror.insertIntoSql())); - g.addPublicStaticFinalField(String.class, "deleteFromSql").value(toJavaString(entityMirror.deleteFromSql())); + TypeRef stringType = new TypeRef(String.class); + TypeRef sqlEntityDescType = new TypeRef(SqlEntityDesc.class); + + ClassG g = new ClassG(PUBLIC, entityMirror.daoType); + 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())); + g.addPublicStaticFinalField(stringType, "deleteFromSql"). + value(toJavaString(entityMirror.deleteFromSql())); + String desc = "new " + sqlEntityDescType + "(" + + toJavaString(entityMirror.tableName) + ", " + + toJavaString(entityMirror.defaultFields()) + + ")"; + g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc); entityMirror.insertInto(sqlUnit, g); entityMirror.delete(g); entityMirror.deleteById(g); + entityMirror.query(sqlUnit, g); JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(entityMirror.daoType.fqName, sqlUnit.elementForEntity(entityMirror)); try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - g.write(w); + for (String s : g.generate()) { + w.println(stripEnd(s, " ")); + } } } @@ -162,7 +180,7 @@ public class EntityHandler extends AbstractHandler { // TODO: Support a name prefix from @SqlEntitySet TypeRef type = new TypeRef(p + ".Session"); - ClassG g = new ClassG(type); + ClassG g = new ClassG(PUBLIC, type); /* TypeRef conType = g.addImport(Connection.class); @@ -180,7 +198,9 @@ public class EntityHandler extends AbstractHandler { JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile(type.fqName, packageElement); try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - g.write(w); + for (String s : g.generate()) { + w.println(stripEnd(s, " ")); + } } } 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 297b9d8..be0b446 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 @@ -69,12 +69,12 @@ public class MyProcessor implements Processor { @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - System.out.println("io.trygvis.container.compiler.MyProcessor.process"); - System.out.println("annotations = " + annotations); - System.out.println("roundEnv = " + roundEnv); +// System.out.println("io.trygvis.container.compiler.MyProcessor.process"); +// System.out.println("annotations = " + annotations); +// System.out.println("roundEnv = " + roundEnv); try { boolean claimed = work(roundEnv); - System.out.println("claimed = " + claimed); +// System.out.println("claimed = " + claimed); return claimed; } catch (CompilerException e) { e.printStackTrace(System.err); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java index fbd7660..f944b1d 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/TransactionalHandler.java @@ -2,7 +2,6 @@ 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.ParameterRef; import io.trygvis.container.compiler.model.Parameters; import io.trygvis.container.compiler.model.TypeRef; import io.trygvis.container.tx.PlatformTransactionManager; @@ -23,6 +22,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import static java.lang.reflect.Modifier.PUBLIC; import static javax.lang.model.util.ElementFilter.constructorsIn; import static org.springframework.util.StringUtils.collectionToDelimitedString; @@ -42,8 +42,8 @@ public class TransactionalHandler extends AbstractHandler { String p = elements.getPackageOf(element).getQualifiedName().toString(); - ClassG g = new ClassG(new TypeRef(p + "." + className), new TypeRef(targetClassName.toString())); - FieldRef transactionManager = g.addField(PlatformTransactionManager.class, "transactionManager"); + ClassG g = new ClassG(PUBLIC, new TypeRef(p + "." + className)).extendsType(new TypeRef(targetClassName.toString())); + FieldRef transactionManager = g.addField(new TypeRef(PlatformTransactionManager.class), "transactionManager"); for (ExecutableElement constructor : constructorsIn(elements.getAllMembers(element))) { if (!constructor.getModifiers().contains(Modifier.PUBLIC)) { @@ -79,12 +79,12 @@ public class TransactionalHandler extends AbstractHandler { boolean isVoid = kind == TypeKind.VOID; TypeRef returnType = isVoid ? TypeRef.VOID : g.addImport(returnTypeMirror); - List parameters = new ArrayList<>(); + Parameters parameters = new Parameters(); List arguments = new ArrayList<>(); for (VariableElement ve : ee.getParameters()) { // parameters.add("final " + ve.asType().toString() + " " + ve.getSimpleName().toString()); TypeRef k = g.addImport(ve.asType()); - parameters.add(new ParameterRef(k, ve.getSimpleName().toString())); + parameters.addParameter(k, ve.getSimpleName().toString()); arguments.add(ve.getSimpleName().toString()); } @@ -107,12 +107,14 @@ public class TransactionalHandler extends AbstractHandler { body.add(" }"); body.add(" });"); - g.addMethod(body, returnType, ee.getSimpleName().toString(), parameters.toArray(new ParameterRef[arguments.size()])); + g.addMethod(body, returnType, ee.getSimpleName().toString(), parameters); } JavaFileObject sourceFile = processingEnv.getFiler().createSourceFile((p.length() == 0 ? "" : p + ".") + className, element); try (PrintWriter w = new PrintWriter(sourceFile.openWriter())) { - g.write(w); + for (String s : g.generate()) { + w.println(s); + } } } @@ -121,7 +123,7 @@ public class TransactionalHandler extends AbstractHandler { List goesToSuper = new ArrayList<>(); TypeRef k = g.addImport(PlatformTransactionManager.class); - ParameterRef transactionManager = parameters.addParameter(k, "transactionManager"); + Parameters.ParameterRef transactionManager = parameters.addParameter(k, "transactionManager"); for (VariableElement p : constructor.getParameters()) { k = g.addImport(p.asType()); diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java index 857311d..e71bbb7 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ClassG.java @@ -1,31 +1,60 @@ package io.trygvis.container.compiler.model; +import io.trygvis.container.compiler.Utils; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.Generated; import javax.lang.model.type.TypeMirror; -import java.io.PrintWriter; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.TreeSet; +import static io.trygvis.container.compiler.Utils.toJavaString; import static java.lang.reflect.Modifier.*; +import static java.util.Arrays.asList; +import static org.apache.commons.lang.StringUtils.join; import static org.springframework.util.StringUtils.collectionToDelimitedString; public class ClassG { + public final int modifiers; public final TypeRef type; - private final TypeRef extendsClass; + private TypeRef extendsType; + private List implementsTypes = new ArrayList<>(); private final Set imports = new TreeSet<>(); private final Set fields = new TreeSet<>(); private final List methods = new ArrayList<>(); private final List constructors = new ArrayList<>(); + private final List innerClasses = new ArrayList<>(); + + public static class InnerClassG extends ClassG { + public final ClassG parent; - public ClassG(TypeRef type) { - this(type, null); + public InnerClassG(ClassG parent, int modifiers, TypeRef type) { + super(modifiers, type); + this.parent = parent; + } } - public ClassG(TypeRef type, TypeRef extendsClass) { + public ClassG(int modifiers, TypeRef type) { + if ((Modifier.classModifiers() & modifiers) != modifiers) { + throw new RuntimeException("Invalid modifiers for class: " + Modifier.toString(modifiers)); + } + + this.modifiers = modifiers; this.type = type; - this.extendsClass = extendsClass; + } + + public ClassG extendsType(TypeRef extendsType) { + this.extendsType = extendsType; + return this; + } + + public ClassG implementsType(TypeRef... implementsTypes) { + this.implementsTypes.addAll(asList(implementsTypes)); + return this; } public TypeRef addImport(final TypeMirror type) { @@ -38,20 +67,20 @@ public class ClassG { public TypeRef addImport(TypeRef klass) { String fqName = klass.fqName; - String name = klass.name; + String name = klass.toString(); for (TypeRef i : imports) { if (i.fqName.equals(fqName)) { return i; } // If we've already found an import with the same name, use the fq version - if (i.name.equals(name)) { + if (i.plainName.equals(name)) { name = fqName; break; } } - TypeRef ref = new TypeRef(name, fqName); + TypeRef ref = new TypeRef(fqName, name); imports.add(ref); return ref; @@ -64,23 +93,23 @@ public class ClassG { return ref; } - public FieldRef addField(int modifiers, Class klass, String name) { - TypeRef type = addImport(klass); - FieldRef ref = new FieldRef(modifiers, type, name); + public FieldRef addField(int modifiers, TypeRef type, String name) { + TypeRef t = addImport(type); + FieldRef ref = new FieldRef(modifiers, t, name); fields.add(ref); return ref; } - public FieldRef addField(Class klass, String name) { - return addField(PRIVATE | FINAL, klass, name); + public FieldRef addField(TypeRef type, String name) { + return addField(PRIVATE | FINAL, type, name); } - public FieldRef addPublicFinalField(Class klass, String name) { - return addField(PUBLIC | FINAL, klass, name); + public FieldRef addPublicFinalField(TypeRef type, String name) { + return addField(PUBLIC | FINAL, type, name); } - public FieldRef addPublicStaticFinalField(Class klass, String name) { - return addField(PUBLIC | STATIC | FINAL, klass, name); + public FieldRef addPublicStaticFinalField(TypeRef type, String name) { + return addField(PUBLIC | STATIC | FINAL, type, name); } public Constructor addConstructor(Parameters parameters, List body) { @@ -89,92 +118,129 @@ public class ClassG { return constructor; } - public MethodRef addMethod(List body, TypeRef returnType, String name, ParameterRef... parameters) { + public MethodRef addMethod(List body, TypeRef returnType, String name, Parameters parameters) { MethodRef ref = new MethodRef(PUBLIC, returnType, name, parameters, body); methods.add(ref); return ref; } - public MethodRef addStaticMethod(List body, TypeRef returnType, String name, ParameterRef... parameters) { + public MethodRef addStaticMethod(List body, TypeRef returnType, String name, Parameters parameters) { MethodRef ref = new MethodRef(PUBLIC | STATIC, returnType, name, parameters, body); methods.add(ref); return ref; } - public void write(PrintWriter writer) { - if (!type.inUnnamedPackage()) { - writer.println("package " + type.packageName() + ";"); - writer.println(); + public InnerClassG addInnerClass(int modifiers, TypeRef type) { + InnerClassG inner = new InnerClassG(this, modifiers, type); + innerClasses.add(inner); + return inner; + } + + public final List generate() { + TypeRef generatedType = addImport(Generated.class); + + List body = new ArrayList<>(); + boolean isInner = this instanceof InnerClassG; + if (!type.inUnnamedPackage() && !isInner) { + body.add("package " + type.packageName() + ";"); + body.add(""); } - for (TypeRef i : imports) { - if (i.isPrimitive() || i.inUnnamedPackage()) { - continue; + if (!isInner) { + // TODO: Add imports from inner classes + for (TypeRef i : getImports()) { + if (i.isPrimitive() || i.inUnnamedPackage()) { + continue; + } + body.add("import " + i.fqName + ";"); + } + if (!imports.isEmpty()) { + body.add(""); } - writer.println("import " + i.fqName + ";"); - } - if (!imports.isEmpty()) { - writer.println(); } - String extendsString = extendsClass == null ? "" : " extends " + extendsClass.name; + String extendsString = extendsType == null ? "" : " extends " + extendsType; + + if (!implementsTypes.isEmpty()) { + extendsString += " implements " + join(implementsTypes, ", "); + } - writer.println("public class " + type.className + extendsString + " {"); + body.add("@" + generatedType + "(" + toJavaString("SQL Persistence, yay!!") + ")"); + body.add(Modifier.toString(modifiers) + " class " + type.className + extendsString + " {"); for (FieldRef field : fields) { - writer.println(); - writer.println(" " + field.toJava() + ";"); + body.add(""); + body.add(" " + field.toJava() + ";"); + } + + for (InnerClassG innerClass : innerClasses) { + body.add(""); + addAll(1, body, innerClass.generate()); } for (Constructor constructor : constructors) { - writer.println(); - for (String s : constructor.write()) { - writer.println(s); - } + body.add(""); + addAll(1, body, constructor.write()); } for (MethodRef method : methods) { - writer.println(); - write(writer, method); + body.add(""); + addAll(1, body, write(method)); } - writer.println("}"); + body.add("}"); + return body; } - private void write(PrintWriter writer, MethodRef method) { + public static void addAll(int indent, List body, List innerBody) { + String prefix = StringUtils.leftPad("", indent * 4); + for (String s : innerBody) { + body.add(prefix + s); + } + } + + protected Collection getImports() { + List imports = new ArrayList<>(this.imports); + for (InnerClassG c : innerClasses) { + imports.addAll(c.getImports()); + } + return imports; + } + + private List write(MethodRef method) { + List body = new ArrayList<>(); String returnString; if (method.returnType == TypeRef.VOID) { returnString = "void"; } else { - returnString = method.returnType.name; + returnString = method.returnType.toString(); } List parameters = new ArrayList<>(); - for (ParameterRef p : method.parameters) { - parameters.add("final " + p.klass.name + " " + p.name); + for (Parameters.ParameterRef p : method.parameters) { + parameters.add("final " + p.klass + " " + p.name); } - writer.print(" " + - Modifier.toString(method.modifiers) + " " + + String m = Modifier.toString(method.modifiers) + " " + returnString + " " + - method.name + "(" + collectionToDelimitedString(parameters, ", ") + ")"); + method.name + "(" + collectionToDelimitedString(parameters, ", ") + ")"; if (method.exceptions.isEmpty()) { - writer.println(" {"); + body.add(m + " {"); } else { - writer.println(" throws"); ArrayList typeRefs = new ArrayList<>(method.exceptions); - for (int i = 0; i < typeRefs.size(); i++) { + String end = typeRefs.size() == 1 ? " {" : ","; + body.add(m + " throws " + typeRefs.get(0).toString() + end); + for (int i = 1; i < typeRefs.size(); i++) { TypeRef e = typeRefs.get(i); - writer.print(" " + e.name); + String s = " " + e; if (i < typeRefs.size() - 1) { - writer.println(","); + s += ","; } else { - writer.println(" {"); + s += " {"; } + body.add(s); } } - for (String s : method.body) { - writer.print(" "); - writer.println(s); - } - writer.println(" }"); + addAll(1, body, method.body); + body.add("}"); + return body; } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java index f669273..0f3ceeb 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Constructor.java @@ -3,7 +3,8 @@ package io.trygvis.container.compiler.model; import java.util.ArrayList; import java.util.List; -import static org.springframework.util.StringUtils.collectionToDelimitedString; +import static io.trygvis.container.compiler.model.ClassG.addAll; +import static org.apache.commons.lang.StringUtils.join; public class Constructor { @@ -18,20 +19,15 @@ public class Constructor { } public List write() { - List body = new ArrayList<>(); - List ps = new ArrayList<>(); - for (ParameterRef p : parameters) { - ps.add(p.klass.name + " " + p.name); + for (Parameters.ParameterRef p : parameters) { + ps.add(p.klass + " " + p.name); } - String params = collectionToDelimitedString(ps, ", "); - - body.add(" public " + g.type.className + "(" + params + ") {"); - for (String s : this.body) { - body.add(" " + s); - } - body.add(" }"); + List body = new ArrayList<>(); + body.add("public " + g.type.className + "(" + join(ps, ", ") + ") {"); + addAll(1, body, this.body); + body.add("}"); return body; } 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 64bf032..b6df4f2 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 @@ -4,18 +4,18 @@ import java.lang.reflect.Modifier; public class FieldRef implements Comparable { public final int modifiers; - public final TypeRef klass; + public final TypeRef type; public final String name; public String value; - public FieldRef(int modifiers, TypeRef klass, String name) { + public FieldRef(int modifiers, TypeRef type, String name) { this.modifiers = modifiers; - this.klass = klass; + this.type = type; this.name = name; } public String toJava() { - String s = Modifier.toString(modifiers) + " " + klass.name + " " + name; + String s = Modifier.toString(modifiers) + " " + type + " " + name; if (value != null) { s += " = " + value; } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java index ee83fa9..902d25a 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/MethodRef.java @@ -11,11 +11,11 @@ public class MethodRef { public final TypeRef returnType; public final String name; public final int modifiers; - public final ParameterRef[] parameters; + public final Parameters parameters; public final Set exceptions = new TreeSet<>(); public final List body; - public MethodRef(int modifiers, TypeRef returnType, String name, ParameterRef[] parameters, List body) { + public MethodRef(int modifiers, TypeRef returnType, String name, Parameters parameters, List body) { this.modifiers = modifiers; this.returnType = returnType; this.name = name; diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java deleted file mode 100644 index fc69cb1..0000000 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/ParameterRef.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.trygvis.container.compiler.model; - -public class ParameterRef { - public final TypeRef klass; - public final String name; - - public ParameterRef(TypeRef klass, String name) { - this.klass = klass; - this.name = name; - } -} diff --git a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java index cfd29f9..8f76714 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/container/compiler/model/Parameters.java @@ -4,13 +4,30 @@ import java.util.ArrayList; import java.util.List; import java.util.ListIterator; -public class Parameters implements Iterable { +public class Parameters implements Iterable { public static final Parameters noParameters = new Parameters(); private final List parameters = new ArrayList<>(); - public ParameterRef addParameter(TypeRef klass, String name) { + public Parameters() { + } + + public Parameters(TypeRef type, String name) { + addParameter(type, name); + } + public Parameters(TypeRef typeA, String nameA, TypeRef typeB, String nameB) { + addParameter(typeA, nameA); + addParameter(typeB, nameB); + } + + public Parameters(TypeRef typeA, String nameA, TypeRef typeB, String nameB, TypeRef typeC, String nameC) { + addParameter(typeA, nameA); + addParameter(typeB, nameB); + addParameter(typeC, nameC); + } + + public ParameterRef addParameter(TypeRef klass, String name) { while (taken(name)) { name = name + "_"; } @@ -34,4 +51,14 @@ public class Parameters implements Iterable { public ListIterator iterator() { return parameters.listIterator(); } + + public static class ParameterRef { + public final TypeRef klass; + public final String name; + + ParameterRef(TypeRef klass, String name) { + this.klass = klass; + this.name = name; + } + } } 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 c6f958a..9c92e73 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 @@ -2,33 +2,48 @@ package io.trygvis.container.compiler.model; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import java.util.Collections; +import java.util.List; + +import static java.util.Arrays.asList; +import static org.apache.commons.lang.StringUtils.join; public class TypeRef implements Comparable { - public static final TypeRef VOID = new TypeRef("void", "void"); - public static final TypeRef BOOLEAN = new TypeRef("boolean", null); - public static final TypeRef BYTE = new TypeRef("byte", null); - public static final TypeRef SHORT = new TypeRef("short", null); - public static final TypeRef CHAR = new TypeRef("char", null); - public static final TypeRef INT = new TypeRef("int", null); - public static final TypeRef LONG = new TypeRef("long", null); - public static final TypeRef FLOAT = new TypeRef("float", null); - public static final TypeRef DOUBLE = new TypeRef("double", null); + public static final TypeRef VOID = new TypeRef("void"); + public static final TypeRef BOOLEAN = new PrimitiveTypeRef("boolean"); + public static final TypeRef BYTE = new PrimitiveTypeRef("byte"); + public static final TypeRef SHORT = new PrimitiveTypeRef("short"); + public static final TypeRef CHAR = new PrimitiveTypeRef("char"); + public static final TypeRef INT = new PrimitiveTypeRef("int"); + public static final TypeRef LONG = new PrimitiveTypeRef("long"); + public static final TypeRef FLOAT = new PrimitiveTypeRef("float"); + public static final TypeRef DOUBLE = new PrimitiveTypeRef("double"); + + private static class PrimitiveTypeRef extends TypeRef { + private PrimitiveTypeRef(String name) { + super(name); + } + } /** * The name of a class used within a class file. Is either the just the name or the fully qualified name. */ - public final String name; + public final String plainName; public final String className; public final String fqName; + private final boolean primitive; - public TypeRef(String name, String fqName) { - this.name = name; - this.primitive = fqName == null; - this.fqName = fqName == null ? name : fqName; + public final List args; + + private TypeRef(String fqName, String name, boolean primitive, List args) { + this.fqName = fqName; + this.plainName = name; + this.primitive = primitive; + this.args = args; int i = this.fqName.lastIndexOf('.'); if (i == -1) { @@ -43,11 +58,15 @@ public class TypeRef implements Comparable { } public TypeRef(Class klass) { - this(klass.getCanonicalName(), klass.getCanonicalName()); + this(klass.getCanonicalName()); } public TypeRef(String fqName) { - this(fqName, fqName); + this(fqName, fqName, false, Collections.emptyList()); + } + + public TypeRef(String fqName, String name) { + this(fqName, name, false, Collections.emptyList()); } public boolean isPrimitive() { @@ -62,12 +81,20 @@ public class TypeRef implements Comparable { int i = fqName.lastIndexOf('.'); if (i == -1) { - throw new RuntimeException("This type is in the unnamed package: " + name); + throw new RuntimeException("This type is in the unnamed package: " + toString()); } return fqName.substring(0, i); } + public TypeRef args(List args) { + return new TypeRef(fqName, plainName, false, args); + } + + public TypeRef args(TypeRef... args) { + return args(asList(args)); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -88,6 +115,14 @@ public class TypeRef implements Comparable { return fqName.compareTo(o.fqName); } + public String toString() { + String s = plainName; + if(args.isEmpty()) { + return s; + } + return s + "<" + join(args, ", ") + ">"; + } + public static TypeRef find(TypeKind kind) { switch (kind) { case BOOLEAN: 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 8e1602c..74c4829 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,18 +3,26 @@ package io.trygvis.persistence; import io.trygvis.container.compiler.NotImplementedException; import io.trygvis.container.compiler.SqlUnitModel; import io.trygvis.container.compiler.model.ClassG; -import io.trygvis.container.compiler.model.ParameterRef; +import io.trygvis.container.compiler.model.Parameters; import io.trygvis.container.compiler.model.TypeRef; +import io.trygvis.persistence.sql.AbstractTypedQuery; +import io.trygvis.persistence.sql.SqlEntityDesc; +import javax.persistence.TypedQuery; import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import static io.trygvis.container.compiler.model.Parameters.ParameterRef; import static io.trygvis.persistence.FieldMirror.PrimitiveFieldMirror; import static io.trygvis.persistence.FieldMirror.ReferenceFieldMirror; import static java.lang.String.format; +import static java.lang.reflect.Modifier.PUBLIC; +import static java.lang.reflect.Modifier.STATIC; +import static java.util.Collections.singletonList; import static org.apache.commons.lang.StringUtils.join; public class EntityMirror implements Comparable { @@ -30,7 +38,7 @@ public class EntityMirror implements Comparable { this.type = type; this.tableName = tableName; - this.daoType = new TypeRef(type.name + "Dao"); + this.daoType = new TypeRef(type.plainName + "Dao").args(type.args); } public void add(FieldMirror field) { @@ -111,41 +119,51 @@ public class EntityMirror implements Comparable { return "DELETE FROM " + tableName + " WHERE " + join(ss, " AND ") + ";"; } + public String defaultFields() { + List names = new ArrayList<>(); + for (FieldMirror field : fields) { + names.add(field.sqlName); + } + + return join(names, ", "); + } + public void insertInto(SqlUnitModel unit, ClassG g) { TypeRef conType = g.addImport(Connection.class); TypeRef psType = g.addImport(PreparedStatement.class); - TypeRef objectType = g.addImport(type); - ParameterRef con = new ParameterRef(conType, "con"); - ParameterRef object = new ParameterRef(objectType, "o"); + Parameters p = new Parameters(); + ParameterRef con = p.addParameter(conType, "con"); + ParameterRef o = p.addParameter(type, "o"); List body = new ArrayList<>(); - body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {"); + 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) { TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); - body.add(" stmt." + typeHandler.setter(i + 1, "o." + field.javaName) + ";"); + body.add(" stmt." + typeHandler.setter(i + 1, o.name + "." + field.javaName) + ";"); } else if (field instanceof ReferenceFieldMirror) { ReferenceFieldMirror ref = (ReferenceFieldMirror) field; EntityMirror referenced = unit.get(ref.type); FieldMirror idField = referenced.getIdField(); TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); - body.add(" stmt." + typeHandler.setter(i + 1, "o." + field.javaName + "." + idField.javaName) + ";"); + body.add(" stmt." + typeHandler.setter(i + 1, o.name + "." + field.javaName + "." + idField.javaName) + ";"); } } body.add(" stmt.executeUpdate();"); body.add("}"); - g.addStaticMethod(body, TypeRef.VOID, "insertInto", con, object). + g.addStaticMethod(body, TypeRef.VOID, "insertInto", p). exception(g.addImport(SQLException.class)); } public void delete(ClassG g) { TypeRef conType = g.addImport(Connection.class); TypeRef objectType = g.addImport(type); - ParameterRef con = new ParameterRef(conType, "con"); - ParameterRef o = new ParameterRef(objectType, "o"); + Parameters p = new Parameters(); + ParameterRef con = p.addParameter(conType, "con"); + ParameterRef o = p.addParameter(objectType, "o"); List arguments = new ArrayList<>(); arguments.add(con.name); @@ -155,32 +173,76 @@ public class EntityMirror implements Comparable { List body = new ArrayList<>(); body.add("deleteById(" + join(arguments, ", ") + ");"); - g.addStaticMethod(body, TypeRef.VOID, "delete", con, o). + g.addStaticMethod(body, TypeRef.VOID, "delete", p). exception(g.addImport(SQLException.class)); } public void deleteById(ClassG g) { TypeRef conType = g.addImport(Connection.class); TypeRef psType = g.addImport(PreparedStatement.class); - ParameterRef con = new ParameterRef(conType, "con"); - - ParameterRef[] parameters = new ParameterRef[idFields.size() + 1]; - parameters[0] = con; + Parameters p = new Parameters(); + ParameterRef con = p.addParameter(conType, "con"); List body = new ArrayList<>(); - body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {"); + body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {"); for (int i = 0; i < idFields.size(); i++) { FieldMirror field = idFields.get(i); + p.addParameter(field.type, field.javaName); TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); - ParameterRef p = new ParameterRef(field.type, field.javaName); - parameters[i + 1] = p; body.add(" stmt." + typeHandler.setter(i + 1, field.javaName) + ";"); } body.add(" stmt.executeUpdate();"); body.add("}"); - g.addStaticMethod(body, TypeRef.VOID, "deleteById", parameters). + g.addStaticMethod(body, TypeRef.VOID, "deleteById", p). + exception(g.addImport(SQLException.class)); + } + + public void query(SqlUnitModel sqlUnit, ClassG g) { + TypeRef conType = g.addImport(Connection.class); + TypeRef abstractQueryType = g.addImport(AbstractTypedQuery.class).args(type); + TypeRef typedQueryType = g.addImport(TypedQuery.class).args(type); + + Parameters p = new Parameters(); + ParameterRef c = p.addParameter(conType, "c"); + + ClassG typedQuery = g.addInnerClass(PUBLIC | STATIC, new TypeRef(type.className + "TypedQuery")). + extendsType(abstractQueryType); + typedQuery.addConstructor(p, singletonList("super(" + c.name + ", " + daoType.className + ".desc);")); + fromResultSet(sqlUnit, typedQuery); + + List body = new ArrayList<>(); + body.add("return new " + typedQuery.type + "(" + c.name + ");"); + g.addStaticMethod(body, typedQueryType, "query", p); + } + + public void fromResultSet(SqlUnitModel unit, ClassG g) { + TypeRef rsType = g.addImport(ResultSet.class); + Parameters p = new Parameters(); + ParameterRef rs = p.addParameter(rsType, "rs"); + + List body = new ArrayList<>(); + List names = new ArrayList<>(); + for (int i = 0; i < fields.size(); i++) { + FieldMirror field = fields.get(i); + 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) { + ReferenceFieldMirror ref = (ReferenceFieldMirror) field; + EntityMirror referenced = unit.get(ref.type); + FieldMirror idField = referenced.getIdField(); + TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); +// body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";"); + body.add(field.type + " " + field.javaName + " = null;"); + } + names.add(field.javaName); + } + + body.add("return new " + type + "(" + join(names, ", ") + ");"); + + g.addMethod(body, type, "fromResultSet", p). exception(g.addImport(SQLException.class)); } @@ -200,7 +262,7 @@ public class EntityMirror implements Comparable { } @Override - public int compareTo(EntityMirror o) { + public int compareTo(@SuppressWarnings("NullableProblems") EntityMirror o) { return type.compareTo(o.type); } } diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java index 3aacd7a..0454a96 100644 --- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java @@ -1,14 +1,21 @@ package io.trygvis.persistence; public interface TypeHandler { - String setter(int i, String ref); + String setter(int i, String expr); + + String getter(String rs, int i); String sqlType(FieldMirror field); public static class IntTypeHandler implements TypeHandler { @Override - public String setter(int i, String ref) { - return "setInt(" + i + ", " + ref + ")"; + public String setter(int i, String expr) { + return "setInt(" + i + ", " + expr + ")"; + } + + @Override + public String getter(String rs, int i) { + return rs + ".getInt(" + i + ")"; } @Override @@ -19,8 +26,13 @@ public interface TypeHandler { public static class LongTypeHandler implements TypeHandler { @Override - public String setter(int i, String ref) { - return "setLong(" + i + ", " + ref + ")"; + public String setter(int i, String expr) { + return "setLong(" + i + ", " + expr + ")"; + } + + @Override + public String getter(String rs, int i) { + return rs + ".getLong(" + i + ")"; } @Override @@ -31,8 +43,13 @@ public interface TypeHandler { public static class StringTypeHandler implements TypeHandler { @Override - public String setter(int i, String ref) { - return "setString(" + i + ", " + ref + ")"; + public String setter(int i, String expr) { + return "setString(" + i + ", " + expr + ")"; + } + + @Override + public String getter(String rs, int i) { + return rs + ".getString(" + i + ")"; } @Override @@ -43,8 +60,13 @@ public interface TypeHandler { public static class DateTypeHandler implements TypeHandler { @Override - public String setter(int i, String ref) { - return "setTimestamp(" + i + ", new java.sql.Timestamp(" + ref + ".getTime()))"; + public String setter(int i, String expr) { + return "setTimestamp(" + i + ", new java.sql.Timestamp(" + expr + ".getTime()))"; + } + + @Override + public String getter(String rs, int i) { + return "new java.util.Date(" + rs + ".getTimestamp(" + i + ").getTime())"; } @Override diff --git a/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java new file mode 100644 index 0000000..94425cc --- /dev/null +++ b/container-compiler-plugin/src/test/java/io/trygvis/container/compiler/model/TypeRefTest.java @@ -0,0 +1,19 @@ +package io.trygvis.container.compiler.model; + +import org.testng.Assert; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertEquals; + +public class TypeRefTest { + @Test + public void testBasic() { + TypeRef foo = new TypeRef("wat.Foo"); + TypeRef string = new TypeRef(String.class); + TypeRef bar = new TypeRef("wat.Bar").args(string); + TypeRef baz = new TypeRef("woot.Baz").args(bar); + assertEquals(foo.toString(), "wat.Foo"); + assertEquals(bar.toString(), "wat.Bar"); + assertEquals(baz.toString(), "woot.Baz>"); + } +} 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 3f1be35..43a0c78 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 @@ -1,14 +1,11 @@ package io.trygvis.persistence.test; -import io.trygvis.persistence.SqlEntity; - import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; import java.util.Date; @Entity -//@SqlEntity("io.trygvis.persistence.test.PersonTypeHandler") public class Person { @Id public Long id; @@ -24,4 +21,10 @@ public class Person { // @OneToMany(mappedBy = "id") // @OrderBy("birthDate asc") // private List children = new ArrayList<>(); + + public Person(Long id, Date birthDate, Person mother) { + this.id = id; + this.birthDate = birthDate; + this.mother = mother; + } } diff --git a/container-core/pom.xml b/container-core/pom.xml index d17a86a..e16c761 100644 --- a/container-core/pom.xml +++ b/container-core/pom.xml @@ -18,11 +18,6 @@ spring-beans ${version.spring} - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - 1.0.1.Final - org.springframework spring-jdbc 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 c8440ff..ec0bffa 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java @@ -1,11 +1,13 @@ package io.trygvis.container.myapp; +import javax.persistence.TypedQuery; import java.io.BufferedReader; import java.io.EOFException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; +import java.util.List; public class AddressBook { @@ -109,7 +111,14 @@ public class AddressBook { public static class ListCommand implements Command { @Override public void run(Connection c) throws Exception { -// PersonDao.insertInto(c, new Person()); + TypedQuery p = PersonDao.query(c); + + List resultList = p.getResultList(); + for (int i = 0; i < resultList.size(); i++) { + Person person = resultList.get(i); + System.out.println("#" + i); + System.out.println("Name: " + person.name); + } } } } 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 ab883b2..6a7a694 100644 --- a/myapp/src/main/java/io/trygvis/container/myapp/Person.java +++ b/myapp/src/main/java/io/trygvis/container/myapp/Person.java @@ -13,4 +13,9 @@ public class Person { public Person(String name) { this.name = name; } + + public Person(Long id, String name) { + this.id = id; + this.name = name; + } } diff --git a/pom.xml b/pom.xml index e9ea30b..907c9b6 100644 --- a/pom.xml +++ b/pom.xml @@ -37,5 +37,6 @@ container-compiler-plugin myapp container-core + sql-persistence diff --git a/sql-persistence/pom.xml b/sql-persistence/pom.xml new file mode 100644 index 0000000..6d5a56d --- /dev/null +++ b/sql-persistence/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + container-playground + io.trygvis.container + 1.0-SNAPSHOT + + sql-persistence + + + org.hibernate.javax.persistence + hibernate-jpa-2.0-api + 1.0.1.Final + + + diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java new file mode 100644 index 0000000..1cb8405 --- /dev/null +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/AbstractTypedQuery.java @@ -0,0 +1,227 @@ +package io.trygvis.persistence.sql; + +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.NoResultException; +import javax.persistence.NonUniqueResultException; +import javax.persistence.Parameter; +import javax.persistence.PersistenceException; +import javax.persistence.TemporalType; +import javax.persistence.TypedQuery; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public abstract class AbstractTypedQuery implements TypedQuery { + private final Connection c; + private final SqlEntityDesc sqlEntity; + + private int firstResult; + private int maxResults; + + protected AbstractTypedQuery(Connection c, SqlEntityDesc sqlEntity) { + this.c = c; + this.sqlEntity = sqlEntity; + } + + public abstract A fromResultSet(ResultSet rs) throws SQLException; + + @Override + public TypedQuery setMaxResults(int maxResult) { + this.maxResults = maxResult; + return this; + } + + @Override + public TypedQuery setFirstResult(int firstResult) { + this.firstResult = firstResult; + return this; + } + + @Override + public TypedQuery setHint(String hintName, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(Parameter param, T value) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(Parameter param, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(Parameter param, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(String name, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(String name, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(String name, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(int position, Object value) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(int position, Calendar value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setParameter(int position, Date value, TemporalType temporalType) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setFlushMode(FlushModeType flushMode) { + throw new UnsupportedOperationException(); + } + + @Override + public TypedQuery setLockMode(LockModeType lockMode) { + throw new UnsupportedOperationException(); + } + + @Override + public int executeUpdate() { + throw new UnsupportedOperationException(); + } + + @Override + public int getMaxResults() { + return maxResults; + } + + @Override + public int getFirstResult() { + return firstResult; + } + + @Override + public Map getHints() { + throw new UnsupportedOperationException(); + } + + @Override + public Set> getParameters() { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter getParameter(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter getParameter(String name, Class type) { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter getParameter(int position) { + throw new UnsupportedOperationException(); + } + + @Override + public Parameter getParameter(int position, Class type) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isBound(Parameter param) { + throw new UnsupportedOperationException(); + } + + @Override + public T getParameterValue(Parameter param) { + throw new UnsupportedOperationException(); + } + + @Override + public Object getParameterValue(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Object getParameterValue(int position) { + throw new UnsupportedOperationException(); + } + + @Override + public FlushModeType getFlushMode() { + throw new UnsupportedOperationException(); + } + + @Override + public LockModeType getLockMode() { + throw new UnsupportedOperationException(); + } + + @Override + public T unwrap(Class cls) { + throw new UnsupportedOperationException(); + } + + public List getResultList() { + return getResultList(null, null); + } + + public List getResultList(Integer offset, Integer limit) { + String sql = "SELECT " + sqlEntity.defaultFields + " FROM " + sqlEntity.tableName; + + if(offset != null) { + sql += " OFFSET " + offset; + } + if(limit != null) { + sql += " LIMIT " + limit; + } + + sql += ";"; + + List list = new ArrayList<>(); + try (PreparedStatement stmt = c.prepareStatement(sql)) { + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + list.add(fromResultSet(rs)); + } + return list; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + public A getSingleResult() { + List list = getResultList(null, 2); + switch (list.size()) { + case 1: + return list.get(0); + case 0: + throw new NoResultException(); + default: + throw new NonUniqueResultException(); + } + } +} diff --git a/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java new file mode 100644 index 0000000..dbbeed7 --- /dev/null +++ b/sql-persistence/src/main/java/io/trygvis/persistence/sql/SqlEntityDesc.java @@ -0,0 +1,11 @@ +package io.trygvis.persistence.sql; + +public class SqlEntityDesc { + public final String tableName; + public final String defaultFields; + + public SqlEntityDesc(String tableName, String defaultFields) { + this.tableName = tableName; + this.defaultFields = defaultFields; + } +} -- cgit v1.2.3