зеркало из https://github.com/mozilla/pjs.git
Bug 360134: Add GUIDs to items so they can be uniquely identified across profiles (for sync purposes). r=mano
This commit is contained in:
Родитель
6ddd341252
Коммит
6bff8dbaa0
|
@ -161,7 +161,7 @@ interface nsINavBookmarkObserver : nsISupports
|
||||||
* folders. A URI in history can be contained in one or more such folders.
|
* folders. A URI in history can be contained in one or more such folders.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(c3307160-525d-4d3c-9d75-b4f13a9ca05d)]
|
[scriptable, uuid(630dcd21-402c-44cd-8336-78bff3efc5f3)]
|
||||||
interface nsINavBookmarksService : nsISupports
|
interface nsINavBookmarksService : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -327,6 +327,35 @@ interface nsINavBookmarksService : nsISupports
|
||||||
*/
|
*/
|
||||||
void removeChildAt(in long long aFolder, in long aIndex);
|
void removeChildAt(in long long aFolder, in long aIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a globally unique identifier for an item, meant to be used in
|
||||||
|
* sync scenarios. Even if their contents are exactly the same
|
||||||
|
* (including an item in a different profile with the same ItemId),
|
||||||
|
* the GUID would be different.
|
||||||
|
* @param aItemId
|
||||||
|
* The ID of the item to get the GUID for
|
||||||
|
* @returns The GUID string
|
||||||
|
*/
|
||||||
|
AString getItemGUID(in long long aItemId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a globally unique identifier. This can be useful when a sync
|
||||||
|
* algorithm deems two independently created items (on different
|
||||||
|
* profiles) to be the same item.
|
||||||
|
* @param aItemId
|
||||||
|
* The id of the item to set the GUID of
|
||||||
|
* @returns The GUID string
|
||||||
|
*/
|
||||||
|
void setItemGUID(in long long aItemId, in AString aGUID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ID of the item with the given GUID.
|
||||||
|
* @param aGUID
|
||||||
|
* The GUID string of the item to search for
|
||||||
|
* @returns The item ID, or -1 if not found
|
||||||
|
*/
|
||||||
|
long long getItemIdForGUID(in AString aGUID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the title for an item.
|
* Set the title for an item.
|
||||||
* @param aItemId
|
* @param aItemId
|
||||||
|
|
|
@ -48,6 +48,9 @@
|
||||||
#include "nsAnnotationService.h"
|
#include "nsAnnotationService.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "nsAutoLock.h"
|
#include "nsAutoLock.h"
|
||||||
|
#include "nsIUUIDGenerator.h"
|
||||||
|
#include "prmem.h"
|
||||||
|
#include "prprf.h"
|
||||||
|
|
||||||
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ID = 0;
|
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ID = 0;
|
||||||
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_Type = 1;
|
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_Type = 1;
|
||||||
|
@ -76,10 +79,11 @@ nsNavBookmarks* nsNavBookmarks::sInstance = nsnull;
|
||||||
|
|
||||||
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
|
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
|
||||||
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
|
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
|
||||||
|
#define GUID_ANNO NS_LITERAL_CSTRING("placesInternal/GUID")
|
||||||
|
|
||||||
nsNavBookmarks::nsNavBookmarks()
|
nsNavBookmarks::nsNavBookmarks()
|
||||||
: mRoot(0), mBookmarksRoot(0), mTagRoot(0), mToolbarFolder(0), mBatchLevel(0),
|
: mRoot(0), mBookmarksRoot(0), mTagRoot(0), mToolbarFolder(0), mBatchLevel(0),
|
||||||
mBatchHasTransaction(PR_FALSE), mLock(nsnull)
|
mItemCount(0), mBatchHasTransaction(PR_FALSE), mLock(nsnull)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!sInstance, "Multiple nsNavBookmarks instances!");
|
NS_ASSERTION(!sInstance, "Multiple nsNavBookmarks instances!");
|
||||||
sInstance = this;
|
sInstance = this;
|
||||||
|
@ -185,6 +189,13 @@ nsNavBookmarks::Init()
|
||||||
getter_AddRefs(mDBGetItemProperties));
|
getter_AddRefs(mDBGetItemProperties));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"SELECT item_id FROM moz_items_annos "
|
||||||
|
"WHERE content = ?1 "
|
||||||
|
"LIMIT 1"),
|
||||||
|
getter_AddRefs(mDBGetItemIdForGUID));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// mDBGetRedirectDestinations
|
// mDBGetRedirectDestinations
|
||||||
// input = page ID, time threshold; output = unique ID input has redirected to
|
// input = page ID, time threshold; output = unique ID input has redirected to
|
||||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
@ -228,6 +239,17 @@ nsNavBookmarks::Init()
|
||||||
getter_AddRefs(mDBGetURIForKeyword));
|
getter_AddRefs(mDBGetURIForKeyword));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// generate a new GUID base for this session
|
||||||
|
nsCOMPtr<nsIUUIDGenerator> uuidgen = do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
nsID GUID;
|
||||||
|
rv = uuidgen->GenerateUUIDInPlace(&GUID);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
char* GUIDChars = GUID.ToString();
|
||||||
|
NS_ENSURE_TRUE(GUIDChars, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
mGUIDBase.Assign(NS_ConvertASCIItoUTF16(GUIDChars));
|
||||||
|
PR_Free(GUIDChars);
|
||||||
|
|
||||||
rv = InitRoots();
|
rv = InitRoots();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
@ -1697,6 +1719,56 @@ nsNavBookmarks::GetItemLastModified(PRInt64 aItemId, PRTime *aLastModified)
|
||||||
return mDBGetItemProperties->GetInt64(kGetItemPropertiesIndex_LastModified, aLastModified);
|
return mDBGetItemProperties->GetInt64(kGetItemPropertiesIndex_LastModified, aLastModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavBookmarks::GetItemGUID(PRInt64 aItemId, nsAString &aGUID)
|
||||||
|
{
|
||||||
|
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
|
||||||
|
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
nsresult rv = annosvc->GetItemAnnotationString(aItemId, GUID_ANNO, aGUID);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) || rv != NS_ERROR_NOT_AVAILABLE)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
nsAutoString tmp;
|
||||||
|
tmp.Assign(mGUIDBase);
|
||||||
|
tmp.AppendInt(mItemCount++);
|
||||||
|
aGUID.Assign(tmp);
|
||||||
|
|
||||||
|
return SetItemGUID(aItemId, aGUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavBookmarks::SetItemGUID(PRInt64 aItemId, const nsAString &aGUID)
|
||||||
|
{
|
||||||
|
PRInt64 checkId;
|
||||||
|
GetItemIdForGUID(aGUID, &checkId);
|
||||||
|
if (checkId != -1)
|
||||||
|
return NS_ERROR_INVALID_ARG; // invalid GUID, already exists
|
||||||
|
|
||||||
|
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
|
||||||
|
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
return annosvc->SetItemAnnotationString(aItemId, GUID_ANNO, aGUID, 0,
|
||||||
|
nsIAnnotationService::EXPIRE_NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNavBookmarks::GetItemIdForGUID(const nsAString &aGUID, PRInt64 *aItemId)
|
||||||
|
{
|
||||||
|
mozStorageStatementScoper scoper(mDBGetItemIdForGUID);
|
||||||
|
nsresult rv = mDBGetItemIdForGUID->BindStringParameter(0, aGUID);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
PRBool hasMore = PR_FALSE;
|
||||||
|
rv = mDBGetItemIdForGUID->ExecuteStep(&hasMore);
|
||||||
|
if (NS_FAILED(rv) || ! hasMore) {
|
||||||
|
*aItemId = -1;
|
||||||
|
return NS_OK; // not found: return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// found, get the itemId
|
||||||
|
return mDBGetItemIdForGUID->GetInt64(0, aItemId);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsAString &aTitle)
|
nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsAString &aTitle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -138,6 +138,9 @@ private:
|
||||||
|
|
||||||
mozIStorageConnection* DBConn() { return History()->GetStorageConnection(); }
|
mozIStorageConnection* DBConn() { return History()->GetStorageConnection(); }
|
||||||
|
|
||||||
|
nsString mGUIDBase;
|
||||||
|
PRInt32 mItemCount;
|
||||||
|
|
||||||
nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
|
nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
|
||||||
PRInt64 mRoot;
|
PRInt64 mRoot;
|
||||||
PRInt64 mBookmarksRoot;
|
PRInt64 mBookmarksRoot;
|
||||||
|
@ -201,6 +204,8 @@ private:
|
||||||
static const PRInt32 kGetItemPropertiesIndex_DateAdded;
|
static const PRInt32 kGetItemPropertiesIndex_DateAdded;
|
||||||
static const PRInt32 kGetItemPropertiesIndex_LastModified;
|
static const PRInt32 kGetItemPropertiesIndex_LastModified;
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageStatement> mDBGetItemIdForGUID;
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> mDBGetRedirectDestinations;
|
nsCOMPtr<mozIStorageStatement> mDBGetRedirectDestinations;
|
||||||
|
|
||||||
// keywords
|
// keywords
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||||
|
/* ***** 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 Bug 360134 (item guids) unit test code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Dan Mills <thunder@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 ***** */
|
||||||
|
|
||||||
|
// Get bookmark service
|
||||||
|
try {
|
||||||
|
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||||
|
getService(Ci.nsINavBookmarksService);
|
||||||
|
} catch(ex) {
|
||||||
|
do_throw("Could not get nav-bookmarks-service\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// main
|
||||||
|
function run_test() {
|
||||||
|
var URI = uri("http://foo.tld.com/");
|
||||||
|
var folderId = bmsvc.createFolder(bmsvc.placesRoot, "test folder",
|
||||||
|
bmsvc.DEFAULT_INDEX);
|
||||||
|
var bookmarkId = bmsvc.insertBookmark(folderId, URI, bmsvc.DEFAULT_INDEX, "a title");
|
||||||
|
var separatorId = bmsvc.insertSeparator(folderId, bmsvc.DEFAULT_INDEX);
|
||||||
|
|
||||||
|
// get & uniqueness
|
||||||
|
do_check_eq(bmsvc.getItemGUID(bookmarkId), bmsvc.getItemGUID(bookmarkId));
|
||||||
|
|
||||||
|
do_check_neq(bmsvc.getItemGUID(folderId), bmsvc.getItemGUID(bookmarkId));
|
||||||
|
do_check_neq(bmsvc.getItemGUID(folderId), "");
|
||||||
|
|
||||||
|
do_check_neq(bmsvc.getItemGUID(separatorId), bmsvc.getItemGUID(bookmarkId));
|
||||||
|
do_check_neq(bmsvc.getItemGUID(separatorId), "");
|
||||||
|
|
||||||
|
// set
|
||||||
|
bmsvc.setItemGUID(bookmarkId, "asdf123");
|
||||||
|
do_check_eq(bmsvc.getItemGUID(bookmarkId), "asdf123");
|
||||||
|
|
||||||
|
bmsvc.setItemGUID(folderId, "123asdf");
|
||||||
|
do_check_eq(bmsvc.getItemGUID(folderId), "123asdf");
|
||||||
|
|
||||||
|
try {
|
||||||
|
bmsvc.setItemGUID(bookmarkId, "123asdf"); // should fail
|
||||||
|
} catch (e) {
|
||||||
|
do_check_eq(e.result, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GUID -> itemId
|
||||||
|
do_check_eq(bmsvc.getItemIdForGUID("asdf123"), bookmarkId);
|
||||||
|
do_check_eq(bmsvc.getItemIdForGUID("123asdf"), folderId);
|
||||||
|
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче