private CodeBlock buildPopulateValuesIntoCursor() {
    CodeBlock.Builder builder = CodeBlock.builder();

    List<ColumnDefinition> columns = schema.getColumns();
    for (int i = 0; i < columns.size(); i++) {
      ColumnDefinition c = columns.get(i);
      RelationDefinition r = c.getRelation();
      TypeName type = c.getUnboxType();
      if (r == null) {
        CodeBlock.Builder getCursorExpr = CodeBlock.builder();

        if (Types.needsTypeAdapter(type)) {
          getCursorExpr.add(
              "conn.getTypeAdapterRegistry().$L($T.$L.type, $L)",
              c.nullable ? "deserializeNullable" : "deserialize",
              schema.getSchemaClassName(),
              c.name,
              cursorGetter(c, i));
        } else {
          getCursorExpr.add("$L", cursorGetter(c, i));
        }

        if (c.setter != null) {
          builder.addStatement("model.$L($L)", c.setter.getSimpleName(), getCursorExpr.build());

        } else {
          builder.addStatement("model.$L = $L", c.name, getCursorExpr.build());
        }
      } else { // SingleRelation
        if (c.setter != null) {
          builder.addStatement(
              "model.$L(new $T<>(conn, OrmaDatabase.schema$T, cursor.getLong($L)))",
              c.setter.getSimpleName(),
              r.relationType,
              r.modelType,
              i);

        } else {
          builder.addStatement(
              "model.$L = new $T<>(conn, OrmaDatabase.schema$T, cursor.getLong($L))",
              c.name,
              r.relationType,
              r.modelType,
              i);
        }
      }
    }
    return builder.build();
  }
  // http://developer.android.com/intl/ja/reference/android/database/sqlite/SQLiteStatement.html
  private CodeBlock buildBindArgs() {
    CodeBlock.Builder builder = CodeBlock.builder();

    List<ColumnDefinition> columns = schema.getColumnsWithoutAutoId();
    for (int i = 0; i < columns.size(); i++) {
      int n = i + 1; // bind index starts 1
      ColumnDefinition c = columns.get(i);
      TypeName type = c.getUnboxType();
      RelationDefinition r = c.getRelation();
      boolean nullable = !type.isPrimitive() && c.nullable;

      if (nullable) {
        builder.beginControlFlow("if (model.$L != null)", c.name);
      }

      if (type.equals(TypeName.BOOLEAN)) {
        builder.addStatement(
            "statement.bindLong($L, model.$L ? 1 : 0)", n, c.getColumnGetterExpr());
      } else if (Types.looksLikeIntegerType(type)) {
        builder.addStatement("statement.bindLong($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (Types.looksLikeFloatType(type)) {
        builder.addStatement("statement.bindDouble($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (type.equals(Types.ByteArray)) {
        builder.addStatement("statement.bindBlob($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (type.equals(Types.String)) {
        builder.addStatement("statement.bindString($L, model.$L)", n, c.getColumnGetterExpr());
      } else if (r != null && r.relationType.equals(Types.SingleRelation)) {
        builder.addStatement(
            "statement.bindLong($L, model.$L.getId())", n, c.getColumnGetterExpr());
      } else {
        builder.addStatement(
            "statement.bindString($L, conn.getTypeAdapterRegistry().serialize($T.$L.type, model.$L))",
            n,
            schema.getSchemaClassName(),
            c.name,
            c.getColumnGetterExpr());
      }

      if (nullable) {
        builder.endControlFlow();
        builder.beginControlFlow("else");
        builder.addStatement("statement.bindNull($L)", n);
        builder.endControlFlow();
      }
    }

    return builder.build();
  }
 private String cursorGetter(ColumnDefinition column, int position) {
   TypeName type = column.getUnboxType();
   if (type.equals(TypeName.BOOLEAN)) {
     return "cursor.getLong(" + position + ") != 0";
   } else if (type.equals(TypeName.BYTE)) {
     return "(byte)cursor.getShort(" + position + ")";
   } else if (type.isPrimitive()) {
     String s = type.toString();
     return "cursor.get" + s.substring(0, 1).toUpperCase() + s.substring(1) + "(" + position + ")";
   } else if (type.equals(Types.String)) {
     return "cursor.getString(" + position + ")";
   } else if (type.equals(Types.ByteArray)) {
     return "cursor.getBlob(" + position + ")";
   } else {
     return "cursor.getString(" + position + ")"; // handled by type adapters
   }
 }