private void writeRemoveWith(Table table, Field field) throws IOException {
    ArrayList<String> params = new ArrayList<String>();
    params.add(SqlUtil.getJavaTypeFor(field.type));
    params.add(field.name);

    // remove with UNIQUE
    writer.emitEmptyLine();
    writer.beginMethod(
        "void",
        "remove" + Util.capitalize(table.name) + "With" + Util.capitalize(field.name),
        EnumSet.of(Modifier.PUBLIC),
        params.toArray(new String[params.size()]));
    writer.emitStatement(
        "ContentProviderOperation.Builder operationBuilder = ContentProviderOperation.newDelete("
            + mModel.getContentProviderName()
            + "."
            + SqlUtil.URI(table)
            + ")");
    writer.emitStatement(
        "operationBuilder.withSelection("
            + mModel.getDbClassName()
            + "."
            + SqlUtil.ROW_COLUMN(table, field)
            + " + \"=?\", new String[]{String.valueOf("
            + field.name
            + ")})");
    insertAddOpBlock();
    writer.endMethod();
  }
 private void emitFields() throws IOException {
   writer.emitEmptyLine();
   writer.emitField(
       "String",
       "TAG",
       EnumSet.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL),
       "\"" + mModel.getContentProviderName() + "\"");
   writer.emitField(
       "String",
       "DATABASE_NAME",
       EnumSet.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL),
       "\"" + mModel.getDbClassName() + ".db\"");
   writer.emitField(
       "int",
       "DATABASE_VERSION",
       EnumSet.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL),
       mModel.getDbVersion());
   writer.emitField(
       "String",
       "ROW_ID",
       EnumSet.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL),
       "\"" + Table.ANDROID_ID + "\"");
   writer.emitEmptyLine();
   writer.emitField(
       "String",
       "AUTHORITY",
       EnumSet.of(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL),
       "\"" + mModel.getContentAuthority() + "\"");
   writer.emitEmptyLine();
   writer.emitField(mModel.getDbClassName(), "mLocalDatabase", EnumSet.of(Modifier.PRIVATE));
   writer.emitEmptyLine();
 }
 private void emitClass() throws IOException {
   writer.beginType(
       mModel.getClassPackage()
           + "."
           + mModel.getContentProviderName()
           + " extends ContentProvider",
       "class",
       EnumSet.of(Modifier.PUBLIC, Modifier.FINAL));
 }
  private void emitContentProviderOperationMethods() throws IOException {
    ArrayList<String> throwing = new ArrayList<String>();
    throwing.add("OperationApplicationException");
    throwing.add("RemoteException");

    ArrayList<String> batchparams = new ArrayList<String>();
    batchparams.add("Context");
    batchparams.add("c");

    writer.emitEmptyLine();
    writer.emitJavadoc("Starts a new batch of operations to run on commit.");
    writer.beginMethod("void", "start", EnumSet.of(Modifier.PUBLIC));
    writer.emitStatement("batchOperations = new ArrayList<ContentProviderOperation>()");
    writer.endMethod();

    writer.emitEmptyLine();
    writer.emitJavadoc(
        "Commits a started batch of operations, this can include any variety of operations.");
    writer.beginMethod(
        "ContentProviderResult[]", "commit", EnumSet.of(Modifier.PUBLIC), batchparams, throwing);
    writer.beginControlFlow("if (batchOperations != null) ");
    writer.emitStatement("ContentResolver cr = c.getContentResolver()");
    writer.emitStatement(
        "ContentProviderResult[] result = cr.applyBatch( "
            + mModel.getContentProviderName()
            + ".AUTHORITY, batchOperations )");
    writer.emitStatement("batchOperations.clear()");
    writer.emitStatement("return result");
    writer.nextControlFlow("else");
    writer.emitStatement(
        "throw new RuntimeException(\""
            + mModel.getCRUDBatchClientName()
            + ".start() needs to be called first!\")");
    writer.endControlFlow();
    writer.endMethod();

    writer.emitEmptyLine();
    writer.emitJavadoc("add an operation to the batch of operations, if this client was started.");
    writer.beginMethod(
        "void", "add", EnumSet.of(Modifier.PUBLIC), "ContentProviderOperation", "operation");
    writer.beginControlFlow("if (batchOperations != null) ");
    writer.emitStatement("batchOperations.add(operation)");
    writer.nextControlFlow("else");
    writer.emitStatement(
        "throw new RuntimeException(\""
            + mModel.getCRUDBatchClientName()
            + ".start() needs to be called first!\")");
    writer.endControlFlow();
    writer.endMethod();
  }
  private void emitTableCRUD(Table table) throws Exception {
    // Default array params for all rows
    ArrayList<String> params = new ArrayList<String>();
    for (Field row : table.fields) {

      params.add(SqlUtil.getJavaTypeFor(row.type));
      params.add(row.name);
    }

    ArrayList<String> paramsWithUnique = new ArrayList<String>();
    paramsWithUnique.add(SqlUtil.getJavaTypeFor(table.getPrimaryKey().type));
    paramsWithUnique.add(table.getPrimaryKey().name);

    ArrayList<String> updateParams = new ArrayList<String>();
    // TODO : add unique id
    updateParams.addAll(params);

    Iterator<Constraint> constraintiter;

    writer.emitEmptyLine();
    writer.emitJavadoc(
        table.name + " OPERATIONS\nall operations require this client to first run start");
    writer.emitEmptyLine();

    // Add through ContentProviderOperation
    writer.beginMethod(
        "void",
        "add" + Util.capitalize(table.name),
        EnumSet.of(Modifier.PUBLIC),
        params.toArray(new String[params.size()]));
    writer.emitStatement(
        "ContentProviderOperation.Builder operationBuilder = ContentProviderOperation.newInsert("
            + mModel.getContentProviderName()
            + "."
            + SqlUtil.URI(table)
            + ")");
    for (Field row : table.fields) {
      writer.emitStatement(
          "operationBuilder.withValue("
              + mModel.getDbClassName()
              + "."
              + SqlUtil.ROW_COLUMN(table, row)
              + ","
              + row.name
              + ")");
    }
    insertAddOpBlock();
    writer.endMethod();

    // Removes
    writeRemoveWith(table, table.getPrimaryKey());

    constraintiter = table.constraints.iterator();

    while (constraintiter.hasNext()) {
      Constraint constraint = constraintiter.next();
      if (constraint.type.equals(Constraint.Type.UNIQUE)) {
        final String[] fields = SqlUtil.getFieldsFromConstraint(constraint);
        for (int i = 0; i < fields.length; i++) {
          writeRemoveWith(table, table.getFieldByName(fields[i]));
        }
      }
    }

    // Remove All results
    writer.emitEmptyLine();
    writer.beginMethod(
        "void", "removeAll" + Util.capitalize(table.name), EnumSet.of(Modifier.PUBLIC));
    writer.emitStatement(
        "ContentProviderOperation.Builder operationBuilder = ContentProviderOperation.newDelete("
            + mModel.getContentProviderName()
            + "."
            + SqlUtil.URI(table)
            + ")");
    insertAddOpBlock();
    writer.endMethod();

    // Update through ContentProviderOperation
    writer.emitEmptyLine();
    writer.beginMethod(
        "void",
        "update" + Util.capitalize(table.name),
        EnumSet.of(Modifier.PUBLIC),
        updateParams.toArray(new String[updateParams.size()]));
    writer.emitStatement(
        "ContentProviderOperation.Builder operationBuilder = ContentProviderOperation.newUpdate("
            + mModel.getContentProviderName()
            + "."
            + SqlUtil.URI(table)
            + ")");
    for (Field row : table.fields) {
      writer.emitStatement(
          "operationBuilder.withValue("
              + mModel.getDbClassName()
              + "."
              + SqlUtil.ROW_COLUMN(table, row)
              + ","
              + row.name
              + ")");
    }
    insertAddOpBlock();
    writer.endMethod();
  }
 public ContentProviderWriter(String javaOut, Model model) throws IOException {
   super(javaOut, model, model.getContentProviderName());
   this.mModel = model;
 }