public boolean equalsExceptVisits(Object o) {
   if (!(o instanceof HistoryRecord)) {
     return false;
   }
   HistoryRecord other = (HistoryRecord) o;
   return super.equals(other)
       && RepoUtils.stringsEqual(this.title, other.title)
       && RepoUtils.stringsEqual(this.histURI, other.histURI);
 }
  public boolean equals(Object o) {
    if (!(o instanceof ClientRecord) || !super.equals(o)) {
      return false;
    }

    ClientRecord other = (ClientRecord) o;
    if (!RepoUtils.stringsEqual(other.name, this.name)
        || !RepoUtils.stringsEqual(other.type, this.type)) {
      return false;
    }
    return true;
  }
 @Override
 public boolean equalPayloads(Object o) {
   if (!(o instanceof HistoryRecord)) {
     Logger.debug(LOG_TAG, "Not a HistoryRecord: " + o.getClass());
     return false;
   }
   HistoryRecord other = (HistoryRecord) o;
   if (!super.equalPayloads(other)) {
     Logger.debug(LOG_TAG, "super.equalPayloads returned false.");
     return false;
   }
   return RepoUtils.stringsEqual(this.title, other.title)
       && RepoUtils.stringsEqual(this.histURI, other.histURI)
       && checkVisitsEquals(other);
 }
 private Cursor checkAndLogCursor(String label, long queryStart, Cursor c)
     throws NullCursorException {
   long queryEnd = android.os.SystemClock.uptimeMillis();
   String logLabel = (label == null) ? tag : (tag + label);
   RepoUtils.queryTimeLogger(logLabel, queryStart, queryEnd);
   return checkNullCursor(logLabel, c);
 }
  private String getParentName(String parentGUID)
      throws ParentNotFoundException, NullCursorException {
    if (parentGUID == null) {
      return "";
    }
    if (SPECIAL_GUIDS_MAP.containsKey(parentGUID)) {
      return SPECIAL_GUIDS_MAP.get(parentGUID);
    }

    // Get parent name from database.
    String parentName = "";
    Cursor name = dataAccessor.fetch(new String[] {parentGUID});
    try {
      name.moveToFirst();
      if (!name.isAfterLast()) {
        parentName = RepoUtils.getStringFromCursor(name, BrowserContract.Bookmarks.TITLE);
      } else {
        Logger.error(
            LOG_TAG,
            "Couldn't find record with guid '" + parentGUID + "' when looking for parent name.");
        throw new ParentNotFoundException(null);
      }
    } finally {
      name.close();
    }
    return parentName;
  }
  @Override
  public void begin(RepositorySessionBeginDelegate delegate)
      throws InvalidSessionTransitionException {
    // Check for the existence of special folders
    // and insert them if they don't exist.
    Cursor cur;
    try {
      Logger.debug(LOG_TAG, "Check and build special GUIDs.");
      dataAccessor.checkAndBuildSpecialGuids();
      cur = dataAccessor.getGuidsIDsForFolders();
      Logger.debug(LOG_TAG, "Got GUIDs for folders.");
    } catch (android.database.sqlite.SQLiteConstraintException e) {
      Logger.error(LOG_TAG, "Got sqlite constraint exception working with Fennec bookmark DB.", e);
      delegate.onBeginFailed(e);
      return;
    } catch (NullCursorException e) {
      delegate.onBeginFailed(e);
      return;
    } catch (Exception e) {
      delegate.onBeginFailed(e);
      return;
    }

    // To deal with parent mapping of bookmarks we have to do some
    // hairy stuff. Here's the setup for it.

    Logger.debug(LOG_TAG, "Preparing folder ID mappings.");

    // Fake our root.
    Logger.debug(LOG_TAG, "Tracking places root as ID 0.");
    parentIDToGuidMap.put(0L, "places");
    parentGuidToIDMap.put("places", 0L);
    try {
      cur.moveToFirst();
      while (!cur.isAfterLast()) {
        String guid = getGUID(cur);
        long id = RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks._ID);
        parentGuidToIDMap.put(guid, id);
        parentIDToGuidMap.put(id, guid);
        Logger.debug(LOG_TAG, "GUID " + guid + " maps to " + id);
        cur.moveToNext();
      }
    } finally {
      cur.close();
    }
    deletionManager = new BookmarksDeletionManager(dataAccessor, DEFAULT_DELETION_FLUSH_THRESHOLD);

    // We just crawled the database enumerating all folders; we'll start the
    // insertion manager with exactly these folders as the known parents (the
    // collection is copied) in the manager constructor.
    insertionManager =
        new BookmarksInsertionManager(
            DEFAULT_INSERTION_FLUSH_THRESHOLD, parentGuidToIDMap.keySet(), this);

    Logger.debug(LOG_TAG, "Done with initial setup of bookmarks session.");
    super.begin(delegate);
  }
 /**
  * We consider two history records to be congruent if they represent the same history record
  * regardless of visits. Titles are allowed to differ, but the URI must be the same.
  */
 @Override
 public boolean congruentWith(Object o) {
   if (!(o instanceof HistoryRecord)) {
     return false;
   }
   HistoryRecord other = (HistoryRecord) o;
   if (!super.congruentWith(other)) {
     return false;
   }
   return RepoUtils.stringsEqual(this.histURI, other.histURI);
 }
 /** Dump all the records in raw format. */
 public void dumpDB() {
   Cursor cur = null;
   try {
     cur = queryHelper.safeQuery(".dumpDB", null, null, null, null);
     RepoUtils.dumpCursor(cur);
   } catch (NullCursorException e) {
   } finally {
     if (cur != null) {
       cur.close();
     }
   }
 }
  // Create a BookmarkRecord object from a cursor on a row containing a Fennec bookmark.
  public static BookmarkRecord bookmarkFromMirrorCursor(
      Cursor cur, String parentGUID, String parentName, JSONArray children) {
    final String collection = "bookmarks";
    final String guid = RepoUtils.getStringFromCursor(cur, BrowserContract.SyncColumns.GUID);
    final long lastModified =
        RepoUtils.getLongFromCursor(cur, BrowserContract.SyncColumns.DATE_MODIFIED);
    final boolean deleted = isDeleted(cur);
    BookmarkRecord rec = new BookmarkRecord(guid, collection, lastModified, deleted);

    // No point in populating it.
    if (deleted) {
      return logBookmark(rec);
    }

    int rowType = getTypeFromCursor(cur);
    String typeString = BrowserContractHelpers.typeStringForCode(rowType);

    if (typeString == null) {
      Logger.warn(LOG_TAG, "Unsupported type code " + rowType);
      return null;
    } else {
      Logger.trace(LOG_TAG, "Record " + guid + " has type " + typeString);
    }

    rec.type = typeString;
    rec.title = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.TITLE);
    rec.bookmarkURI = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.URL);
    rec.description = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.DESCRIPTION);
    rec.tags = RepoUtils.getJSONArrayFromCursor(cur, BrowserContract.Bookmarks.TAGS);
    rec.keyword = RepoUtils.getStringFromCursor(cur, BrowserContract.Bookmarks.KEYWORD);

    rec.androidID = RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks._ID);
    rec.androidPosition = RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks.POSITION);
    rec.children = children;

    // Need to restore the parentId since it isn't stored in content provider.
    // We also take this opportunity to fix up parents for special folders,
    // allowing us to map between the hierarchies used by Fennec and Places.
    BookmarkRecord withParentFields = computeParentFields(rec, parentGUID, parentName);
    if (withParentFields == null) {
      // Oh dear. Something went wrong.
      return null;
    }
    return logBookmark(withParentFields);
  }
 /**
  * Fetch records for the provided GUIDs.
  *
  * <p>The caller is responsible for closing the cursor.
  *
  * @param guids The GUIDs of the records to fetch.
  * @return A cursor. You <b>must</b> close this when you're done with it.
  * @throws NullCursorException
  */
 public Cursor fetch(String guids[]) throws NullCursorException {
   String where = RepoUtils.computeSQLInClause(guids.length, "guid");
   return queryHelper.safeQuery(".fetch", getAllColumns(), where, guids, null);
 }
 protected static boolean isDeleted(Cursor cur) {
   return RepoUtils.getLongFromCursor(cur, BrowserContract.SyncColumns.IS_DELETED) != 0;
 }
 private long getPosition(Cursor cur) {
   return RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks.POSITION);
 }
 private long getParentID(Cursor cur) {
   return RepoUtils.getLongFromCursor(cur, BrowserContract.Bookmarks.PARENT);
 }
 private String getGUID(Cursor cur) {
   return RepoUtils.getStringFromCursor(cur, "guid");
 }
 private static int getTypeFromCursor(Cursor cur) {
   return RepoUtils.getIntFromCursor(cur, BrowserContract.Bookmarks.TYPE);
 }