summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2010-08-06 14:46:32 -0700
committerShawn O. Pearce <sop@google.com>2010-08-06 15:53:25 -0700
commit5f41fad97ef9f7b7ddd942fb59dcd24bdd3666e1 (patch)
treee12be4b5e98ba0f909cd801def5b9a66e3b1c078
parent7de9ead36336e353e8b0f89b7bc8df9f88adfc81 (diff)
downloadgwtorm-5f41fad97ef9f7b7ddd942fb59dcd24bdd3666e1.tar.gz
Expose all relations and all entities
This permits someone to write a tool that iterates through the schema, such as to dump it to an external backup file. Change-Id: I58049e5e66ff827c59959823df5dca787cc7db2e Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--src/main/java/com/google/gwtorm/client/Access.java10
-rw-r--r--src/main/java/com/google/gwtorm/client/Schema.java5
-rw-r--r--src/main/java/com/google/gwtorm/jdbc/AccessGen.java1
-rw-r--r--src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java2
-rw-r--r--src/main/java/com/google/gwtorm/nosql/AccessGen.java1
-rw-r--r--src/main/java/com/google/gwtorm/nosql/NoSqlAccess.java3
-rw-r--r--src/main/java/com/google/gwtorm/server/SchemaGen.java58
-rw-r--r--src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java12
8 files changed, 83 insertions, 9 deletions
diff --git a/src/main/java/com/google/gwtorm/client/Access.java b/src/main/java/com/google/gwtorm/client/Access.java
index 2f1fff9..c989135 100644
--- a/src/main/java/com/google/gwtorm/client/Access.java
+++ b/src/main/java/com/google/gwtorm/client/Access.java
@@ -47,6 +47,16 @@ import java.util.Map;
* implementation. Entity specific key subclasses are recommended.
*/
public interface Access<T extends Object, K extends Key<?>> {
+ /** @return the name of this relation. */
+ String getRelationName();
+
+ /**
+ * Iterate through all members of the relation.
+ *
+ * @return an iterator over all members. This is most likely not fast.
+ */
+ ResultSet<T> iterateAllEntities() throws OrmException;
+
/**
* Obtain the primary key of an entity instance.
*
diff --git a/src/main/java/com/google/gwtorm/client/Schema.java b/src/main/java/com/google/gwtorm/client/Schema.java
index 28bfd25..95aa9e4 100644
--- a/src/main/java/com/google/gwtorm/client/Schema.java
+++ b/src/main/java/com/google/gwtorm/client/Schema.java
@@ -78,6 +78,11 @@ public interface Schema {
void pruneSchema(StatementExecutor e) throws OrmException;
/**
+ * @return access interface for each declared relation.
+ */
+ Access<?, ?>[] allRelations();
+
+ /**
* Close the schema and release all resources.
*/
void close();
diff --git a/src/main/java/com/google/gwtorm/jdbc/AccessGen.java b/src/main/java/com/google/gwtorm/jdbc/AccessGen.java
index 819dafe..573e8d2 100644
--- a/src/main/java/com/google/gwtorm/jdbc/AccessGen.java
+++ b/src/main/java/com/google/gwtorm/jdbc/AccessGen.java
@@ -116,6 +116,7 @@ class AccessGen implements Opcodes {
for (final QueryModel q : model.getQueries()) {
implementQuery(q);
}
+ implementQuery(new QueryModel(model, "iterateAllEntities", ""));
cw.visitEnd();
classLoader.defineClass(implClassName, cw.toByteArray());
diff --git a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
index 4105d75..afcab77 100644
--- a/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
+++ b/src/main/java/com/google/gwtorm/jdbc/JdbcAccess.java
@@ -303,8 +303,6 @@ public abstract class JdbcAccess<T, K extends Key<?>> extends
protected abstract T newEntityInstance();
- protected abstract String getRelationName();
-
protected abstract String getInsertOneSql();
protected abstract String getUpdateOneSql();
diff --git a/src/main/java/com/google/gwtorm/nosql/AccessGen.java b/src/main/java/com/google/gwtorm/nosql/AccessGen.java
index eb72b15..71828c4 100644
--- a/src/main/java/com/google/gwtorm/nosql/AccessGen.java
+++ b/src/main/java/com/google/gwtorm/nosql/AccessGen.java
@@ -107,6 +107,7 @@ class AccessGen implements Opcodes {
for (final QueryModel q : model.getQueries()) {
implementQuery(q);
}
+ implementQuery(new QueryModel(model, "iterateAllEntities", ""));
cw.visitEnd();
classLoader.defineClass(implClassName, cw.toByteArray());
diff --git a/src/main/java/com/google/gwtorm/nosql/NoSqlAccess.java b/src/main/java/com/google/gwtorm/nosql/NoSqlAccess.java
index 822bd60..291279b 100644
--- a/src/main/java/com/google/gwtorm/nosql/NoSqlAccess.java
+++ b/src/main/java/com/google/gwtorm/nosql/NoSqlAccess.java
@@ -62,9 +62,6 @@ public abstract class NoSqlAccess<T, K extends Key<?>> extends
// -- These are all provided by AccessGen when it builds a subclass --
- /** @return name of the relation in the schema. */
- protected abstract String getRelationName();
-
/** @return encoder/decoder for the object data. */
protected abstract ProtobufCodec<T> getObjectCodec();
diff --git a/src/main/java/com/google/gwtorm/server/SchemaGen.java b/src/main/java/com/google/gwtorm/server/SchemaGen.java
index 91bc24b..24854bf 100644
--- a/src/main/java/com/google/gwtorm/server/SchemaGen.java
+++ b/src/main/java/com/google/gwtorm/server/SchemaGen.java
@@ -14,6 +14,7 @@
package com.google.gwtorm.server;
+import com.google.gwtorm.client.Access;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.Schema;
import com.google.gwtorm.schema.RelationModel;
@@ -27,6 +28,8 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
/** Generates a concrete implementation of a {@link Schema} extension. */
@@ -64,6 +67,8 @@ public class SchemaGen<S extends AbstractSchema> implements Opcodes {
implementConstructor();
implementSequenceMethods();
implementRelationMethods();
+ implementAllRelationsMethod();
+
cw.visitEnd();
classLoader.defineClass(getImplClassName(), cw.toByteArray());
return loadClass();
@@ -97,6 +102,17 @@ public class SchemaGen<S extends AbstractSchema> implements Opcodes {
final Class<?> a = accessGen.create(classLoader, rel);
relations.add(new RelationGen(rel, a));
}
+
+ Collections.sort(relations, new Comparator<RelationGen>() {
+ @Override
+ public int compare(RelationGen a, RelationGen b) {
+ int cmp = a.model.getRelationID() - b.model.getRelationID();
+ if (cmp == 0) {
+ cmp = a.model.getRelationName().compareTo(b.model.getRelationName());
+ }
+ return cmp;
+ }
+ });
}
private void init() {
@@ -182,6 +198,37 @@ public class SchemaGen<S extends AbstractSchema> implements Opcodes {
}
}
+ private void implementAllRelationsMethod() {
+ final MethodVisitor mv =
+ cw.visitMethod(ACC_PUBLIC | ACC_FINAL, "allRelations", Type
+ .getMethodDescriptor(Type.getType(Access[].class), new Type[] {}),
+ null, null);
+ mv.visitCode();
+
+ final int r = 1;
+ CodeGenSupport cgs = new CodeGenSupport(mv);
+ cgs.push(relations.size());
+ mv.visitTypeInsn(ANEWARRAY, Type.getType(Access.class).getInternalName());
+ mv.visitVarInsn(ASTORE, r);
+
+ int index = 0;
+ for (RelationGen info : relations) {
+ mv.visitVarInsn(ALOAD, r);
+ cgs.push(index++);
+
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, getImplTypeName(), info.model
+ .getMethodName(), info.getDescriptor());
+
+ mv.visitInsn(AASTORE);
+ }
+
+ mv.visitVarInsn(ALOAD, r);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+
private class RelationGen {
final RelationModel model;
final Type accessType;
@@ -202,10 +249,8 @@ public class SchemaGen<S extends AbstractSchema> implements Opcodes {
void implementMethod() {
final MethodVisitor mv =
- cw.visitMethod(ACC_PUBLIC | ACC_FINAL, model.getMethodName(), Type
- .getMethodDescriptor(Type.getObjectType(model
- .getAccessInterfaceName().replace('.', '/')), new Type[] {}),
- null, null);
+ cw.visitMethod(ACC_PUBLIC | ACC_FINAL, model.getMethodName(),
+ getDescriptor(), null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implTypeName, getAccessInstanceFieldName(),
@@ -214,5 +259,10 @@ public class SchemaGen<S extends AbstractSchema> implements Opcodes {
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
+
+ String getDescriptor() {
+ return Type.getMethodDescriptor(Type.getObjectType(model
+ .getAccessInterfaceName().replace('.', '/')), new Type[] {});
+ }
}
}
diff --git a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
index c3f5c08..7c221b5 100644
--- a/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
+++ b/src/test/java/com/google/gwtorm/server/PhoneBookDbTestCase.java
@@ -14,6 +14,7 @@
package com.google.gwtorm.server;
+import com.google.gwtorm.client.Access;
import com.google.gwtorm.client.OrmConcurrencyException;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.data.PersonAccess;
@@ -100,11 +101,22 @@ public class PhoneBookDbTestCase extends TestCase {
public void testGetPeopleAccess() throws Exception {
final PhoneBookDb schema = open();
assertNotNull(schema.people());
+ assertEquals("people", schema.people().getRelationName());
}
public void testGetAddressAccess() throws Exception {
final PhoneBookDb schema = open();
assertNotNull(schema.addresses());
+ assertEquals("addresses", schema.addresses().getRelationName());
+ }
+
+ public void testGetAllRelations() throws Exception {
+ final PhoneBookDb schema = open();
+ Access<?, ?>[] all = schema.allRelations();
+ assertNotNull(all);
+ assertEquals(2, all.length);
+ assertSame(schema.people(), all[0]);
+ assertSame(schema.addresses(), all[1]);
}
public void testCreateSchema() throws Exception {