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 java.sql.Connection; import java.sql.PreparedStatement; 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.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 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 = o.name + "." + field.javaName; String idAccessor = field.referenceAccessor(o, idField); setter = " stmt." + typeHandler.setter(i, idAccessor) + ";"; } 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 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.getterType == GetterType.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); return g; } // 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)); // } }