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/DaoGenerator.java | 214 +++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java (limited to 'container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java') 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 new file mode 100644 index 0000000..d9ac482 --- /dev/null +++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java @@ -0,0 +1,214 @@ +package io.trygvis.persistence.generators; + +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.Constructor; +import io.trygvis.container.compiler.model.FieldRef; +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.SqlDao; +import io.trygvis.persistence.sql.SqlEntityMeta; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import static io.trygvis.container.compiler.Utils.toJavaString; +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 java.lang.String.format; +import static java.lang.reflect.Modifier.PUBLIC; +import static org.apache.commons.lang.StringUtils.join; + +public class DaoGenerator { + + private final GeneratorConfiguration generatorConfiguration; + private final SqlUnitModel unit; + private final EntityMirror entity; + + public DaoGenerator(GeneratorConfiguration generatorConfiguration, SqlUnitModel unit, EntityMirror entity) { + this.generatorConfiguration = generatorConfiguration; + this.unit = unit; + this.entity = entity; + } + + public ClassG generate() throws IOException { + ClassG g = new ClassG(PUBLIC, entity.daoType). + extendsType(new TypeRef(SqlDao.class).args(entity.idType, entity.type)); + Parameters p = new Parameters(); + Parameters.ParameterRef c = p.addParameter(new TypeRef(Connection.class), "c"); + g.add(new Constructor(p, "super(" + c.name + ");")); + + TypeRef stringType = 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;")); + FieldRef dropTableSql = g.addPublicStaticFinalField(stringType, "dropTableSql"). + value(toJavaString(dropTableSql())); + g.add(new MethodRef(PUBLIC, stringType, "dropTableSql", "return dropTableSql;")); + g.addPublicStaticFinalField(stringType, "insertIntoSql"). + value(toJavaString(insertIntoSql())); + g.addPublicStaticFinalField(stringType, "deleteFromSql"). + value(toJavaString(deleteFromSql())); + String desc = "new " + sqlEntityDescType + "(" + + toJavaString(entity.tableName) + ", " + + toJavaString(defaultFields()) + ", " + + createTableSql.name + ", " + + dropTableSql.name + + ")"; + g.addPublicStaticFinalField(sqlEntityDescType, "desc").value(desc); + DaoUtilsGenerator daoUtil = new DaoUtilsGenerator(unit, generatorConfiguration, entity); + g.addInnerClass(daoUtil.queryType(g.imports)); + g.addInnerClass(daoUtil.utils()); + + { + p = new Parameters(); + Parameters.ParameterRef rs = p.addParameter(new TypeRef(ResultSet.class), "rs"); + g.add(new MethodRef(PUBLIC, entity.type, "fromResultSet", p, + "return Utils.fromResultSet" + entity.type.className + "(" + rs.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); + g.add(new MethodRef(PUBLIC, VOID, "insert", p, + "Utils.insert" + this.entity.type.className + "(super.c, " + entity.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef id = p.addParameter(entity.idType, "id"); + g.add(new MethodRef(PUBLIC, entity.type, "selectById", p, + "return Utils.select" + entity.type.className + "ById(super.c, " + id.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef where = p.addParameter(stringType, "where"); + g.add(new MethodRef(PUBLIC, listOfEntityType, "selectWhere", p, + "return Utils.select" + entity.type.className + "Where(super.c, " + where.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); + g.add(new MethodRef(PUBLIC, VOID, "delete", p, + "Utils.delete" + this.entity.type.className + "(super.c, " + entity.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef id = p.addParameter(entity.idType, "id"); + g.add(new MethodRef(PUBLIC, VOID, "deleteById", p, + "Utils.delete" + entity.type.className + "ById(super.c, " + id.name + ");"). + exception(sqlException)); + } + + { + p = new Parameters(); + Parameters.ParameterRef entity = p.addParameter(this.entity.type, "entity"); + g.add(new MethodRef(PUBLIC, VOID, "update", p, + "Utils.update" + this.entity.type.className + "(super.c, " + entity.name + ");"). + exception(sqlException)); + } + + return g; + } + + public String createTableSql() { + List columns = new ArrayList<>(); + for (FieldMirror field : entity.fields) { + String s; + if (field.fieldType == PRIMITIVE) { + TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type); + s = " " + field.sqlName + " " + typeHandler.sqlType(field); + if (field.id) { + s += " PRIMARY KEY"; + } else if (field.notNull) { + s += " NOT NULL"; + } else if (field.unique) { + s += " UNIQUE"; + } + } else if (field.fieldType == REFERENCE) { + EntityMirror referenced = unit.get(field.type); + if (referenced.idFields.size() == 1) { + FieldMirror idField = referenced.idFields.get(0); + TypeHandler typeHandler = generatorConfiguration.typeHandler(idField.type); + s = " " + field.sqlName + " " + typeHandler.sqlType(field); + s += " REFERENCES " + referenced.tableName + "(" + idField.sqlName + ")"; + if (field.notNull) { + s += " NOT NULL"; + } else if (field.unique) { + s += " UNIQUE"; + } + } else { + throw new NotImplementedException(); + } + } else { + throw new RuntimeException("Unknown field type: " + field.getClass()); + } + columns.add(s); + } + + return format("CREATE TABLE " + entity.tableName + "(%n" + + join(columns, ",%n") + + "%n);"); + } + + public String dropTableSql() { + return "DROP TABLE " + entity.tableName + ";"; + } + + public String insertIntoSql() { + List columns = new ArrayList<>(); + List values = new ArrayList<>(); + for (FieldMirror field : entity.fields) { + columns.add(field.sqlName); + if (field.id) { + values.add("nextval('" + unit.getDefaultSequence().sequenceName + "')"); + } else { + values.add("?"); + } + } + + return "INSERT INTO " + entity.tableName + "(" + join(columns, ", ") + ") " + + "VALUES(" + join(values, ", ") + ");"; + } + + public String deleteFromSql() { + List ss = new ArrayList<>(); + for (FieldMirror field : entity.idFields) { + ss.add(field.sqlName + "=?"); + } + + return "DELETE FROM " + entity.tableName + " WHERE " + join(ss, " AND ") + ";"; + } + + public String defaultFields() { + List names = new ArrayList<>(); + for (FieldMirror field : entity.fields) { + names.add(field.sqlName); + } + + return join(names, ", "); + } +} -- cgit v1.2.3