// 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();
  }
  @Override
  public Changes changes(long since, int limit) {
    Preconditions.checkState(this.isOpen(), "Database is closed");
    Preconditions.checkArgument(limit > 0, "Limit must be positive number");
    since = since >= 0 ? since : 0;

    String[] args = {Long.toString(since), Long.toString(since + limit)};
    Cursor cursor = null;
    try {
      Long lastSequence = since;
      List<Long> ids = new ArrayList<Long>();
      cursor = this.sqlDb.rawQuery(SQL_CHANGE_IDS_SINCE_LIMIT, args);
      while (cursor.moveToNext()) {
        ids.add(cursor.getLong(0));
        lastSequence = Math.max(lastSequence, cursor.getLong(1));
      }
      List<DocumentRevision> results = this.getDocumentsWithInternalIds(ids);
      if (results.size() != ids.size()) {
        throw new IllegalStateException(
            "The number of document does not match number of ids, "
                + "something must be wrong here.");
      }

      return new Changes(lastSequence, results);
    } catch (SQLException e) {
      throw new IllegalStateException(
          "Error querying all changes since: " + since + ", limit: " + limit, e);
    } finally {
      DatabaseUtils.closeCursorQuietly(cursor);
    }
  }
  private DocumentRevisionTree getAllRevisionsOfDocument(long docNumericID) {
    String sql =
        "SELECT "
            + FULL_DOCUMENT_COLS
            + " FROM revs, docs "
            + "WHERE revs.doc_id=? AND revs.doc_id = docs.doc_id ORDER BY sequence ASC";

    String[] args = {Long.toString(docNumericID)};
    Cursor cursor = null;

    try {
      DocumentRevisionTree tree = new DocumentRevisionTree();
      cursor = this.sqlDb.rawQuery(sql, args);
      while (cursor.moveToNext()) {
        DocumentRevision rev = SQLDatabaseUtils.getFullRevisionFromCurrentCursor(cursor);
        Log.v(LOG_TAG, "Rev: " + rev);
        tree.add(rev);
      }
      return tree;
    } catch (SQLException e) {
      Log.e(LOG_TAG, "Error getting all revisions of document", e);
      return null;
    } finally {
      DatabaseUtils.closeCursorQuietly(cursor);
    }
  }
  /**
   * 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);
    }
  }
Пример #6
0
  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();
  }
  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;
 }
 private List<DocumentRevision> getRevisionsFromRawQuery(String sql, String[] args) {
   List<DocumentRevision> result = new ArrayList<DocumentRevision>();
   Cursor cursor = null;
   try {
     cursor = this.sqlDb.rawQuery(sql, args);
     while (cursor.moveToNext()) {
       DocumentRevision row = SQLDatabaseUtils.getFullRevisionFromCurrentCursor(cursor);
       result.add(row);
     }
   } catch (SQLException e) {
     e
         .printStackTrace(); // To change bodyOne of catch statement use File | Settings | File
                             // Templates.
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
   return result;
 }
 @Override
 public long getDocNumericId(String docId) {
   Preconditions.checkState(this.isOpen(), "Database is closed");
   Preconditions.checkArgument(
       !Strings.isNullOrEmpty(docId), "Input document id can not be empty");
   Cursor cursor = null;
   try {
     cursor = this.sqlDb.rawQuery("SELECT doc_id FROM docs WHERE docid = ?", new String[] {docId});
     if (cursor.moveToFirst()) {
       return cursor.getLong(0);
     }
   } catch (SQLException e) {
     Log.e(LOG_TAG, "Error getting doc numeric id", e);
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
   return -1;
 }
 @Override
 public int getDocumentCount() {
   Preconditions.checkState(this.isOpen(), "Database is closed");
   String sql = "SELECT COUNT(DISTINCT doc_id) FROM revs WHERE current=1 AND deleted=0";
   Cursor cursor = null;
   int result = 0;
   try {
     cursor = this.sqlDb.rawQuery(sql, null);
     if (cursor.moveToFirst()) {
       result = cursor.getInt(0);
     }
   } catch (SQLException e) {
     Log.e(LOG_TAG, "Error getting document count", e);
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
   return result;
 }
 @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);
   }
 }
 @Override
 public BasicDocumentRevision getDocument(String id, String rev) {
   Preconditions.checkState(this.isOpen(), "Database is closed");
   Preconditions.checkArgument(
       !Strings.isNullOrEmpty(id), "DocumentRevisionTree id can not be empty");
   Cursor cursor = null;
   try {
     String[] args = (rev == null) ? new String[] {id} : new String[] {id, rev};
     String sql = (rev == null) ? GET_DOCUMENT_CURRENT_REVISION : GET_DOCUMENT_GIVEN_REVISION;
     cursor = this.sqlDb.rawQuery(sql, args);
     if (cursor.moveToFirst()) {
       return SQLDatabaseUtils.getFullRevisionFromCurrentCursor(cursor);
     } else {
       return null;
     }
   } catch (SQLException e) {
     throw new SQLRuntimeException("Error getting document with id: " + id + "and rev" + rev, e);
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
 }
 @Override
 public long getLastSequence() {
   Preconditions.checkState(this.isOpen(), "Database is closed");
   String sql = "SELECT MAX(sequence) FROM revs";
   Cursor cursor = null;
   long result = 0;
   try {
     cursor = this.sqlDb.rawQuery(sql, null);
     if (cursor.moveToFirst()) {
       if (cursor.columnType(0) == Cursor.FIELD_TYPE_INTEGER) {
         result = cursor.getLong(0);
       } else if (cursor.columnType(0) == Cursor.FIELD_TYPE_NULL) {
         result = SEQUENCE_NUMBER_START;
       } else {
         throw new IllegalStateException("SQLite return an unexpected value.");
       }
     }
   } catch (SQLException e) {
     Log.e(LOG_TAG, "Error getting last sequence", e);
   } finally {
     DatabaseUtils.closeCursorQuietly(cursor);
   }
   return result;
 }