diff --git a/src/main/java/com/google/gwtorm/nosql/IndexFunction.java b/src/main/java/com/google/gwtorm/nosql/IndexFunction.java
new file mode 100644
index 0000000..f13b050
--- /dev/null
+++ b/src/main/java/com/google/gwtorm/nosql/IndexFunction.java
@@ -0,0 +1,52 @@
+// Copyright 2010 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gwtorm.nosql;
+
+/**
+ * A function to produce a NoSQL secondary index key from an object.
+ * <p>
+ * An index function computes a row key for a secondary index table by appending
+ * the relevant values to builder's internal buffer in the order they are
+ * referenced in the query.
+ * <p>
+ * Typically an IndexFunction would be code generated at runtime by
+ * {@link IndexFunctionGen} as necessary by a NoSQL implementation.
+ *
+ * @param <T> type of the object the index record references.
+ */
+public abstract class IndexFunction<T> {
+  /** @return name of this index, should be unique within the relation. */
+  public abstract String getName();
+
+  /**
+   * Should this object exist in the index?
+   * <p>
+   * Objects that shouldn't appear in this index are skipped because field
+   * values are currently {@code null} or because one or more constants doesn't
+   * match as expected.
+   *
+   * @param object the object to read fields from.
+   * @return true if the object should be indexed by this index.
+   */
+  public abstract boolean includes(T object);
+
+  /**
+   * Encodes the current values from the object into the index buffer.
+   *
+   * @param dst the buffer to append the indexed field value(s) onto.
+   * @param object the object to read current field values from.
+   */
+  public abstract void encode(IndexKeyBuilder dst, T object);
+}
diff --git a/src/main/java/com/google/gwtorm/nosql/IndexFunctionGen.java b/src/main/java/com/google/gwtorm/nosql/IndexFunctionGen.java
new file mode 100644
index 0000000..206e238
--- /dev/null
+++ b/src/main/java/com/google/gwtorm/nosql/IndexFunctionGen.java
@@ -0,0 +1,491 @@
+// Copyright 2010 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gwtorm.nosql;
+
+import com.google.gwtorm.client.OrmException;
+import com.google.gwtorm.schema.ColumnModel;
+import com.google.gwtorm.schema.QueryModel;
+import com.google.gwtorm.schema.QueryParser;
+import com.google.gwtorm.schema.Util;
+import com.google.gwtorm.server.CodeGenSupport;
+import com.google.gwtorm.server.GeneratedClassLoader;
+
+import org.antlr.runtime.tree.Tree;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/** Generates {@link IndexFunction} implementations. */
+class IndexFunctionGen<T> implements Opcodes {
+  private static final Type string = Type.getType(String.class);
+  private static final Type object = Type.getType(Object.class);
+  private static final Type indexKeyBuilder =
+      Type.getType(IndexKeyBuilder.class);
+
+  private final GeneratedClassLoader classLoader;
+  private final QueryModel query;
+  private final List<ColumnModel> myFields;
+  private final Class<T> pojo;
+  private final Type pojoType;
+
+  private ClassWriter cw;
+  private String superTypeName;
+  private String implClassName;
+  private String implTypeName;
+
+  public IndexFunctionGen(final GeneratedClassLoader loader,
+      final QueryModel qm, final Class<T> t) {
+    classLoader = loader;
+    query = qm;
+
+    myFields = new ArrayList<ColumnModel>();
+
+    // Only add each parameter column once, but in the order used.
+    // This avoids a range test on the same column from duplicating
+    // the data in the index record.
+    //
+    for (ColumnModel m : leaves(query.getParameters())) {
+      if (!myFields.contains(m)) {
+        myFields.add(m);
+      }
+    }
+
+    // Skip ORDER BY columns that match with the parameters, then
+    // add anything else onto the end.
+    //
+    int p = 0;
+    Iterator<ColumnModel> orderby = leaves(query.getOrderBy()).iterator();
+    while (p < myFields.size() && orderby.hasNext()) {
+      ColumnModel c = orderby.next();
+      if (!myFields.get(p).equals(c)) {
+        myFields.add(c);
+        break;
+      }
+      p++;
+    }
+    while (orderby.hasNext()) {
+      myFields.add(orderby.next());
+    }
+
+    pojo = t;
+    pojoType = Type.getType(pojo);
+  }
+
+  private List<ColumnModel> leaves(List<ColumnModel> in) {
+    ArrayList<ColumnModel> r = new ArrayList<ColumnModel>(in.size());
+    for (ColumnModel m : in) {
+      if (m.isNested()) {
+        r.addAll(m.getAllLeafColumns());
+      } else {
+        r.add(m);
+      }
+    }
+    return r;
+  }
+
+  public IndexFunction<T> create() throws OrmException {
+    init();
+    implementConstructor();
+    implementGetName();
+    implementIncludes();
+    implementEncode();
+    cw.visitEnd();
+    classLoader.defineClass(implClassName, cw.toByteArray());
+
+    try {
+      final Class<?> c = Class.forName(implClassName, true, classLoader);
+      return cast(c.newInstance());
+    } catch (InstantiationException e) {
+      throw new OrmException("Cannot create new encoder", e);
+    } catch (IllegalAccessException e) {
+      throw new OrmException("Cannot create new encoder", e);
+    } catch (ClassNotFoundException e) {
+      throw new OrmException("Cannot create new encoder", e);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T> IndexFunction<T> cast(final Object c) {
+    return (IndexFunction<T>) c;
+  }
+
+  private void init() {
+    superTypeName = Type.getInternalName(IndexFunction.class);
+    implClassName =
+        pojo.getName() + "_IndexFunction_" + query.getName() + "_"
+            + Util.createRandomName();
+    implTypeName = implClassName.replace('.', '/');
+
+    cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+    cw.visit(V1_3, ACC_PUBLIC | ACC_FINAL | ACC_SUPER, implTypeName, null,
+        superTypeName, new String[] {});
+  }
+
+  private void implementConstructor() {
+    final String consName = "<init>";
+    final String consDesc =
+        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {});
+    final MethodVisitor mv =
+        cw.visitMethod(ACC_PUBLIC, consName, consDesc, null, null);
+    mv.visitCode();
+
+    mv.visitVarInsn(ALOAD, 0);
+    mv.visitMethodInsn(INVOKESPECIAL, superTypeName, consName, consDesc);
+
+    mv.visitInsn(RETURN);
+    mv.visitMaxs(-1, -1);
+    mv.visitEnd();
+  }
+
+  private void implementGetName() {
+    final MethodVisitor mv =
+        cw.visitMethod(ACC_PUBLIC | ACC_FINAL, "getName", Type
+            .getMethodDescriptor(Type.getType(String.class), new Type[] {}),
+            null, null);
+    mv.visitCode();
+    mv.visitLdcInsn(query.getName());
+    mv.visitInsn(ARETURN);
+    mv.visitMaxs(-1, -1);
+    mv.visitEnd();
+  }
+
+  private void implementIncludes() throws OrmException {
+    final MethodVisitor mv =
+        cw.visitMethod(ACC_PUBLIC, "includes", Type.getMethodDescriptor(
+            Type.BOOLEAN_TYPE, new Type[] {object}), null, null);
+    mv.visitCode();
+    final IncludeCGS cgs = new IncludeCGS(mv);
+    cgs.setEntityType(pojoType);
+
+    mv.visitVarInsn(ALOAD, 1);
+    mv.visitTypeInsn(CHECKCAST, pojoType.getInternalName());
+    mv.visitVarInsn(ASTORE, 1);
+
+    Set<ColumnModel> checked = new HashSet<ColumnModel>();
+    checkNotNullFields(myFields, checked, mv, cgs);
+
+    final Tree parseTree = query.getParseTree();
+    if (parseTree != null) {
+      checkConstants(parseTree, mv, cgs);
+    }
+
+    cgs.push(1);
+    mv.visitInsn(IRETURN);
+
+    mv.visitLabel(cgs.no);
+    cgs.push(0);
+    mv.visitInsn(IRETURN);
+
+    mv.visitMaxs(-1, -1);
+    mv.visitEnd();
+  }
+
+  private static void checkNotNullFields(Collection<ColumnModel> myFields,
+      Set<ColumnModel> checked, MethodVisitor mv, IncludeCGS cgs)
+      throws OrmException {
+    for (ColumnModel f : myFields) {
+      if (f.isNested()) {
+        checkNotNullFields(f.getNestedColumns(), checked, mv, cgs);
+      } else {
+        checkNotNullScalar(mv, checked, cgs, f);
+      }
+    }
+  }
+
+  private static void checkNotNullScalar(MethodVisitor mv,
+      Set<ColumnModel> checked, IncludeCGS cgs, ColumnModel f)
+      throws OrmException {
+    checkParentNotNull(f.getParent(), checked, mv, cgs);
+    cgs.setFieldReference(f);
+
+    switch (Type.getType(f.getPrimitiveType()).getSort()) {
+      case Type.BOOLEAN:
+      case Type.BYTE:
+      case Type.SHORT:
+      case Type.CHAR:
+      case Type.INT:
+      case Type.LONG:
+        break;
+
+      case Type.ARRAY:
+      case Type.OBJECT: {
+        if (f.getPrimitiveType() == byte[].class) {
+          cgs.pushFieldValue();
+          mv.visitJumpInsn(IFNULL, cgs.no);
+
+        } else if (f.getPrimitiveType() == String.class) {
+          cgs.pushFieldValue();
+          mv.visitJumpInsn(IFNULL, cgs.no);
+
+        } else if (f.getPrimitiveType() == java.sql.Timestamp.class
+            || f.getPrimitiveType() == java.util.Date.class
+            || f.getPrimitiveType() == java.sql.Date.class) {
+          cgs.pushFieldValue();
+          mv.visitJumpInsn(IFNULL, cgs.no);
+
+        } else {
+          throw new OrmException("Type " + f.getPrimitiveType()
+              + " not supported for field " + f.getPathToFieldName());
+        }
+        break;
+      }
+
+      default:
+        throw new OrmException("Type " + f.getPrimitiveType()
+            + " not supported for field " + f.getPathToFieldName());
+    }
+  }
+
+  private static void checkParentNotNull(ColumnModel f,
+      Set<ColumnModel> checked, MethodVisitor mv, IncludeCGS cgs) {
+    if (f != null && checked.add(f)) {
+      checkParentNotNull(f.getParent(), checked, mv, cgs);
+      cgs.setFieldReference(f);
+      cgs.pushFieldValue();
+      mv.visitJumpInsn(IFNULL, cgs.no);
+    }
+  }
+
+  private void checkConstants(Tree node, MethodVisitor mv, IncludeCGS cgs)
+      throws OrmException {
+    switch (node.getType()) {
+      // These don't impact the constant evaluation
+      case QueryParser.ORDER:
+      case QueryParser.LIMIT:
+        break;
+
+      case 0: // nil node used to join other nodes together
+      case QueryParser.WHERE:
+      case QueryParser.AND:
+        for (int i = 0; i < node.getChildCount(); i++) {
+          checkConstants(node.getChild(i), mv, cgs);
+        }
+        break;
+
+      case QueryParser.LT:
+      case QueryParser.LE:
+      case QueryParser.GT:
+      case QueryParser.GE:
+      case QueryParser.EQ: {
+        final Tree lhs = node.getChild(0);
+        final Tree rhs = node.getChild(1);
+        if (lhs.getType() != QueryParser.ID) {
+          throw new OrmException("Unsupported query token");
+        }
+
+        cgs.setFieldReference(((QueryParser.Column) lhs).getField());
+        switch (rhs.getType()) {
+          case QueryParser.PLACEHOLDER:
+            // Parameter evaluated at runtime
+            break;
+
+          case QueryParser.TRUE:
+            cgs.pushFieldValue();
+            mv.visitJumpInsn(IFEQ, cgs.no);
+            break;
+
+          case QueryParser.FALSE:
+            cgs.pushFieldValue();
+            mv.visitJumpInsn(IFNE, cgs.no);
+            break;
+
+          case QueryParser.CONSTANT_INTEGER:
+            cgs.pushFieldValue();
+            cgs.push(Integer.parseInt(rhs.getText()));
+            mv.visitJumpInsn(IF_ICMPNE, cgs.no);
+            break;
+
+          case QueryParser.CONSTANT_STRING:
+            if (cgs.getFieldReference().getPrimitiveType() == Character.TYPE) {
+              cgs.push(dequote(rhs.getText()).charAt(0));
+              cgs.pushFieldValue();
+              mv.visitJumpInsn(IF_ICMPNE, cgs.no);
+            } else {
+              mv.visitLdcInsn(dequote(rhs.getText()));
+              cgs.pushFieldValue();
+              mv.visitMethodInsn(INVOKEVIRTUAL, string.getInternalName(),
+                  "equals", Type.getMethodDescriptor(Type.BOOLEAN_TYPE,
+                      new Type[] {object}));
+              mv.visitJumpInsn(IFEQ, cgs.no);
+            }
+            break;
+        }
+        break;
+      }
+
+      default:
+        throw new OrmException("Unsupported query token " + node.toStringTree());
+    }
+  }
+
+  private static String dequote(String text) {
+    return text.substring(1, text.length() - 1);
+  }
+
+  private void implementEncode() throws OrmException {
+    final MethodVisitor mv =
+        cw.visitMethod(ACC_PUBLIC, "encode", Type.getMethodDescriptor(
+            Type.VOID_TYPE, new Type[] {indexKeyBuilder, object}), null, null);
+    mv.visitCode();
+    final EncodeCGS cgs = new EncodeCGS(mv);
+    cgs.setEntityType(pojoType);
+
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitTypeInsn(CHECKCAST, pojoType.getInternalName());
+    mv.visitVarInsn(ASTORE, 2);
+
+    encodeFields(myFields, mv, cgs);
+
+    mv.visitInsn(RETURN);
+    mv.visitMaxs(-1, -1);
+    mv.visitEnd();
+  }
+
+  private static void encodeFields(final Collection<ColumnModel> myFields,
+      final MethodVisitor mv, final EncodeCGS cgs) throws OrmException {
+    Iterator<ColumnModel> i = myFields.iterator();
+    while (i.hasNext()) {
+      ColumnModel f = i.next();
+      encodeScalar(f, mv, cgs);
+      if (i.hasNext()) {
+        cgs.delimiter();
+      }
+    }
+  }
+
+  static void encodeField(ColumnModel f, final MethodVisitor mv,
+      final EncodeCGS cgs) throws OrmException {
+    if (f.isNested()) {
+      encodeFields(f.getAllLeafColumns(), mv, cgs);
+    } else {
+      encodeScalar(f, mv, cgs);
+    }
+  }
+
+  private static void encodeScalar(final ColumnModel f, final MethodVisitor mv,
+      final EncodeCGS cgs) throws OrmException {
+    cgs.setFieldReference(f);
+
+    switch (Type.getType(f.getPrimitiveType()).getSort()) {
+      case Type.BOOLEAN:
+      case Type.BYTE:
+      case Type.SHORT:
+      case Type.CHAR:
+      case Type.INT:
+        cgs.pushBuilder();
+        cgs.pushFieldValue();
+        mv.visitInsn(I2L);
+        mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+            "add", Type.getMethodDescriptor(Type.VOID_TYPE,
+                new Type[] {Type.LONG_TYPE}));
+        break;
+
+      case Type.LONG:
+        cgs.pushBuilder();
+        cgs.pushFieldValue();
+        mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+            "add", Type.getMethodDescriptor(Type.VOID_TYPE,
+                new Type[] {Type.LONG_TYPE}));
+        break;
+
+      case Type.ARRAY:
+      case Type.OBJECT: {
+        if (f.getPrimitiveType() == byte[].class) {
+          cgs.pushBuilder();
+          cgs.pushFieldValue();
+          mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+              "add", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {Type
+                  .getType(byte[].class)}));
+
+        } else if (f.getPrimitiveType() == String.class) {
+          cgs.pushBuilder();
+          cgs.pushFieldValue();
+          mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+              "add", Type.getMethodDescriptor(Type.VOID_TYPE,
+                  new Type[] {string}));
+
+        } else if (f.getPrimitiveType() == java.sql.Timestamp.class
+            || f.getPrimitiveType() == java.util.Date.class
+            || f.getPrimitiveType() == java.sql.Date.class) {
+          cgs.pushBuilder();
+          cgs.pushFieldValue();
+          String tsType = Type.getType(f.getPrimitiveType()).getInternalName();
+          mv.visitMethodInsn(INVOKEVIRTUAL, tsType, "getTime", Type
+              .getMethodDescriptor(Type.LONG_TYPE, new Type[] {}));
+          mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+              "add", Type.getMethodDescriptor(Type.VOID_TYPE,
+                  new Type[] {Type.LONG_TYPE}));
+        } else {
+          throw new OrmException("Type " + f.getPrimitiveType()
+              + " not supported for field " + f.getPathToFieldName());
+        }
+        break;
+      }
+
+      default:
+        throw new OrmException("Type " + f.getPrimitiveType()
+            + " not supported for field " + f.getPathToFieldName());
+    }
+  }
+
+  private static final class IncludeCGS extends CodeGenSupport {
+    final Label no = new Label();
+
+    private IncludeCGS(MethodVisitor method) {
+      super(method);
+    }
+
+    @Override
+    public void pushEntity() {
+      mv.visitVarInsn(ALOAD, 1);
+    }
+  }
+
+  private static final class EncodeCGS extends CodeGenSupport {
+    private EncodeCGS(MethodVisitor method) {
+      super(method);
+    }
+
+    void infinity() {
+      pushBuilder();
+      mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+          "infinity", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
+    }
+
+    void delimiter() {
+      pushBuilder();
+      mv.visitMethodInsn(INVOKEVIRTUAL, indexKeyBuilder.getInternalName(),
+          "delimiter", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
+    }
+
+    void pushBuilder() {
+      mv.visitVarInsn(ALOAD, 1);
+    }
+
+    @Override
+    public void pushEntity() {
+      mv.visitVarInsn(ALOAD, 2);
+    }
+  }
+}
diff --git a/src/main/java/com/google/gwtorm/schema/QueryModel.java b/src/main/java/com/google/gwtorm/schema/QueryModel.java
index 44447e3..b94e224 100644
--- a/src/main/java/com/google/gwtorm/schema/QueryModel.java
+++ b/src/main/java/com/google/gwtorm/schema/QueryModel.java
@@ -31,24 +31,31 @@
 public class QueryModel {
   private final RelationModel model;
   private final String name;
-  private final Query query;
   private final Tree parsedQuery;
 
   public QueryModel(final RelationModel rel, final String queryName,
       final Query q) throws OrmException {
+    this(rel, queryName, queryTextOf(queryName, q));
+  }
+
+  private static String queryTextOf(String queryName, Query q)
+      throws OrmException {
     if (q == null) {
       throw new OrmException("Query " + queryName + " is missing "
           + Query.class.getName() + " annotation");
     }
+    return q.value();
+  }
 
+  public QueryModel(final RelationModel rel, final String queryName,
+      final String queryText) throws OrmException {
     model = rel;
     name = queryName;
-    query = q;
 
     try {
-      parsedQuery = QueryParser.parse(model, q.value());
+      parsedQuery = QueryParser.parse(model, queryText);
     } catch (QueryParseException e) {
-      throw new OrmException("Cannot parse query " + q.value(), e);
+      throw new OrmException("Cannot parse query " + queryText, e);
     }
   }
 
@@ -68,6 +75,20 @@
     return r;
   }
 
