324958 - folder undo delete back to previous folder id. Implement folder removal transaction in bookmarks service itself, using private methods to restore folders back to previous ids. Adjust fe to use new api. r=brettw (C++), annie.sullivan (JS)

Original committer: beng%bengoodger.com
Original revision: 1.56
Original date: 2006/03/25 00:46:09
This commit is contained in:
benjamin%smedbergs.us 2006-07-18 14:48:53 +00:00
Родитель 1b35b6df12
Коммит e1220c4389
1 изменённых файлов: 99 добавлений и 31 удалений

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

@ -283,6 +283,9 @@ nsNavBookmarks::InitTables(mozIStorageConnection* aDBConn)
// bookmark folders will reference a random folder. This slows down inserts
// a little bit, which is why we don't always use it, but bookmark folders
// are not created very often.
// NOTE: The folder undo code depends on the autoincrement behavior because
// it must be able to undo deleting of a folder back to the old folder ID,
// which we assume has not been taken by something else.
rv = aDBConn->TableExists(NS_LITERAL_CSTRING("moz_bookmarks_folders"), &exists);
NS_ENSURE_SUCCESS(rv, rv);
if (! exists) {
@ -962,6 +965,22 @@ nsNavBookmarks::ReplaceItem(PRInt64 aFolder, nsIURI *aItem, nsIURI *aNewItem)
NS_IMETHODIMP
nsNavBookmarks::CreateFolder(PRInt64 aParent, const nsAString &aName,
PRInt32 aIndex, PRInt64 *aNewFolder)
{
return CreateFolderWithID(-1, aParent, aName, aIndex, aNewFolder);
}
NS_IMETHODIMP
nsNavBookmarks::CreateContainer(PRInt64 aParent, const nsAString &aName,
PRInt32 aIndex, const nsAString &aType,
PRInt64 *aNewFolder)
{
return CreateContainerWithID(-1, aParent, aName, aIndex, aType, aNewFolder);
}
nsresult
nsNavBookmarks::CreateFolderWithID(PRInt64 aFolder, PRInt64 aParent,
const nsAString& aName, PRInt32 aIndex,
PRInt64* aNewFolder)
{
mozIStorageConnection *dbConn = DBConn();
mozStorageTransaction transaction(dbConn, PR_FALSE);
@ -973,13 +992,24 @@ nsNavBookmarks::CreateFolder(PRInt64 aParent, const nsAString &aName,
{
nsCOMPtr<mozIStorageStatement> statement;
if (aFolder == -1) {
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_folders (name, type) VALUES (?1, null)"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindStringParameter(0, aName);
NS_ENSURE_SUCCESS(rv, rv);
}
else {
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("INSERT INTO moz_bookmarks_folders (id, name, type) VALUES (?1, ?2, null)"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64Parameter(0, aFolder);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindStringParameter(1, aName);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
}
@ -1009,13 +1039,13 @@ nsNavBookmarks::CreateFolder(PRInt64 aParent, const nsAString &aName,
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::CreateContainer(PRInt64 aParent, const nsAString &aName,
PRInt32 aIndex, const nsAString &aType,
PRInt64 *aNewFolder)
nsresult
nsNavBookmarks::CreateContainerWithID(PRInt64 aFolder, PRInt64 aParent,
const nsAString &aName, PRInt32 aIndex,
const nsAString &aType, PRInt64 *aNewFolder)
{
// Containers are wrappers around read-only folders, with a specific type.
nsresult rv = CreateFolder(aParent, aName, aIndex, aNewFolder);
nsresult rv = CreateFolderWithID(aFolder, aParent, aName, aIndex, aNewFolder);
NS_ENSURE_SUCCESS(rv, rv);
// Set the type.
@ -1035,7 +1065,6 @@ nsNavBookmarks::CreateContainer(PRInt64 aParent, const nsAString &aName,
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex)
{
@ -1165,6 +1194,31 @@ nsNavBookmarks::RemoveChildAt(PRInt64 aParent, PRInt32 aIndex)
return NS_OK;
}
nsresult
nsNavBookmarks::GetParentAndIndexOfFolder(PRInt64 aFolder, PRInt64* aParent,
PRInt32* aIndex)
{
nsCAutoString buffer;
buffer.AssignLiteral("SELECT parent, position FROM moz_bookmarks WHERE folder_child = ");
buffer.AppendInt(aFolder);
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = DBConn()->CreateStatement(buffer, getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
PRBool results;
rv = statement->ExecuteStep(&results);
NS_ENSURE_SUCCESS(rv, rv);
if (!results) {
return NS_ERROR_INVALID_ARG; // folder is not in the hierarchy
}
*aParent = statement->AsInt64(0);
*aIndex = statement->AsInt32(1);
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::RemoveFolder(PRInt64 aFolder)
{
@ -1186,32 +1240,16 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolder)
mozIStorageConnection *dbConn = DBConn();
mozStorageTransaction transaction(dbConn, PR_FALSE);
nsCAutoString buffer;
buffer.AssignLiteral("SELECT parent, position FROM moz_bookmarks WHERE folder_child = ");
buffer.AppendInt(aFolder);
PRInt64 parent;
PRInt32 index;
{
nsCOMPtr<mozIStorageStatement> statement;
rv = dbConn->CreateStatement(buffer, getter_AddRefs(statement));
rv = GetParentAndIndexOfFolder(aFolder, &parent, &index);
NS_ENSURE_SUCCESS(rv, rv);
PRBool results;
rv = statement->ExecuteStep(&results);
NS_ENSURE_SUCCESS(rv, rv);
if (!results) {
return NS_ERROR_INVALID_ARG; // folder is not in the hierarchy
}
parent = statement->AsInt64(0);
index = statement->AsInt32(1);
}
// Remove all of the folder's children
RemoveFolderChildren(aFolder);
// Remove the folder from its parent
nsCAutoString buffer;
buffer.AssignLiteral("DELETE FROM moz_bookmarks WHERE folder_child = ");
buffer.AppendInt(aFolder);
rv = dbConn->ExecuteSimpleSQL(buffer);
@ -1235,6 +1273,36 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolder)
return NS_OK;
}
NS_IMPL_ISUPPORTS1(nsNavBookmarks::RemoveFolderTransaction, nsITransaction)
NS_IMETHODIMP
nsNavBookmarks::GetRemoveFolderTransaction(PRInt64 aFolder, nsITransaction** aResult)
{
// Create and initialize a RemoveFolderTransaction object that can be used to
// recreate the folder safely later.
nsAutoString title;
nsresult rv = GetFolderTitle(aFolder, title);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 parent;
PRInt32 index;
rv = GetParentAndIndexOfFolder(aFolder, &parent, &index);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString type;
rv = GetFolderType(aFolder, type);
NS_ENSURE_SUCCESS(rv, rv);
RemoveFolderTransaction* rft =
new RemoveFolderTransaction(aFolder, parent, title, index, type);
if (!rft)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult = rft);
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolder)