From 5a1256a8ed931f7a5ba05c4328353411bae31f2b Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 10 Aug 2013 15:44:58 +0200 Subject: o Moving code out to separate generators. o Creating SqlSession and SqlSessionFactory. --- .../persistence/generators/DaoUtilsGenerator.java | 265 +++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java (limited to 'container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoUtilsGenerator.java') 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 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 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 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 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 body = new ArrayList<>(); + List 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)); + } +} -- cgit v1.2.3