From dd150071369e825d4b4a59e15ad3291841c7ba13 Mon Sep 17 00:00:00 2001
From: Trygve Laugstøl <trygvis@inamo.no>
Date: Sun, 4 Aug 2013 23:08:37 +0200
Subject: wip o Fixing bugs.

---
 .../java/io/trygvis/persistence/EntityMirror.java  |  46 ++--
 .../java/io/trygvis/persistence/FieldMirror.java   |  19 ++
 .../io/trygvis/container/myapp/AbstractEntity.java |   7 +-
 .../io/trygvis/container/myapp/AddressBook.java    | 245 +++++++++++++++------
 .../java/io/trygvis/container/myapp/Company.java   |  12 +
 .../java/io/trygvis/container/myapp/Contact.java   |  19 +-
 6 files changed, 245 insertions(+), 103 deletions(-)
 create mode 100644 myapp/src/main/java/io/trygvis/container/myapp/Company.java

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
index f0f4ae7..5d6defb 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/EntityMirror.java
@@ -160,31 +160,31 @@ public class EntityMirror implements Comparable<EntityMirror> {
 
             i++;
 
+            TypeHandler typeHandler;
+            String accessor;
+            String setter;
             if (field.fieldType == PRIMITIVE) {
-                TypeHandler typeHandler = generatorConfiguration.typeHandler(field.type);
-                String access;
-                if (field.accessorType == FIELD) {
-                    access = o.name + "." + field.javaName;
-                } else {
-                    access = o.name + "." + toGetterName(field.javaName) + "()";
-                }
-                String setter = "    stmt." + typeHandler.setter(i, access) + ";";
-
-                if (field.notNull) {
-                    body.add(setter);
-                } else {
-                    body.add("    " + field.type + " " + field.javaName + " = " + access + ";");
-                    body.add("    if(" + field.javaName + " == null) {");
-                    body.add("        stmt.setNull(" + i + ", " + typesType + "." + typeHandler.typeName() + ");");
-                    body.add("    } else {");
-                    body.add("    " + setter);
-                    body.add("    }");
-                }
-            } else if (field.fieldType == REFERENCE) {
+                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 typeHandler = generatorConfiguration.typeHandler(idField.type);
-                body.add("    stmt." + typeHandler.setter(i, o.name + "." + field.javaName + "." + idField.javaName) + ";");
+                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();");
@@ -202,7 +202,7 @@ public class EntityMirror implements Comparable<EntityMirror> {
         List<String> arguments = new ArrayList<>();
         arguments.add(con.name);
         for (FieldMirror field : idFields) {
-            if(field.accessorType == FIELD) {
+            if (field.accessorType == FIELD) {
                 arguments.add(o.name + "." + field.javaName);
             } else {
                 arguments.add(o.name + "." + toGetterName(field.javaName) + "()");
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
index 07fa769..5a2d221 100644
--- a/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
+++ b/container-compiler-plugin/src/main/java/io/trygvis/persistence/FieldMirror.java
@@ -2,6 +2,10 @@ package io.trygvis.persistence;
 
 import io.trygvis.container.compiler.model.TypeRef;
 
+import static io.trygvis.container.compiler.Utils.toGetterName;
+import static io.trygvis.container.compiler.model.Parameters.ParameterRef;
+import static io.trygvis.persistence.FieldMirror.AccessorType.FIELD;
+
 /**
  * TODO: a single field might have to be mapped to multiple sql columns.
  */
@@ -37,6 +41,21 @@ public class FieldMirror {
         this.unique = unique;
     }
 
+    public String fieldAccessor(ParameterRef o) {
+        return fieldAccessor(o.name);
+    }
+
+    public String referenceAccessor(ParameterRef o, FieldMirror f) {
+        return f.fieldAccessor(o.name + "." + javaName);
+    }
+
+    private String fieldAccessor(String o) {
+        if (accessorType == FIELD) {
+            return o + "." + javaName;
+        }
+        return o + "." + toGetterName(javaName) + "()";
+    }
+
     @Override
     public String toString() {
         return "FieldMirror{" +
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java b/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java
index 40896e0..287ce6d 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/AbstractEntity.java
@@ -5,8 +5,11 @@ import javax.persistence.Id;
 public abstract class AbstractEntity {
     private Long id;
 
-    protected AbstractEntity(Long id) {
-        this.id = id;
+    /**
+     * For transient entities.
+     */
+    protected AbstractEntity() {
+        id = null;
     }
 
     @Id
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
index d5a1170..d5c93fe 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/AddressBook.java
@@ -6,13 +6,19 @@ import java.io.EOFException;
 import java.io.InputStreamReader;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.List;
 
+import static io.trygvis.container.myapp.Contact.Gender.FEMALE;
+import static io.trygvis.container.myapp.Contact.Gender.MALE;
+
 public class AddressBook {
 
     private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
 
+    private Connection c;
+
     public static void main(String[] args) throws Exception {
         try {
             new AddressBook().work();
@@ -23,109 +29,208 @@ public class AddressBook {
     private void work() throws Exception {
         boolean done = false;
         while (!done) {
-            String cmd = Character.toString(menu());
+            c = DriverManager.getConnection("jdbc:h2:mem:address-book;DB_CLOSE_DELAY=-1");
+            try {
+                c.setAutoCommit(false);
+                done = main();
+                c.commit();
+                System.out.println("OK");
+            } finally {
+                c.close();
+            }
+        }
+    }
+
+    private boolean main() throws Exception {
+        System.out.println("Menu:");
+        System.out.println("c Create");
+        System.out.println("d Drop");
+        System.out.println("m Company menu");
+        System.out.println("n Contact menu");
+        System.out.println("q Quit");
+        String cmd = cmd();
+        switch (cmd) {
+            case "c":
+                create();
+                break;
+            case "d":
+                drop();
+                break;
+            case "m":
+                company();
+                break;
+            case "n":
+                contact();
+                break;
+            case "q":
+                return true;
+            default:
+                System.out.println("Unknown command: " + cmd);
+        }
+        return false;
+    }
+
+    private String cmd() throws Exception {
+        String cmd = null;
+        do {
+            String read = line();
+            if (read.length() != 0) {
+                cmd = read.trim();
+            }
+        } while (cmd == null);
+        return cmd;
+    }
+
+    private String line() throws Exception {
+        String line = reader.readLine();
+        if (line == null) {
+            throw new EOFException();
+        }
+        return line.trim();
+    }
+
+    public void create() throws SQLException {
+        Statement statement = c.createStatement();
+        statement.executeUpdate(CompanyDao.createTableSql);
+        statement.executeUpdate(ContactDao.createTableSql);
+        for (String sql : Sequences.createSequences) {
+            statement.executeUpdate(sql);
+        }
+    }
+
+    public void drop() throws SQLException {
+        Statement statement = c.createStatement();
+        for (String sql : Sequences.dropSequences) {
+            statement.executeUpdate(sql);
+        }
+        statement.executeUpdate(ContactDao.dropTableSql);
+        statement.executeUpdate(CompanyDao.dropTableSql);
+    }
+
+    // -----------------------------------------------------------------------
+    // Company
+    // -----------------------------------------------------------------------
+
+    private void company() throws Exception {
+        while (true) {
+            System.out.println("Company menu:");
+            System.out.println("c Create");
+            System.out.println("d Drop");
+            System.out.println("d List");
+            System.out.println("q Back");
+            String cmd = cmd();
             switch (cmd) {
                 case "c":
-                    run(new CreateTablesCommand());
+                    addCompany();
                     break;
                 case "d":
-                    run(new DropTablesCommand());
-                    break;
-                case "a":
-                    run(new AddCommand());
+                    deleteCompany();
                     break;
                 case "l":
-                    run(new ListCommand());
+                    listCompanies();
                     break;
                 case "q":
-                    done = true;
-                    break;
+                    return;
                 default:
                     System.out.println("Unknown command: " + cmd);
             }
         }
     }
 
-    private String line() throws Exception {
-        String line = reader.readLine();
-        if(line == null) {
-           throw new EOFException();
-        }
-        return line.trim();
+    public void addCompany() throws Exception {
+        System.out.print("Name: ");
+        String name = line();
+
+        Company company = new Company(name);
+        CompanyDao.insertInto(c, company);
     }
 
-    public static interface Command {
-        void run(Connection c) throws Exception;
+    public void deleteCompany() {
     }
 
-    public void run(Command command) throws Exception {
-        try (Connection c = DriverManager.getConnection("jdbc:h2:mem:address-book;DB_CLOSE_DELAY=-1")) {
-            c.setAutoCommit(false);
-            command.run(c);
-            c.commit();
-            System.out.println("OK");
+    public void listCompanies() {
+        TypedQuery<Company> p = CompanyDao.query(c);
+
+        List<Company> resultList = p.getResultList();
+        for (Company company : resultList) {
+            System.out.println("=====================");
+            System.out.println("Id:     " + company.getId());
+            System.out.println("Name:   " + company.name);
         }
+        System.out.println();
     }
 
-    private char menu() throws Exception {
-        System.out.println("Menu:");
-        System.out.println("c Create");
-        System.out.println("d Drop");
-        System.out.println("l List");
-        System.out.println("a Add");
-        System.out.println("q Quit");
+    // -----------------------------------------------------------------------
+    // Contact
+    // -----------------------------------------------------------------------
+
+    private void contact() throws Exception {
         while (true) {
-            String read = line();
-            if (read.length() != 0) {
-                return read.charAt(0);
+            System.out.println("Contact menu:");
+            System.out.println("c Create");
+            System.out.println("d Drop");
+            System.out.println("q Back");
+            String cmd = cmd();
+            switch (cmd) {
+                case "c":
+                    addContact();
+                    break;
+                case "d":
+                    deleteContact();
+                    break;
+                case "l":
+                    listContacts();
+                    break;
+                case "q":
+                    return;
+                default:
+                    System.out.println("Unknown command: " + cmd);
             }
         }
     }
 
-    public static class CreateTablesCommand implements Command {
-        @Override
-        public void run(Connection c) throws Exception {
-            Statement statement = c.createStatement();
-            statement.executeUpdate(ContactDao.createTableSql);
-            for (String sql : Sequences.createSequences) {
-                statement.executeUpdate(sql);
+    public void addContact() throws Exception {
+        System.out.print("Name: ");
+        String name = line();
+        Contact.Gender g = null;
+        while (g == null) {
+            System.out.print("Gender (m/f): ");
+            try {
+                String line = line();
+                switch (line) {
+                    case "m":
+                        g = MALE;
+                        break;
+                    case "f":
+                        g = FEMALE;
+                        break;
+                    default:
+                        g = Contact.Gender.valueOf(line);
+                        break;
+                }
+            } catch (IllegalArgumentException ignore) {
             }
         }
-    }
 
-    public static class DropTablesCommand implements Command {
-        @Override
-        public void run(Connection c) throws Exception {
-            Statement statement = c.createStatement();
-            statement.executeUpdate(ContactDao.dropTableSql);
-            for (String sql : Sequences.dropSequences) {
-                statement.executeUpdate(sql);
-            }
-        }
+        Company company = null;
+        Contact o = new Contact(name, g, company);
+        ContactDao.insertInto(c, o);
     }
 
-    public class AddCommand implements Command {
-        @Override
-        public void run(Connection c) throws Exception {
-            System.out.print("Name: ");
-            String name = line();
-            Contact o = new Contact(name);
-            ContactDao.insertInto(c, o);
-        }
+    public void deleteContact() {
+
     }
 
-    public static class ListCommand implements Command {
-        @Override
-        public void run(Connection c) throws Exception {
-            TypedQuery<Contact> p = ContactDao.query(c);
-
-            List<Contact> resultList = p.getResultList();
-            for (int i = 0; i < resultList.size(); i++) {
-                Contact contact = resultList.get(i);
-                System.out.println("Item #" + i + ":");
-                System.out.println("Id:   " + contact.getId());
-                System.out.println("Name: " + contact.name);
-            }
+    public void listContacts() {
+        TypedQuery<Contact> p = ContactDao.query(c);
+
+        List<Contact> resultList = p.getResultList();
+        for (Contact contact : resultList) {
+            System.out.println("=====================");
+            System.out.println("Id:     " + contact.getId());
+            System.out.println("Name:   " + contact.name);
+            System.out.println("Gender: " + contact.gender);
         }
+        System.out.println();
     }
 }
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Company.java b/myapp/src/main/java/io/trygvis/container/myapp/Company.java
new file mode 100644
index 0000000..f1e2863
--- /dev/null
+++ b/myapp/src/main/java/io/trygvis/container/myapp/Company.java
@@ -0,0 +1,12 @@
+package io.trygvis.container.myapp;
+
+import javax.persistence.Entity;
+
+@Entity
+public class Company extends AbstractEntity {
+    public final String name;
+
+    public Company(String name) {
+        this.name = name;
+    }
+}
diff --git a/myapp/src/main/java/io/trygvis/container/myapp/Contact.java b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java
index 87e58c5..5ce87c7 100644
--- a/myapp/src/main/java/io/trygvis/container/myapp/Contact.java
+++ b/myapp/src/main/java/io/trygvis/container/myapp/Contact.java
@@ -7,17 +7,20 @@ import javax.persistence.SequenceGenerator;
 @SequenceGenerator(name = "id_seq")
 public class Contact extends AbstractEntity {
 
-    public String name;
+    public final String name;
 
-//    public Contact mother;
-
-    public Contact(String name) {
-        super(null);
-        this.name = name;
+    public enum Gender {
+        MALE,
+        FEMALE
     }
 
-    public Contact(Long id, String name) {
-        super(id);
+    public final Gender gender;
+
+    public final Company company;
+
+    public Contact(String name, Gender gender, Company company) {
         this.name = name;
+        this.gender = gender;
+        this.company = company;
     }
 }
-- 
cgit v1.2.3