summaryrefslogtreecommitdiff
path: root/container-compiler-plugin/src/main/java/io/trygvis/persistence
diff options
context:
space:
mode:
Diffstat (limited to 'container-compiler-plugin/src/main/java/io/trygvis/persistence')
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java65
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java63
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java41
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/SqlEntity.java17
-rw-r--r--container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java26
5 files changed, 212 insertions, 0 deletions
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
new file mode 100644
index 0000000..fe50e17
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
@@ -0,0 +1,65 @@
+package io.trygvis.persistence;
+
+import io.trygvis.container.compiler.model.ClassG;
+import io.trygvis.container.compiler.model.ParameterRef;
+import io.trygvis.container.compiler.model.TypeRef;
+
+import javax.lang.model.type.TypeMirror;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.apache.commons.lang.StringUtils.join;
+
+public class EntityMirror {
+ public final GeneratorSupport generatorSupport;
+ public final List<FieldMirror> fields = new ArrayList<>();
+ public final TypeMirror javaName;
+ public final String tableName;
+
+ public EntityMirror(GeneratorSupport generatorSupport, TypeMirror javaName, String tableName) {
+ this.generatorSupport = generatorSupport;
+ this.javaName = javaName;
+ this.tableName = tableName;
+ }
+
+ public void add(FieldMirror field) {
+ fields.add(field);
+ }
+
+ public String insertIntoSql() {
+ List<String> names = new ArrayList<>();
+ List<String> placeholders = new ArrayList<>();
+ for (FieldMirror field : fields) {
+ names.add(field.sqlName);
+ placeholders.add("?");
+ }
+
+ return "INSERT INTO " + tableName + "(" + join(names, ", ") + ") " +
+ "VALUES(" + join(placeholders, ", ") + ");";
+ }
+
+ public void insertInto(ClassG g) {
+ TypeRef conType = g.addImport(Connection.class);
+ TypeRef psType = g.addImport(PreparedStatement.class);
+ TypeRef objectType = g.addImport(javaName);
+ ParameterRef con = new ParameterRef(conType, "con");
+ ParameterRef object = new ParameterRef(objectType, "o");
+
+ List<String> body = new ArrayList<>();
+
+ body.add("try(" + psType.name + " stmt = " + con.name + ".prepareStatement(insertIntoSql)) {");
+ for (int i = 0; i < fields.size(); i++) {
+ FieldMirror field = fields.get(i);
+ TypeHandler typeHandler = generatorSupport.typeHandler(field.element);
+ body.add(" stmt." + typeHandler.resultSetSetter(i + 1, "o", field) + ";");
+ }
+ body.add(" stmt.executeUpdate();");
+ body.add("}");
+
+ g.addMethod(body, TypeRef.VOID, "insertInto", con, object).
+ exception(g.addImport(SQLException.class));
+ }
+}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
new file mode 100644
index 0000000..e14fb9f
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
@@ -0,0 +1,63 @@
+package io.trygvis.persistence;
+
+import javax.lang.model.element.VariableElement;
+
+import static io.trygvis.persistence.FieldMirror.FieldType.PRIMITIVE;
+import static io.trygvis.persistence.FieldMirror.FieldType.REFERENCE;
+
+/**
+ * TODO: a single field might have to be mapped to multiple sql columns.
+ */
+public abstract class FieldMirror {
+ public final FieldType fieldType;
+ public final VariableElement element;
+ public final String javaName;
+ public final String sqlName;
+ public final boolean notNull;
+
+ public enum FieldType {
+ PRIMITIVE,
+ REFERENCE,
+ }
+
+ protected FieldMirror(FieldType fieldType, VariableElement element, String javaName, String sqlName, boolean notNull) {
+ this.fieldType = fieldType;
+ this.element = element;
+ this.javaName = javaName;
+ this.sqlName = sqlName;
+ this.notNull = notNull;
+ }
+
+ public static class PrimitiveFieldMirror extends FieldMirror {
+ public PrimitiveFieldMirror(VariableElement element, String javaName, String sqlName, boolean notNull) {
+ super(PRIMITIVE, element, javaName, sqlName, notNull);
+ }
+
+ @Override
+ public String toString() {
+ return "PrimitiveFieldMirror{" +
+ "javaName='" + javaName + '\'' +
+ ", sqlName='" + sqlName + '\'' +
+ ", notNull=" + notNull +
+ '}';
+ }
+ }
+
+ public static class ReferenceFieldMirror extends FieldMirror {
+ public ReferenceFieldMirror(VariableElement element, String javaName, String sqlName, boolean notNull) {
+ super(REFERENCE, element, javaName, sqlName, notNull);
+ }
+
+ @Override
+ public String toString() {
+ return "ReferenceFieldMirror{" +
+ "javaName='" + javaName + '\'' +
+ ", sqlName='" + sqlName + '\'' +
+ ", notNull=" + notNull +
+ '}';
+ }
+ }
+
+ @Override
+ public abstract String toString();
+}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java
new file mode 100644
index 0000000..7ac30d9
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/GeneratorSupport.java
@@ -0,0 +1,41 @@
+package io.trygvis.persistence;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import java.util.HashMap;
+import java.util.Map;
+
+public class GeneratorSupport {
+
+ private final Map<String, TypeHandler> primitiveTypeHandlers = new HashMap<>();
+ private final Map<String, TypeHandler> typeHandlers = new HashMap<>();
+
+ {
+ typeHandlers.put("java.lang.Integer", new TypeHandler.IntTypeHandler());
+ typeHandlers.put("java.lang.Long", new TypeHandler.LongTypeHandler());
+ typeHandlers.put("java.util.Date", new TypeHandler.DateTypeHandler());
+
+ primitiveTypeHandlers.putAll(typeHandlers);
+ }
+
+ public void addTypeHandler(String type, TypeHandler typeHandler) {
+ typeHandlers.put(type, typeHandler);
+ }
+
+ public TypeHandler typeHandler(Element element) {
+ String type = element.asType().toString();
+ TypeHandler typeHandler = typeHandlers.get(type);
+ if (typeHandler == null)
+ throw new RuntimeException("Unsupported field type: " + type);
+ return typeHandler;
+ }
+
+ public boolean isPrimitive(TypeMirror type) {
+ return primitiveTypeHandlers.containsKey(type.toString());
+ }
+
+ public boolean hasTypeHandler(TypeMirror type) {
+ return typeHandlers.containsKey(type.toString());
+ }
+}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/SqlEntity.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/SqlEntity.java
new file mode 100644
index 0000000..e298eee
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/SqlEntity.java
@@ -0,0 +1,17 @@
+package io.trygvis.persistence;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface SqlEntity {
+ /**
+ * The name of a class that implements {@link io.trygvis.persistence.TypeHandler}.
+ *
+ * The class needs to be available at compile time, but not runtime.
+ */
+ String value();
+}
diff --git a/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java
new file mode 100644
index 0000000..252f4b4
--- /dev/null
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/TypeHandler.java
@@ -0,0 +1,26 @@
+package io.trygvis.persistence;
+
+public interface TypeHandler {
+ String resultSetSetter(int i, String o, FieldMirror field);
+
+ public static class IntTypeHandler implements TypeHandler {
+ @Override
+ public String resultSetSetter(int i, String o, FieldMirror field) {
+ return "setInt(" + i + ", " + o + "." + field.javaName + ")";
+ }
+ }
+
+ public static class LongTypeHandler implements TypeHandler {
+ @Override
+ public String resultSetSetter(int i, String o, FieldMirror field) {
+ return "setLong(" + i + ", " + o + "." + field.javaName + ")";
+ }
+ }
+
+ public static class DateTypeHandler implements TypeHandler {
+ @Override
+ public String resultSetSetter(int i, String o, FieldMirror field) {
+ return "setTimestamp(" + i + ", new java.sql.Timestamp(" + o + "." + field.javaName + ".getTime()))";
+ }
+ }
+}