+  public List<ColumnModel> getOrderBy() {
+    final ArrayList<ColumnModel> r = new ArrayList<ColumnModel>();
+    if (parsedQuery != null) {
+      Tree node = findOrderBy(parsedQuery);
+      if (node != null) {
+        for (int i = 0; i < node.getChildCount(); i++) {
+          final Tree id = node.getChild(i);
+          r.add(((QueryParser.Column) id).getField());
+        }
+      }
+    }
+    return r;
+  }
+
   private void findParameters(final List<ColumnModel> r, final Tree node) {
     switch (node.getType()) {
       case QueryParser.WHERE:
@@ -134,6 +155,24 @@
     }
   }
 
+  private Tree findOrderBy(final Tree node) {
+    if (node == null) {
+      return null;
+    }
+    switch (node.getType()) {
+      case QueryParser.ORDER:
+        return node;
+      default:
+        for (int i = 0; i < node.getChildCount(); i++) {
+          final Tree r = findOrderBy(node.getChild(i));
+          if (r != null) {
+            return r;
+          }
+        }
+        return null;
+    }
+  }
+
   public String getSelectSql(final SqlDialect dialect, final String tableAlias) {
     final StringBuilder buf = new StringBuilder();
     buf.append(model.getSelectSql(dialect, tableAlias));
@@ -254,7 +293,7 @@
 
   @Override
   public String toString() {
-    return "Query[" + name + " " + query.value() + "]";
+    return "Query[" + name + " " + getParseTree().toStringTree() + "]";
   }
 
   private Tree expand(final Tree node) {
diff --git a/src/main/java/com/google/gwtorm/schema/java/JavaSchemaModel.java b/src/main/java/com/google/gwtorm/schema/java/JavaSchemaModel.java
index 53eabc9..b8a0748 100644
--- a/src/main/java/com/google/gwtorm/schema/java/JavaSchemaModel.java
+++ b/src/main/java/com/google/gwtorm/schema/java/JavaSchemaModel.java
@@ -18,6 +18,7 @@
 import com.google.gwtorm.client.Relation;
 import com.google.gwtorm.client.Schema;
 import com.google.gwtorm.client.Sequence;
+import com.google.gwtorm.schema.RelationModel;
 import com.google.gwtorm.schema.SchemaModel;
 import com.google.gwtorm.schema.SequenceModel;
 
@@ -55,6 +56,15 @@
     }
   }
 
