mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 450290 - Sync the temp tables to the permanent tables.
This changeset adds code that is run at app-startup that will flush out changes to the temporary tables into the permanent ones. For moz_places, this is done whenever we sync moz_historyvisits and when we add or modify a bookmark. For moz_historyvisits, this is done on a timer controlled by the preference places.syncDBTableIntervalInSecs. Changeset includes full test coverage for the above behaviors. r=dietrich r=Mak77 --HG-- rename : toolkit/components/places/tests/unit/head_bookmarks.js => toolkit/components/places/tests/background/head_background.js
This commit is contained in:
parent
ec97557606
commit
16fef55947
@ -234,6 +234,7 @@ bin/components/libbrowsercomps.so
|
||||
bin/components/txEXSLTRegExFunctions.js
|
||||
bin/components/nsLivemarkService.js
|
||||
bin/components/nsTaggingService.js
|
||||
bin/components/nsPlacesDBFlush.js
|
||||
bin/components/nsDefaultCLH.js
|
||||
bin/components/nsContentPrefService.js
|
||||
bin/components/nsContentDispatchChooser.js
|
||||
|
@ -241,6 +241,7 @@ bin\components\brwsrcmp.dll
|
||||
bin\components\txEXSLTRegExFunctions.js
|
||||
bin\components\nsLivemarkService.js
|
||||
bin\components\nsTaggingService.js
|
||||
bin\components\nsPlacesDBFlush.js
|
||||
bin\components\nsDefaultCLH.js
|
||||
bin\components\nsContentPrefService.js
|
||||
bin\components\nsContentDispatchChooser.js
|
||||
|
@ -105,6 +105,7 @@ LOCAL_INCLUDES += -I$(srcdir)/../../build
|
||||
|
||||
EXTRA_PP_COMPONENTS = nsLivemarkService.js \
|
||||
nsTaggingService.js \
|
||||
nsPlacesDBFlush.js \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_JS_MODULES = \
|
||||
|
@ -49,6 +49,7 @@ const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
const kQuitApplication = "quit-application";
|
||||
const kPlacesBackgroundShutdown = "places-background-shutdown";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsPlacesBackgound class
|
||||
@ -84,6 +85,12 @@ nsPlacesBackground.prototype = {
|
||||
observe: function PlacesBackground_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == kQuitApplication) {
|
||||
// Notify consumers that we are shutting down.
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, kPlacesBackgroundShutdown, null);
|
||||
|
||||
// Now shut the thread down.
|
||||
this._thread.shutdown();
|
||||
this._thread = null;
|
||||
}
|
||||
|
@ -991,6 +991,9 @@ nsNavHistory::InitTempTables()
|
||||
"CREATE INDEX moz_places_temp_frecencyindex ON moz_places_temp (frecency)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_PLACES_SYNC_TRIGGER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
// moz_historyvisits_temp
|
||||
rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_TEMP);
|
||||
@ -1011,6 +1014,9 @@ nsNavHistory::InitTempTables()
|
||||
"ON moz_historyvisits_temp (visit_date)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->ExecuteSimpleSQL(CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
277
toolkit/components/places/src/nsPlacesDBFlush.js
Normal file
277
toolkit/components/places/src/nsPlacesDBFlush.js
Normal file
@ -0,0 +1,277 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Constants
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
const kPlacesBackgroundShutdown = "places-background-shutdown";
|
||||
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const kDefaultSyncInterval = 120;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsPlacesDBFlush class
|
||||
|
||||
function nsPlacesDBFlush()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Smart Getters
|
||||
|
||||
this.__defineGetter__("_db", function() {
|
||||
delete this._db;
|
||||
return this._db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
});
|
||||
|
||||
this.__defineGetter__("_bh", function() {
|
||||
delete this._bh;
|
||||
return this._bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
});
|
||||
|
||||
|
||||
// Get our sync interval
|
||||
this._prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefService).
|
||||
getBranch("places.");
|
||||
try {
|
||||
// We want to silently fail if the preference does not exist, and use a
|
||||
// default to fallback to.
|
||||
this._syncInterval = this._prefs.getIntPref(kSyncPrefName);
|
||||
if (this._syncInterval <= 0)
|
||||
this._syncInterval = kDefaultSyncInterval;
|
||||
}
|
||||
catch (e) {
|
||||
// The preference did not exist, so default to two minutes.
|
||||
this._syncInterval = kDefaultSyncInterval;
|
||||
}
|
||||
|
||||
// Register observers
|
||||
this._bh.addObserver(this, false);
|
||||
|
||||
this._prefs.QueryInterface(Ci.nsIPrefBranch2).addObserver("", this, false);
|
||||
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver(this, kPlacesBackgroundShutdown, false);
|
||||
|
||||
// Create our timer to update everything
|
||||
this._timer = this._newTimer();
|
||||
}
|
||||
|
||||
nsPlacesDBFlush.prototype = {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIObserver
|
||||
|
||||
observe: function DBFlush_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == kPlacesBackgroundShutdown) {
|
||||
this._bh.removeObserver(this);
|
||||
this._timer.cancel();
|
||||
this._timer = null;
|
||||
this._syncAll();
|
||||
}
|
||||
else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) {
|
||||
// Get the new pref value, and then update our timer
|
||||
this._syncInterval = aSubject.getIntPref(kSyncPrefName);
|
||||
if (this._syncInterval <= 0)
|
||||
this._syncInterval = kDefaultSyncInterval;
|
||||
|
||||
// We may have canceled the timer already for batch updates, so we want to
|
||||
// exit early.
|
||||
if (!this._timer)
|
||||
return;
|
||||
|
||||
this._timer.cancel();
|
||||
this._timer = this._newTimer();
|
||||
}
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsINavBookmarkObserver
|
||||
|
||||
onBeginUpdateBatch: function DBFlush_onBeginUpdateBatch()
|
||||
{
|
||||
this._inBatchMode = true;
|
||||
|
||||
// We do not want to sync while we are doing batch work.
|
||||
this._timer.cancel();
|
||||
this._timer = null;
|
||||
},
|
||||
|
||||
onEndUpdateBatch: function DBFlush_onEndUpdateBatch()
|
||||
{
|
||||
this._inBatchMode = false;
|
||||
|
||||
// We need to sync and restore our timer now.
|
||||
this._syncAll();
|
||||
this._timer = this._newTimer();
|
||||
},
|
||||
|
||||
onItemAdded: function() this._syncMozPlaces(),
|
||||
|
||||
onItemChanged: function DBFlush_onItemChanged(aItemId, aProperty,
|
||||
aIsAnnotationProperty,
|
||||
aValue)
|
||||
{
|
||||
if (aProperty == "uri")
|
||||
this._syncMozPlaces();
|
||||
},
|
||||
|
||||
onItemRemoved: function() { },
|
||||
onItemVisited: function() { },
|
||||
onItemMoved: function() { },
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsITimerCallback
|
||||
|
||||
notify: function() this._syncAll(),
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsPlacesDBFlush
|
||||
|
||||
/**
|
||||
* Dispatches an event to the background thread to run _doSyncMozX("places").
|
||||
*/
|
||||
_syncMozPlaces: function DBFlush_syncMozPlaces()
|
||||
{
|
||||
// No need to do extra work if we are in batch mode
|
||||
if (this._inBatchMode)
|
||||
return;
|
||||
|
||||
let self = this;
|
||||
PlacesBackground.dispatch({
|
||||
run: function() self._doSyncMozX("places")
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatches an event to the background thread to sync all temporary tables.
|
||||
*/
|
||||
_syncAll: function DBFlush_syncAll()
|
||||
{
|
||||
let self = this;
|
||||
PlacesBackground.dispatch({
|
||||
run: function() {
|
||||
// We try to get a transaction, but if we can't don't worry
|
||||
let ourTransaction = false;
|
||||
try {
|
||||
this._db.beginTransaction();
|
||||
ourTransaction = true;
|
||||
}
|
||||
catch (e) { }
|
||||
|
||||
try {
|
||||
// This needs to also sync moz_places in order to maintain data
|
||||
// integrity
|
||||
self._doSyncMozX("places");
|
||||
self._doSyncMozX("historyvisits");
|
||||
}
|
||||
catch (e) {
|
||||
if (ourTransaction)
|
||||
this._db.rollbackTransaction();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (ourTransaction)
|
||||
this._db.commitTransaction();
|
||||
}
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronizes the moz_{aName} and moz_{aName}_temp by copying all the data
|
||||
* from the temporary table into the permanent one. It then deletes the data
|
||||
* in the temporary table. All of this is done in a transaction that is
|
||||
* rolled back upon failure at any point.
|
||||
*/
|
||||
_doSyncMozX: function DBFlush_doSyncMozX(aName)
|
||||
{
|
||||
// Delete all the data in the temp table.
|
||||
// We have triggers setup that ensure that the data is transfered over
|
||||
// upon deletion.
|
||||
this._db.executeSimpleSQL("DELETE FROM moz_" + aName + "_temp");
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new timer bases on this._timerInterval.
|
||||
*
|
||||
* @returns a REPEATING_SLACK nsITimer that runs every this._timerInterval.
|
||||
*/
|
||||
_newTimer: function DBFlush_newTimer()
|
||||
{
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback(this, this._syncInterval * 1000,
|
||||
Ci.nsITimer.TYPE_REPEATING_SLACK);
|
||||
return timer;
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// nsISupports
|
||||
|
||||
classDescription: "Used to synchronize the temporary and permanent tables of Places",
|
||||
classID: Components.ID("c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a"),
|
||||
contractID: "@mozilla.org/places/sync;1",
|
||||
_xpcom_categories: [{
|
||||
category: "profile-after-change",
|
||||
}],
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIObserver,
|
||||
Ci.nsINavBookmarkObserver,
|
||||
Ci.nsITimerCallback,
|
||||
])
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Module Registration
|
||||
|
||||
let components = [nsPlacesDBFlush];
|
||||
function NSGetModule(compMgr, fileSpec)
|
||||
{
|
||||
return XPCOMUtils.generateModule(components);
|
||||
}
|
@ -202,4 +202,26 @@
|
||||
"END" \
|
||||
)
|
||||
|
||||
/**
|
||||
* This trigger moves the data out of a temporary table into the permanent one
|
||||
* before deleting from the temporary table.
|
||||
*
|
||||
* Note - it's OK to use an INSERT OR REPLACE here because the only conflict
|
||||
* that will happen is the primary key. As a result, the row will be deleted,
|
||||
* and the replacement will be inserted with the same id.
|
||||
*/
|
||||
#define CREATE_TEMP_SYNC_TRIGGER_BASE(__table) NS_LITERAL_CSTRING( \
|
||||
"CREATE TEMPORARY TRIGGER " __table "_beforedelete_trigger " \
|
||||
"BEFORE DELETE ON " __table "_temp FOR EACH ROW " \
|
||||
"BEGIN " \
|
||||
"INSERT OR REPLACE INTO " __table " " \
|
||||
"SELECT * FROM " __table "_temp " \
|
||||
"WHERE id = OLD.id;" \
|
||||
"END" \
|
||||
)
|
||||
#define CREATE_MOZ_PLACES_SYNC_TRIGGER \
|
||||
CREATE_TEMP_SYNC_TRIGGER_BASE("moz_places")
|
||||
#define CREATE_MOZ_HISTORYVISITS_SYNC_TRIGGER \
|
||||
CREATE_TEMP_SYNC_TRIGGER_BASE("moz_historyvisits")
|
||||
|
||||
#endif // __nsPlacesTriggers_h__
|
||||
|
275
toolkit/components/places/tests/background/head_background.js
Normal file
275
toolkit/components/places/tests/background/head_background.js
Normal file
@ -0,0 +1,275 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Google Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Ryner <bryner@brianryner.com>
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const NS_APP_USER_PROFILE_50_DIR = "ProfD";
|
||||
const NS_APP_HISTORY_50_FILE = "UHist";
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
|
||||
function LOG(aMsg) {
|
||||
aMsg = ("*** PLACES TESTS: " + aMsg);
|
||||
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
|
||||
logStringMessage(aMsg);
|
||||
print(aMsg);
|
||||
}
|
||||
|
||||
// If there's no location registered for the profile direcotry, register one now.
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
var profileDir = null;
|
||||
try {
|
||||
profileDir = dirSvc.get(NS_APP_USER_PROFILE_50_DIR, Ci.nsIFile);
|
||||
} catch (e) {}
|
||||
if (!profileDir) {
|
||||
// Register our own provider for the profile directory.
|
||||
// It will simply return the current directory.
|
||||
var provider = {
|
||||
getFile: function(prop, persistent) {
|
||||
persistent.value = true;
|
||||
if (prop == NS_APP_USER_PROFILE_50_DIR) {
|
||||
return dirSvc.get("CurProcD", Ci.nsIFile);
|
||||
}
|
||||
if (prop == NS_APP_HISTORY_50_FILE) {
|
||||
var histFile = dirSvc.get("CurProcD", Ci.nsIFile);
|
||||
histFile.append("history.dat");
|
||||
return histFile;
|
||||
}
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
},
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsIDirectoryServiceProvider) ||
|
||||
iid.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
dirSvc.QueryInterface(Ci.nsIDirectoryService).registerProvider(provider);
|
||||
}
|
||||
|
||||
var iosvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
|
||||
function uri(spec) {
|
||||
return iosvc.newURI(spec, null, null);
|
||||
}
|
||||
|
||||
// Delete a previously created sqlite file
|
||||
function clearDB() {
|
||||
try {
|
||||
var file = dirSvc.get('ProfD', Ci.nsIFile);
|
||||
file.append("places.sqlite");
|
||||
if (file.exists())
|
||||
file.remove(false);
|
||||
} catch(ex) { dump("Exception: " + ex); }
|
||||
}
|
||||
clearDB();
|
||||
|
||||
/**
|
||||
* Dumps the rows of a table out to the console.
|
||||
*
|
||||
* @param aName
|
||||
* The name of the table or view to output.
|
||||
*/
|
||||
function dump_table(aName)
|
||||
{
|
||||
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement("SELECT * FROM " + aName);
|
||||
|
||||
dump("\n*** Printing data from " + aName + ":\n");
|
||||
let count = 0;
|
||||
while (stmt.executeStep()) {
|
||||
let columns = stmt.numEntries;
|
||||
|
||||
if (count == 0) {
|
||||
// print the column names
|
||||
for (let i = 0; i < columns; i++)
|
||||
dump(stmt.getColumnName(i) + "\t");
|
||||
dump("\n");
|
||||
}
|
||||
|
||||
// print the row
|
||||
for (let i = 0; i < columns; i++) {
|
||||
switch (stmt.getTypeOfIndex(i)) {
|
||||
case Ci.mozIStorageValueArray.VALUE_TYPE_NULL:
|
||||
dump("NULL\t");
|
||||
break;
|
||||
case Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER:
|
||||
dump(stmt.getInt64(i) + "\t");
|
||||
break;
|
||||
case Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT:
|
||||
dump(stmt.getDouble(i) + "\t");
|
||||
break;
|
||||
case Ci.mozIStorageValueArray.VALUE_TYPE_TEXT:
|
||||
dump(stmt.getString(i) + "\t");
|
||||
break;
|
||||
}
|
||||
}
|
||||
dump("\n");
|
||||
|
||||
count++;
|
||||
}
|
||||
dump("*** There were a total of " + count + " rows of data.\n\n");
|
||||
|
||||
stmt.reset();
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This dispatches the observer topic "quit-application" to clean up the
|
||||
* background thread.
|
||||
*/
|
||||
function finish_test()
|
||||
{
|
||||
// This next bit needs to run on the main thread
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].
|
||||
getService(Ci.nsIThreadManager);
|
||||
tm.mainThread.dispatch({
|
||||
run: function()
|
||||
{
|
||||
// xpcshell doesn't dispatch shutdown-application
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
do_test_finished();
|
||||
}
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function tests to see if the place associated with the bookmark with id
|
||||
* aBookmarkId has the uri aExpectedURI. The event will call finish_test() if
|
||||
* aFinish is true.
|
||||
*
|
||||
* @param aBookmarkId
|
||||
* The bookmark to check against.
|
||||
* @param aExpectedURI
|
||||
* The URI we expect to be in moz_places.
|
||||
* @param aExpected
|
||||
* Indicates if we expect to get a result or not.
|
||||
* @param [optional] aFinish
|
||||
* Indicates if the test should be completed or not.
|
||||
*/
|
||||
function new_test_bookmark_uri_event(aBookmarkId, aExpectedURI, aExpected, aFinish)
|
||||
{
|
||||
return {
|
||||
run: function()
|
||||
{
|
||||
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT moz_places.url " +
|
||||
"FROM moz_bookmarks INNER JOIN moz_places " +
|
||||
"ON moz_bookmarks.fk = moz_places.id " +
|
||||
"WHERE moz_bookmarks.id = ?1"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, aBookmarkId);
|
||||
|
||||
if (aExpected) {
|
||||
do_check_true(stmt.executeStep());
|
||||
do_check_eq(stmt.getUTF8String(0), aExpectedURI);
|
||||
}
|
||||
else {
|
||||
do_check_false(stmt.executeStep());
|
||||
}
|
||||
stmt.reset();
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
|
||||
if (aFinish)
|
||||
finish_test();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Function tests to see if the place associated with the visit with id aVisitId
|
||||
* has the uri aExpectedURI. The event will call finish_test() if aFinish is
|
||||
* true.
|
||||
*
|
||||
* @param aVisitId
|
||||
* The visit to check against.
|
||||
* @param aExpectedURI
|
||||
* The URI we expect to be in moz_places.
|
||||
* @param aExpected
|
||||
* Indicates if we expect to get a result or not.
|
||||
* @param [optional] aFinish
|
||||
* Indicates if the test should be completed or not.
|
||||
*/
|
||||
function new_test_visit_uri_event(aVisitId, aExpectedURI, aExpected, aFinish)
|
||||
{
|
||||
return {
|
||||
run: function()
|
||||
{
|
||||
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT moz_places.url " +
|
||||
"FROM moz_historyvisits INNER JOIN moz_places " +
|
||||
"ON moz_historyvisits.place_id = moz_places.id " +
|
||||
"WHERE moz_historyvisits.id = ?1"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, aVisitId);
|
||||
|
||||
if (aExpected) {
|
||||
do_check_true(stmt.executeStep());
|
||||
do_check_eq(stmt.getUTF8String(0), aExpectedURI);
|
||||
}
|
||||
else {
|
||||
do_check_false(stmt.executeStep());
|
||||
}
|
||||
stmt.reset();
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
|
||||
if (aFinish)
|
||||
finish_test();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// profile-after-change doesn't create components in xpcshell, so we have to do
|
||||
// it ourselves
|
||||
Cc["@mozilla.org/places/sync;1"].getService(Ci.nsISupports);
|
||||
|
@ -39,10 +39,6 @@
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
function test_service_exists()
|
||||
{
|
||||
do_check_neq(PlacesBackground, null);
|
||||
@ -87,10 +83,32 @@ function test_two_events_same_thread()
|
||||
do_check_eq(event.thread1, event.thread2);
|
||||
}
|
||||
|
||||
function test_places_background_shutdown_topic()
|
||||
{
|
||||
// Ensures that the places shutdown topic is dispatched before the thread is
|
||||
// shutdown.
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver({
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
// We should still be able to dispatch an event without throwing now!
|
||||
PlacesBackground.dispatch({
|
||||
run: function()
|
||||
{
|
||||
do_test_finished();
|
||||
}
|
||||
}, Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}
|
||||
}, "places-background-shutdown", false);
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
let tests = [
|
||||
test_service_exists,
|
||||
test_isOnCurrentThread,
|
||||
test_two_events_same_thread,
|
||||
test_places_background_shutdown_topic,
|
||||
];
|
||||
|
||||
function run_test()
|
||||
|
@ -0,0 +1,55 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First insert it
|
||||
let bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let id = bh.insertBookmark(bh.unfiledBookmarksFolder, uri(TEST_URI),
|
||||
bh.DEFAULT_INDEX, "test");
|
||||
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id, TEST_URI, true, true),
|
||||
Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
do_test_pending();
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First insert it
|
||||
let bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let id = null;
|
||||
bh.runInBatchMode({
|
||||
runBatched: function(aUserData)
|
||||
{
|
||||
id = bh.insertBookmark(bh.unfiledBookmarksFolder, uri(TEST_URI),
|
||||
bh.DEFAULT_INDEX, "test");
|
||||
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id, TEST_URI, false),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
}
|
||||
}, null);
|
||||
do_check_neq(id, null);
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id, TEST_URI, true, true),
|
||||
Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
do_test_pending();
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 1;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First set the preference for the timer to a small value
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefService).
|
||||
getBranch("places.");
|
||||
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
|
||||
|
||||
// Now add the visit
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
|
||||
// Check the visit, but after enough time has passed for the DB flush service
|
||||
// to have fired it's timer.
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback({
|
||||
notify: function(aTimer)
|
||||
{
|
||||
PlacesBackground.dispatch(new_test_visit_uri_event(id, TEST_URI, true, true),
|
||||
Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}
|
||||
}, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
do_test_pending();
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// Now add the visit in batch mode
|
||||
let bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let id = null;
|
||||
bh.runInBatchMode({
|
||||
runBatched: function(aUserData)
|
||||
{
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
PlacesBackground.dispatch(new_test_visit_uri_event(id, TEST_URI, false),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
}
|
||||
}, null);
|
||||
do_check_neq(id, null);
|
||||
PlacesBackground.dispatch(new_test_visit_uri_event(id, TEST_URI, true, true),
|
||||
Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
do_test_pending();
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
const MODIFIED_URI = "http://test.com/index.html";
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First insert it
|
||||
let bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let id = bh.insertBookmark(bh.unfiledBookmarksFolder, uri(TEST_URI),
|
||||
bh.DEFAULT_INDEX, "test");
|
||||
|
||||
// Dispatch the check synchronously so we don't modify the data before this
|
||||
// test runs
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id, TEST_URI, true),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
|
||||
// Now modify the bookmark
|
||||
bh.changeBookmarkURI(id, uri(MODIFIED_URI));
|
||||
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id, MODIFIED_URI, true, true),
|
||||
Ci.nsIEventTarget.DISPATCH_NORMAL);
|
||||
do_test_pending();
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 600; // ten minutes
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First set the preference for the timer to a really large value so it won't
|
||||
// run before the test finishes.
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefService).
|
||||
getBranch("places.");
|
||||
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
|
||||
|
||||
// Now add the visit
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
|
||||
// Notify that we are quitting the app - we should sync!
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Check the visit. The background thread should have joined with the main
|
||||
// thread by now if everything is working correctly.
|
||||
new_test_visit_uri_event(id, TEST_URI, true, false).run();
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This test ensures that adding a bookmark (which has an implicit sync), then
|
||||
* adding another one that has the same place, we end up with only one entry in
|
||||
* moz_places.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
|
||||
let db = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// Add the first bookmark
|
||||
let bh = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
let id1 = bh.insertBookmark(bh.unfiledBookmarksFolder, uri(TEST_URI),
|
||||
bh.DEFAULT_INDEX, "test");
|
||||
|
||||
// Ensure it was added
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id1, TEST_URI, true),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
|
||||
// Get the place_id
|
||||
let stmt = db.createStatement(
|
||||
"SELECT fk " +
|
||||
"FROM moz_bookmarks " +
|
||||
"WHERE id = ?"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, id1);
|
||||
do_check_true(stmt.executeStep());
|
||||
let place_id = stmt.getInt64(0);
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
|
||||
// Now we add another bookmark to a different folder
|
||||
let id2 = bh.insertBookmark(bh.toolbarFolder, uri(TEST_URI),
|
||||
bh.DEFAULT_INDEX, "test");
|
||||
do_check_neq(id1, id2);
|
||||
|
||||
// Ensure it was added
|
||||
PlacesBackground.dispatch(new_test_bookmark_uri_event(id2, TEST_URI, true),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
|
||||
// Check to make sure we have the same place_id
|
||||
stmt = db.createStatement(
|
||||
"SELECT * " +
|
||||
"FROM moz_bookmarks " +
|
||||
"WHERE id = ?1 " +
|
||||
"AND fk = ?2"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, id2);
|
||||
stmt.bindInt64Parameter(1, place_id);
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
|
||||
// finish_test() calls do_test_finished, so we call do_test_pending()...
|
||||
do_test_pending();
|
||||
finish_test();
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* This test ensures that when adding a visit, then syncing, and adding another
|
||||
* visit to the same url creates two visits and that we only end up with one
|
||||
* entry in moz_places.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/PlacesBackground.jsm");
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 1;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// First set the preference for the timer to a small value
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefService).
|
||||
getBranch("places.");
|
||||
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
|
||||
|
||||
// Now add the first visit
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
|
||||
// Check the visit, but after enough time has passed for the DB flush service
|
||||
// to have fired it's timer.
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback({
|
||||
notify: function(aTimer)
|
||||
{
|
||||
PlacesBackground.dispatch(new_test_visit_uri_event(id, TEST_URI, true),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
|
||||
// Get the place_id and pass it on
|
||||
let db = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT place_id " +
|
||||
"FROM moz_historyvisits " +
|
||||
"WHERE id = ?"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, id);
|
||||
do_check_true(stmt.executeStep());
|
||||
continue_test(id, stmt.getInt64(0));
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
}
|
||||
}, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function continue_test(aLastVisitId, aPlaceId)
|
||||
{
|
||||
// Now we add another visit
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
let id = hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
do_check_neq(aLastVisitId, id);
|
||||
|
||||
// Check the visit, but after enough time has passed for the DB flush service
|
||||
// to have fired it's timer.
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.initWithCallback({
|
||||
notify: function(aTimer)
|
||||
{
|
||||
PlacesBackground.dispatch(new_test_visit_uri_event(id, TEST_URI, true),
|
||||
Ci.nsIEventTarget.DISPATCH_SYNC);
|
||||
|
||||
// Check to make sure we have the same place_id
|
||||
let db = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
let stmt = db.createStatement(
|
||||
"SELECT * " +
|
||||
"FROM moz_historyvisits " +
|
||||
"WHERE id = ?1 " +
|
||||
"AND place_id = ?2"
|
||||
);
|
||||
stmt.bindInt64Parameter(0, id);
|
||||
stmt.bindInt64Parameter(1, aPlaceId);
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
|
||||
finish_test();
|
||||
}
|
||||
}, (SYNC_INTERVAL * 1000) * 2, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
Loading…
Reference in New Issue
Block a user