зеркало из 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.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(c3307160-525d-4d3c-9d75-b4f13a9ca05d)]
|
||||
[scriptable, uuid(630dcd21-402c-44cd-8336-78bff3efc5f3)]
|
||||
interface nsINavBookmarksService : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -327,6 +327,35 @@ interface nsINavBookmarksService : nsISupports
|
|||
*/
|
||||
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.
|
||||
* @param aItemId
|
||||
|
|
|
@ -48,6 +48,9 @@
|
|||
#include "nsAnnotationService.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "prmem.h"
|
||||
#include "prprf.h"
|
||||
|
||||
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ID = 0;
|
||||
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_Type = 1;
|
||||
|
@ -76,10 +79,11 @@ nsNavBookmarks* nsNavBookmarks::sInstance = nsnull;
|
|||
|
||||
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
|
||||
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
|
||||
#define GUID_ANNO NS_LITERAL_CSTRING("placesInternal/GUID")
|
||||
|
||||
nsNavBookmarks::nsNavBookmarks()
|
||||
: 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!");
|
||||
sInstance = this;
|
||||
|
@ -185,6 +189,13 @@ nsNavBookmarks::Init()
|
|||
getter_AddRefs(mDBGetItemProperties));
|
||||
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
|
||||
// input = page ID, time threshold; output = unique ID input has redirected to
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
|
@ -228,6 +239,17 @@ nsNavBookmarks::Init()
|
|||
getter_AddRefs(mDBGetURIForKeyword));
|
||||
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();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -1697,6 +1719,56 @@ nsNavBookmarks::GetItemLastModified(PRInt64 aItemId, PRTime *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
|
||||
nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsAString &aTitle)
|
||||
{
|
||||
|
|
|
@ -138,6 +138,9 @@ private:
|
|||
|
||||
mozIStorageConnection* DBConn() { return History()->GetStorageConnection(); }
|
||||
|
||||
nsString mGUIDBase;
|
||||
PRInt32 mItemCount;
|
||||
|
||||
nsMaybeWeakPtrArray<nsINavBookmarkObserver> mObservers;
|
||||
PRInt64 mRoot;
|
||||
PRInt64 mBookmarksRoot;
|
||||
|
@ -201,6 +204,8 @@ private:
|
|||
static const PRInt32 kGetItemPropertiesIndex_DateAdded;
|
||||
static const PRInt32 kGetItemPropertiesIndex_LastModified;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetItemIdForGUID;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> mDBGetRedirectDestinations;
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче