diff options
author | Shawn O. Pearce <sop@google.com> | 2010-08-06 14:46:32 -0700 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2010-08-06 15:53:25 -0700 |
commit | 5f41fad97ef9f7b7ddd942fb59dcd24bdd3666e1 (patch) | |
tree | e12be4b5e98ba0f909cd801def5b9a66e3b1c078 | |
parent | 7de9ead36336e353e8b0f89b7bc8df9f88adfc81 (diff) | |
download | gwtorm-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>
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 { |