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

This commit is contained in:
Ben Turner 2010-08-26 13:57:30 -07:00
parent d004d346ff
commit 4e765058fe
6 changed files with 212 additions and 4 deletions

View File

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

View File

@ -146,6 +146,25 @@ public:
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
{
public:
@ -920,7 +939,16 @@ IDBObjectStore::Add(const jsval &aValue,
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;
Key key;
@ -1032,6 +1060,32 @@ IDBObjectStore::Remove(nsIVariant* aKey,
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
IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
PRUint16 aDirection,
@ -1607,6 +1661,36 @@ RemoveHelper::GetSuccessResult(nsIWritableVariant* aResult)
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
OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{

View File

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

View File

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

View File

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

View File

@ -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>