+  public RelationModel getRelation(String name) {
+    for (RelationModel m : getRelations()) {
+      if (m.getMethodName().equals(name)) {
+        return m;
+      }
+    }
+    throw new IllegalArgumentException("No relation named " + name);
+  }
+
   @Override
   public String getSchemaClassName() {
     return schema.getName();
diff --git a/src/test/java/com/google/gwtorm/nosql/IndexFunctionTest.java b/src/test/java/com/google/gwtorm/nosql/IndexFunctionTest.java
new file mode 100644
index 0000000..862456a
--- /dev/null
+++ b/src/test/java/com/google/gwtorm/nosql/IndexFunctionTest.java
@@ -0,0 +1,200 @@
+// Copyright 2010 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gwtorm.nosql;
+
+import com.google.gwtorm.client.OrmException;
+import com.google.gwtorm.data.PhoneBookDb;
+import com.google.gwtorm.data.TestPerson;
+import com.google.gwtorm.schema.QueryModel;
+import com.google.gwtorm.schema.RelationModel;
+import com.google.gwtorm.schema.java.JavaSchemaModel;
+import com.google.gwtorm.server.GeneratedClassLoader;
+
+import junit.framework.TestCase;
+
+@SuppressWarnings("unchecked")
+public class IndexFunctionTest extends TestCase {
+  private JavaSchemaModel schema;
+  private RelationModel people;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    schema = new JavaSchemaModel(PhoneBookDb.class);
+    people = schema.getRelation("people");
+  }
+
+  public void testPersonByName() throws Exception {
+    IndexFunction<TestPerson> idx = index("testMyQuery", "WHERE name=?");
+    assertEquals("testMyQuery", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("bob"), 12);
+    assertTrue(idx.includes(p));
+    idx.encode(b, p);
+    assertEquals(new byte[] {'b', 'o', 'b'}, b);
+  }
+
+  public void testPersonByNameAge() throws Exception {
+    IndexFunction<TestPerson> idx = index("nameAge", "WHERE name=? AND age=?");
+    assertEquals("nameAge", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("hm"), 42);
+    assertTrue(idx.includes(p));
+    idx.encode(b, p);
+    assertEquals(new byte[] {'h', 'm', 0x00, 0x01, 0x01, 42}, b);
+
+    p = new TestPerson(new TestPerson.Key(null), 0);
+    assertFalse(idx.includes(p));
+
+    b = new IndexKeyBuilder();
+    assertFalse(idx.includes(p));
+  }
+
+  public void testPersonByNameAge_OrderByName() throws Exception {
+    IndexFunction<TestPerson> idx =
+        index("nameAge", "WHERE name=? AND age=? ORDER BY name");
+    assertEquals("nameAge", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("qy"), 42);
+    assertTrue(idx.includes(p));
+    idx.encode(b, p);
+    assertEquals(new byte[] {'q', 'y', 0x00, 0x01, 0x01, 42}, b);
+  }
+
+  public void testPersonByNameAge_OrderByRegistered() throws Exception {
+    IndexFunction<TestPerson> idx =
+        index("nameAge", "WHERE name=? AND age=? ORDER BY registered");
+    assertEquals("nameAge", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("q"), 42);
+    p.register();
+    assertTrue(idx.includes(p));
+    idx.encode(b, p);
+    assertEquals(new byte[] {'q', 0x00, 0x01, // name
+        0x01, 42, 0x00, 0x01, // age
+        0x01, 0x01 // registered
+        }, b);
+  }
+
+  public void testPersonByNameRange_OrderByName() throws Exception {
+    IndexFunction<TestPerson> idx =
+        index("nameSuggest", "WHERE name >= ? AND name <= ? ORDER BY name");
+    assertEquals("nameSuggest", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("q"), 42);
+    assertTrue(idx.includes(p));
+    idx.encode(b, p);
+    assertEquals(new byte[] {'q'}, b);
+  }
+
+  public void testOnlyRegistered() throws Exception {
+    IndexFunction<TestPerson> idx =
+        index("isregistered", "WHERE registered = true ORDER BY name");
+    assertEquals("isregistered", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("q"), 42);
+    assertFalse(idx.includes(p));
+    p.register();
+    assertTrue(idx.includes(p));
+
+    idx.encode(b, p);
+    assertEquals(new byte[] {'q'}, b);
+  }
+
+  public void testOnlyAge42() throws Exception {
+    IndexFunction<TestPerson> idx =
+        index("isOldEnough", "WHERE age = 42 ORDER BY name");
+    assertEquals("isOldEnough", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("q"), 32);
+    assertFalse(idx.includes(p));
+
+    p = new TestPerson(new TestPerson.Key("q"), 42);
+    assertTrue(idx.includes(p));
+
+    idx.encode(b, p);
+    assertEquals(new byte[] {'q'}, b);
+  }
+
+  public void testOnlyBob() throws Exception {
+    IndexFunction<TestPerson> idx = index("isbob", "WHERE name.name = 'bob'");
+    assertEquals("isbob", idx.getName());
+
+    IndexKeyBuilder b;
+    TestPerson p;
+
+    b = new IndexKeyBuilder();
+    p = new TestPerson(new TestPerson.Key("q"), 42);
+    assertFalse(idx.includes(p));
+
+    p = new TestPerson(new TestPerson.Key("bob"), 42);
+    assertTrue(idx.includes(p));
+
+    idx.encode(b, p);
+    assertEquals(new byte[] {}, b);
+  }
+
+  private IndexFunction<TestPerson> index(String name, String query)
+      throws OrmException {
+    final QueryModel qm = new QueryModel(people, name, query);
+    return new IndexFunctionGen(new GeneratedClassLoader(TestPerson.class
+        .getClassLoader()), qm, TestPerson.class).create();
+  }
+
+  private static void assertEquals(byte[] exp, IndexKeyBuilder ic) {
+    assertEquals(toString(exp), toString(ic.toByteArray()));
+  }
+
+  private static String toString(byte[] bin) {
+    StringBuilder dst = new StringBuilder(bin.length * 2);
+    for (byte b : bin) {
+      dst.append(hexchar[(b >>> 4) & 0x0f]);
+      dst.append(hexchar[b & 0x0f]);
+    }
+    return dst.toString();
+  }
+
+  private static final char[] hexchar =
+      {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', //
+          'a', 'b', 'c', 'd', 'e', 'f'};
+}
