summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java')
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/generators/DaoGenerator.java214
1 files changed, 214 insertions, 0 deletions
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<String> 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<String> columns = new ArrayList<>();
+ List<String> 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<String> 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<String> names = new ArrayList<>();
+ for (FieldMirror field : entity.fields) {
+ names.add(field.sqlName);
+ }
+
+ return join(names, ", ");
+ }
+}