зеркало из https://github.com/mozilla/pjs.git
Bug 506402 - Add GUIDs to satchel form entries. r=zpao, r=gavin
This commit is contained in:
Родитель
628a008cf4
Коммит
5fdca1b890
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include "nsStorageFormHistory.h"
|
||||
|
||||
#include "plbase64.h"
|
||||
#include "prmem.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
@ -69,7 +71,7 @@
|
|||
#include "nsIPrivateBrowsingService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
||||
#define DB_SCHEMA_VERSION 2
|
||||
#define DB_SCHEMA_VERSION 3
|
||||
#define DB_FILENAME NS_LITERAL_STRING("formhistory.sqlite")
|
||||
#define DB_CORRUPT_FILENAME NS_LITERAL_STRING("formhistory.sqlite.corrupt")
|
||||
|
||||
|
@ -124,6 +126,9 @@ nsFormHistory::Init()
|
|||
{
|
||||
PRBool doImport;
|
||||
|
||||
mUUIDService = do_GetService("@mozilla.org/uuid-generator;1");
|
||||
NS_ENSURE_TRUE(mUUIDService, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = OpenDatabase(&doImport);
|
||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||
/* If the DB is corrupt, nuke it and try again with a new DB. */
|
||||
|
@ -182,6 +187,22 @@ nsFormHistory::FormHistoryEnabled()
|
|||
return gFormHistoryEnabled;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormHistory::GenerateGUID(nsACString &guidString) {
|
||||
nsID rawguid;
|
||||
nsresult rv = mUUIDService->GenerateUUIDInPlace(&rawguid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Encode 12 bytes (96bits) of randomness into a 16 character base-64 string.
|
||||
char *b64 = PL_Base64Encode(reinterpret_cast<const char *>(&rawguid), 12, nsnull);
|
||||
if (!b64)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
guidString.Assign(b64);
|
||||
PR_Free(b64);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIFormHistory2
|
||||
|
@ -229,6 +250,10 @@ nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
|
|||
rv = mDBUpdateEntry->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
nsCAutoString guid;
|
||||
rv = GenerateGUID(guid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt64 now = PR_Now();
|
||||
|
||||
mozStorageStatementScoper scope(mDBInsertNameValue);
|
||||
|
@ -247,6 +272,9 @@ nsFormHistory::AddEntry(const nsAString &aName, const nsAString &aValue)
|
|||
// lastUsed
|
||||
rv = mDBInsertNameValue->BindInt64Parameter(4, now);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// guid
|
||||
rv = mDBInsertNameValue->BindUTF8StringParameter(5, guid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBInsertNameValue->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -601,12 +629,14 @@ nsFormHistory::CreateTable()
|
|||
"CREATE TABLE moz_formhistory ("
|
||||
"id INTEGER PRIMARY KEY, fieldname TEXT NOT NULL, "
|
||||
"value TEXT NOT NULL, timesUsed INTEGER, "
|
||||
"firstUsed INTEGER, lastUsed INTEGER)"));
|
||||
"firstUsed INTEGER, lastUsed INTEGER, guid TEXT)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE INDEX moz_formhistory_index ON moz_formhistory (fieldname)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE INDEX moz_formhistory_lastused_index ON moz_formhistory (lastUsed)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE INDEX moz_formhistory_guid_index ON moz_formhistory (guid)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mDBConn->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -635,7 +665,7 @@ nsFormHistory::CreateStatements()
|
|||
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"INSERT INTO moz_formhistory (fieldname, value, timesUsed, "
|
||||
"firstUsed, lastUsed) VALUES (?1, ?2, ?3, ?4, ?5)"),
|
||||
"firstUsed, lastUsed, guid) VALUES (?1, ?2, ?3, ?4, ?5, ?6)"),
|
||||
getter_AddRefs(mDBInsertNameValue));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -712,6 +742,10 @@ nsFormHistory::dbMigrate()
|
|||
rv = MigrateToVersion2();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// (fallthrough to the next upgrade)
|
||||
case 2:
|
||||
rv = MigrateToVersion3();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// (fallthrough to the next upgrade)
|
||||
case DB_SCHEMA_VERSION:
|
||||
// (current version, nothing more to do)
|
||||
break;
|
||||
|
@ -814,6 +848,72 @@ nsFormHistory::MigrateToVersion2()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* MigrateToVersion3
|
||||
*
|
||||
* Updates the DB schema to v3 (bug 506402).
|
||||
* Adds guid column and index.
|
||||
*/
|
||||
nsresult
|
||||
nsFormHistory::MigrateToVersion3()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Check to see if the new column already exists (could be a v3 DB that
|
||||
// was downgraded to v2). If they exist, we don't need to add them.
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT guid FROM moz_formhistory"),
|
||||
getter_AddRefs(stmt));
|
||||
|
||||
PRBool columnExists = !!NS_SUCCEEDED(rv);
|
||||
|
||||
if (!columnExists) {
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_formhistory ADD COLUMN guid TEXT"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("CREATE INDEX IF NOT EXISTS moz_formhistory_guid_index ON moz_formhistory (guid)"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mozStorageTransaction transaction(mDBConn, PR_FALSE);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> selectStatement;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id FROM moz_formhistory WHERE guid isnull"),
|
||||
getter_AddRefs(selectStatement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> updateStatement;
|
||||
rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"UPDATE moz_formhistory SET guid = ?1 WHERE id = ?2"),
|
||||
getter_AddRefs(updateStatement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool hasMore;
|
||||
while (NS_SUCCEEDED(selectStatement->ExecuteStep(&hasMore)) && hasMore) {
|
||||
PRUint64 id = selectStatement->AsInt64(0);
|
||||
|
||||
nsCAutoString guid;
|
||||
rv = GenerateGUID(guid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = updateStatement->BindInt64Parameter(1, id);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = updateStatement->BindUTF8StringParameter(0, guid);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = updateStatement->Execute();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = mDBConn->SetSchemaVersion(3);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return transaction.Commit();
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsFormHistory::GetDatabaseFile(nsIFile** aFile)
|
||||
{
|
||||
|
@ -860,7 +960,7 @@ nsFormHistory::dbAreExpectedColumnsPresent()
|
|||
// If the statement succeeds, all the columns are there.
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT fieldname, value, timesUsed, firstUsed, lastUsed "
|
||||
"SELECT fieldname, value, timesUsed, firstUsed, lastUsed, guid "
|
||||
"FROM moz_formhistory"), getter_AddRefs(stmt));
|
||||
return NS_SUCCEEDED(rv) ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "mozIStorageService.h"
|
||||
|
@ -106,6 +107,7 @@ public:
|
|||
nsresult dbCleanup();
|
||||
nsresult MigrateToVersion1();
|
||||
nsresult MigrateToVersion2();
|
||||
nsresult MigrateToVersion3();
|
||||
PRBool dbAreExpectedColumnsPresent();
|
||||
|
||||
nsresult CreateTable();
|
||||
|
@ -119,10 +121,12 @@ public:
|
|||
static PRBool gSaveHttpsForms;
|
||||
static PRBool gPrefsInitialized;
|
||||
|
||||
nsresult GenerateGUID(nsACString &guid);
|
||||
nsresult ExpireOldEntries();
|
||||
PRInt32 CountAllEntries();
|
||||
PRInt64 GetExistingEntryID(const nsAString &aName, const nsAString &aValue);
|
||||
|
||||
nsCOMPtr<nsIUUIDGenerator> mUUIDService;
|
||||
nsCOMPtr<nsIPrefBranch> mPrefBranch;
|
||||
nsCOMPtr<mozIStorageService> mStorageService;
|
||||
nsCOMPtr<mozIStorageStatement> mDBFindEntry;
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
toolkit/components/satchel/test/unit/formhistory_v999a.sqlite
Двоичные данные
toolkit/components/satchel/test/unit/formhistory_v999a.sqlite
Двоичный файл не отображается.
|
@ -38,7 +38,7 @@
|
|||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
||||
const CURRENT_SCHEMA = 2;
|
||||
const CURRENT_SCHEMA = 3;
|
||||
const PR_HOURS = 60 * 60 * 1000000;
|
||||
|
||||
do_get_profile();
|
||||
|
@ -55,3 +55,13 @@ function getDBVersion(dbfile) {
|
|||
|
||||
return version;
|
||||
}
|
||||
|
||||
const isGUID = /[A-Za-z0-9\+\/]{16}/;
|
||||
|
||||
function getGUIDforID(conn, id) {
|
||||
var stmt = conn.createStatement("SELECT guid from moz_formhistory WHERE id = " + id);
|
||||
stmt.executeStep();
|
||||
var guid = stmt.getString(0);
|
||||
stmt.finalize();
|
||||
return guid;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* ***** 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 Satchel Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Justin Dolske <dolske@mozilla.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 ***** */
|
||||
|
||||
var testnum = 0;
|
||||
var fh;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
try {
|
||||
|
||||
// ===== test init =====
|
||||
var testfile = do_get_file("formhistory_v2.sqlite");
|
||||
var profileDir = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
|
||||
// Cleanup from any previous tests or failures.
|
||||
var destFile = profileDir.clone();
|
||||
destFile.append("formhistory.sqlite");
|
||||
if (destFile.exists())
|
||||
destFile.remove(false);
|
||||
|
||||
testfile.copyTo(profileDir, "formhistory.sqlite");
|
||||
do_check_eq(2, getDBVersion(testfile));
|
||||
|
||||
fh = Cc["@mozilla.org/satchel/form-history;1"].
|
||||
getService(Ci.nsIFormHistory2);
|
||||
|
||||
|
||||
// ===== 1 =====
|
||||
testnum++;
|
||||
|
||||
// Check that the index was added
|
||||
do_check_true(fh.DBConnection.indexExists("moz_formhistory_guid_index"));
|
||||
// check for upgraded schema.
|
||||
do_check_eq(CURRENT_SCHEMA, fh.DBConnection.schemaVersion);
|
||||
|
||||
do_check_true(fh.entryExists("name-A", "value-A"));
|
||||
var guid = getGUIDforID(fh.DBConnection, 1);
|
||||
do_check_true(isGUID.test(guid));
|
||||
|
||||
// Add a new entry and check that it gets a GUID
|
||||
do_check_false(fh.entryExists("name-B", "value-B"));
|
||||
fh.addEntry("name-B", "value-B");
|
||||
do_check_true(fh.entryExists("name-B", "value-B"));
|
||||
|
||||
guid = getGUIDforID(fh.DBConnection, 2);
|
||||
do_check_true(isGUID.test(guid));
|
||||
|
||||
} catch (e) {
|
||||
throw "FAILED in test #" + testnum + " -- " + e;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/* ***** 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 Satchel Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Justin Dolske <dolske@mozilla.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 ***** */
|
||||
|
||||
var testnum = 0;
|
||||
var fh;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
try {
|
||||
|
||||
// ===== test init =====
|
||||
var testfile = do_get_file("formhistory_v2v3.sqlite");
|
||||
var profileDir = dirSvc.get("ProfD", Ci.nsIFile);
|
||||
|
||||
// Cleanup from any previous tests or failures.
|
||||
var destFile = profileDir.clone();
|
||||
destFile.append("formhistory.sqlite");
|
||||
if (destFile.exists())
|
||||
destFile.remove(false);
|
||||
|
||||
testfile.copyTo(profileDir, "formhistory.sqlite");
|
||||
do_check_eq(2, getDBVersion(testfile));
|
||||
|
||||
fh = Cc["@mozilla.org/satchel/form-history;1"].
|
||||
getService(Ci.nsIFormHistory2);
|
||||
|
||||
|
||||
// ===== 1 =====
|
||||
testnum++;
|
||||
|
||||
// Check that the index was added
|
||||
do_check_true(fh.DBConnection.indexExists("moz_formhistory_guid_index"));
|
||||
// check for upgraded schema.
|
||||
do_check_eq(CURRENT_SCHEMA, fh.DBConnection.schemaVersion);
|
||||
|
||||
// Entry added by v3 code, has a GUID that shouldn't be changed.
|
||||
do_check_true(fh.entryExists("name-A", "value-A"));
|
||||
var guid = getGUIDforID(fh.DBConnection, 1);
|
||||
do_check_eq(guid, "dgdaRfzsTnOOZ7wK");
|
||||
|
||||
// Entry added by v2 code after a downgrade, GUID should be assigned on upgrade.
|
||||
do_check_true(fh.entryExists("name-B", "value-B"));
|
||||
guid = getGUIDforID(fh.DBConnection, 2);
|
||||
do_check_true(isGUID.test(guid));
|
||||
|
||||
// Add a new entry and check that it gets a GUID
|
||||
do_check_false(fh.entryExists("name-C", "value-C"));
|
||||
fh.addEntry("name-C", "value-C");
|
||||
do_check_true(fh.entryExists("name-C", "value-C"));
|
||||
|
||||
guid = getGUIDforID(fh.DBConnection, 3);
|
||||
do_check_true(isGUID.test(guid));
|
||||
|
||||
} catch (e) {
|
||||
throw "FAILED in test #" + testnum + " -- " + e;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче