Bug 675996 - Part 1: extend moz_favicons with GUID to support Sync. r=mak

This commit is contained in:
Richard Newman 2011-12-01 13:58:19 -08:00
Родитель c19dff8b5d
Коммит a190b385bb
8 изменённых файлов: 103 добавлений и 19 удалений

Просмотреть файл

@ -21,6 +21,7 @@
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net> (original author)
* Richard Newman <rnewman@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
@ -724,11 +725,18 @@ AsyncAssociateIconToPage::Run()
// If there is no entry for this icon, or the entry is obsolete, replace it.
if (mIcon.id == 0 || (mIcon.status & ICON_STATUS_CHANGED)) {
// The 'multi-coalesce' here ensures that replacing a favicon without
// specifying a :guid parameter doesn't cause it to be allocated a new
// GUID.
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
"INSERT OR REPLACE INTO moz_favicons "
"(id, url, data, mime_type, expiration) "
"(id, url, data, mime_type, expiration, guid) "
"VALUES ((SELECT id FROM moz_favicons WHERE url = :icon_url), "
":icon_url, :data, :mime_type, :expiration) "
":icon_url, :data, :mime_type, :expiration, "
"COALESCE(:guid, "
"(SELECT guid FROM moz_favicons "
"WHERE url = :icon_url), "
"GENERATE_GUID()))"
);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scoper(stmt);
@ -741,6 +749,16 @@ AsyncAssociateIconToPage::Run()
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("expiration"), mIcon.expiration);
NS_ENSURE_SUCCESS(rv, rv);
// Binding a GUID allows us to override the current (or generated) GUID.
if (mIcon.guid.IsEmpty()) {
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("guid"));
}
else {
rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("guid"), mIcon.guid);
}
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -75,6 +75,7 @@ struct IconData
, fetchMode(FETCH_NEVER)
, status(ICON_STATUS_UNKNOWN)
{
guid.SetIsVoid(PR_TRUE);
}
PRInt64 id;
@ -84,6 +85,7 @@ struct IconData
PRTime expiration;
enum AsyncFaviconFetchMode fetchMode;
PRUint16 status; // This is a bitset, see ICON_STATUS_* defines above.
nsCString guid;
};
/**

Просмотреть файл

@ -33,6 +33,7 @@
* Drew Willcoxon <adw@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Paolo Amadini <http://www.amadzone.org/>
* Richard Newman <rnewman@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
@ -642,7 +643,13 @@ Database::InitSchema(bool* aDatabaseMigrated)
rv = MigrateV13Up();
NS_ENSURE_SUCCESS(rv, rv);
}
// Firefox 11 uses schema version 13.
if (currentSchemaVersion < 14) {
rv = MigrateV14Up();
NS_ENSURE_SUCCESS(rv, rv);
}
// Firefox 11 uses schema version 14.
// Schema Upgrades must add migration code here.
}
@ -950,7 +957,7 @@ Database::MigrateV7Up()
mozStorageTransaction transaction(mMainConn, false);
// We need an index on lastModified to catch quickly last modified bookmark
// title for tag container's children. This will be useful for sync too.
// title for tag container's children. This will be useful for Sync, too.
bool lastModIndexExists = false;
rv = mMainConn->IndexExists(
NS_LITERAL_CSTRING("moz_bookmarks_itemlastmodifiedindex"),
@ -1282,8 +1289,8 @@ Database::MigrateV11Up()
rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_BOOKMARKS_GUID);
NS_ENSURE_SUCCESS(rv, rv);
// moz_placess grew a guid column. Add the column, but do not populate it
// with anything just yet. We will do that soon.
// moz_places grew a guid column. Add the column, but do not populate it
// with anything just yet. We will do that soon.
rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE moz_places "
"ADD COLUMN guid TEXT"
@ -1306,9 +1313,7 @@ Database::MigrateV13Up()
{
MOZ_ASSERT(NS_IsMainThread());
// Dynamic containers are no more supported.
// For existing profiles, we may not have a moz_bookmarks.guid column
// Dynamic containers are no longer supported.
nsCOMPtr<mozIStorageAsyncStatement> deleteDynContainersStmt;
nsresult rv = mMainConn->CreateAsyncStatement(NS_LITERAL_CSTRING(
"DELETE FROM moz_bookmarks WHERE type = :item_type"),
@ -1325,6 +1330,38 @@ Database::MigrateV13Up()
return NS_OK;
}
nsresult
Database::MigrateV14Up()
{
// For existing profiles, we may not have a moz_favicons.guid column.
// Add it here. We want it to be unique, but ALTER TABLE doesn't allow
// a uniqueness constraint, so the index must be created separately.
nsCOMPtr<mozIStorageStatement> hasGuidStatement;
nsresult rv = mMainConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT guid FROM moz_favicons"),
getter_AddRefs(hasGuidStatement));
if (NS_FAILED(rv)) {
rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"ALTER TABLE moz_favicons "
"ADD COLUMN guid TEXT"
));
NS_ENSURE_SUCCESS(rv, rv);
// Generate GUIDs for our existing favicons.
rv = mMainConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"UPDATE moz_favicons "
"SET guid = GENERATE_GUID()"
));
NS_ENSURE_SUCCESS(rv, rv);
// And now we can make the column unique.
rv = mMainConn->ExecuteSimpleSQL(CREATE_IDX_MOZ_FAVICONS_GUID);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
void
Database::Shutdown()
{
@ -1412,6 +1449,10 @@ Database::Observe(nsISupports *aSubject,
"SELECT 1 "
"FROM moz_bookmarks "
"WHERE guid IS NULL "
"UNION ALL "
"SELECT 1 "
"FROM moz_favicons "
"WHERE guid IS NULL "
), getter_AddRefs(stmt));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -45,9 +45,9 @@
#include "mozilla/storage.h"
#include "mozilla/storage/StatementCache.h"
// This is the schema version, update it at any schema change and add a
// This is the schema version. Update it at any schema change and add a
// corresponding migrateVxx method below.
#define DATABASE_SCHEMA_VERSION 13
#define DATABASE_SCHEMA_VERSION 14
// Fired after Places inited.
#define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
@ -288,8 +288,10 @@ protected:
nsresult MigrateV9Up();
nsresult MigrateV10Up();
nsresult MigrateV11Up();
nsresult CheckAndUpdateGUIDs();
nsresult MigrateV13Up();
nsresult MigrateV14Up();
nsresult CheckAndUpdateGUIDs();
private:
~Database();

Просмотреть файл

@ -238,12 +238,15 @@ nsFaviconService::SetFaviconUrlForPage(nsIURI* aPageURI, nsIURI* aFaviconURI)
if (iconId == -1) {
// We did not find any entry for this icon, so create a new one.
nsCOMPtr<mozIStorageStatement> stmt = mDB->GetStatement(
"INSERT INTO moz_favicons (id, url, data, mime_type, expiration) "
"VALUES (:icon_id, :icon_url, :data, :mime_type, :expiration)"
"INSERT INTO moz_favicons (id, url, data, mime_type, expiration, guid) "
"VALUES (:icon_id, :icon_url, :data, :mime_type, :expiration, "
"COALESCE(:guid, GENERATE_GUID()))"
);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scoper(stmt);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("guid"));
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("icon_id"));
NS_ENSURE_SUCCESS(rv, rv);
rv = URIBinder::Bind(stmt, NS_LITERAL_CSTRING("icon_url"), aFaviconURI);
@ -443,12 +446,17 @@ nsFaviconService::SetFaviconData(nsIURI* aFaviconURI, const PRUint8* aData,
rv = stmt->GetInt64(0, &id);
NS_ENSURE_SUCCESS(rv, rv);
statement = mDB->GetStatement(
"UPDATE moz_favicons SET data = :data, mime_type = :mime_type, "
"expiration = :expiration "
"UPDATE moz_favicons SET "
"guid = COALESCE(:guid, guid), "
"data = :data, "
"mime_type = :mime_type, "
"expiration = :expiration "
"WHERE id = :icon_id"
);
NS_ENSURE_STATE(statement);
rv = statement->BindNullByName(NS_LITERAL_CSTRING("guid"));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("icon_id"), id);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindBlobByName(NS_LITERAL_CSTRING("data"), data, dataLen);
@ -461,9 +469,9 @@ nsFaviconService::SetFaviconData(nsIURI* aFaviconURI, const PRUint8* aData,
else {
// Insert a new entry.
statement = mDB->GetStatement(
"INSERT INTO moz_favicons (id, url, data, mime_type, expiration) "
"VALUES (:icon_id, :icon_url, :data, :mime_type, :expiration)"
);
"INSERT INTO moz_favicons (id, url, data, mime_type, expiration, guid) "
"VALUES (:icon_id, :icon_url, :data, :mime_type, :expiration, "
"COALESCE(:guid, GENERATE_GUID()))");
NS_ENSURE_STATE(statement);
rv = statement->BindNullByName(NS_LITERAL_CSTRING("icon_id"));
@ -476,6 +484,8 @@ nsFaviconService::SetFaviconData(nsIURI* aFaviconURI, const PRUint8* aData,
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64ByName(NS_LITERAL_CSTRING("expiration"), aExpiration);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindNullByName(NS_LITERAL_CSTRING("guid"));
NS_ENSURE_SUCCESS(rv, rv);
}
}
mozStorageStatementScoper statementScoper(statement);

Просмотреть файл

@ -30,6 +30,7 @@
* Drew Willcoxon <adw@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Paolo Amadini <http://www.amadzone.org/>
* Richard Newman <rnewman@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

Просмотреть файл

@ -145,5 +145,13 @@
"itemattributeindex", "moz_items_annos", "item_id, anno_attribute_id", "UNIQUE" \
)
/**
* moz_favicons
*/
#define CREATE_IDX_MOZ_FAVICONS_GUID \
CREATE_PLACES_IDX( \
"guid_uniqueindex", "moz_favicons", "guid", "UNIQUE" \
)
#endif // nsPlacesIndexes_h__

Просмотреть файл

@ -22,6 +22,7 @@
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
* Richard Newman <rnewman@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
@ -127,6 +128,7 @@
", data BLOB" \
", mime_type VARCHAR(32)" \
", expiration LONG" \
", guid TEXT" \
")" \
)