Bug 914687 - API for presetting GUIDs on bookmarks. r=mak. sr=gavin

This commit is contained in:
Asaf Romano 2013-11-19 17:13:27 +02:00
Родитель 0cf4101913
Коммит bd6038d32e
4 изменённых файлов: 145 добавлений и 49 удалений

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

@ -223,7 +223,7 @@ interface nsINavBookmarkObserver : nsISupports
* folders. A URI in history can be contained in one or more such folders.
*/
[scriptable, uuid(2299598b-8d83-4b67-9b13-b6d4707dcf7b)]
[scriptable, uuid(A78EA368-E28E-462E-897A-26606D4DDCE6)]
interface nsINavBookmarksService : nsISupports
{
/**
@ -276,13 +276,19 @@ interface nsINavBookmarksService : nsISupports
* The index to insert at, or DEFAULT_INDEX to append
* @param aTitle
* The title for the new bookmark
* @param [optional] aGUID
* The GUID to be set for the new item. If not set, a new GUID is
* generated. Unless you've a very sound reason, such as an undo
* manager implementation, do not pass this argument.
* @return The ID of the newly-created bookmark.
*
* @note aTitle will be truncated to TITLE_LENGTH_MAX and
* aURI will be truncated to URI_LENGTH_MAX.
* @throws if aGUID is malformed.
*/
long long insertBookmark(in long long aParentId, in nsIURI aURI,
in long aIndex, in AUTF8String aTitle);
in long aIndex, in AUTF8String aTitle,
[optional] in ACString aGUID);
/**
* Removes a child item. Used to delete a bookmark or separator.
@ -299,10 +305,16 @@ interface nsINavBookmarksService : nsISupports
* The name of the new folder
* @param aIndex
* The index to insert at, or DEFAULT_INDEX to append
* @param [optional] aGUID
* The GUID to be set for the new item. If not set, a new GUID is
* generated. Unless you've a very sound reason, such as an undo
* manager implementation, do not pass this argument.
* @return The ID of the newly-inserted folder.
* @throws if aGUID is malformed.
*/
long long createFolder(in long long aParentFolder, in AUTF8String name,
in long index);
in long index,
[optional] in ACString aGUID);
/**
* Gets an undo-able transaction for removing a folder from the bookmarks
@ -352,9 +364,15 @@ interface nsINavBookmarksService : nsISupports
* The id of the parent folder
* @param aIndex
* The separator's index under folder, or DEFAULT_INDEX to append
* @param [optional] aGUID
* The GUID to be set for the new item. If not set, a new GUID is
* generated. Unless you've a very sound reason, such as an undo
* manager implementation, do not pass this argument.
* @return The ID of the new separator.
* @throws if aGUID is malformed.
*/
long long insertSeparator(in long long aParentId, in long aIndex);
long long insertSeparator(in long long aParentId, in long aIndex,
[optional] in ACString aGUID);
/**
* Get the itemId given the containing folder and the index.

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

@ -438,7 +438,7 @@ nsNavBookmarks::InsertBookmarkInDB(int64_t aPlaceId,
"dateAdded, lastModified, guid) "
"VALUES (:item_id, :page_id, :item_type, :parent, :item_index, "
":item_title, :date_added, :last_modified, "
"GENERATE_GUID())"
"IFNULL(:item_guid, GENERATE_GUID()))"
);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scoper(stmt);
@ -482,6 +482,17 @@ nsNavBookmarks::InsertBookmarkInDB(int64_t aPlaceId,
}
NS_ENSURE_SUCCESS(rv, rv);
// Could use IsEmpty because our callers check for GUID validity,
// but it doesn't hurt.
if (_guid.Length() == 12) {
MOZ_ASSERT(IsValidGUID(_guid));
rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("item_guid"), _guid);
}
else {
rv = stmt->BindNullByName(NS_LITERAL_CSTRING("item_guid"));
}
NS_ENSURE_SUCCESS(rv, rv);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
@ -551,12 +562,16 @@ nsNavBookmarks::InsertBookmark(int64_t aFolder,
nsIURI* aURI,
int32_t aIndex,
const nsACString& aTitle,
const nsACString& aGUID,
int64_t* aNewBookmarkId)
{
NS_ENSURE_ARG(aURI);
NS_ENSURE_ARG_POINTER(aNewBookmarkId);
NS_ENSURE_ARG_MIN(aIndex, nsINavBookmarksService::DEFAULT_INDEX);
if (!aGUID.IsEmpty() && !IsValidGUID(aGUID))
return NS_ERROR_INVALID_ARG;
mozStorageTransaction transaction(mDB->MainConn(), false);
nsNavHistory* history = nsNavHistory::GetHistoryService();
@ -585,7 +600,7 @@ nsNavBookmarks::InsertBookmark(int64_t aFolder,
*aNewBookmarkId = -1;
PRTime dateAdded = PR_Now();
nsAutoCString guid;
nsAutoCString guid(aGUID);
nsCString title;
TruncateTitle(aTitle, title);
@ -753,18 +768,22 @@ nsNavBookmarks::RemoveItem(int64_t aItemId)
NS_IMETHODIMP
nsNavBookmarks::CreateFolder(int64_t aParent, const nsACString& aName,
int32_t aIndex, int64_t* aNewFolder)
int32_t aIndex, const nsACString& aGUID,
int64_t* aNewFolder)
{
// NOTE: aParent can be null for root creation, so not checked
NS_ENSURE_ARG_POINTER(aNewFolder);
if (!aGUID.IsEmpty() && !IsValidGUID(aGUID))
return NS_ERROR_INVALID_ARG;
// CreateContainerWithID returns the index of the new folder, but that's not
// used here. To avoid any risk of corrupting data should this function
// be changed, we'll use a local variable to hold it. The true argument
// will cause notifications to be sent to bookmark observers.
int32_t localIndex = aIndex;
nsresult rv = CreateContainerWithID(-1, aParent, aName, true, &localIndex,
aNewFolder);
aGUID, aNewFolder);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -815,6 +834,7 @@ nsNavBookmarks::CreateContainerWithID(int64_t aItemId,
const nsACString& aTitle,
bool aIsBookmarkFolder,
int32_t* aIndex,
const nsACString& aGUID,
int64_t* aNewFolder)
{
NS_ENSURE_ARG_MIN(*aIndex, nsINavBookmarksService::DEFAULT_INDEX);
@ -840,7 +860,7 @@ nsNavBookmarks::CreateContainerWithID(int64_t aItemId,
*aNewFolder = aItemId;
PRTime dateAdded = PR_Now();
nsAutoCString guid;
nsAutoCString guid(aGUID);
nsCString title;
TruncateTitle(aTitle, title);
@ -865,12 +885,16 @@ nsNavBookmarks::CreateContainerWithID(int64_t aItemId,
NS_IMETHODIMP
nsNavBookmarks::InsertSeparator(int64_t aParent,
int32_t aIndex,
const nsACString& aGUID,
int64_t* aNewItemId)
{
NS_ENSURE_ARG_MIN(aParent, 1);
NS_ENSURE_ARG_MIN(aIndex, nsINavBookmarksService::DEFAULT_INDEX);
NS_ENSURE_ARG_POINTER(aNewItemId);
if (!aGUID.IsEmpty() && !IsValidGUID(aGUID))
return NS_ERROR_INVALID_ARG;
// Get the correct index for insertion. This also ensures the parent exists.
int32_t index, folderCount;
int64_t grandParentId;
@ -895,7 +919,7 @@ nsNavBookmarks::InsertSeparator(int64_t aParent,
// Set a NULL title rather than an empty string.
nsCString voidString;
voidString.SetIsVoid(true);
nsAutoCString guid;
nsAutoCString guid(aGUID);
PRTime dateAdded = PR_Now();
rv = InsertBookmarkInDB(-1, SEPARATOR, aParent, index, voidString, dateAdded,
0, folderGuid, grandParentId, nullptr,

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

@ -184,6 +184,7 @@ public:
const nsACString& aTitle,
bool aIsBookmarkFolder,
int32_t* aIndex,
const nsACString& aGUID,
int64_t* aNewFolder);
/**
@ -396,7 +397,7 @@ private:
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
int64_t newFolder;
return bookmarks->CreateContainerWithID(mID, mParent, mTitle, true,
&mIndex, &newFolder);
&mIndex, EmptyCString(), &newFolder);
}
NS_IMETHOD RedoTransaction() {

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

@ -22,13 +22,7 @@ add_task(function test_addBookmarksAndCheckGuids() {
let s1 = bmsvc.insertSeparator(folder, bmsvc.DEFAULT_INDEX);
let f1 = bmsvc.createFolder(folder, "test folder 2", bmsvc.DEFAULT_INDEX);
let options = histsvc.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
let query = histsvc.getNewQuery();
query.setFolders([folder], 1);
let result = histsvc.executeQuery(query, options);
let root = result.root;
root.containerOpen = true;
let root = PlacesUtils.getFolderContents(folder).root;
do_check_eq(root.childCount, 5);
// check bookmark guids
@ -71,13 +65,7 @@ add_task(function test_updateBookmarksAndCheckGuids() {
bmsvc.DEFAULT_INDEX, "1 title");
let f1 = bmsvc.createFolder(folder, "test folder 2", bmsvc.DEFAULT_INDEX);
let options = histsvc.getNewQueryOptions();
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS;
let query = histsvc.getNewQuery();
query.setFolders([folder], 1);
let result = histsvc.executeQuery(query, options);
let root = result.root;
root.containerOpen = true;
let root = PlacesUtils.getFolderContents(folder).root;
do_check_eq(root.childCount, 2);
// ensure the bookmark and page guids remain the same after modifing other property.
@ -110,18 +98,83 @@ add_task(function test_addVisitAndCheckGuid() {
let options = histsvc.getNewQueryOptions();
let query = histsvc.getNewQuery();
query.uri = sourceURI;
result = histsvc.executeQuery(query, options);
let root = result.root;
let root = histsvc.executeQuery(query, options).root;
root.containerOpen = true;
do_check_eq(root.childCount, 1);
pageGuidZero = root.getChild(0).pageGuid;
do_check_eq(pageGuidZero.length, 12);
do_check_valid_places_guid(root.getChild(0).pageGuid);
do_check_eq(root.getChild(0).bookmarkGuid, "");
root.containerOpen = false;
yield promiseClearHistory();
});
add_task(function test_addItemsWithInvalidGUIDsFails() {
const INVALID_GUID = "XYZ";
try {
bmsvc.createFolder(bmsvc.placesRoot, "XYZ folder",
bmsvc.DEFAULT_INDEX, INVALID_GUID);
do_throw("Adding a folder with an invalid guid should fail");
}
catch(ex) { }
let folder = bmsvc.createFolder(bmsvc.placesRoot, "test folder",
bmsvc.DEFAULT_INDEX);
try {
bmsvc.insertBookmark(folder, uri("http://test.tld"), bmsvc.DEFAULT_INDEX,
"title", INVALID_GUID);
do_throw("Adding a bookmark with an invalid guid should fail");
}
catch(ex) { }
try {
bmsvc.insertSeparator(folder, bmsvc.DEFAULT_INDEX, INVALID_GUID);
do_throw("Adding a separator with an invalid guid should fail");
}
catch(ex) { }
remove_all_bookmarks();
});
add_task(function test_addItemsWithGUIDs() {
const FOLDER_GUID = "FOLDER--GUID";
const BOOKMARK_GUID = "BM------GUID";
const SEPARATOR_GUID = "SEP-----GUID";
let folder = bmsvc.createFolder(bmsvc.placesRoot, "test folder",
bmsvc.DEFAULT_INDEX, FOLDER_GUID);
bmsvc.insertBookmark(folder, uri("http://test1.com/"), bmsvc.DEFAULT_INDEX,
"1 title", BOOKMARK_GUID);
bmsvc.insertSeparator(folder, bmsvc.DEFAULT_INDEX, SEPARATOR_GUID);
let root = PlacesUtils.getFolderContents(folder).root;
do_check_eq(root.childCount, 2);
do_check_eq(root.bookmarkGuid, FOLDER_GUID);
do_check_eq(root.getChild(0).bookmarkGuid, BOOKMARK_GUID);
do_check_eq(root.getChild(1).bookmarkGuid, SEPARATOR_GUID);
root.containerOpen = false;
remove_all_bookmarks();
});
add_task(function test_emptyGUIDIgnored() {
let folder = bmsvc.createFolder(bmsvc.placesRoot, "test folder",
bmsvc.DEFAULT_INDEX, "");
do_check_valid_places_guid(PlacesUtils.getFolderContents(folder)
.root.bookmarkGuid);
remove_all_bookmarks();
});
add_task(function test_usingSameGUIDFails() {
const GUID = "XYZXYZXYZXYZ";
bmsvc.createFolder(bmsvc.placesRoot, "test folder",
bmsvc.DEFAULT_INDEX, GUID);
try {
bmsvc.createFolder(bmsvc.placesRoot, "test folder 2",
bmsvc.DEFAULT_INDEX, GUID);
do_throw("Using the same guid twice should fail");
}
catch(ex) { }
remove_all_bookmarks();
});