diff --git a/browser/components/migration/content/migration.js b/browser/components/migration/content/migration.js index 06846c1cad3..dae0e154093 100644 --- a/browser/components/migration/content/migration.js +++ b/browser/components/migration/content/migration.js @@ -395,12 +395,12 @@ var MigrationWizard = { this._listItems("migratingItems"); setTimeout(this.onMigratingMigrate, 0, this); }, - + onMigratingMigrate: function (aOuter) { aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile); }, - + _listItems: function (aID) { var items = document.getElementById(aID); diff --git a/browser/components/migration/public/nsIBrowserProfileMigrator.idl b/browser/components/migration/public/nsIBrowserProfileMigrator.idl index 80b8ff7bcbf..e0d875b69ee 100644 --- a/browser/components/migration/public/nsIBrowserProfileMigrator.idl +++ b/browser/components/migration/public/nsIBrowserProfileMigrator.idl @@ -57,7 +57,7 @@ interface nsIBrowserProfileMigrator : nsISupports /** * Copy user profile information to the current active profile. * @param aItems list of data items to migrate. see above for values. - * @param aReplace replace or append current data where applicable. + * @param aStartup helper interface which is non-null if called during startup. * @param aProfile profile to migrate from, if there is more than one. */ void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in wstring aProfile); @@ -67,7 +67,7 @@ interface nsIBrowserProfileMigrator : nsISupports * offers for import. * @param aProfile the profile that we are looking for available data * to import - * @param aStarting "true" if the profile is not currently being used. + * @param aDoingStartup "true" if the profile is not currently being used. * @returns bit field containing profile items (see above) */ unsigned short getMigrateData(in wstring aProfile, in boolean aDoingStartup); diff --git a/browser/components/migration/src/nsIEProfileMigrator.cpp b/browser/components/migration/src/nsIEProfileMigrator.cpp index 30ac29d8532..d8d37e3f859 100644 --- a/browser/components/migration/src/nsIEProfileMigrator.cpp +++ b/browser/components/migration/src/nsIEProfileMigrator.cpp @@ -502,7 +502,7 @@ nsIEProfileMigrator::GetSourceHomePageURL(nsACString& aResult) /////////////////////////////////////////////////////////////////////////////// // nsIEProfileMigrator -NS_IMPL_ISUPPORTS1(nsIEProfileMigrator, nsIBrowserProfileMigrator); +NS_IMPL_ISUPPORTS2(nsIEProfileMigrator, nsIBrowserProfileMigrator, nsINavHistoryBatchCallback); nsIEProfileMigrator::nsIEProfileMigrator() { @@ -515,6 +515,16 @@ nsIEProfileMigrator::~nsIEProfileMigrator() nsresult nsIEProfileMigrator::CopyHistory(PRBool aReplace) +{ + nsresult rv; + nsCOMPtr history = do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + return history->RunInBatchMode(this, nsnull); +} + +NS_IMETHODIMP +nsIEProfileMigrator::RunBatched(nsISupports* aUserData) { nsCOMPtr hist(do_GetService(NS_GLOBALHISTORY2_CONTRACTID)); nsCOMPtr ios(do_GetService(NS_IOSERVICE_CONTRACTID)); diff --git a/browser/components/migration/src/nsIEProfileMigrator.h b/browser/components/migration/src/nsIEProfileMigrator.h index 74983991f2d..f8bfe9fdc7e 100644 --- a/browser/components/migration/src/nsIEProfileMigrator.h +++ b/browser/components/migration/src/nsIEProfileMigrator.h @@ -46,6 +46,7 @@ #include "nsIBrowserProfileMigrator.h" #include "nsIObserverService.h" #include "nsVoidArray.h" +#include "nsINavHistoryService.h" class nsIFile; class nsICookieManager2; @@ -56,9 +57,11 @@ class nsIPrefBranch; #import PSTOREC_DLL raw_interfaces_only using namespace PSTORECLib; -class nsIEProfileMigrator : public nsIBrowserProfileMigrator { +class nsIEProfileMigrator : public nsIBrowserProfileMigrator, + public nsINavHistoryBatchCallback { public: NS_DECL_NSIBROWSERPROFILEMIGRATOR + NS_DECL_NSINAVHISTORYBATCHCALLBACK NS_DECL_ISUPPORTS nsIEProfileMigrator(); diff --git a/browser/components/places/public/nsIPlacesImportExportService.idl b/browser/components/places/public/nsIPlacesImportExportService.idl index 826f9d14167..0439b632262 100644 --- a/browser/components/places/public/nsIPlacesImportExportService.idl +++ b/browser/components/places/public/nsIPlacesImportExportService.idl @@ -49,18 +49,17 @@ interface nsILocalFile; interface nsIPlacesImportExportService: nsISupports { /** - * Loads the given bookmarks.html file and merges it with the current - * bookmarks hierarchy. + * Loads the given bookmarks.html file and replaces it with the current + * bookmarks hierarchy (if aIsInitialImport is true) or appends it + * (if aIsInitialImport is false) */ void importHTMLFromFile(in nsILocalFile aFile, in boolean aIsInitialImport); - /** * Loads the given bookmarks.html file and puts it in the given folder */ void importHTMLFromFileToFolder(in nsILocalFile aFile, in PRInt64 aFolder, in boolean aIsInitialImport); - /** * Saves the current bookmarks hierarchy to a bookmarks.html file. */ diff --git a/toolkit/components/places/src/nsNavHistory.cpp b/toolkit/components/places/src/nsNavHistory.cpp index 697e5b002fd..bda9e67d383 100644 --- a/toolkit/components/places/src/nsNavHistory.cpp +++ b/toolkit/components/places/src/nsNavHistory.cpp @@ -79,6 +79,7 @@ #include "mozStorageCID.h" #include "mozStorageHelper.h" #include "nsAppDirectoryServiceDefs.h" +#include "nsAutoLock.h" // Microsecond timeout for "recent" events such as typed and bookmark following. // If you typed it more than this time ago, it's not recent. @@ -239,9 +240,11 @@ nsNavHistory* nsNavHistory::gHistoryService; nsNavHistory::nsNavHistory() : mNowValid(PR_FALSE), mExpireNowTimer(nsnull), mExpire(this), - mBatchesInProgress(0), mExpireDays(0), - mAutoCompleteOnlyTyped(PR_FALSE) + mAutoCompleteOnlyTyped(PR_FALSE), + mBatchLevel(0), + mLock(nsnull), + mBatchHasTransaction(PR_FALSE) { #ifdef LAZY_ADD mLazyTimerSet = PR_TRUE; @@ -260,6 +263,9 @@ nsNavHistory::~nsNavHistory() // in case somebody creates an extra instance of the service. NS_ASSERTION(gHistoryService == this, "YOU CREATED 2 COPIES OF THE HISTORY SERVICE."); gHistoryService = nsnull; + + if (mLock) + PR_DestroyLock(mLock); } @@ -277,6 +283,9 @@ nsNavHistory::Init() rv = prefService->GetBranch(PREF_BRANCH_BASE, getter_AddRefs(mPrefBranch)); NS_ENSURE_SUCCESS(rv, rv); + mLock = PR_NewLock(); + NS_ENSURE_TRUE(mLock, NS_ERROR_OUT_OF_MEMORY); + // init db file rv = InitDBFile(PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); @@ -2428,29 +2437,33 @@ nsNavHistory::RemoveObserver(nsINavHistoryObserver* aObserver) return mObservers.RemoveWeakElement(aObserver); } - // nsNavHistory::BeginUpdateBatch - +// See RunInBatchMode, mLock _must_ be set when batching nsresult nsNavHistory::BeginUpdateBatch() { - mBatchesInProgress ++; - if (mBatchesInProgress == 1) { + if (mBatchLevel++ == 0) { + PRBool transactionInProgress = PR_TRUE; // default to no transaction on err + mDBConn->GetTransactionInProgress(&transactionInProgress); + mBatchHasTransaction = ! transactionInProgress; + if (mBatchHasTransaction) + mDBConn->BeginTransaction(); + ENUMERATE_WEAKARRAY(mObservers, nsINavHistoryObserver, OnBeginUpdateBatch()) } + mozStorageTransaction transaction(mDBConn, PR_FALSE); return NS_OK; } - // nsNavHistory::EndUpdateBatch - nsresult nsNavHistory::EndUpdateBatch() { - if (mBatchesInProgress == 0) - return NS_ERROR_FAILURE; - if (--mBatchesInProgress == 0) { + if (--mBatchLevel == 0) { + if (mBatchHasTransaction) + mDBConn->CommitTransaction(); + mBatchHasTransaction = PR_FALSE; ENUMERATE_WEAKARRAY(mObservers, nsINavHistoryObserver, OnEndUpdateBatch()) } return NS_OK; @@ -2458,9 +2471,13 @@ nsNavHistory::EndUpdateBatch() NS_IMETHODIMP nsNavHistory::RunInBatchMode(nsINavHistoryBatchCallback* aCallback, - nsISupports* aUserData) { + nsISupports* aUserData) +{ + NS_ENSURE_STATE(mLock); NS_ENSURE_ARG_POINTER(aCallback); + nsAutoLock lock(mLock); + UpdateBatchScoper batch(*this); nsresult rv = aCallback->RunBatched(aUserData); NS_ENSURE_SUCCESS(rv, rv); diff --git a/toolkit/components/places/src/nsNavHistory.h b/toolkit/components/places/src/nsNavHistory.h index 3f543a2e3c6..701e40b8b05 100644 --- a/toolkit/components/places/src/nsNavHistory.h +++ b/toolkit/components/places/src/nsNavHistory.h @@ -302,6 +302,16 @@ public: nsresult BeginUpdateBatch(); nsresult EndUpdateBatch(); + // the level of nesting of batches, 0 when no batches are open + PRInt32 mBatchLevel; + + // lock for RunInBatchMode + PRLock* mLock; + + // true if the outermost batch has an associated transaction that should + // be committed when our batch level reaches 0 again. + PRBool mBatchHasTransaction; + // better alternative to QueryStringToQueries (in nsNavHistoryQuery.cpp) nsresult QueryStringToQueryArray(const nsACString& aQueryString, nsCOMArray* aQueries, @@ -511,7 +521,6 @@ protected: // observers nsMaybeWeakPtrArray mObservers; - PRInt32 mBatchesInProgress; // localization nsCOMPtr mBundle; diff --git a/toolkit/components/places/src/nsNavHistoryResult.cpp b/toolkit/components/places/src/nsNavHistoryResult.cpp index 93350ba1a2a..99d2390d808 100644 --- a/toolkit/components/places/src/nsNavHistoryResult.cpp +++ b/toolkit/components/places/src/nsNavHistoryResult.cpp @@ -3363,7 +3363,8 @@ nsNavHistoryResult::nsNavHistoryResult(nsNavHistoryContainerResultNode* aRoot) : mRootNode(aRoot), mIsHistoryObserver(PR_FALSE), mIsBookmarkFolderObserver(PR_FALSE), - mIsAllBookmarksObserver(PR_FALSE) + mIsAllBookmarksObserver(PR_FALSE), + mBatchInProgress(PR_FALSE) { mRootNode->mResult = this; } @@ -3721,6 +3722,7 @@ nsNavHistoryResult::GetRoot(nsINavHistoryContainerResultNode** aRoot) NS_IMETHODIMP nsNavHistoryResult::OnBeginUpdateBatch() { + mBatchInProgress = PR_TRUE; ENUMERATE_HISTORY_OBSERVERS(OnBeginUpdateBatch()); ENUMERATE_ALL_BOOKMARKS_OBSERVERS(OnBeginUpdateBatch()); return NS_OK; @@ -3732,6 +3734,8 @@ nsNavHistoryResult::OnBeginUpdateBatch() NS_IMETHODIMP nsNavHistoryResult::OnEndUpdateBatch() { + NS_ASSERTION(mBatchInProgress, "EndUpdateBatch without a begin"); + mBatchInProgress = PR_FALSE; ENUMERATE_HISTORY_OBSERVERS(OnEndUpdateBatch()); ENUMERATE_ALL_BOOKMARKS_OBSERVERS(OnEndUpdateBatch()); return NS_OK; diff --git a/toolkit/components/places/src/nsNavHistoryResult.h b/toolkit/components/places/src/nsNavHistoryResult.h index ad8a79cf873..3fecab41606 100644 --- a/toolkit/components/places/src/nsNavHistoryResult.h +++ b/toolkit/components/places/src/nsNavHistoryResult.h @@ -195,6 +195,8 @@ public: PRBool aExpand); void InvalidateTree(); + + PRBool mBatchInProgress; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)