This commit is contained in:
Ben Turner 2010-08-26 14:14:44 -07:00
Родитель 8060e40213 cc122a0efc
Коммит bc8155e5d5
20 изменённых файлов: 479 добавлений и 201 удалений

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

@ -37,15 +37,12 @@
*
* ***** END LICENSE BLOCK ***** */
// XXX remove once we can get jsvals out of XPIDL
#include "jscntxt.h"
#include "jsapi.h"
#include "IDBCursor.h"
#include "nsIIDBDatabaseException.h"
#include "nsIVariant.h"
#include "jscntxt.h"
#include "mozilla/storage.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
@ -484,7 +481,8 @@ IDBCursor::Update(const jsval &aValue,
rv = json->EncodeFromJSVal(clone.jsval_addr(), aCx, jsonValue);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<UpdateHelper> helper =
@ -518,7 +516,8 @@ IDBCursor::Remove(nsIIDBRequest** _retval)
const Key& key = mData[mDataIndex].key;
NS_ASSERTION(!key.IsUnset() && !key.IsNull(), "Bad key!");
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<RemoveHelper> helper =

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

@ -364,6 +364,7 @@ NS_IMETHODIMP
IDBDatabase::CreateObjectStore(const nsAString& aName,
const nsAString& aKeyPath,
PRBool aAutoIncrement,
JSContext* aCx,
nsIIDBRequest** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -388,9 +389,6 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
return NS_ERROR_ALREADY_INITIALIZED;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsTArray<nsString> objectStores;
nsString* name = objectStores.AppendElement(aName);
if (!name) {
@ -399,9 +397,14 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
}
nsRefPtr<IDBTransaction> transaction =
IDBTransaction::Create(this, objectStores, nsIIDBTransaction::READ_WRITE,
IDBTransaction::Create(aCx, this, objectStores,
nsIIDBTransaction::READ_WRITE,
kDefaultDatabaseTimeoutSeconds);
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<CreateObjectStoreHelper> helper =
new CreateObjectStoreHelper(transaction, request, aName, keyPath,
!!aAutoIncrement);
@ -414,6 +417,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
NS_IMETHODIMP
IDBDatabase::RemoveObjectStore(const nsAString& aName,
JSContext* aCx,
nsIIDBRequest** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -439,12 +443,14 @@ IDBDatabase::RemoveObjectStore(const nsAString& aName,
}
nsRefPtr<IDBTransaction> transaction =
IDBTransaction::Create(this, storesToOpen, nsIIDBTransaction::READ_WRITE,
IDBTransaction::Create(aCx, this, storesToOpen,
nsIIDBTransaction::READ_WRITE,
kDefaultDatabaseTimeoutSeconds);
NS_ENSURE_TRUE(transaction, NS_ERROR_FAILURE);
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<RemoveObjectStoreHelper> helper =
new RemoveObjectStoreHelper(transaction, request, aName);
@ -457,6 +463,7 @@ IDBDatabase::RemoveObjectStore(const nsAString& aName,
NS_IMETHODIMP
IDBDatabase::SetVersion(const nsAString& aVersion,
JSContext* aCx,
nsIIDBRequest** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -467,15 +474,17 @@ IDBDatabase::SetVersion(const nsAString& aVersion,
return NS_ERROR_UNEXPECTED;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
// Lock the whole database
nsTArray<nsString> storesToOpen;
nsRefPtr<IDBTransaction> transaction =
IDBTransaction::Create(this, storesToOpen, IDBTransaction::FULL_LOCK,
IDBTransaction::Create(aCx, this, storesToOpen, IDBTransaction::FULL_LOCK,
kDefaultDatabaseTimeoutSeconds);
NS_ENSURE_TRUE(transaction, NS_ERROR_FAILURE);
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<SetVersionHelper> helper =
new SetVersionHelper(transaction, request, aVersion);
nsresult rv = helper->DispatchToTransactionPool();
@ -489,6 +498,7 @@ NS_IMETHODIMP
IDBDatabase::Transaction(nsIVariant* aStoreNames,
PRUint16 aMode,
PRUint32 aTimeout,
JSContext* aCx,
PRUint8 aOptionalArgCount,
nsIIDBTransaction** _retval)
{
@ -613,7 +623,7 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
}
nsRefPtr<IDBTransaction> transaction =
IDBTransaction::Create(this, storesToOpen, aMode,
IDBTransaction::Create(aCx, this, storesToOpen, aMode,
kDefaultDatabaseTimeoutSeconds);
NS_ENSURE_TRUE(transaction, NS_ERROR_FAILURE);
@ -624,6 +634,7 @@ IDBDatabase::Transaction(nsIVariant* aStoreNames,
NS_IMETHODIMP
IDBDatabase::ObjectStore(const nsAString& aName,
PRUint16 aMode,
JSContext* aCx,
PRUint8 aOptionalArgCount,
nsIIDBObjectStore** _retval)
{
@ -661,7 +672,7 @@ IDBDatabase::ObjectStore(const nsAString& aName,
}
nsRefPtr<IDBTransaction> transaction =
IDBTransaction::Create(this, storesToOpen, aMode,
IDBTransaction::Create(aCx, this, storesToOpen, aMode,
kDefaultDatabaseTimeoutSeconds);
NS_ENSURE_TRUE(transaction, NS_ERROR_FAILURE);

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

@ -41,6 +41,7 @@
#include "nsIIDBDatabaseException.h"
#include "nsILocalFile.h"
#include "nsIScriptContext.h"
#include "mozilla/storage.h"
#include "nsAppDirectoryServiceDefs.h"
@ -49,6 +50,7 @@
#include "nsDirectoryServiceUtils.h"
#include "nsDOMClassInfo.h"
#include "nsHashKeys.h"
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCID.h"
@ -59,7 +61,7 @@
#include "IDBKeyRange.h"
#include "LazyIdleThread.h"
#define DB_SCHEMA_VERSION 2
#define DB_SCHEMA_VERSION 3
USING_INDEXEDDB_NAMESPACE
@ -163,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"
");"
@ -518,6 +519,7 @@ DOMCI_DATA(IDBFactory, IDBFactory)
NS_IMETHODIMP
IDBFactory::Open(const nsAString& aName,
const nsAString& aDescription,
JSContext* aCx,
nsIIDBRequest** _retval)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -540,7 +542,21 @@ IDBFactory::Open(const nsAString& aName,
NS_ENSURE_SUCCESS(rv, nsnull);
}
nsRefPtr<IDBRequest> request = GenerateRequest();
nsIScriptContext* context = GetScriptContextFromJSContext(aCx);
NS_ENSURE_STATE(context);
nsCOMPtr<nsPIDOMWindow> innerWindow;
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(context->GetGlobalObject());
if (window) {
innerWindow = window->GetCurrentInnerWindow();
}
NS_ENSURE_STATE(innerWindow);
nsRefPtr<IDBRequest> request = GenerateRequest(context, innerWindow);
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<LazyIdleThread> thread(new LazyIdleThread(kDefaultThreadTimeoutMS,
nsnull));

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

@ -319,12 +319,14 @@ IDBIndex::Get(nsIVariant* aKey,
return NS_ERROR_INVALID_ARG;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetHelper> helper =
new GetHelper(mObjectStore->Transaction(), request, key, mId, mUnique,
mAutoIncrement);
new GetHelper(transaction, request, key, mId, mUnique, mAutoIncrement);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -346,11 +348,14 @@ IDBIndex::GetObject(nsIVariant* aKey,
return NS_ERROR_INVALID_ARG;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetObjectHelper> helper =
new GetObjectHelper(mObjectStore->Transaction(), request, key, mId, mUnique,
new GetObjectHelper(transaction, request, key, mId, mUnique,
mAutoIncrement);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -379,12 +384,15 @@ IDBIndex::GetAll(nsIVariant* aKey,
aLimit = PR_UINT32_MAX;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetAllHelper> helper =
new GetAllHelper(mObjectStore->Transaction(), request, key, mId, mUnique,
mAutoIncrement, aLimit);
new GetAllHelper(transaction, request, key, mId, mUnique, mAutoIncrement,
aLimit);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -412,12 +420,15 @@ IDBIndex::GetAllObjects(nsIVariant* aKey,
aLimit = PR_UINT32_MAX;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetAllObjectsHelper> helper =
new GetAllObjectsHelper(mObjectStore->Transaction(), request, key, mId,
mUnique, mAutoIncrement, aLimit);
new GetAllObjectsHelper(transaction, request, key, mId, mUnique,
mAutoIncrement, aLimit);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -477,13 +488,16 @@ IDBIndex::OpenCursor(nsIIDBKeyRange* aKeyRange,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<OpenCursorHelper> helper =
new OpenCursorHelper(mObjectStore->Transaction(), request, this, mId,
mUnique, mAutoIncrement, leftKey, rightKey,
keyRangeFlags, aDirection, aPreload);
new OpenCursorHelper(transaction, request, this, mId, mUnique,
mAutoIncrement, leftKey, rightKey, keyRangeFlags,
aDirection, aPreload);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -544,13 +558,16 @@ IDBIndex::OpenObjectCursor(nsIIDBKeyRange* aKeyRange,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
IDBTransaction* transaction = mObjectStore->Transaction();
nsRefPtr<IDBRequest> request =
GenerateRequest(transaction->ScriptContext(), transaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<OpenObjectCursorHelper> helper =
new OpenObjectCursorHelper(mObjectStore->Transaction(), request, this, mId,
mUnique, mAutoIncrement, leftKey, rightKey,
keyRangeFlags, aDirection, aPreload);
new OpenObjectCursorHelper(transaction, request, this, mId, mUnique,
mAutoIncrement, leftKey, rightKey, keyRangeFlags,
aDirection, aPreload);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);

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

@ -76,12 +76,11 @@ public:
const nsAString& aValue,
const Key& aKey,
bool aAutoIncrement,
bool aCreate,
bool aOverwrite,
nsTArray<IndexUpdateInfo>& aIndexUpdateInfo)
: AsyncConnectionHelper(aTransaction, aRequest), mOSID(aObjectStoreID),
mKeyPath(aKeyPath), mValue(aValue), mKey(aKey),
mAutoIncrement(aAutoIncrement), mCreate(aCreate), mOverwrite(aOverwrite)
mAutoIncrement(aAutoIncrement), mOverwrite(aOverwrite)
{
mIndexUpdateInfo.SwapElements(aIndexUpdateInfo);
}
@ -101,7 +100,6 @@ private:
nsString mValue;
Key mKey;
const bool mAutoIncrement;
const bool mCreate;
const bool mOverwrite;
nsTArray<IndexUpdateInfo> mIndexUpdateInfo;
};
@ -148,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:
@ -839,7 +856,8 @@ IDBObjectStore::Get(nsIVariant* aKey,
return NS_ERROR_ILLEGAL_VALUE;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
nsRefPtr<IDBRequest> request =
GenerateRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetHelper> helper =
@ -889,7 +907,8 @@ IDBObjectStore::GetAll(nsIIDBKeyRange* aKeyRange,
NS_ENSURE_SUCCESS(rv, rv);
}
nsRefPtr<IDBRequest> request = GenerateRequest();
nsRefPtr<IDBRequest> request =
GenerateRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<GetAllHelper> helper =
@ -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;
@ -935,12 +963,13 @@ IDBObjectStore::Add(const jsval &aValue,
return NS_ERROR_ILLEGAL_VALUE;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<AddHelper> helper =
new AddHelper(mTransaction, request, mId, mKeyPath, jsonValue, key,
!!mAutoIncrement, true, false, updateInfo);
!!mAutoIncrement, false, updateInfo);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -949,7 +978,7 @@ IDBObjectStore::Add(const jsval &aValue,
}
NS_IMETHODIMP
IDBObjectStore::Modify(const jsval &aValue,
IDBObjectStore::Put(const jsval &aValue,
const jsval &aKey,
JSContext* aCx,
PRUint8 aOptionalArgCount,
@ -980,57 +1009,13 @@ IDBObjectStore::Modify(const jsval &aValue,
return NS_ERROR_ILLEGAL_VALUE;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<AddHelper> helper =
new AddHelper(mTransaction, request, mId, mKeyPath, jsonValue, key,
!!mAutoIncrement, false, true, updateInfo);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
IDBObjectStore::AddOrModify(const jsval &aValue,
const jsval &aKey,
JSContext* aCx,
PRUint8 aOptionalArgCount,
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;
}
jsval keyval = (aOptionalArgCount >= 1) ? aKey : JSVAL_VOID;
nsString jsonValue;
Key key;
nsTArray<IndexUpdateInfo> updateInfo;
nsresult rv = GetAddInfo(aCx, aValue, keyval, jsonValue, key, updateInfo);
if (NS_FAILED(rv)) {
return rv;
}
if (key.IsUnset() || key.IsNull()) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<AddHelper> helper =
new AddHelper(mTransaction, request, mId, mKeyPath, jsonValue, key,
!!mAutoIncrement, true, true, updateInfo);
!!mAutoIncrement, true, updateInfo);
rv = helper->DispatchToTransactionPool();
NS_ENSURE_SUCCESS(rv, rv);
@ -1062,7 +1047,8 @@ IDBObjectStore::Remove(nsIVariant* aKey,
return NS_ERROR_ILLEGAL_VALUE;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<RemoveHelper> helper =
@ -1074,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,
@ -1127,7 +1139,8 @@ IDBObjectStore::OpenCursor(nsIIDBKeyRange* aKeyRange,
return NS_ERROR_NOT_IMPLEMENTED;
}
nsRefPtr<IDBRequest> request = GenerateRequest();
nsRefPtr<IDBRequest> request =
GenerateRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<OpenCursorHelper> helper =
@ -1178,7 +1191,8 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
return NS_ERROR_UNEXPECTED;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<CreateIndexHelper> helper =
@ -1257,7 +1271,9 @@ IDBObjectStore::RemoveIndex(const nsAString& aName,
return NS_ERROR_NOT_AVAILABLE;
}
nsRefPtr<IDBRequest> request = GenerateWriteRequest();
nsRefPtr<IDBRequest> request =
GenerateWriteRequest(mTransaction->ScriptContext(), mTransaction->Owner());
NS_ENSURE_TRUE(request, NS_ERROR_FAILURE);
nsRefPtr<RemoveIndexHelper> helper =
new RemoveIndexHelper(mTransaction, request, aName, this);
@ -1341,7 +1357,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
// Now we add it to the database (or update, depending on our variables).
stmt = mTransaction->AddStatement(mCreate, mayOverwrite, mAutoIncrement);
stmt = mTransaction->AddStatement(true, mayOverwrite, mAutoIncrement);
NS_ENSURE_TRUE(stmt, nsIIDBDatabaseException::UNKNOWN_ERR);
mozStorageStatementScoper scoper(stmt);
@ -1371,7 +1387,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
rv = stmt->Execute();
if (NS_FAILED(rv)) {
if (mCreate && mayOverwrite && rv == NS_ERROR_STORAGE_CONSTRAINT) {
if (mayOverwrite && rv == NS_ERROR_STORAGE_CONSTRAINT) {
scoper.Abandon();
stmt = mTransaction->AddStatement(false, true, mAutoIncrement);
@ -1409,7 +1425,7 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
// If we are supposed to generate a key, get the new id.
if (mAutoIncrement && mCreate && !mOverwrite) {
if (mAutoIncrement && !mOverwrite) {
#ifdef DEBUG
PRInt64 oldKey = unsetKey ? 0 : mKey.IntValue();
#endif
@ -1645,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)
{

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

@ -45,6 +45,8 @@
#include "nsComponentManagerUtils.h"
#include "nsDOMClassInfo.h"
#include "nsDOMJSUtils.h"
#include "nsPIDOMWindow.h"
#include "nsStringGlue.h"
#include "nsThreadUtils.h"
@ -52,14 +54,29 @@
USING_INDEXEDDB_NAMESPACE
IDBRequest::IDBRequest(Generator* aGenerator,
bool aWriteRequest)
: mGenerator(aGenerator),
mReadyState(nsIIDBRequest::INITIAL),
mAborted(false),
mWriteRequest(aWriteRequest)
already_AddRefed<IDBRequest>
IDBRequest::Generator::GenerateRequestInternal(nsIScriptContext* aScriptContext,
nsPIDOMWindow* aOwner,
PRBool aWriteRequest)
{
NS_ASSERTION(aGenerator, "Null generator!");
if (!aScriptContext || !aOwner) {
NS_ERROR("Null context and owner!");
return nsnull;
}
nsRefPtr<IDBRequest> request(new IDBRequest());
request->mGenerator = this;
request->mWriteRequest = aWriteRequest;
request->mScriptContext = aScriptContext;
request->mOwner = aOwner;
if (!mLiveRequests.AppendElement(request)) {
NS_ERROR("Append failed!");
return nsnull;
}
return request.forget();
}
IDBRequest::~IDBRequest()
@ -84,7 +101,7 @@ IDBRequest::Abort()
return NS_ERROR_NOT_AVAILABLE;
}
mAborted = true;
mAborted = PR_TRUE;
mReadyState = nsIIDBRequest::DONE;
return NS_OK;
}

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

@ -49,6 +49,9 @@
#include "nsDOMEventTargetHelper.h"
#include "nsCycleCollectionParticipant.h"
class nsIScriptContext;
class nsPIDOMWindow;
BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
@ -72,20 +75,16 @@ public:
NS_ASSERTION(mLiveRequests.IsEmpty(), "Huh?!");
}
IDBRequest* GenerateRequest() {
IDBRequest* request = new IDBRequest(this, false);
if (!mLiveRequests.AppendElement(request)) {
NS_ERROR("Append failed!");
}
return request;
already_AddRefed<IDBRequest>
GenerateRequest(nsIScriptContext* aScriptContext,
nsPIDOMWindow* aOwner) {
return GenerateRequestInternal(aScriptContext, aOwner, PR_FALSE);
}
IDBRequest* GenerateWriteRequest() {
IDBRequest* request = new IDBRequest(this, true);
if (!mLiveRequests.AppendElement(request)) {
NS_ERROR("Append failed!");
}
return request;
already_AddRefed<IDBRequest>
GenerateWriteRequest(nsIScriptContext* aScriptContext,
nsPIDOMWindow* aOwner) {
return GenerateRequestInternal(aScriptContext, aOwner, PR_TRUE);
}
void NoteDyingRequest(IDBRequest* aRequest) {
@ -94,6 +93,11 @@ public:
}
private:
already_AddRefed<IDBRequest>
GenerateRequestInternal(nsIScriptContext* aScriptContext,
nsPIDOMWindow* aOwner,
PRBool aWriteRequest);
// XXXbent Assuming infallible nsTArray here, make sure it lands!
nsAutoTArray<IDBRequest*, 1> mLiveRequests;
};
@ -113,8 +117,11 @@ public:
private:
// Only called by IDBRequestGenerator::Generate().
IDBRequest(Generator* aGenerator,
bool aWriteRequest);
IDBRequest()
: mReadyState(nsIIDBRequest::INITIAL),
mAborted(PR_FALSE),
mWriteRequest(PR_FALSE)
{ }
nsRefPtr<Generator> mGenerator;
@ -122,11 +129,12 @@ protected:
// Called by Release().
~IDBRequest();
PRUint16 mReadyState;
PRBool mAborted;
PRBool mWriteRequest;
nsRefPtr<nsDOMEventListenerWrapper> mOnSuccessListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
PRUint16 mReadyState;
PRPackedBool mAborted;
PRPackedBool mWriteRequest;
};
END_INDEXEDDB_NAMESPACE

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

@ -39,8 +39,11 @@
#include "IDBTransaction.h"
#include "nsIScriptContext.h"
#include "mozilla/storage.h"
#include "nsDOMClassInfo.h"
#include "nsPIDOMWindow.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
@ -72,7 +75,8 @@ DoomCachedStatements(const nsACString& aQuery,
// static
already_AddRefed<IDBTransaction>
IDBTransaction::Create(IDBDatabase* aDatabase,
IDBTransaction::Create(JSContext* aCx,
IDBDatabase* aDatabase,
nsTArray<nsString>& aObjectStoreNames,
PRUint16 aMode,
PRUint32 aTimeout)
@ -95,6 +99,21 @@ IDBTransaction::Create(IDBDatabase* aDatabase,
return nsnull;
}
nsIScriptContext* context = GetScriptContextFromJSContext(aCx);
if (context) {
transaction->mScriptContext = context;
nsCOMPtr<nsPIDOMWindow> window =
do_QueryInterface(context->GetGlobalObject());
if (window) {
transaction->mOwner = window->GetCurrentInnerWindow();
}
}
if (!transaction->mOwner) {
NS_ERROR("Couldn't get script context and owner!");
return nsnull;
}
return transaction.forget();
}

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

@ -53,7 +53,9 @@
#include "nsHashKeys.h"
#include "nsInterfaceHashtable.h"
class nsIScriptContext;
class nsIThread;
class nsPIDOMWindow;
BEGIN_INDEXEDDB_NAMESPACE
@ -78,7 +80,8 @@ public:
nsDOMEventTargetHelper)
static already_AddRefed<IDBTransaction>
Create(IDBDatabase* aDatabase,
Create(JSContext* aCx,
IDBDatabase* aDatabase,
nsTArray<nsString>& aObjectStoreNames,
PRUint16 aMode,
PRUint32 aTimeout);
@ -144,6 +147,16 @@ public:
enum { FULL_LOCK = nsIIDBTransaction::SNAPSHOT_READ + 1 };
nsIScriptContext* ScriptContext()
{
return mScriptContext;
}
nsPIDOMWindow* Owner()
{
return mOwner;
}
private:
IDBTransaction();
~IDBTransaction();

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

@ -43,6 +43,7 @@
#include "nsIProgrammingLanguage.h"
#include "jsapi.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"

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

@ -45,6 +45,10 @@ interface nsIIDBRequest;
interface nsIIDBTransaction;
interface nsIDOMDOMStringList;
%{C++
#include "jsapi.h"
%}
/**
* IDBDatabase interface. See
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
@ -61,24 +65,27 @@ interface nsIIDBDatabase : nsISupports
readonly attribute nsIDOMDOMStringList objectStoreNames;
[implicit_jscontext]
nsIIDBRequest
createObjectStore(in AString name,
in AString keyPath,
[optional /* false */] in boolean autoIncrement);
[implicit_jscontext]
nsIIDBRequest
removeObjectStore(in AString name);
[implicit_jscontext]
nsIIDBRequest
setVersion(in AString version);
[optional_argc]
[optional_argc, implicit_jscontext]
nsIIDBTransaction
transaction(in nsIVariant storeNames, // js array of strings
[optional /* READ_ONLY */] in unsigned short mode,
[optional /* 5000ms */] in unsigned long timeout);
[optional_argc]
[optional_argc, implicit_jscontext]
nsIIDBObjectStore
objectStore(in AString name,
[optional /* READ_ONLY */] in unsigned short mode);

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

@ -44,6 +44,10 @@ interface nsIIDBKeyRange;
interface nsIIDBRequest;
interface nsIVariant;
%{C++
#include "jsapi.h"
%}
/**
* Interface that defines the indexedDB property on a window. See
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
@ -52,6 +56,7 @@ interface nsIVariant;
[scriptable, uuid(a1e1dbd1-53a7-490a-ab6f-aa55809dd867)]
interface nsIIDBFactory : nsISupports
{
[implicit_jscontext]
nsIIDBRequest
open(in AString name,
in AString description);

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

@ -82,19 +82,17 @@ interface nsIIDBObjectStore : nsISupports
// Success fires IDBTransactionEvent, result == key
[implicit_jscontext, optional_argc]
nsIIDBRequest
modify(in jsval value,
[optional /* undefined */] in jsval key);
// Success fires IDBTransactionEvent, result == key
[implicit_jscontext, optional_argc]
nsIIDBRequest
addOrModify(in jsval value,
put(in jsval value,
[optional /* undefined */] in jsval key);
// Success fires IDBTransactionEvent, result == null
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]

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

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

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

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

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

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

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

@ -282,7 +282,7 @@
is(event.result, "bar", "Update succeeded");
request = objectStore.modify("foo", sortedKeys[4]);
request = objectStore.put("foo", sortedKeys[4]);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;

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

@ -37,21 +37,21 @@
let key1 = event.result;
request = objectStore.modify({}, key1);
request = objectStore.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "modify gave the same key back");
is(event.result, key1, "put gave the same key back");
let key2 = 10;
request = objectStore.addOrModify({}, key2);
request = objectStore.put({}, key2);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "modify gave the same key back");
is(event.result, key2, "put gave the same key back");
key2 = 100;
@ -60,22 +60,22 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "modify gave the same key back");
is(event.result, key2, "put gave the same key back");
try {
objectStore.addOrModify({});
ok(false, "addOrModify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "addOrModify with no key threw");
ok(true, "put with no key threw");
}
try {
objectStore.modify({});
ok(false, "modify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "modify with no key threw");
ok(true, "put with no key threw");
}
try {
@ -102,19 +102,19 @@
}
try {
objectStore.addOrModify({});
ok(false, "addOrModify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "addOrModify with no key threw");
ok(true, "put with no key threw");
}
try {
objectStore.modify({});
ok(false, "modify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "modify with no key threw");
ok(true, "put with no key threw");
}
try {
@ -141,19 +141,19 @@
}
try {
objectStore.addOrModify({});
ok(false, "addOrModify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "addOrModify with no key threw");
ok(true, "put with no key threw");
}
try {
objectStore.modify({});
ok(false, "modify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "modify with no key threw");
ok(true, "put with no key threw");
}
try {
@ -173,19 +173,19 @@
is(event.result, key1, "add gave back the same key");
request = objectStore.modify({id:10});
request = objectStore.put({id:10});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "modify gave back the same key");
is(event.result, key1, "put gave back the same key");
request = objectStore.addOrModify({id:10});
request = objectStore.put({id:10});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "addOrModify gave back the same key");
is(event.result, key1, "put gave back the same key");
request = objectStore.add({id:10});
request.onerror = grabEventAndContinueHandler;
@ -200,19 +200,19 @@
is(typeof(event.result), "string", "Good generated key");
try {
objectStore.modify({}, null);
ok(false, "modify with null key should throw!");
objectStore.put({}, null);
ok(false, "put with null key should throw!");
}
catch (e) {
ok(true, "modify with null key threw");
ok(true, "put with null key threw");
}
try {
objectStore.addOrModify({}, null);
ok(false, "addOrModify with null key should throw!");
objectStore.put({}, null);
ok(false, "put with null key should throw!");
}
catch (e) {
ok(true, "addOrModify with null key threw");
ok(true, "put with null key threw");
}
try {
@ -237,36 +237,36 @@
key1 = event.result;
request = objectStore.modify({id:key1});
request = objectStore.put({id:key1});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "modify gave the same key back");
is(event.result, key1, "put gave the same key back");
key2 = 10;
request = objectStore.addOrModify({id:key2});
request = objectStore.put({id:key2});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "modify gave the same key back");
is(event.result, key2, "put gave the same key back");
try {
objectStore.addOrModify({});
ok(false, "addOrModify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "addOrModify with no key threw");
ok(true, "put with no key threw");
}
try {
objectStore.modify({});
ok(false, "modify with no key should throw!");
objectStore.put({});
ok(false, "put with no key should throw!");
}
catch (e) {
ok(true, "modify with no key threw");
ok(true, "put with no key threw");
}
try {

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

@ -60,7 +60,7 @@
request = db.transaction([osName], READ_WRITE)
.objectStore(osName)
.addOrModify({}, key1);
.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
@ -68,7 +68,7 @@
}
yield;
request = db.objectStore(osName, READ_WRITE).addOrModify({}, key2);
request = db.objectStore(osName, READ_WRITE).put({}, key2);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
@ -78,7 +78,7 @@
request = db.transaction([osName], READ_WRITE)
.objectStore(osName)
.modify({}, key1);
.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
@ -86,7 +86,7 @@
}
yield;
request = db.objectStore(osName, READ_WRITE).modify({}, key1);
request = db.objectStore(osName, READ_WRITE).put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
@ -129,7 +129,7 @@
}
try {
request = db.transaction([osName]).objectStore(osName).addOrModify({});
request = db.transaction([osName]).objectStore(osName).put({});
ok(false, "Adding or modifying a readonly transaction should fail!");
}
catch (e) {
@ -137,7 +137,7 @@
}
try {
request = db.objectStore(osName).addOrModify({});
request = db.objectStore(osName).put({});
ok(false, "Adding or modifying a readonly transaction should fail!");
}
catch (e) {
@ -145,7 +145,7 @@
}
try {
request = db.transaction([osName]).objectStore(osName).modify({}, key1);
request = db.transaction([osName]).objectStore(osName).put({}, key1);
ok(false, "Modifying a readonly transaction should fail!");
}
catch (e) {
@ -153,7 +153,7 @@
}
try {
request = db.objectStore(osName).modify({}, key1);
request = db.objectStore(osName).put({}, key1);
ok(false, "Modifying a readonly transaction should fail!");
}
catch (e) {

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

@ -91,19 +91,19 @@
}
try {
objectStore.modify({}, 1);
objectStore.put({}, 1);
ok(false, "Should have thrown");
}
catch (e) {
ok(true, "Modify threw");
ok(true, "Put threw");
}
try {
objectStore.addOrModify({}, 1);
objectStore.put({}, 1);
ok(false, "Should have thrown");
}
catch (e) {
ok(true, "AddOrModify threw");
ok(true, "Put threw");
}
try {