Bug 648338 - Remove Firefox 3.5/3.6 compat code in the history engine. r=rnewman
authorPhilipp von Weitershausen <philipp@weitershausen.de>
Thu, 07 Apr 2011 15:30:44 -0700
changeset 67774 20ab4d32a215b9112ebe239946942eefdaea2ee7
parent 67773 f73ae964d03329cb86fae0c12004c68e425f845c
child 67775 7249a475841963025662109455c1ba4cbda88a48
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs648338
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 648338 - Remove Firefox 3.5/3.6 compat code in the history engine. r=rnewman
services/sync/modules/engines/history.js
services/sync/tests/unit/test_history_store.js
services/sync/tests/unit/test_places_guid_downgrade.js
--- a/services/sync/modules/engines/history.js
+++ b/services/sync/modules/engines/history.js
@@ -73,19 +73,16 @@ function HistoryEngine() {
 HistoryEngine.prototype = {
   __proto__: SyncEngine.prototype,
   _recordObj: HistoryRec,
   _storeObj: HistoryStore,
   _trackerObj: HistoryTracker,
   downloadLimit: MAX_HISTORY_DOWNLOAD,
   applyIncomingBatchSize: HISTORY_STORE_BATCH_SIZE,
 
-  // For Gecko <2.0
-  _sync: Utils.batchSync("History", SyncEngine),
-
   _findDupe: function _findDupe(item) {
     return this._store.GUIDForUri(item.histUri);
   }
 };
 
 function HistoryStore(name) {
   Store.call(this, name);
 
@@ -108,200 +105,59 @@ HistoryStore.prototype = {
                     QueryInterface(Ci.nsIGlobalHistory2).
                     QueryInterface(Ci.nsIBrowserHistory).
                     QueryInterface(Ci.nsPIPlacesDatabase);
     return this.__hsvc;
   },
 
   __asyncHistory: null,
   get _asyncHistory() {
-    if (!this.__asyncHistory && "mozIAsyncHistory" in Components.interfaces) {
+    if (!this.__asyncHistory) {
       this.__asyncHistory = Cc["@mozilla.org/browser/history;1"]
                               .getService(Ci.mozIAsyncHistory);
     }
     return this.__asyncHistory;
   },
 
-  get _db() {
-    return this._hsvc.DBConnection;
-  },
-
   _stmts: {},
   _getStmt: function(query) {
     if (query in this._stmts)
       return this._stmts[query];
 
     this._log.trace("Creating SQL statement: " + query);
-    return this._stmts[query] = Utils.createStatement(this._db, query);
-  },
-
-  get _haveTempTablesStm() {
-    return this._getStmt(
-      "SELECT name FROM sqlite_temp_master " +
-      "WHERE name IN ('moz_places_temp', 'moz_historyvisits_temp')");
-  },
-  _haveTempTablesCols: ["name"],
-
-  __haveTempTables: null,
-  get _haveTempTables() {
-    if (this.__haveTempTables === null) {
-      this.__haveTempTables = !!Utils.queryAsync(
-        this._haveTempTablesStm, this._haveTempTablesCols).length;
-    }
-    return this.__haveTempTables;
-  },
-
-  __haveGUIDColumn: null,
-  get _haveGUIDColumn() {
-    if (this.__haveGUIDColumn !== null) {
-      return this.__haveGUIDColumn;
-    }
-    let stmt;
-    try {
-      stmt = this._db.createStatement("SELECT guid FROM moz_places");
-      stmt.finalize();
-      return this.__haveGUIDColumn = true;
-    } catch(ex) {
-      return this.__haveGUIDColumn = false;
-    }
-  },
-
-  get _addGUIDAnnotationNameStm() {
-    // Gecko <2.0 only
-    let stmt = this._getStmt(
-      "INSERT OR IGNORE INTO moz_anno_attributes (name) VALUES (:anno_name)");
-    stmt.params.anno_name = GUID_ANNO;
-    return stmt;
+    return this._stmts[query] = this._hsvc.DBConnection
+                                    .createAsyncStatement(query);
   },
 
-  get _checkGUIDPageAnnotationStm() {
-    // Gecko <2.0 only
-    let stmt = this._getStmt(
-      "SELECT h.id AS place_id, " +
-        "(SELECT id FROM moz_anno_attributes WHERE name = :anno_name) AS name_id, " +
-        "a.id AS anno_id, a.dateAdded AS anno_date " +
-      "FROM (SELECT id FROM moz_places_temp WHERE url = :page_url " +
-            "UNION " +
-            "SELECT id FROM moz_places WHERE url = :page_url) AS h " +
-      "LEFT JOIN moz_annos a ON a.place_id = h.id " +
-                           "AND a.anno_attribute_id = name_id");
-    stmt.params.anno_name = GUID_ANNO;
-    return stmt;
-  },
-  _checkGUIDPageAnnotationCols: ["place_id", "name_id", "anno_id",
-                                 "anno_date"],
-
-  get _addPageAnnotationStm() {
-    // Gecko <2.0 only
+  get _setGUIDStm() {
     return this._getStmt(
-    "INSERT OR REPLACE INTO moz_annos " +
-      "(id, place_id, anno_attribute_id, mime_type, content, flags, " +
-       "expiration, type, dateAdded, lastModified) " +
-    "VALUES (:id, :place_id, :name_id, :mime_type, :content, :flags, " +
-            ":expiration, :type, :date_added, :last_modified)");
-  },
-
-  __setGUIDStm: null,
-  get _setGUIDStm() {
-    if (this.__setGUIDStm !== null) {
-      return this.__setGUIDStm;
-    }
-
-    // Obtains a statement to set the guid iff the guid column exists.
-    let stmt;
-    if (this._haveGUIDColumn) {
-      stmt = this._getStmt(
-        "UPDATE moz_places " +
-        "SET guid = :guid " +
-        "WHERE url = :page_url");
-    } else {
-      stmt = false;
-    }
-
-    return this.__setGUIDStm = stmt;
+      "UPDATE moz_places " +
+      "SET guid = :guid " +
+      "WHERE url = :page_url");
   },
 
   // Some helper functions to handle GUIDs
   setGUID: function setGUID(uri, guid) {
     uri = uri.spec ? uri.spec : uri;
 
     if (!guid)
       guid = Utils.makeGUID();
 
-    // If we can, set the GUID on moz_places and do not do any other work.
-    let (stmt = this._setGUIDStm) {
-      if (stmt) {
-        stmt.params.guid = guid;
-        stmt.params.page_url = uri;
-        Utils.queryAsync(stmt);
-        return guid;
-      }
-    }
-
-    // Ensure annotation name exists
-    Utils.queryAsync(this._addGUIDAnnotationNameStm);
-
-    let stmt = this._checkGUIDPageAnnotationStm;
+    let stmt = this._setGUIDStm;
+    stmt.params.guid = guid;
     stmt.params.page_url = uri;
-    let result = Utils.queryAsync(stmt, this._checkGUIDPageAnnotationCols)[0];
-    if (!result) {
-      let log = Log4Moz.repository.getLogger("Engine.History");
-      log.warn("Couldn't annotate URI " + uri);
-      return guid;
-    }
-
-    stmt = this._addPageAnnotationStm;
-    if (result.anno_id) {
-      stmt.params.id = result.anno_id;
-      stmt.params.date_added = result.anno_date;
-    } else {
-      stmt.params.id = null;
-      stmt.params.date_added = Date.now() * 1000;
-    }
-    stmt.params.place_id = result.place_id;
-    stmt.params.name_id = result.name_id;
-    stmt.params.content = guid;
-    stmt.params.flags = 0;
-    stmt.params.expiration = Ci.nsIAnnotationService.EXPIRE_WITH_HISTORY;
-    stmt.params.type = Ci.nsIAnnotationService.TYPE_STRING;
-    stmt.params.last_modified = Date.now() * 1000;
     Utils.queryAsync(stmt);
-
     return guid;
   },
 
-  __guidStm: null,
   get _guidStm() {
-    if (this.__guidStm) {
-      return this.__guidStm;
-    }
-
-    // Try to first read from moz_places.  Creating the statement will throw
-    // if the column doesn't exist, though so fallback to just reading from
-    // the annotation table.
-    let stmt;
-    if (this._haveGUIDColumn) {
-      stmt = this._getStmt(
-        "SELECT guid " +
-        "FROM moz_places " +
-        "WHERE url = :page_url");
-    } else {
-      stmt = this._getStmt(
-        "SELECT a.content AS guid " +
-        "FROM moz_annos a " +
-        "JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id " +
-        "JOIN ( " +
-          "SELECT id FROM moz_places_temp WHERE url = :page_url " +
-          "UNION " +
-          "SELECT id FROM moz_places WHERE url = :page_url " +
-        ") AS h ON h.id = a.place_id " +
-        "WHERE n.name = '" + GUID_ANNO + "'");
-    }
-
-    return this.__guidStmt = stmt;
+    return this._getStmt(
+      "SELECT guid " +
+      "FROM moz_places " +
+      "WHERE url = :page_url");
   },
   _guidCols: ["guid"],
 
   GUIDForUri: function GUIDForUri(uri, create) {
     let stm = this._guidStm;
     stm.params.page_url = uri.spec ? uri.spec : uri;
 
     // Use the existing GUID if it exists
@@ -310,86 +166,33 @@ HistoryStore.prototype = {
       return result.guid;
 
     // Give the uri a GUID if it doesn't have one
     if (create)
       return this.setGUID(uri);
   },
 
   get _visitStm() {
-    // Gecko <2.0
-    if (this._haveTempTables) {
-      let where = 
-        "WHERE place_id = IFNULL( " +
-          "(SELECT id FROM moz_places_temp WHERE url = :url), " +
-          "(SELECT id FROM moz_places WHERE url = :url) " +
-        ") ";
-      return this._getStmt(
-        "SELECT visit_type type, visit_date date " +
-        "FROM moz_historyvisits_temp " + where + "UNION " +
-        "SELECT visit_type type, visit_date date " +
-        "FROM moz_historyvisits " + where +
-        "ORDER BY date DESC LIMIT 10 ");
-    }
-    // Gecko 2.0
     return this._getStmt(
       "SELECT visit_type type, visit_date date " +
       "FROM moz_historyvisits " +
       "WHERE place_id = (SELECT id FROM moz_places WHERE url = :url) " +
       "ORDER BY date DESC LIMIT 10");
   },
   _visitCols: ["date", "type"],
 
-  __urlStmt: null,
   get _urlStm() {
-    if (this.__urlStmt) {
-      return this.__urlStmt;
-    }
-
-    // Try to first read from moz_places.  Creating the statement will throw
-    // if the column doesn't exist, though so fallback to just reading from
-    // the annotation table.
-    let stmt;
-    if (this._haveGUIDColumn) {
-      stmt = this._getStmt(
-        "SELECT url, title, frecency " +
-        "FROM moz_places " +
-        "WHERE guid = :guid");
-    } else {
-      let where =
-        "WHERE id = (" +
-          "SELECT place_id " +
-          "FROM moz_annos " +
-          "WHERE content = :guid AND anno_attribute_id = (" +
-            "SELECT id " +
-            "FROM moz_anno_attributes " +
-            "WHERE name = '" + GUID_ANNO + "')) ";
-      stmt = this._getStmt(
-        "SELECT url, title, frecency FROM moz_places_temp " + where +
-        "UNION ALL " +
-        "SELECT url, title, frecency FROM moz_places " + where + "LIMIT 1");
-    }
-
-    return this.__urlStmt = stmt;
+    return this._getStmt(
+      "SELECT url, title, frecency " +
+      "FROM moz_places " +
+      "WHERE guid = :guid");
   },
   _urlCols: ["url", "title", "frecency"],
 
   get _allUrlStm() {
-    // Gecko <2.0
-    if (this._haveTempTables)
-      return this._getStmt(
-        "SELECT url, frecency FROM moz_places_temp " +
-        "WHERE last_visit_date > :cutoff_date " +
-        "UNION " +
-        "SELECT url, frecency FROM moz_places " +
-        "WHERE last_visit_date > :cutoff_date " +
-        "ORDER BY 2 DESC " +
-        "LIMIT :max_results");
-
-    // Gecko 2.0
     return this._getStmt(
       "SELECT url " +
       "FROM moz_places " +
       "WHERE last_visit_date > :cutoff_date " +
       "ORDER BY frecency DESC " +
       "LIMIT :max_results");
   },
   _allUrlCols: ["url"],
@@ -420,22 +223,16 @@ HistoryStore.prototype = {
     let self = this;
     return urls.reduce(function(ids, item) {
       ids[self.GUIDForUri(item.url, true)] = item.url;
       return ids;
     }, {});
   },
 
   applyIncomingBatch: function applyIncomingBatch(records) {
-    // Gecko <2.0
-    if (!this._asyncHistory) {
-      return Store.prototype.applyIncomingBatch.call(this, records);
-    }
-
-    // Gecko 2.0
     let failed = [];
 
     // Convert incoming records to mozIPlaceInfo objects. Some records can be
     // ignored or handled directly, so we're rewriting the array in-place.
     let i, k;
     for (i = 0, k = 0; i < records.length; i++) {
       let record = records[k] = records[i];
       let shouldApply;
@@ -524,19 +321,18 @@ HistoryStore.prototype = {
     for (i = 0, k = 0; i < record.visits.length; i++) {
       let visit = record.visits[k] = record.visits[i];
 
       if (!visit.date || typeof visit.date != "number") {
         this._log.warn("Encountered record with invalid visit date: "
                        + visit.date);
         throw "Visit has no date!";
       }
-      // TRANSITION_FRAMED_LINK = TRANSITION_DOWNLOAD + 1 is new in Gecko 2.0
       if (!visit.type || !(visit.type >= Svc.History.TRANSITION_LINK &&
-                           visit.type <= Svc.History.TRANSITION_DOWNLOAD + 1)) {
+                           visit.type <= Svc.History.TRANSITION_FRAMED_LINK)) {
         this._log.warn("Encountered record with invalid visit type: "
                        + visit.type);
         throw "Invalid visit type!";
       }
       // Dates need to be integers
       visit.date = Math.round(visit.date);
 
       if (curVisits.indexOf(visit.date + "," + visit.type) != -1) {
@@ -558,57 +354,28 @@ HistoryStore.prototype = {
       this._log.trace("Ignoring record " + record.id + " with URI "
                       + record.uri.spec + ": no visits to add.");
       return false;
     }
 
     return true;
   },
 
-  create: function HistStore_create(record) {
-    // Add the url and set the GUID
-    this.update(record);
-    this.setGUID(record.histUri, record.id);
-  },
-
   remove: function HistStore_remove(record) {
     let page = this._findURLByGUID(record.id);
     if (page == null) {
       this._log.debug("Page already removed: " + record.id);
       return;
     }
 
     let uri = Utils.makeURI(page.url);
     Svc.History.removePage(uri);
     this._log.trace("Removed page: " + [record.id, page.url, page.title]);
   },
 
-  update: function HistStore_update(record) {
-    this._log.trace("  -> processing history entry: " + record.histUri);
-
-    if (!this._recordToPlaceInfo(record)) {
-      return;
-    }
-
-    for each (let {visitDate, transitionType} in record.visits) {
-      Svc.History.addVisit(record.uri, visitDate, null, transitionType,
-                           transitionType == 5 || transitionType == 6, 0);
-    }
-
-    if (record.title) {
-      try {
-        this._hsvc.setPageTitle(record.uri, record.title);
-      } catch (ex if ex.result == Cr.NS_ERROR_NOT_AVAILABLE) {
-        // There's no entry for the given URI, either because it's a
-        // URI that Places ignores (e.g. javascript:) or there were no
-        // visits.  We can just ignore those cases.
-      }
-    }
-  },
-
   itemExists: function HistStore_itemExists(id) {
     if (this._findURLByGUID(id))
       return true;
     return false;
   },
 
   urlExists: function HistStore_urlExists(url) {
     if (typeof(url) == "string")
--- a/services/sync/tests/unit/test_history_store.js
+++ b/services/sync/tests/unit/test_history_store.js
@@ -155,21 +155,20 @@ function run_test() {
     let queryres = queryHistoryVisits(resuri);
     do_check_eq(queryres.length, 1);
     do_check_eq(queryres[0].time, TIMESTAMP3);
     next();
 
   }, function (next) {
 
     _("Make sure we handle invalid URLs in places databases gracefully.");
-    let table = store._haveTempTables ? "moz_places_temp" : "moz_places";
-    let query = "INSERT INTO " + table + " "
+    let query = "INSERT INTO moz_places "
       + "(url, title, rev_host, visit_count, last_visit_date) "
       + "VALUES ('invalid-uri', 'Invalid URI', '.', 1, " + TIMESTAMP3 + ")";
-    let stmt = Utils.createStatement(Svc.History.DBConnection, query);
+    let stmt = Svc.History.DBConnection.createAsyncStatement(query);
     let result = Utils.queryAsync(stmt);    
     do_check_eq([id for (id in store.getAllIDs())].length, 4);
 
     _("Make sure we report records with invalid URIs.");
     let invalid_uri_guid = Utils.makeGUID();
     let failed = store.applyIncomingBatch([{
       id: invalid_uri_guid,
       histUri: ":::::::::::::::",
--- a/services/sync/tests/unit/test_places_guid_downgrade.js
+++ b/services/sync/tests/unit/test_places_guid_downgrade.js
@@ -90,31 +90,29 @@ function test_history_guids() {
     Svc.Bookmark.toolbarFolder, uri, Svc.Bookmark.DEFAULT_INDEX, "Mozilla");
 
   let fxguid = store.GUIDForUri(fxuri, true);
   let tbguid = store.GUIDForUri(tburi, true);
   dump("fxguid: " + fxguid + "\n");
   dump("tbguid: " + tbguid + "\n");
 
   _("History: Verify GUIDs are added to the guid column.");
-  let stmt = Utils.createStatement(
-    Svc.History.DBConnection,
+  let stmt = Svc.History.DBConnection.createAsyncStatement(
     "SELECT id FROM moz_places WHERE guid = :guid");
 
   stmt.params.guid = fxguid;
   let result = Utils.queryAsync(stmt, ["id"]);
   do_check_eq(result.length, 1);
 
   stmt.params.guid = tbguid;
   result = Utils.queryAsync(stmt, ["id"]);
   do_check_eq(result.length, 1);
 
   _("History: Verify GUIDs weren't added to annotations.");
-  stmt = Utils.createStatement(
-    Svc.History.DBConnection,
+  stmt = Svc.History.DBConnection.createAsyncStatement(
     "SELECT a.content AS guid FROM moz_annos a WHERE guid = :guid");
 
   stmt.params.guid = fxguid;
   result = Utils.queryAsync(stmt, ["guid"]);
   do_check_eq(result.length, 0);
 
   stmt.params.guid = tbguid;
   result = Utils.queryAsync(stmt, ["guid"]);
@@ -131,33 +129,31 @@ function test_bookmark_guids() {
   let tbid = Svc.Bookmark.insertBookmark(
     Svc.Bookmark.toolbarFolder, tburi, Svc.Bookmark.DEFAULT_INDEX,
     "Get Thunderbird!");
 
   let fxguid = store.GUIDForId(fxid);
   let tbguid = store.GUIDForId(tbid);
 
   _("Bookmarks: Verify GUIDs are added to the guid column.");
-  let stmt = Utils.createStatement(
-    Svc.History.DBConnection,
+  let stmt = Svc.History.DBConnection.createAsyncStatement(
     "SELECT id FROM moz_bookmarks WHERE guid = :guid");
 
   stmt.params.guid = fxguid;
   let result = Utils.queryAsync(stmt, ["id"]);
   do_check_eq(result.length, 1);
   do_check_eq(result[0].id, fxid);
 
   stmt.params.guid = tbguid;
   result = Utils.queryAsync(stmt, ["id"]);
   do_check_eq(result.length, 1);
   do_check_eq(result[0].id, tbid);
 
   _("Bookmarks: Verify GUIDs weren't added to annotations.");
-  stmt = Utils.createStatement(
-    Svc.History.DBConnection,
+  stmt = Svc.History.DBConnection.createAsyncStatement(
     "SELECT a.content AS guid FROM moz_items_annos a WHERE guid = :guid");
 
   stmt.params.guid = fxguid;
   result = Utils.queryAsync(stmt, ["guid"]);
   do_check_eq(result.length, 0);
 
   stmt.params.guid = tbguid;
   result = Utils.queryAsync(stmt, ["guid"]);