static BasicDocumentRevision getFullRevisionFromCurrentCursor(Cursor cursor) {
    String docId = cursor.getString(0);
    long internalId = cursor.getLong(1);
    String revId = cursor.getString(2);
    long sequence = cursor.getLong(3);
    byte[] json = cursor.getBlob(4);
    boolean current = cursor.getInt(5) > 0;
    boolean deleted = cursor.getInt(6) > 0;

    long parent = -1L;
    if (cursor.columnType(7) == Cursor.FIELD_TYPE_INTEGER) {
      parent = cursor.getLong(7);
    } else if (cursor.columnType(7) == Cursor.FIELD_TYPE_NULL) {
    } else {
      throw new IllegalArgumentException("Unexpected type: " + cursor.columnType(7));
    }

    DocumentRevisionBuilder builder =
        new DocumentRevisionBuilder()
            .setDocId(docId)
            .setRevId(revId)
            .setBody(BasicDocumentBody.bodyWith(json))
            .setDeleted(deleted)
            .setSequence(sequence)
            .setInternalId(internalId)
            .setCurrnet(current)
            .setParent(parent);

    return builder.buildBasicDBObject();
  }
  // Keep in mind we do not keep local document revision history
  private BasicDocumentRevision doGetLocalDocument(String docId, String revId) {
    assert !Strings.isNullOrEmpty(docId);
    Cursor cursor = null;
    try {
      String[] args = {docId};
      cursor = this.sqlDb.rawQuery("SELECT revid, json FROM localdocs WHERE docid=?", args);
      if (cursor.moveToFirst()) {
        String gotRevID = cursor.getString(0);

        if (revId != null && !revId.equals(gotRevID)) {
          //                    throw new DocumentNotFoundException("No local document found with
          // id: " + docId + ", revId: " + revId);
          return null;
        }

        byte[] json = cursor.getBlob(1);

        DocumentRevisionBuilder builder =
            new DocumentRevisionBuilder()
                .setDocId(docId)
                .setRevId(gotRevID)
                .setBody(BasicDocumentBody.bodyWith(json));

        return builder.buildBasicDBObjectLocalDocument();
      } else {
        return null;
      }
    } catch (SQLException e) {
      throw new SQLRuntimeException("Error getting local document with id: " + docId, e);
    } finally {
      DatabaseUtils.closeCursorQuietly(cursor);
    }
  }
  @Override
  public Iterator<String> getConflictedDocumentIds() {

    // the "SELECT DISTINCT ..." subquery selects all the parent
    // sequence, and so the outer "SELECT ..." practically selects
    // all the leaf nodes. The "GROUP BY" and "HAVING COUNT(*) > 1"
    // make sure only those document with more than one leafs are
    // returned.
    final String sql =
        "SELECT docs.docid, COUNT(*) FROM docs,revs "
            + "WHERE revs.doc_id = docs.doc_id "
            + "AND deleted = 0 AND revs.sequence NOT IN "
            + "(SELECT DISTINCT parent FROM revs WHERE parent NOT NULL) "
            + "GROUP BY docs.docid HAVING COUNT(*) > 1";

    List<String> conflicts = new ArrayList<String>();
    Cursor cursor = null;
    try {
      cursor = this.sqlDb.rawQuery(sql, new String[] {});
      while (cursor.moveToNext()) {
        String docId = cursor.getString(0);
        conflicts.add(docId);
      }
    } catch (SQLException e) {
      Log.e(LOG_TAG, "Error getting conflicted document: ", e);
    } finally {
      DatabaseUtils.closeCursorQuietly(cursor);
    }
    return conflicts.iterator();
  }
  /**
   * Removes revisions present in the datastore from the input map.
   *
   * @param revisions an multimap from document id to set of revisions. The map is modified in place
   *     for performance consideration.
   */
  void revsDiffBatch(Multimap<String, String> revisions) {

    final String sql =
        String.format(
            "SELECT docs.docid, revs.revid FROM docs, revs "
                + "WHERE docs.doc_id = revs.doc_id AND docs.docid IN (%s) AND revs.revid IN (%s) "
                + "ORDER BY docs.docid",
            SQLDatabaseUtils.makePlaceholders(revisions.keySet().size()),
            SQLDatabaseUtils.makePlaceholders(revisions.size()));

    String[] args = new String[revisions.keySet().size() + revisions.size()];
    String[] keys = revisions.keySet().toArray(new String[revisions.keySet().size()]);
    String[] values = revisions.values().toArray(new String[revisions.size()]);
    System.arraycopy(keys, 0, args, 0, revisions.keySet().size());
    System.arraycopy(values, 0, args, revisions.keySet().size(), revisions.size());

    Cursor cursor = null;
    try {
      cursor = this.sqlDb.rawQuery(sql, args);
      while (cursor.moveToNext()) {
        String docId = cursor.getString(0);
        String revId = cursor.getString(1);
        revisions.remove(docId, revId);
      }
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      DatabaseUtils.closeCursorQuietly(cursor);
    }
  }
  public static Set<String> getAllTableNames(SQLDatabase db) throws SQLException {
    Cursor cursor = null;
    try {
      cursor = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", new String[] {});
      Set<String> tables = new HashSet<String>();
      while (cursor.moveToNext()) {
        tables.add(cursor.getString(0));
      }
      return tables;
    } finally {

    }
  }
 public static Set<String> getCompileOptions(SQLDatabase db) throws SQLException {
   Cursor cursor = null;
   Set<String> compileOptions = new HashSet<String>();
   try {
     cursor = db.rawQuery("PRAGMA compile_options", new String[] {});
     while (cursor.moveToNext()) {
       compileOptions.add(cursor.getString(0));
     }
   } finally {
     if (cursor != null) {
       cursor.close();
     }
   }
   return compileOptions;
 }
 @Override
 public String getPublicIdentifier() {
   Preconditions.checkState(this.isOpen(), "Database is closed");
   Cursor cursor = null;
   try {
     cursor = this.sqlDb.rawQuery("SELECT value FROM info WHERE key='publicUUID'", null);
     if (cursor.moveToFirst()) {
       return "touchdb_" + cursor.getString(0);
     } else {
       throw new IllegalStateException(
           "Error querying PublicUUID, "
               + "it is probably because the sqlDatabase is not probably initialized.");
     }
   } catch (SQLException e) {
     throw new SQLRuntimeException("Error querying publicUUID: ", e);
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
 }