Bug 589355 - 'IndexedDB: Add IDBObjectStore::Clear'. r=sicking

This commit is contained in:
Ben Turner 2010-08-26 13:57:30 -07:00
Родитель 248eae0489
Коммит cc122a0efc
6 изменённых файлов: 212 добавлений и 4 удалений

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

@ -61,7 +61,7 @@
#include "IDBKeyRange.h" #include "IDBKeyRange.h"
#include "LazyIdleThread.h" #include "LazyIdleThread.h"
#define DB_SCHEMA_VERSION 2 #define DB_SCHEMA_VERSION 3
USING_INDEXEDDB_NAMESPACE USING_INDEXEDDB_NAMESPACE
@ -165,10 +165,9 @@ CreateTables(mozIStorageConnection* aDBConn)
// Table `ai_object_data` // Table `ai_object_data`
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING( rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE ai_object_data (" "CREATE TABLE ai_object_data ("
"id INTEGER, " "id INTEGER PRIMARY KEY AUTOINCREMENT, "
"object_store_id INTEGER NOT NULL, " "object_store_id INTEGER NOT NULL, "
"data TEXT NOT NULL, " "data TEXT NOT NULL, "
"PRIMARY KEY (id), "
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE " "FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
"CASCADE" "CASCADE"
");" ");"

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

@ -146,6 +146,25 @@ public:
PRUint16 GetSuccessResult(nsIWritableVariant* aResult); PRUint16 GetSuccessResult(nsIWritableVariant* aResult);
}; };
class ClearHelper : public AsyncConnectionHelper
{
public:
ClearHelper(IDBTransaction* aTransaction,
IDBRequest* aRequest,
PRInt64 aObjectStoreID,
bool aAutoIncrement)
: AsyncConnectionHelper(aTransaction, aRequest), mOSID(aObjectStoreID),
mAutoIncrement(aAutoIncrement)
{ }
PRUint16 DoDatabaseWork(mozIStorageConnection* aConnection);
protected:
// In-params.
const PRInt64 mOSID;
const bool mAutoIncrement;
};
class OpenCursorHelper : public AsyncConnectionHelper class OpenCursorHelper : public AsyncConnectionHelper
{ {
public: public:
@ -920,7 +939,16 @@ IDBObjectStore::Add(const jsval &aValue,
return NS_ERROR_OBJECT_IS_IMMUTABLE; return NS_ERROR_OBJECT_IS_IMMUTABLE;
} }
jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID; jsval keyval;
if (aOptionalArgCount >= 1) {
keyval = aKey;
if (mAutoIncrement && JSVAL_IS_NULL(keyval)) {
return NS_ERROR_ILLEGAL_VALUE;
}
}
else {
keyval = JSVAL_VOID;
}
nsString jsonValue; nsString jsonValue;
Key key; Key key;
@ -1032,6 +1060,32 @@ IDBObjectStore::Remove(nsIVariant* aKey,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
IDBObjectStore::Clear(nsIIDBRequest** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mTransaction->TransactionIsOpen()) {
return NS_ERROR_UNEXPECTED;
}
if (mMode != nsIIDBTransaction::READ_WRITE) {
return NS_ERROR_OBJECT_IS_IMMUTABLE;
}
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<ClearHelper> helper =
new ClearHelper(mTransaction, request, mId, !!mAutoIncrement);
nsresult rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange, IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
PRUint16 aDirection, PRUint16 aDirection,
@ -1607,6 +1661,36 @@ RemoveHelper::GetSuccessResult(nsIWritableVariant* aResult)
return OK; return OK;
} }
PRUint16
ClearHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{
NS_PRECONDITION(aConnection, "Passed a null connection!");
nsCString table;
if (mAutoIncrement) {
table.AssignLiteral("ai_object_data");
}
else {
table.AssignLiteral("object_data");
}
nsCString query = NS_LITERAL_CSTRING("DELETE FROM ") + table +
NS_LITERAL_CSTRING(" WHERE object_store_id = :osid");
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
nsresult rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("osid"), mOSID);
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, nsIIDBDatabaseException::UNKNOWN_ERR);
return OK;
}
PRUint16 PRUint16
OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection) OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{ {

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

@ -89,6 +89,10 @@ interface nsIIDBObjectStore : nsISupports
nsIIDBRequest nsIIDBRequest
remove(in nsIVariant key); remove(in nsIVariant key);
// Success fires IDBTransactionEvent, result == null
nsIIDBRequest
clear();
// Success fires IDBTransactionEvent, result == IDBCursor or // Success fires IDBTransactionEvent, result == IDBCursor or
// IDBCursorPreloadedRequest if preload == true. result == null if no match. // IDBCursorPreloadedRequest if preload == true. result == null if no match.
[optional_argc] [optional_argc]

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

@ -48,6 +48,7 @@ _TEST_FILES = \
helpers.js \ helpers.js \
test_add_twice_failure.html \ test_add_twice_failure.html \
test_bad_keypath.html \ test_bad_keypath.html \
test_clear.html \
test_create_index.html \ test_create_index.html \
test_create_objectStore.html \ test_create_objectStore.html \
test_cursors.html \ test_cursors.html \

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

@ -23,6 +23,13 @@ function grabEventAndContinueHandler(event)
testGenerator.send(event); testGenerator.send(event);
} }
function continueToNextStep()
{
SimpleTest.executeSoon(function() {
testGenerator.next();
});
}
function errorHandler(event) function errorHandler(event)
{ {
ok(false, "indexedDB error (" + event.code + "): " + event.message); ok(false, "indexedDB error (" + event.code + "): " + event.message);

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

@ -0,0 +1,113 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<html>
<head>
<title>Indexed Database Property Test</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript;version=1.7">
function testSteps()
{
const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
const name = window.location.pathname;
const description = "My Test Database";
const entryCount = 1000;
let request = moz_indexedDB.open(name, description);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
request = db.createObjectStore("foo", "", true);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
event.transaction.oncomplete = continueToNextStep;
let objectStore = event.result;
let firstKey;
for (let i = 0; i < entryCount; i++) {
request = objectStore.add({});
request.onerror = errorHandler;
if (!i) {
request.onsuccess = function(event) {
firstKey = event.result;
};
}
}
yield;
isnot(firstKey, undefined, "got first key");
let seenEntryCount = 0;
request = db.objectStore("foo").openCursor();
request.onerror = errorHandler;
request.onsuccess = function(event) {
let cursor = event.result;
if (cursor) {
seenEntryCount++;
cursor.continue();
}
else {
continueToNextStep();
}
}
yield;
is(seenEntryCount, entryCount, "Correct entry count");
try {
db.objectStore("foo").clear();
ok(false, "clear should throw on READ_ONLY transactions");
}
catch (e) {
ok(true, "clear should throw on READ_ONLY transactions");
}
request = db.objectStore("foo", READ_WRITE).clear();
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.result === null, "Correct event.result");
request = db.objectStore("foo").openCursor();
request.onerror = errorHandler;
request.onsuccess = function(event) {
let cursor = event.result;
if (cursor) {
ok(false, "Shouldn't have any entries");
}
continueToNextStep();
}
yield;
request = db.objectStore("foo", READ_WRITE).add({});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
isnot(event.result, firstKey, "Got a different key");
finishTest();
yield;
}
</script>
<script type="text/javascript;version=1.7" src="helpers.js"></script>
</head>
<body onload="runTest();"></body>
</html>