зеркало из https://github.com/mozilla/gecko-dev.git
Bug 457110 - Support in-memory DB for the downloads manager back-end, r=sdwilsh
This commit is contained in:
Родитель
ecdd8feaed
Коммит
83f6c4545b
|
@ -26,6 +26,7 @@
|
|||
* Srirang G Doddihal <brahmana@doddihal.com>
|
||||
* Edward Lee <edward.lee@engineering.uiuc.edu>
|
||||
* Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>
|
||||
* Ehsan Akhgari <ehsan.akhgari@gmail.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
|
||||
|
@ -276,16 +277,63 @@ nsDownloadManager::ResumeOnWakeCallback(nsITimer *aTimer, void *aClosure)
|
|||
(void)dlMgr->ResumeAllDownloads(PR_FALSE);
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageConnection>
|
||||
nsDownloadManager::GetFileDBConnection(nsIFile *dbFile) const
|
||||
{
|
||||
NS_ASSERTION(dbFile, "GetFileDBConnection called with an invalid nsIFile");
|
||||
|
||||
nsCOMPtr<mozIStorageService> storage =
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(storage, nsnull);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
nsresult rv = storage->OpenDatabase(dbFile, getter_AddRefs(conn));
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
// delete and try again, since we don't care so much about losing a user's
|
||||
// download history
|
||||
rv = dbFile->Remove(PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
rv = storage->OpenDatabase(dbFile, getter_AddRefs(conn));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
return conn.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageConnection>
|
||||
nsDownloadManager::GetMemoryDBConnection() const
|
||||
{
|
||||
nsCOMPtr<mozIStorageService> storage =
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(storage, nsnull);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> conn;
|
||||
nsresult rv = storage->OpenSpecialDatabase("memory", getter_AddRefs(conn));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
return conn.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDownloadManager::InitDB(PRBool *aDoImport)
|
||||
nsDownloadManager::InitMemoryDB()
|
||||
{
|
||||
mDBConn = GetMemoryDBConnection();
|
||||
if (!mDBConn)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsresult rv = CreateTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mDBType = DATABASE_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDownloadManager::InitFileDB(PRBool *aDoImport)
|
||||
{
|
||||
nsresult rv;
|
||||
*aDoImport = PR_FALSE;
|
||||
|
||||
nsCOMPtr<mozIStorageService> storage =
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> dbFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
|
||||
getter_AddRefs(dbFile));
|
||||
|
@ -293,15 +341,8 @@ nsDownloadManager::InitDB(PRBool *aDoImport)
|
|||
rv = dbFile->Append(DM_DB_NAME);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = storage->OpenDatabase(dbFile, getter_AddRefs(mDBConn));
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
// delete and try again, since we don't care so much about losing a users
|
||||
// download history
|
||||
rv = dbFile->Remove(PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = storage->OpenDatabase(dbFile, getter_AddRefs(mDBConn));
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mDBConn = GetFileDBConnection(dbFile);
|
||||
NS_ENSURE_TRUE(mDBConn, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
PRBool tableExists;
|
||||
rv = mDBConn->TableExists(NS_LITERAL_CSTRING("moz_downloads"), &tableExists);
|
||||
|
@ -310,9 +351,12 @@ nsDownloadManager::InitDB(PRBool *aDoImport)
|
|||
*aDoImport = PR_TRUE;
|
||||
rv = CreateTable();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mDBType = DATABASE_DISK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDBType = DATABASE_DISK;
|
||||
|
||||
// Checking the database schema now
|
||||
PRInt32 schemaVersion;
|
||||
rv = mDBConn->GetSchemaVersion(&schemaVersion);
|
||||
|
@ -526,6 +570,9 @@ nsDownloadManager::InitDB(PRBool *aDoImport)
|
|||
|
||||
// if the statement fails, that means all the columns were not there.
|
||||
// First we backup the database
|
||||
nsCOMPtr<mozIStorageService> storage =
|
||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(storage, NS_ERROR_NOT_AVAILABLE);
|
||||
nsCOMPtr<nsIFile> backup;
|
||||
rv = storage->BackupDatabaseFile(dbFile, DM_DB_CORRUPT_FILENAME, nsnull,
|
||||
getter_AddRefs(backup));
|
||||
|
@ -894,8 +941,20 @@ nsDownloadManager::Init()
|
|||
mObserverService = do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool doImport;
|
||||
rv = InitDB(&doImport);
|
||||
PRBool doImport = PR_FALSE;
|
||||
switch (mDBType) {
|
||||
case DATABASE_MEMORY:
|
||||
rv = InitMemoryDB();
|
||||
break;
|
||||
|
||||
case DATABASE_DISK:
|
||||
rv = InitFileDB(&doImport);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(0, "Unexpected value encountered for nsDownloadManager::mDBType");
|
||||
break;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (doImport)
|
||||
|
@ -1783,6 +1842,20 @@ nsDownloadManager::NotifyListenersOnStateChange(nsIWebProgress *aProgress,
|
|||
aDownload);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDownloadManager::SwitchDatabaseTypeTo(enum nsDownloadManager::DatabaseType aType)
|
||||
{
|
||||
if (aType == mDBType)
|
||||
return NS_OK; // no-op
|
||||
|
||||
mDBType = aType;
|
||||
|
||||
(void)PauseAllDownloads(PR_TRUE);
|
||||
(void)RemoveAllDownloads();
|
||||
|
||||
return Init();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsINavHistoryObserver
|
||||
|
||||
|
@ -1930,6 +2003,12 @@ nsDownloadManager::Observe(nsISupports *aSubject,
|
|||
// We can now resume all downloads that are supposed to auto-resume.
|
||||
(void)ResumeAllDownloads(PR_FALSE);
|
||||
}
|
||||
else if (strcmp(aTopic, "dlmgr-switchdb") == 0) {
|
||||
if (NS_LITERAL_STRING("memory").Equals(aData))
|
||||
return SwitchDatabaseTypeTo(DATABASE_MEMORY);
|
||||
else if (NS_LITERAL_STRING("disk").Equals(aData))
|
||||
return SwitchDatabaseTypeTo(DATABASE_DISK);
|
||||
}
|
||||
else if (strcmp(aTopic, "alertclickcallback") == 0) {
|
||||
nsCOMPtr<nsIDownloadManagerUI> dmui =
|
||||
do_GetService("@mozilla.org/download-manager-ui;1", &rv);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
* Shawn Wilsher <me@shawnwilsher.com>
|
||||
* Srirang G Doddihal <brahmana@doddihal.com>
|
||||
* Edward Lee <edward.lee@engineering.uiuc.edu>
|
||||
* Ehsan Akhgari <ehsan.akhgari@gmail.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
|
||||
|
@ -93,10 +94,23 @@ public:
|
|||
static nsDownloadManager *GetSingleton();
|
||||
|
||||
virtual ~nsDownloadManager();
|
||||
nsDownloadManager() {};
|
||||
nsDownloadManager() :
|
||||
mDBType(DATABASE_DISK)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
nsresult InitDB(PRBool *aDoImport);
|
||||
enum DatabaseType
|
||||
{
|
||||
DATABASE_DISK = 0, // default
|
||||
DATABASE_MEMORY
|
||||
};
|
||||
|
||||
nsresult InitFileDB(PRBool *aDoImport);
|
||||
nsresult InitMemoryDB();
|
||||
already_AddRefed<mozIStorageConnection> GetFileDBConnection(nsIFile *dbFile) const;
|
||||
already_AddRefed<mozIStorageConnection> GetMemoryDBConnection() const;
|
||||
nsresult SwitchDatabaseTypeTo(enum DatabaseType aType);
|
||||
nsresult CreateTable();
|
||||
nsresult ImportDownloadHistory();
|
||||
|
||||
|
@ -254,6 +268,8 @@ private:
|
|||
nsCOMPtr<mozIStorageStatement> mGetIdsForURIStatement;
|
||||
nsAutoPtr<mozStorageTransaction> mHistoryTransaction;
|
||||
|
||||
enum DatabaseType mDBType;
|
||||
|
||||
static nsDownloadManager *gDownloadManagerService;
|
||||
|
||||
friend class nsDownload;
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/* ***** 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 Download Manager Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ehsan Akhgari <ehsan.akhgari@gmail.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 tests the switching of the download manager database types between disk
|
||||
// and memory based databases. This feature was added in bug 457110.
|
||||
|
||||
const nsIDownloadManager = Ci.nsIDownloadManager;
|
||||
const dm = Cc["@mozilla.org/download-manager;1"].getService(nsIDownloadManager);
|
||||
|
||||
function run_test() {
|
||||
let observer = dm.QueryInterface(Ci.nsIObserver);
|
||||
|
||||
// make sure the initial disk-based DB is initialized correctly
|
||||
let connDisk = dm.DBConnection;
|
||||
do_check_true(connDisk.connectionReady);
|
||||
do_check_neq(connDisk.databaseFile, null);
|
||||
|
||||
// switch to a disk DB -- should be a no-op
|
||||
observer.observe(null, "dlmgr-switchdb", "disk");
|
||||
|
||||
// make sure that the database has not changed
|
||||
do_check_true(dm.DBConnection.connectionReady);
|
||||
do_check_neq(dm.DBConnection.databaseFile, null);
|
||||
do_check_true(connDisk.databaseFile.equals(dm.DBConnection.databaseFile));
|
||||
connDisk = dm.DBConnection;
|
||||
|
||||
// switch to a memory DB
|
||||
observer.observe(null, "dlmgr-switchdb", "memory");
|
||||
|
||||
// make sure the DB is has been switched correctly
|
||||
let connMemory = dm.DBConnection;
|
||||
do_check_true(connMemory.connectionReady);
|
||||
do_check_eq(connMemory.databaseFile, null);
|
||||
|
||||
// switch to a memory DB -- should be a no-op
|
||||
observer.observe(null, "dlmgr-switchdb", "memory");
|
||||
|
||||
// make sure that the database is still memory based
|
||||
connMemory = dm.DBConnection;
|
||||
do_check_true(connMemory.connectionReady);
|
||||
do_check_eq(connMemory.databaseFile, null);
|
||||
|
||||
// switch back to the disk DB
|
||||
observer.observe(null, "dlmgr-switchdb", "disk");
|
||||
|
||||
// make sure that the disk database is initialized correctly
|
||||
do_check_true(dm.DBConnection.connectionReady);
|
||||
do_check_neq(dm.DBConnection.databaseFile, null);
|
||||
do_check_true(connDisk.databaseFile.equals(dm.DBConnection.databaseFile));
|
||||
}
|
Загрузка…
Ссылка в новой задаче