summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java')
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java265
1 files changed, 265 insertions, 0 deletions
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
new file mode 100644
index 0000000..115223a
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java
@@ -0,0 +1,265 @@
+package io.trygvis.persistence.generators;
+
+import io.trygvis.container.compiler.SqlUnitModel;
+import io.trygvis.container.compiler.model.ClassG;
+import io.trygvis.container.compiler.model.Constructor;
+import io.trygvis.container.compiler.model.Imports;
+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.FieldMirror;
+import io.trygvis.persistence.GeneratorConfiguration;
+import io.trygvis.persistence.TypeHandler;
+import io.trygvis.persistence.sql.AbstractTypedQuery;
+import io.trygvis.persistence.sql.FromResultSet;
+
+import javax.persistence.TypedQuery;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+
+import static io.trygvis.container.compiler.Utils.toGetterName;
+import static io.trygvis.container.compiler.Utils.toSetterName;
+import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD;
+import static io.trygvis.persistence.FieldMirror.AccessorType.METHOD;
+import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
+import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
+import static io.trygvis.persistence.generators.GeneratorUtils.staticVersion;
+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 DaoUtilsGenerator {
+
+ private final SqlUnitModel unit;
+ private final GeneratorConfiguration generatorConfiguration;
+ private final EntityMirror entity;
+
+ public DaoUtilsGenerator(SqlUnitModel unit, GeneratorConfiguration generatorConfiguration, EntityMirror entity) {
+ this.unit = unit;
+ this.generatorConfiguration = generatorConfiguration;
+ this.entity = entity;
+ }
+
+ public ClassG utils() {
+ ClassG g = new ClassG(PUBLIC | STATIC, entity.utilsType);
+ g.add(insertInto(g.imports));
+ g.add(selectById(g.imports));
+ g.add(selectWhere(g.imports));
+ g.add(update(g.imports));
+ g.add(delete(g.imports));
+ g.add(deleteById(g.imports));
+ g.add(query(g.imports));
+ MethodRef fromResultSet = fromResultSet(g.imports);
+ g.add(fromResultSet);
+ g.add(staticVersion(new TypeRef(FromResultSet.class).args(entity.type), "fromResultSet", fromResultSet, g.type));
+ return g;
+ }
+
+ public MethodRef insertInto(Imports imports) {
+ TypeRef sqlExceptionType = imports.add(SQLException.class);
+ TypeRef typesType = imports.add(Types.class);
+ TypeRef conType = imports.add(Connection.class);
+ TypeRef psType = imports.add(PreparedStatement.class);
+ Parameters p = new Parameters();
+ Parameters.ParameterRef con = p.addParameter(conType, "con");
+ Parameters.ParameterRef o = p.addParameter(entity.type, "o");
+
+ List<String> body = new ArrayList<>();
+
+ body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
+ int i = 0;
+ for (FieldMirror field : entity.fields) {
+ // Assume all ID fields are generated for now.
+ if (field.id) {
+ continue;
+ }
+
+ i++;
+
+ TypeHandler typeHandler;
+ String accessor;
+ String setter;
+ if (field.fieldType == PRIMITIVE) {
+ typeHandler = generatorConfiguration.typeHandler(field.type);
+ accessor = field.fieldAccessor(o);
+ setter = " stmt." + typeHandler.setter(i, accessor) + ";";
+ } else {
+ EntityMirror referenced = unit.get(field.type);
+ FieldMirror idField = referenced.getIdField();
+ typeHandler = generatorConfiguration.typeHandler(idField.type);
+ accessor = field.referenceAccessor(o, idField);
+ setter = " stmt." + typeHandler.setter(i, accessor) + ";";
+ accessor = "null";
+ }
+
+ if (field.notNull) {
+ body.add(setter);
+ } else {
+ body.add(" " + field.type + " " + field.javaName + " = " + accessor + ";");
+ body.add(" if (" + field.javaName + " == null) {");
+ body.add(" stmt.setNull(" + i + ", " + typesType + "." + typeHandler.typeName() + ");");
+ body.add(" } else {");
+ body.add(" " + setter);
+ body.add(" }");
+ }
+ }
+ body.add(" stmt.executeUpdate();");
+ body.add("}");
+ return new MethodRef(PUBLIC | STATIC, TypeRef.VOID, "insert" + entity.type.className, p, body).exception(sqlExceptionType);
+ }
+
+ public MethodRef selectById(Imports imports) {
+ Parameters p = new Parameters();
+ p.addParameter(imports.add(Connection.class), "c");
+ p.addParameter(entity.idType, "id");
+ return new MethodRef(PUBLIC | STATIC, entity.type, "select" + entity.type.className + "ById", p,
+ "throw new UnsupportedOperationException(\"Not implemented\");");
+ }
+
+ public MethodRef selectWhere(Imports imports) {
+ TypeRef sqlExceptionType = imports.add(SQLException.class);
+ Parameters p = new Parameters();
+ Parameters.ParameterRef c = p.addParameter(imports.add(Connection.class), "c");
+ Parameters.ParameterRef where = p.addParameter(imports.add(String.class), "where");
+ List<String> body = new ArrayList<>();
+ body.add("String sql = \"SELECT \" + desc.defaultFields + \" FROM " + entity.tableName + " WHERE \" + " + where.name + " + \";\";");
+ body.add("return runQuery(" + c.name + ", sql, " + entity.utilsType + ".fromResultSet" + entity.type.className + ");");
+
+ TypeRef listOfEntityType = new TypeRef(List.class).args(entity.type);
+ return new MethodRef(PUBLIC | STATIC, listOfEntityType, "select" + entity.type.className + "Where", p, body).
+ exception(sqlExceptionType);
+ }
+
+ public MethodRef update(Imports imports) {
+ Parameters p = new Parameters();
+ p.addParameter(imports.add(Connection.class), "c");
+ p.addParameter(entity.type, "entity");
+ return new MethodRef(PUBLIC | STATIC, entity.type, "update" + entity.type.className, p,
+ "throw new UnsupportedOperationException(\"Not implemented\");");
+ }
+
+ public MethodRef delete(Imports imports) {
+ TypeRef conType = imports.add(Connection.class);
+ TypeRef objectType = imports.add(entity.type);
+ Parameters p = new Parameters();
+ Parameters.ParameterRef con = p.addParameter(conType, "con");
+ Parameters.ParameterRef o = p.addParameter(objectType, "o");
+
+ List<String> arguments = new ArrayList<>();
+ arguments.add(con.name);
+ for (FieldMirror field : entity.idFields) {
+ if (field.accessorType == FIELD) {
+ arguments.add(o.name + "." + field.javaName);
+ } else {
+ arguments.add(o.name + "." + toGetterName(field.javaName) + "()");
+ }
+ }
+
+ return new MethodRef(PUBLIC | STATIC, TypeRef.VOID, "delete" + entity.type.className, p,
+ "delete" + entity.type.className + "ById(" + join(arguments, ", ") + ");").exception(imports.add(SQLException.class));
+ }
+
+ public MethodRef deleteById(Imports imports) {
+ TypeRef conType = imports.add(Connection.class);
+ TypeRef psType = imports.add(PreparedStatement.class);
+ Parameters p = new Parameters();
+ Parameters.ParameterRef con = p.addParameter(conType, "con");
+
+ List<String> body = new ArrayList<>();
+
+ body.add("try(" + psType + " stmt = " + con.name + ".prepareStatement(deleteFromSql)) {");
+ for (int i = 0; i < entity.idFields.size(); i++) {
+ FieldMirror field = entity.idFields.get(i);
+ p.addParameter(field.type, field.javaName);
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add(" stmt." + typeHandler.setter(i + 1, field.javaName) + ";");
+ }
+ body.add(" stmt.executeUpdate();");
+ body.add("}");
+
+ return new MethodRef(PUBLIC | STATIC, TypeRef.VOID, "delete" + entity.type.className + "ById", p, body).
+ exception(imports.add(SQLException.class));
+ }
+
+ public ClassG queryType(Imports imports) {
+ TypeRef sqlQueryType = imports.add(AbstractTypedQuery.class).args(entity.type);
+ TypeRef conType = imports.add(Connection.class);
+ TypeRef entityTypedQuery = new TypeRef(entity.type.className + "TypedQuery");
+ TypeRef sqlExceptionType = new TypeRef(SQLException.class);
+
+ Parameters p = new Parameters();
+ Parameters.ParameterRef c = p.addParameter(conType, "c");
+ Constructor constructor = new Constructor(p, singletonList("super(" + c.name + ", " + entity.daoType.className + ".desc);"));
+ ClassG g = new ClassG(PUBLIC | STATIC, entityTypedQuery).
+ extendsType(sqlQueryType).
+ add(constructor);
+ p = new Parameters();
+ Parameters.ParameterRef rs = p.addParameter(new TypeRef(ResultSet.class), "rs");
+ MethodRef fromResultSet = new MethodRef(PUBLIC, entity.type, "fromResultSet", p,
+ "return " + entity.utilsType.className + ".fromResultSet" + entity.type.className + "(" + rs.name + ");").
+ exception(sqlExceptionType);
+ g.add(fromResultSet);
+ return g;
+ }
+
+ public MethodRef query(Imports imports) {
+ TypeRef conType = imports.add(Connection.class);
+ TypeRef typedQueryType = imports.add(TypedQuery.class).args(entity.type);
+ TypeRef entityTypedQuery = new TypeRef(entity.type.className + "TypedQuery");
+
+ Parameters p = new Parameters();
+ Parameters.ParameterRef c = p.addParameter(conType, "c");
+ return new MethodRef(PUBLIC | STATIC, typedQueryType, "query" + entity.type.className, p,
+ "return new " + entityTypedQuery + "(" + c.name + ");");
+ }
+
+ public MethodRef fromResultSet(Imports g) {
+ TypeRef rsType = g.add(ResultSet.class);
+ Parameters p = new Parameters();
+ Parameters.ParameterRef rs = p.addParameter(rsType, "rs");
+
+ List<String> body = new ArrayList<>();
+ List<String> names = new ArrayList<>();
+ for (int i = 0; i < entity.fields.size(); i++) {
+ FieldMirror field = entity.fields.get(i);
+ if (field.accessorType != FIELD) {
+ continue;
+ }
+ if (field.fieldType == PRIMITIVE) {
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add(field.type + " " + field.javaName + " = " + typeHandler.getter(rs.name, i + 1) + ";");
+ } else if (field.fieldType == REFERENCE) {
+ body.add(field.type + " " + field.javaName + " = null;");
+ }
+ names.add(field.javaName);
+ }
+
+ body.add(entity.type + " returnValue = new " + entity.type + "(" + join(names, ", ") + ");");
+
+ for (int i = 0; i < entity.fields.size(); i++) {
+ FieldMirror field = entity.fields.get(i);
+ if (field.accessorType != METHOD) {
+ continue;
+ }
+ if (field.fieldType == PRIMITIVE) {
+ TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
+ body.add("returnValue." + toSetterName(field.javaName) + "(" + typeHandler.getter(rs.name, i + 1) + ");");
+ } else if (field.fieldType == REFERENCE) {
+ body.add("returnValue." + toSetterName(field.javaName) + "(" + null + ");");
+ }
+ names.add(field.javaName);
+ }
+
+ body.add("return returnValue;");
+
+ return new MethodRef(PUBLIC | STATIC, entity.type, "fromResultSet" + entity.type.className, p, body).
+ exception(g.add(SQLException.class));
+ }
+}