зеркало из https://github.com/mozilla/gecko-dev.git
Bug 687361: Implement the new IndexedDB setVersion API. r=bent
--HG-- rename : dom/indexedDB/nsIIDBVersionChangeRequest.idl => dom/indexedDB/nsIIDBOpenDBRequest.idl
This commit is contained in:
Родитель
4533393482
Коммит
bee1f84b2f
|
@ -646,6 +646,7 @@ GK_ATOM(onbeforepaste, "onbeforepaste")
|
||||||
GK_ATOM(onbeforeprint, "onbeforeprint")
|
GK_ATOM(onbeforeprint, "onbeforeprint")
|
||||||
GK_ATOM(onbeforescriptexecute, "onbeforescriptexecute")
|
GK_ATOM(onbeforescriptexecute, "onbeforescriptexecute")
|
||||||
GK_ATOM(onbeforeunload, "onbeforeunload")
|
GK_ATOM(onbeforeunload, "onbeforeunload")
|
||||||
|
GK_ATOM(onblocked, "onblocked")
|
||||||
GK_ATOM(onblur, "onblur")
|
GK_ATOM(onblur, "onblur")
|
||||||
GK_ATOM(onbroadcast, "onbroadcast")
|
GK_ATOM(onbroadcast, "onbroadcast")
|
||||||
GK_ATOM(onchange, "onchange")
|
GK_ATOM(onchange, "onchange")
|
||||||
|
@ -741,6 +742,7 @@ GK_ATOM(ontouchcancel, "ontouchcancel")
|
||||||
GK_ATOM(ontransitionend, "ontransitionend")
|
GK_ATOM(ontransitionend, "ontransitionend")
|
||||||
GK_ATOM(onunderflow, "onunderflow")
|
GK_ATOM(onunderflow, "onunderflow")
|
||||||
GK_ATOM(onunload, "onunload")
|
GK_ATOM(onunload, "onunload")
|
||||||
|
GK_ATOM(onupgradeneeded, "onupgradeneeded")
|
||||||
GK_ATOM(open, "open")
|
GK_ATOM(open, "open")
|
||||||
GK_ATOM(optgroup, "optgroup")
|
GK_ATOM(optgroup, "optgroup")
|
||||||
GK_ATOM(optimum, "optimum")
|
GK_ATOM(optimum, "optimum")
|
||||||
|
|
|
@ -95,9 +95,11 @@ DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR, "A mutation operation was at
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR, "A request was placed against a transaction which is currently not active, or which is finished.")
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR, "A request was placed against a transaction which is currently not active, or which is finished.")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, "A request was aborted, for example through a call to IDBTransaction.abort.")
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, "A request was aborted, for example through a call to IDBTransaction.abort.")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR, "A mutation operation was attempted in a READ_ONLY transaction.")
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR, "A mutation operation was attempted in a READ_ONLY transaction.")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR, "The operation failed because the database was prevented from taking an action. The operation might be able to succeed if the application performs some recovery steps and retries the entire transaction. For example, there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database.")
|
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TRANSIENT_ERR, "The operation failed because of some temporary problems. The failed operation might be able to succeed when the operation is retried without any intervention by application-level functionality.")
|
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR, "A lock for the transaction could not be obtained in a reasonable time.")
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR, "A lock for the transaction could not be obtained in a reasonable time.")
|
||||||
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR, "The current transaction exceeded its quota limitations.")
|
||||||
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_VERSION_ERR, "The operation failed because the stored database is a higher version than the version requested.")
|
||||||
|
|
||||||
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR, "The operation failed because the database was prevented from taking an action. The operation might be able to succeed if the application performs some recovery steps and retries the entire transaction. For example, there was not enough remaining storage space, or the storage quota was reached and the user declined to give more space to the database.")
|
||||||
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR, "The current transaction was automatically rolled back by the database because of deadlock or other transaction serialization failures.")
|
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR, "The current transaction was automatically rolled back by the database because of deadlock or other transaction serialization failures.")
|
||||||
|
|
||||||
/* DOM error codes defined by us */
|
/* DOM error codes defined by us */
|
||||||
|
|
|
@ -1505,7 +1505,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeEvent, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(IDBVersionChangeRequest, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(IDBOpenDBRequest, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(IDBDatabaseException, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(IDBDatabaseException, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
@ -4087,8 +4087,8 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
DOM_CLASSINFO_MAP_BEGIN(IDBVersionChangeRequest, nsIIDBVersionChangeRequest)
|
DOM_CLASSINFO_MAP_BEGIN(IDBOpenDBRequest, nsIIDBOpenDBRequest)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIIDBVersionChangeRequest)
|
DOM_CLASSINFO_MAP_ENTRY(nsIIDBOpenDBRequest)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIIDBRequest)
|
DOM_CLASSINFO_MAP_ENTRY(nsIIDBRequest)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
|
@ -506,7 +506,7 @@ DOMCI_CLASS(IDBCursorWithValue)
|
||||||
DOMCI_CLASS(IDBKeyRange)
|
DOMCI_CLASS(IDBKeyRange)
|
||||||
DOMCI_CLASS(IDBIndex)
|
DOMCI_CLASS(IDBIndex)
|
||||||
DOMCI_CLASS(IDBVersionChangeEvent)
|
DOMCI_CLASS(IDBVersionChangeEvent)
|
||||||
DOMCI_CLASS(IDBVersionChangeRequest)
|
DOMCI_CLASS(IDBOpenDBRequest)
|
||||||
DOMCI_CLASS(IDBDatabaseException)
|
DOMCI_CLASS(IDBDatabaseException)
|
||||||
|
|
||||||
DOMCI_CLASS(Touch)
|
DOMCI_CLASS(Touch)
|
||||||
|
|
|
@ -100,10 +100,12 @@
|
||||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,7)
|
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,7)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_ABORT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,8)
|
#define NS_ERROR_DOM_INDEXEDDB_ABORT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,8)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,9)
|
#define NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,9)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,10)
|
#define NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,10)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_TRANSIENT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,11)
|
#define NS_ERROR_DOM_INDEXEDDB_QUOTA_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,11)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,12)
|
#define NS_ERROR_DOM_INDEXEDDB_VERSION_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,12)
|
||||||
#define NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,13)
|
|
||||||
|
#define NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,1001)
|
||||||
|
#define NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,1002)
|
||||||
|
|
||||||
/* DOM error codes defined by us */
|
/* DOM error codes defined by us */
|
||||||
|
|
||||||
|
|
|
@ -120,10 +120,31 @@ ConvertCloneBuffersToArrayInternal(
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
HelperBase::WrapNative(JSContext* aCx,
|
||||||
|
nsISupports* aNative,
|
||||||
|
jsval* aResult)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aCx, "Null context!");
|
||||||
|
NS_ASSERTION(aNative, "Null pointer!");
|
||||||
|
NS_ASSERTION(aResult, "Null pointer!");
|
||||||
|
NS_ASSERTION(mRequest, "Null request!");
|
||||||
|
|
||||||
|
JSObject* global =
|
||||||
|
static_cast<JSObject*>(mRequest->ScriptContext()->GetNativeGlobal());
|
||||||
|
NS_ENSURE_TRUE(global, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
nsresult rv =
|
||||||
|
nsContentUtils::WrapNative(aCx, global, aNative, aResult);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
AsyncConnectionHelper::AsyncConnectionHelper(IDBDatabase* aDatabase,
|
AsyncConnectionHelper::AsyncConnectionHelper(IDBDatabase* aDatabase,
|
||||||
IDBRequest* aRequest)
|
IDBRequest* aRequest)
|
||||||
: mDatabase(aDatabase),
|
: HelperBase(aRequest),
|
||||||
mRequest(aRequest),
|
mDatabase(aDatabase),
|
||||||
mTimeoutDuration(TimeDuration::FromMilliseconds(kDefaultTimeoutMS)),
|
mTimeoutDuration(TimeDuration::FromMilliseconds(kDefaultTimeoutMS)),
|
||||||
mResultCode(NS_OK),
|
mResultCode(NS_OK),
|
||||||
mDispatched(false)
|
mDispatched(false)
|
||||||
|
@ -133,9 +154,9 @@ AsyncConnectionHelper::AsyncConnectionHelper(IDBDatabase* aDatabase,
|
||||||
|
|
||||||
AsyncConnectionHelper::AsyncConnectionHelper(IDBTransaction* aTransaction,
|
AsyncConnectionHelper::AsyncConnectionHelper(IDBTransaction* aTransaction,
|
||||||
IDBRequest* aRequest)
|
IDBRequest* aRequest)
|
||||||
: mDatabase(aTransaction->mDatabase),
|
: HelperBase(aRequest),
|
||||||
|
mDatabase(aTransaction->mDatabase),
|
||||||
mTransaction(aTransaction),
|
mTransaction(aTransaction),
|
||||||
mRequest(aRequest),
|
|
||||||
mTimeoutDuration(TimeDuration::FromMilliseconds(kDefaultTimeoutMS)),
|
mTimeoutDuration(TimeDuration::FromMilliseconds(kDefaultTimeoutMS)),
|
||||||
mResultCode(NS_OK),
|
mResultCode(NS_OK),
|
||||||
mDispatched(false)
|
mDispatched(false)
|
||||||
|
@ -195,7 +216,7 @@ AsyncConnectionHelper::Run()
|
||||||
gCurrentTransaction = mTransaction;
|
gCurrentTransaction = mTransaction;
|
||||||
|
|
||||||
if (mRequest) {
|
if (mRequest) {
|
||||||
nsresult rv = mRequest->SetDone(this);
|
nsresult rv = mRequest->NotifyHelperCompleted(this);
|
||||||
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
|
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
|
||||||
mResultCode = rv;
|
mResultCode = rv;
|
||||||
}
|
}
|
||||||
|
@ -379,14 +400,19 @@ AsyncConnectionHelper::Init()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsDOMEvent>
|
||||||
|
AsyncConnectionHelper::CreateSuccessEvent()
|
||||||
|
{
|
||||||
|
return CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
AsyncConnectionHelper::OnSuccess()
|
AsyncConnectionHelper::OnSuccess()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(mRequest, "Null request!");
|
NS_ASSERTION(mRequest, "Null request!");
|
||||||
|
|
||||||
nsRefPtr<nsDOMEvent> event =
|
nsRefPtr<nsDOMEvent> event = CreateSuccessEvent();
|
||||||
CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
NS_ERROR("Failed to create event!");
|
NS_ERROR("Failed to create event!");
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
@ -468,27 +494,6 @@ AsyncConnectionHelper::ReleaseMainThreadObjects()
|
||||||
mRequest = nsnull;
|
mRequest = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
AsyncConnectionHelper::WrapNative(JSContext* aCx,
|
|
||||||
nsISupports* aNative,
|
|
||||||
jsval* aResult)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(aCx, "Null context!");
|
|
||||||
NS_ASSERTION(aNative, "Null pointer!");
|
|
||||||
NS_ASSERTION(aResult, "Null pointer!");
|
|
||||||
NS_ASSERTION(mRequest, "Null request!");
|
|
||||||
|
|
||||||
JSObject* global =
|
|
||||||
static_cast<JSObject*>(mRequest->ScriptContext()->GetNativeGlobal());
|
|
||||||
NS_ENSURE_TRUE(global, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
nsresult rv =
|
|
||||||
nsContentUtils::WrapNative(aCx, global, aNative, aResult);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult
|
nsresult
|
||||||
AsyncConnectionHelper::ConvertCloneBuffersToArray(
|
AsyncConnectionHelper::ConvertCloneBuffersToArray(
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
#include "nsIRunnable.h"
|
#include "nsIRunnable.h"
|
||||||
#include "nsIThread.h"
|
#include "nsIThread.h"
|
||||||
|
|
||||||
|
#include "nsDOMEvent.h"
|
||||||
|
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
|
|
||||||
class mozIStorageConnection;
|
class mozIStorageConnection;
|
||||||
|
@ -57,6 +59,33 @@ BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
|
|
||||||
|
// A common base class for AsyncConnectionHelper and OpenDatabaseHelper that
|
||||||
|
// IDBRequest can use.
|
||||||
|
class HelperBase : public nsIRunnable
|
||||||
|
{
|
||||||
|
friend class IDBRequest;
|
||||||
|
public:
|
||||||
|
virtual nsresult GetResultCode() = 0;
|
||||||
|
|
||||||
|
virtual nsresult GetSuccessResult(JSContext* aCx,
|
||||||
|
jsval* aVal) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HelperBase(IDBRequest* aRequest)
|
||||||
|
: mRequest(aRequest)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to wrap a native into a jsval. Uses the global object of the request
|
||||||
|
* to parent the native.
|
||||||
|
*/
|
||||||
|
nsresult WrapNative(JSContext* aCx,
|
||||||
|
nsISupports* aNative,
|
||||||
|
jsval* aResult);
|
||||||
|
|
||||||
|
nsRefPtr<IDBRequest> mRequest;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be subclassed. The subclass must implement DoDatabaseWork. It may then
|
* Must be subclassed. The subclass must implement DoDatabaseWork. It may then
|
||||||
* choose to implement OnSuccess and OnError depending on the needs of the
|
* choose to implement OnSuccess and OnError depending on the needs of the
|
||||||
|
@ -66,11 +95,9 @@ class IDBTransaction;
|
||||||
* and Dispatched from the main thread only. Target thread may not be the main
|
* and Dispatched from the main thread only. Target thread may not be the main
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
class AsyncConnectionHelper : public nsIRunnable,
|
class AsyncConnectionHelper : public HelperBase,
|
||||||
public mozIStorageProgressHandler
|
public mozIStorageProgressHandler
|
||||||
{
|
{
|
||||||
friend class IDBRequest;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIRUNNABLE
|
NS_DECL_NSIRUNNABLE
|
||||||
|
@ -128,6 +155,13 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0;
|
virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the event to be dispatched at the request when
|
||||||
|
* OnSuccess is called. A subclass can override this to fire an event other
|
||||||
|
* than "success" at the request.
|
||||||
|
*/
|
||||||
|
virtual already_AddRefed<nsDOMEvent> CreateSuccessEvent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback is run on the main thread if DoDatabaseWork returned NS_OK.
|
* This callback is run on the main thread if DoDatabaseWork returned NS_OK.
|
||||||
* The default implementation fires a "success" DOM event with its target set
|
* The default implementation fires a "success" DOM event with its target set
|
||||||
|
@ -157,14 +191,6 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void ReleaseMainThreadObjects();
|
virtual void ReleaseMainThreadObjects();
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper to wrap a native into a jsval. Uses the global object of the request
|
|
||||||
* to parent the native.
|
|
||||||
*/
|
|
||||||
nsresult WrapNative(JSContext* aCx,
|
|
||||||
nsISupports* aNative,
|
|
||||||
jsval* aResult);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to make a JS array object out of an array of clone buffers.
|
* Helper to make a JS array object out of an array of clone buffers.
|
||||||
*/
|
*/
|
||||||
|
@ -176,7 +202,6 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
nsRefPtr<IDBDatabase> mDatabase;
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
nsRefPtr<IDBRequest> mRequest;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsCOMPtr<mozIStorageProgressHandler> mOldProgressHandler;
|
nsCOMPtr<mozIStorageProgressHandler> mOldProgressHandler;
|
||||||
|
|
|
@ -150,7 +150,7 @@ CheckPermissionsHelper::Run()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<AsyncConnectionHelper> helper;
|
nsRefPtr<OpenDatabaseHelper> helper;
|
||||||
helper.swap(mHelper);
|
helper.swap(mHelper);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> window;
|
nsCOMPtr<nsIDOMWindow> window;
|
||||||
|
@ -168,7 +168,8 @@ CheckPermissionsHelper::Run()
|
||||||
"Unknown permission!");
|
"Unknown permission!");
|
||||||
|
|
||||||
helper->SetError(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
helper->SetError(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
|
||||||
return helper->Run();
|
|
||||||
|
return helper->RunImmediately();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#define mozilla_dom_indexeddb_checkpermissionshelper_h__
|
#define mozilla_dom_indexeddb_checkpermissionshelper_h__
|
||||||
|
|
||||||
// Only meant to be included in IndexedDB source files, not exported.
|
// Only meant to be included in IndexedDB source files, not exported.
|
||||||
#include "AsyncConnectionHelper.h"
|
#include "OpenDatabaseHelper.h"
|
||||||
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
NS_DECL_NSIOBSERVER
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
CheckPermissionsHelper(AsyncConnectionHelper* aHelper,
|
CheckPermissionsHelper(OpenDatabaseHelper* aHelper,
|
||||||
nsIDOMWindow* aWindow,
|
nsIDOMWindow* aWindow,
|
||||||
const nsAString& aName,
|
const nsAString& aName,
|
||||||
const nsACString& aASCIIOrigin)
|
const nsACString& aASCIIOrigin)
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<AsyncConnectionHelper> mHelper;
|
nsRefPtr<OpenDatabaseHelper> mHelper;
|
||||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||||
nsString mName;
|
nsString mName;
|
||||||
nsCString mASCIIOrigin;
|
nsCString mASCIIOrigin;
|
||||||
|
|
|
@ -68,7 +68,7 @@ struct DatabaseInfo
|
||||||
bool ContainsStoreName(const nsAString& aName);
|
bool ContainsStoreName(const nsAString& aName);
|
||||||
|
|
||||||
nsString name;
|
nsString name;
|
||||||
nsString version;
|
PRUint64 version;
|
||||||
PRUint32 id;
|
PRUint32 id;
|
||||||
nsString filePath;
|
nsString filePath;
|
||||||
PRInt64 nextObjectStoreId;
|
PRInt64 nextObjectStoreId;
|
||||||
|
|
|
@ -72,24 +72,6 @@ mozilla::Mutex* gPromptHelpersMutex = nsnull;
|
||||||
// Protected by gPromptHelpersMutex.
|
// Protected by gPromptHelpersMutex.
|
||||||
nsTArray<nsRefPtr<CheckQuotaHelper> >* gPromptHelpers = nsnull;
|
nsTArray<nsRefPtr<CheckQuotaHelper> >* gPromptHelpers = nsnull;
|
||||||
|
|
||||||
class SetVersionHelper : public AsyncConnectionHelper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SetVersionHelper(IDBTransaction* aTransaction,
|
|
||||||
IDBRequest* aRequest,
|
|
||||||
const nsAString& aVersion)
|
|
||||||
: AsyncConnectionHelper(aTransaction, aRequest), mVersion(aVersion)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
|
||||||
nsresult GetSuccessResult(JSContext* aCx,
|
|
||||||
jsval* aVal);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// In-params
|
|
||||||
nsString mVersion;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CreateObjectStoreHelper : public AsyncConnectionHelper
|
class CreateObjectStoreHelper : public AsyncConnectionHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -502,14 +484,14 @@ IDBDatabase::GetName(nsAString& aName)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
IDBDatabase::GetVersion(nsAString& aVersion)
|
IDBDatabase::GetVersion(PRUint64* aVersion)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
DatabaseInfo* info;
|
DatabaseInfo* info;
|
||||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
||||||
NS_ERROR("This should never fail!");
|
NS_ERROR("This should never fail!");
|
||||||
}
|
}
|
||||||
aVersion.Assign(info->version);
|
*aVersion = info->version;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,48 +669,6 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
IDBDatabase::SetVersion(const nsAString& aVersion,
|
|
||||||
JSContext* aCx,
|
|
||||||
nsIIDBRequest** _retval)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
if (mClosed) {
|
|
||||||
// XXX Update spec for a real error code here.
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
DatabaseInfo* info;
|
|
||||||
if (!DatabaseInfo::Get(mDatabaseId, &info)) {
|
|
||||||
NS_ERROR("This should never fail!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock the whole database.
|
|
||||||
nsTArray<nsString> storesToOpen;
|
|
||||||
nsRefPtr<IDBTransaction> transaction =
|
|
||||||
IDBTransaction::Create(this, storesToOpen, IDBTransaction::VERSION_CHANGE,
|
|
||||||
kDefaultDatabaseTimeoutSeconds, true);
|
|
||||||
NS_ENSURE_TRUE(transaction, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
nsRefPtr<IDBVersionChangeRequest> request =
|
|
||||||
IDBVersionChangeRequest::Create(static_cast<nsIDOMEventTarget*>(this),
|
|
||||||
ScriptContext(), Owner(), transaction);
|
|
||||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
nsRefPtr<SetVersionHelper> helper =
|
|
||||||
new SetVersionHelper(transaction, request, aVersion);
|
|
||||||
|
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
|
||||||
NS_ASSERTION(mgr, "This should never be null!");
|
|
||||||
|
|
||||||
nsresult rv = mgr->SetDatabaseVersion(this, request, aVersion, helper);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
request.forget(_retval);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
IDBDatabase::Transaction(nsIVariant* aStoreNames,
|
||||||
PRUint16 aMode,
|
PRUint16 aMode,
|
||||||
|
@ -933,47 +873,6 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(aConnection, "Passing a null connection!");
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
|
||||||
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
|
||||||
"UPDATE database "
|
|
||||||
"SET version = :version"
|
|
||||||
), getter_AddRefs(stmt));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("version"), mVersion);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
if (NS_FAILED(stmt->Execute())) {
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
SetVersionHelper::GetSuccessResult(JSContext* aCx,
|
|
||||||
jsval* aVal)
|
|
||||||
{
|
|
||||||
DatabaseInfo* info;
|
|
||||||
if (!DatabaseInfo::Get(mDatabase->Id(), &info)) {
|
|
||||||
NS_ERROR("This should never fail!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
info->version = mVersion;
|
|
||||||
|
|
||||||
nsresult rv = WrapNative(aCx, NS_ISUPPORTS_CAST(nsIDOMEventTarget*,
|
|
||||||
mTransaction),
|
|
||||||
aVal);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
CreateObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
CreateObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,9 +103,10 @@ mozilla::dom::indexedDB::CreateGenericEventRunnable(const nsAString& aType,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<nsIDOMEvent>
|
already_AddRefed<nsDOMEvent>
|
||||||
IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
|
IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
|
||||||
const nsAString& aVersion)
|
PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion)
|
||||||
{
|
{
|
||||||
nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent());
|
nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent());
|
||||||
|
|
||||||
|
@ -115,7 +116,8 @@ IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
|
||||||
rv = event->SetTrusted(true);
|
rv = event->SetTrusted(true);
|
||||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||||
|
|
||||||
event->mVersion = aVersion;
|
event->mOldVersion = aOldVersion;
|
||||||
|
event->mNewVersion = aNewVersion;
|
||||||
|
|
||||||
nsDOMEvent* result;
|
nsDOMEvent* result;
|
||||||
event.forget(&result);
|
event.forget(&result);
|
||||||
|
@ -125,10 +127,12 @@ IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
|
||||||
// static
|
// static
|
||||||
already_AddRefed<nsIRunnable>
|
already_AddRefed<nsIRunnable>
|
||||||
IDBVersionChangeEvent::CreateRunnableInternal(const nsAString& aType,
|
IDBVersionChangeEvent::CreateRunnableInternal(const nsAString& aType,
|
||||||
const nsAString& aVersion,
|
PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion,
|
||||||
nsIDOMEventTarget* aTarget)
|
nsIDOMEventTarget* aTarget)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMEvent> event = CreateInternal(aType, aVersion);
|
nsRefPtr<nsDOMEvent> event =
|
||||||
|
CreateInternal(aType, aOldVersion, aNewVersion);
|
||||||
NS_ENSURE_TRUE(event, nsnull);
|
NS_ENSURE_TRUE(event, nsnull);
|
||||||
|
|
||||||
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
|
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
|
||||||
|
@ -146,8 +150,17 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||||
DOMCI_DATA(IDBVersionChangeEvent, IDBVersionChangeEvent)
|
DOMCI_DATA(IDBVersionChangeEvent, IDBVersionChangeEvent)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
IDBVersionChangeEvent::GetVersion(nsAString& aVersion)
|
IDBVersionChangeEvent::GetOldVersion(PRUint64* aOldVersion)
|
||||||
{
|
{
|
||||||
aVersion.Assign(mVersion);
|
NS_ENSURE_ARG_POINTER(aOldVersion);
|
||||||
|
*aOldVersion = mOldVersion;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
IDBVersionChangeEvent::GetNewVersion(PRUint64* aNewVersion)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aNewVersion);
|
||||||
|
*aNewVersion = mNewVersion;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#define TIMEOUT_EVT_STR "timeout"
|
#define TIMEOUT_EVT_STR "timeout"
|
||||||
#define VERSIONCHANGE_EVT_STR "versionchange"
|
#define VERSIONCHANGE_EVT_STR "versionchange"
|
||||||
#define BLOCKED_EVT_STR "blocked"
|
#define BLOCKED_EVT_STR "blocked"
|
||||||
|
#define UPGRADENEEDED_EVT_STR "upgradeneeded"
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
|
@ -75,48 +76,65 @@ public:
|
||||||
NS_FORWARD_TO_NSDOMEVENT
|
NS_FORWARD_TO_NSDOMEVENT
|
||||||
NS_DECL_NSIIDBVERSIONCHANGEEVENT
|
NS_DECL_NSIIDBVERSIONCHANGEEVENT
|
||||||
|
|
||||||
inline static already_AddRefed<nsIDOMEvent>
|
inline static already_AddRefed<nsDOMEvent>
|
||||||
Create(const nsAString& aVersion)
|
Create(PRInt64 aOldVersion,
|
||||||
|
PRInt64 aNewVersion)
|
||||||
{
|
{
|
||||||
return CreateInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR), aVersion);
|
return CreateInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
||||||
|
aOldVersion, aNewVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static already_AddRefed<nsIDOMEvent>
|
inline static already_AddRefed<nsDOMEvent>
|
||||||
CreateBlocked(const nsAString& aVersion)
|
CreateBlocked(PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion)
|
||||||
{
|
{
|
||||||
return CreateInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR), aVersion);
|
return CreateInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR),
|
||||||
|
aOldVersion, aNewVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static already_AddRefed<nsDOMEvent>
|
||||||
|
CreateUpgradeNeeded(PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion)
|
||||||
|
{
|
||||||
|
return CreateInternal(NS_LITERAL_STRING(UPGRADENEEDED_EVT_STR),
|
||||||
|
aOldVersion, aNewVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static already_AddRefed<nsIRunnable>
|
inline static already_AddRefed<nsIRunnable>
|
||||||
CreateRunnable(const nsAString& aVersion,
|
CreateRunnable(PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion,
|
||||||
nsIDOMEventTarget* aTarget)
|
nsIDOMEventTarget* aTarget)
|
||||||
{
|
{
|
||||||
return CreateRunnableInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
return CreateRunnableInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
|
||||||
aVersion, aTarget);
|
aOldVersion, aNewVersion, aTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<nsIRunnable>
|
static already_AddRefed<nsIRunnable>
|
||||||
CreateBlockedRunnable(const nsAString& aVersion,
|
CreateBlockedRunnable(PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion,
|
||||||
nsIDOMEventTarget* aTarget)
|
nsIDOMEventTarget* aTarget)
|
||||||
{
|
{
|
||||||
return CreateRunnableInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR), aVersion,
|
return CreateRunnableInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR),
|
||||||
aTarget);
|
aOldVersion, aNewVersion, aTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IDBVersionChangeEvent() : nsDOMEvent(nsnull, nsnull) { }
|
IDBVersionChangeEvent() : nsDOMEvent(nsnull, nsnull) { }
|
||||||
virtual ~IDBVersionChangeEvent() { }
|
virtual ~IDBVersionChangeEvent() { }
|
||||||
|
|
||||||
static already_AddRefed<nsIDOMEvent>
|
static already_AddRefed<nsDOMEvent>
|
||||||
CreateInternal(const nsAString& aType,
|
CreateInternal(const nsAString& aType,
|
||||||
const nsAString& aVersion);
|
PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion);
|
||||||
|
|
||||||
static already_AddRefed<nsIRunnable>
|
static already_AddRefed<nsIRunnable>
|
||||||
CreateRunnableInternal(const nsAString& aType,
|
CreateRunnableInternal(const nsAString& aType,
|
||||||
const nsAString& aVersion,
|
PRUint64 aOldVersion,
|
||||||
|
PRUint64 aNewVersion,
|
||||||
nsIDOMEventTarget* aTarget);
|
nsIDOMEventTarget* aTarget);
|
||||||
|
|
||||||
nsString mVersion;
|
PRUint64 mOldVersion;
|
||||||
|
PRUint64 mNewVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
END_INDEXEDDB_NAMESPACE
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "nsDirectoryServiceUtils.h"
|
#include "nsDirectoryServiceUtils.h"
|
||||||
#include "nsDOMClassInfoID.h"
|
#include "nsDOMClassInfoID.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsEscape.h"
|
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
@ -65,6 +64,7 @@
|
||||||
#include "CheckPermissionsHelper.h"
|
#include "CheckPermissionsHelper.h"
|
||||||
#include "DatabaseInfo.h"
|
#include "DatabaseInfo.h"
|
||||||
#include "IDBDatabase.h"
|
#include "IDBDatabase.h"
|
||||||
|
#include "IDBEvents.h"
|
||||||
#include "IDBKeyRange.h"
|
#include "IDBKeyRange.h"
|
||||||
#include "IndexedDatabaseManager.h"
|
#include "IndexedDatabaseManager.h"
|
||||||
#include "LazyIdleThread.h"
|
#include "LazyIdleThread.h"
|
||||||
|
@ -72,8 +72,6 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
#define DB_SCHEMA_VERSION 4
|
|
||||||
|
|
||||||
USING_INDEXEDDB_NAMESPACE
|
USING_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -89,360 +87,6 @@ struct ObjectStoreInfoMap
|
||||||
ObjectStoreInfo* info;
|
ObjectStoreInfo* info;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenDatabaseHelper : public AsyncConnectionHelper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OpenDatabaseHelper(IDBRequest* aRequest,
|
|
||||||
const nsAString& aName,
|
|
||||||
const nsACString& aASCIIOrigin)
|
|
||||||
: AsyncConnectionHelper(static_cast<IDBDatabase*>(nsnull), aRequest),
|
|
||||||
mName(aName), mASCIIOrigin(aASCIIOrigin), mDatabaseId(0),
|
|
||||||
mLastObjectStoreId(0), mLastIndexId(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
|
||||||
nsresult GetSuccessResult(JSContext* aCx,
|
|
||||||
jsval* aVal);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// In-params.
|
|
||||||
nsString mName;
|
|
||||||
nsCString mASCIIOrigin;
|
|
||||||
|
|
||||||
// Out-params.
|
|
||||||
nsTArray<nsAutoPtr<ObjectStoreInfo> > mObjectStores;
|
|
||||||
nsString mVersion;
|
|
||||||
PRUint32 mDataVersion;
|
|
||||||
nsString mDatabaseFilePath;
|
|
||||||
PRUint32 mDatabaseId;
|
|
||||||
PRInt64 mLastObjectStoreId;
|
|
||||||
PRInt64 mLastIndexId;
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
CreateTables(mozIStorageConnection* aDBConn)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(!NS_IsMainThread(),
|
|
||||||
"Creating tables on the main thread!");
|
|
||||||
NS_PRECONDITION(aDBConn, "Passing a null database connection!");
|
|
||||||
|
|
||||||
// Table `database`
|
|
||||||
nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE database ("
|
|
||||||
"name TEXT NOT NULL, "
|
|
||||||
"version TEXT DEFAULT NULL, "
|
|
||||||
"dataVersion INTEGER NOT NULL"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `object_store`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE object_store ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"name TEXT NOT NULL, "
|
|
||||||
"key_path TEXT NOT NULL, "
|
|
||||||
"auto_increment INTEGER NOT NULL DEFAULT 0, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"UNIQUE (name)"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `object_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE object_data ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"object_store_id INTEGER NOT NULL, "
|
|
||||||
"data BLOB NOT NULL, "
|
|
||||||
"key_value DEFAULT NULL, " // NONE affinity
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE UNIQUE INDEX key_index "
|
|
||||||
"ON object_data (key_value, object_store_id);"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `ai_object_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE ai_object_data ("
|
|
||||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
"object_store_id INTEGER NOT NULL, "
|
|
||||||
"data BLOB NOT NULL, "
|
|
||||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE UNIQUE INDEX ai_key_index "
|
|
||||||
"ON ai_object_data (id, object_store_id);"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `index`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE object_store_index ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"object_store_id INTEGER NOT NULL, "
|
|
||||||
"name TEXT NOT NULL, "
|
|
||||||
"key_path TEXT NOT NULL, "
|
|
||||||
"unique_index INTEGER NOT NULL, "
|
|
||||||
"object_store_autoincrement INTERGER NOT NULL, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"UNIQUE (object_store_id, name), "
|
|
||||||
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `index_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE index_data ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"index_id INTEGER NOT NULL, "
|
|
||||||
"object_data_id INTEGER NOT NULL, "
|
|
||||||
"object_data_key NOT NULL, " // NONE affinity
|
|
||||||
"value NOT NULL, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
|
||||||
"CASCADE, "
|
|
||||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE INDEX value_index "
|
|
||||||
"ON index_data (index_id, value);"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `unique_index_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE unique_index_data ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"index_id INTEGER NOT NULL, "
|
|
||||||
"object_data_id INTEGER NOT NULL, "
|
|
||||||
"object_data_key NOT NULL, " // NONE affinity
|
|
||||||
"value NOT NULL, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"UNIQUE (index_id, value), "
|
|
||||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
|
||||||
"CASCADE "
|
|
||||||
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `ai_index_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE ai_index_data ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"index_id INTEGER NOT NULL, "
|
|
||||||
"ai_object_data_id INTEGER NOT NULL, "
|
|
||||||
"value NOT NULL, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
|
||||||
"CASCADE, "
|
|
||||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE INDEX ai_value_index "
|
|
||||||
"ON ai_index_data (index_id, value);"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Table `ai_unique_index_data`
|
|
||||||
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"CREATE TABLE ai_unique_index_data ("
|
|
||||||
"id INTEGER, "
|
|
||||||
"index_id INTEGER NOT NULL, "
|
|
||||||
"ai_object_data_id INTEGER NOT NULL, "
|
|
||||||
"value NOT NULL, "
|
|
||||||
"PRIMARY KEY (id), "
|
|
||||||
"UNIQUE (index_id, value), "
|
|
||||||
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
|
||||||
"CASCADE, "
|
|
||||||
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
|
||||||
"CASCADE"
|
|
||||||
");"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = aDBConn->SetSchemaVersion(DB_SCHEMA_VERSION);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
CreateMetaData(mozIStorageConnection* aConnection,
|
|
||||||
const nsAString& aName)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
|
|
||||||
NS_PRECONDITION(aConnection, "Null database!");
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
|
||||||
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
|
||||||
"INSERT OR REPLACE INTO database (name, dataVersion) "
|
|
||||||
"VALUES (:name, :dataVersion)"
|
|
||||||
), getter_AddRefs(stmt));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), aName);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("dataVersion"),
|
|
||||||
JS_STRUCTURED_CLONE_VERSION);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return stmt->Execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
GetDatabaseFile(const nsACString& aASCIIOrigin,
|
|
||||||
const nsAString& aName,
|
|
||||||
nsIFile** aDatabaseFile)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!aASCIIOrigin.IsEmpty() && !aName.IsEmpty(), "Bad arguments!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> dbFile;
|
|
||||||
nsresult rv = IDBFactory::GetDirectory(getter_AddRefs(dbFile));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_ConvertASCIItoUTF16 originSanitized(aASCIIOrigin);
|
|
||||||
originSanitized.ReplaceChar(":/", '+');
|
|
||||||
|
|
||||||
rv = dbFile->Append(originSanitized);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsAutoString filename;
|
|
||||||
filename.AppendInt(HashString(aName));
|
|
||||||
|
|
||||||
nsCString escapedName;
|
|
||||||
if (!NS_Escape(NS_ConvertUTF16toUTF8(aName), escapedName, url_XPAlphas)) {
|
|
||||||
NS_WARNING("Can't escape database name!");
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* forwardIter = escapedName.BeginReading();
|
|
||||||
const char* backwardIter = escapedName.EndReading() - 1;
|
|
||||||
|
|
||||||
nsCString substring;
|
|
||||||
while (forwardIter <= backwardIter && substring.Length() < 21) {
|
|
||||||
if (substring.Length() % 2) {
|
|
||||||
substring.Append(*backwardIter--);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
substring.Append(*forwardIter++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filename.Append(NS_ConvertASCIItoUTF16(substring));
|
|
||||||
filename.AppendLiteral(".sqlite");
|
|
||||||
|
|
||||||
rv = dbFile->Append(filename);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
dbFile.forget(aDatabaseFile);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
CreateDatabaseConnection(const nsAString& aName,
|
|
||||||
nsIFile* aDBFile,
|
|
||||||
mozIStorageConnection** aConnection)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> dbDirectory;
|
|
||||||
nsresult rv = aDBFile->GetParent(getter_AddRefs(dbDirectory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
rv = aDBFile->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_NAMED_LITERAL_CSTRING(quotaVFSName, "quota");
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageServiceQuotaManagement> ss =
|
|
||||||
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(ss, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> connection;
|
|
||||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
|
||||||
getter_AddRefs(connection));
|
|
||||||
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
|
||||||
// Nuke the database file. The web services can recreate their data.
|
|
||||||
rv = aDBFile->Remove(false);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
exists = false;
|
|
||||||
|
|
||||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
|
||||||
getter_AddRefs(connection));
|
|
||||||
}
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// Check to make sure that the database schema is correct.
|
|
||||||
PRInt32 schemaVersion;
|
|
||||||
rv = connection->GetSchemaVersion(&schemaVersion);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (schemaVersion != DB_SCHEMA_VERSION) {
|
|
||||||
if (exists) {
|
|
||||||
// If the connection is not at the right schema version, nuke it.
|
|
||||||
rv = aDBFile->Remove(false);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
|
||||||
getter_AddRefs(connection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
mozStorageTransaction transaction(connection, false,
|
|
||||||
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
|
||||||
|
|
||||||
rv = CreateTables(connection);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = CreateMetaData(connection, aName);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
rv = transaction.Commit();
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check to make sure that the database schema is correct again.
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
|
||||||
schemaVersion == DB_SCHEMA_VERSION,
|
|
||||||
"CreateTables failed!");
|
|
||||||
|
|
||||||
// Turn on foreign key constraints.
|
|
||||||
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
|
||||||
"PRAGMA foreign_keys = ON;"
|
|
||||||
));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
connection.forget(aConnection);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
IDBFactory::IDBFactory()
|
IDBFactory::IDBFactory()
|
||||||
|
@ -571,13 +215,12 @@ IDBFactory::GetDirectoryForOrigin(const nsACString& aASCIIOrigin,
|
||||||
nsresult
|
nsresult
|
||||||
IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
||||||
PRUint32 aDatabaseId,
|
PRUint32 aDatabaseId,
|
||||||
nsAString& aVersion,
|
PRUint64* aVersion,
|
||||||
ObjectStoreInfoArray& aObjectStores)
|
ObjectStoreInfoArray& aObjectStores)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(aConnection, "Null pointer!");
|
NS_ASSERTION(aConnection, "Null pointer!");
|
||||||
|
|
||||||
aVersion.Truncate();
|
|
||||||
aObjectStores.Clear();
|
aObjectStores.Clear();
|
||||||
|
|
||||||
// Load object store names and ids.
|
// Load object store names and ids.
|
||||||
|
@ -672,21 +315,18 @@ IDBFactory::LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsString version;
|
PRInt64 version = 0;
|
||||||
rv = stmt->GetString(0, version);
|
rv = stmt->GetInt64(0, &version);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (version.IsVoid()) {
|
*aVersion = NS_MAX<PRInt64>(version, 0);
|
||||||
version.SetIsVoid(false);
|
|
||||||
}
|
return rv;
|
||||||
aVersion = version;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
nsresult
|
nsresult
|
||||||
IDBFactory::UpdateDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
IDBFactory::UpdateDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
||||||
const nsAString& aVersion,
|
PRUint64 aVersion,
|
||||||
ObjectStoreInfoArray& aObjectStores)
|
ObjectStoreInfoArray& aObjectStores)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
@ -739,11 +379,16 @@ DOMCI_DATA(IDBFactory, IDBFactory)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
IDBFactory::Open(const nsAString& aName,
|
IDBFactory::Open(const nsAString& aName,
|
||||||
|
PRInt64 aVersion,
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
nsIIDBRequest** _retval)
|
nsIIDBOpenDBRequest** _retval)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
if (aVersion < 1) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||||
// Force ContentChild to cache the path from the parent, so that
|
// Force ContentChild to cache the path from the parent, so that
|
||||||
// we do not end up in a side thread that asks for the path (which
|
// we do not end up in a side thread that asks for the path (which
|
||||||
|
@ -784,12 +429,12 @@ IDBFactory::Open(const nsAString& aName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<IDBRequest> request = IDBRequest::Create(this, context, window,
|
nsRefPtr<IDBOpenDBRequest> request =
|
||||||
nsnull);
|
IDBOpenDBRequest::Create(context, window);
|
||||||
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
nsRefPtr<OpenDatabaseHelper> openHelper =
|
nsRefPtr<OpenDatabaseHelper> openHelper =
|
||||||
new OpenDatabaseHelper(request, aName, origin);
|
new OpenDatabaseHelper(request, aName, origin, aVersion);
|
||||||
|
|
||||||
nsRefPtr<CheckPermissionsHelper> permissionHelper =
|
nsRefPtr<CheckPermissionsHelper> permissionHelper =
|
||||||
new CheckPermissionsHelper(openHelper, window, aName, origin);
|
new CheckPermissionsHelper(openHelper, window, aName, origin);
|
||||||
|
@ -803,200 +448,3 @@ IDBFactory::Open(const nsAString& aName,
|
||||||
request.forget(_retval);
|
request.forget(_retval);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
bool correctThread;
|
|
||||||
NS_ASSERTION(NS_SUCCEEDED(IndexedDatabaseManager::Get()->IOThread()->
|
|
||||||
IsOnCurrentThread(&correctThread)) &&
|
|
||||||
correctThread,
|
|
||||||
"Running on the wrong thread!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
NS_ASSERTION(!aConnection, "Huh?!");
|
|
||||||
|
|
||||||
if (IndexedDatabaseManager::IsShuttingDown()) {
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> dbFile;
|
|
||||||
nsresult rv = GetDatabaseFile(mASCIIOrigin, mName, getter_AddRefs(dbFile));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
rv = dbFile->GetPath(mDatabaseFilePath);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> dbDirectory;
|
|
||||||
rv = dbFile->GetParent(getter_AddRefs(dbDirectory));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
bool exists;
|
|
||||||
rv = dbDirectory->Exists(&exists);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (exists) {
|
|
||||||
bool isDirectory;
|
|
||||||
rv = dbDirectory->IsDirectory(&isDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
NS_ENSURE_TRUE(isDirectory, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rv = dbDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
|
||||||
NS_ASSERTION(mgr, "This should never be null!");
|
|
||||||
|
|
||||||
rv = mgr->EnsureQuotaManagementForDirectory(dbDirectory);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
nsCOMPtr<mozIStorageConnection> connection;
|
|
||||||
rv = CreateDatabaseConnection(mName, dbFile, getter_AddRefs(connection));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
// Get the data version.
|
|
||||||
nsCOMPtr<mozIStorageStatement> stmt;
|
|
||||||
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
|
||||||
"SELECT dataVersion "
|
|
||||||
"FROM database"
|
|
||||||
), getter_AddRefs(stmt));
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
bool hasResult;
|
|
||||||
rv = stmt->ExecuteStep(&hasResult);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
if (!hasResult) {
|
|
||||||
NS_ERROR("Database has no dataVersion!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt64 dataVersion;
|
|
||||||
rv = stmt->GetInt64(0, &dataVersion);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
if (dataVersion > JS_STRUCTURED_CLONE_VERSION) {
|
|
||||||
NS_ERROR("Bad data version!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataVersion < JS_STRUCTURED_CLONE_VERSION) {
|
|
||||||
// Need to upgrade the database, here, before returning to the main thread.
|
|
||||||
NS_NOTYETIMPLEMENTED("Implement me!");
|
|
||||||
}
|
|
||||||
|
|
||||||
mDatabaseId = HashString(mDatabaseFilePath);
|
|
||||||
NS_ASSERTION(mDatabaseId, "HashString gave us 0?!");
|
|
||||||
|
|
||||||
rv = IDBFactory::LoadDatabaseInformation(connection, mDatabaseId, mVersion,
|
|
||||||
mObjectStores);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < mObjectStores.Length(); i++) {
|
|
||||||
nsAutoPtr<ObjectStoreInfo>& objectStoreInfo = mObjectStores[i];
|
|
||||||
for (PRUint32 j = 0; j < objectStoreInfo->indexes.Length(); j++) {
|
|
||||||
IndexInfo& indexInfo = objectStoreInfo->indexes[j];
|
|
||||||
mLastIndexId = NS_MAX(indexInfo.id, mLastIndexId);
|
|
||||||
}
|
|
||||||
mLastObjectStoreId = NS_MAX(objectStoreInfo->id, mLastObjectStoreId);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
OpenDatabaseHelper::GetSuccessResult(JSContext* aCx,
|
|
||||||
jsval *aVal)
|
|
||||||
{
|
|
||||||
DatabaseInfo* dbInfo;
|
|
||||||
if (DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
|
|
||||||
NS_ASSERTION(dbInfo->referenceCount, "Bad reference count!");
|
|
||||||
++dbInfo->referenceCount;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
NS_ASSERTION(dbInfo->name == mName &&
|
|
||||||
dbInfo->version == mVersion &&
|
|
||||||
dbInfo->id == mDatabaseId &&
|
|
||||||
dbInfo->filePath == mDatabaseFilePath,
|
|
||||||
"Metadata mismatch!");
|
|
||||||
|
|
||||||
PRUint32 objectStoreCount = mObjectStores.Length();
|
|
||||||
for (PRUint32 index = 0; index < objectStoreCount; index++) {
|
|
||||||
nsAutoPtr<ObjectStoreInfo>& info = mObjectStores[index];
|
|
||||||
NS_ASSERTION(info->databaseId == mDatabaseId, "Huh?!");
|
|
||||||
|
|
||||||
ObjectStoreInfo* otherInfo;
|
|
||||||
NS_ASSERTION(ObjectStoreInfo::Get(mDatabaseId, info->name, &otherInfo),
|
|
||||||
"ObjectStore not known!");
|
|
||||||
|
|
||||||
NS_ASSERTION(info->name == otherInfo->name &&
|
|
||||||
info->id == otherInfo->id &&
|
|
||||||
info->keyPath == otherInfo->keyPath &&
|
|
||||||
info->autoIncrement == otherInfo->autoIncrement &&
|
|
||||||
info->databaseId == otherInfo->databaseId,
|
|
||||||
"Metadata mismatch!");
|
|
||||||
NS_ASSERTION(dbInfo->ContainsStoreName(info->name),
|
|
||||||
"Object store names out of date!");
|
|
||||||
NS_ASSERTION(info->indexes.Length() == otherInfo->indexes.Length(),
|
|
||||||
"Bad index length!");
|
|
||||||
|
|
||||||
PRUint32 indexCount = info->indexes.Length();
|
|
||||||
for (PRUint32 indexIndex = 0; indexIndex < indexCount; indexIndex++) {
|
|
||||||
const IndexInfo& indexInfo = info->indexes[indexIndex];
|
|
||||||
const IndexInfo& otherIndexInfo = otherInfo->indexes[indexIndex];
|
|
||||||
NS_ASSERTION(indexInfo.id == otherIndexInfo.id,
|
|
||||||
"Bad index id!");
|
|
||||||
NS_ASSERTION(indexInfo.name == otherIndexInfo.name,
|
|
||||||
"Bad index name!");
|
|
||||||
NS_ASSERTION(indexInfo.keyPath == otherIndexInfo.keyPath,
|
|
||||||
"Bad index keyPath!");
|
|
||||||
NS_ASSERTION(indexInfo.unique == otherIndexInfo.unique,
|
|
||||||
"Bad index unique value!");
|
|
||||||
NS_ASSERTION(indexInfo.autoIncrement == otherIndexInfo.autoIncrement,
|
|
||||||
"Bad index autoIncrement value!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsAutoPtr<DatabaseInfo> newInfo(new DatabaseInfo());
|
|
||||||
|
|
||||||
newInfo->name = mName;
|
|
||||||
newInfo->id = mDatabaseId;
|
|
||||||
newInfo->filePath = mDatabaseFilePath;
|
|
||||||
newInfo->referenceCount = 1;
|
|
||||||
|
|
||||||
if (!DatabaseInfo::Put(newInfo)) {
|
|
||||||
NS_ERROR("Failed to add to hash!");
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbInfo = newInfo.forget();
|
|
||||||
|
|
||||||
nsresult rv = IDBFactory::UpdateDatabaseMetadata(dbInfo, mVersion,
|
|
||||||
mObjectStores);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
|
||||||
|
|
||||||
NS_ASSERTION(mObjectStores.IsEmpty(), "Should have swapped!");
|
|
||||||
}
|
|
||||||
|
|
||||||
dbInfo->nextObjectStoreId = mLastObjectStoreId + 1;
|
|
||||||
dbInfo->nextIndexId = mLastIndexId + 1;
|
|
||||||
|
|
||||||
nsRefPtr<IDBDatabase> database =
|
|
||||||
IDBDatabase::Create(mRequest->ScriptContext(), mRequest->Owner(), dbInfo,
|
|
||||||
mASCIIOrigin);
|
|
||||||
if (!database) {
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WrapNative(aCx, NS_ISUPPORTS_CAST(nsIDOMEventTarget*, database),
|
|
||||||
aVal);
|
|
||||||
}
|
|
||||||
|
|
|
@ -85,12 +85,12 @@ public:
|
||||||
static nsresult
|
static nsresult
|
||||||
LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
LoadDatabaseInformation(mozIStorageConnection* aConnection,
|
||||||
PRUint32 aDatabaseId,
|
PRUint32 aDatabaseId,
|
||||||
nsAString& aVersion,
|
PRUint64* aVersion,
|
||||||
ObjectStoreInfoArray& aObjectStores);
|
ObjectStoreInfoArray& aObjectStores);
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
UpdateDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
UpdateDatabaseMetadata(DatabaseInfo* aDatabaseInfo,
|
||||||
const nsAString& aVersion,
|
PRUint64 aVersion,
|
||||||
ObjectStoreInfoArray& aObjectStores);
|
ObjectStoreInfoArray& aObjectStores);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -121,7 +121,7 @@ IDBRequest::Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
IDBRequest::SetDone(AsyncConnectionHelper* aHelper)
|
IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
|
NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!");
|
||||||
|
@ -203,12 +203,10 @@ IDBRequest::GetReadyState(PRUint16* aReadyState)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
if (mHaveResultOrErrorCode) {
|
*aReadyState = mHaveResultOrErrorCode ?
|
||||||
*aReadyState = nsIIDBRequest::DONE;
|
nsIIDBRequest::DONE :
|
||||||
}
|
nsIIDBRequest::LOADING;
|
||||||
else {
|
|
||||||
*aReadyState = nsIIDBRequest::LOADING;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +343,7 @@ IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDBVersionChangeRequest::~IDBVersionChangeRequest()
|
IDBOpenDBRequest::~IDBOpenDBRequest()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
@ -355,11 +353,9 @@ IDBVersionChangeRequest::~IDBVersionChangeRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
already_AddRefed<IDBVersionChangeRequest>
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
IDBVersionChangeRequest::Create(nsISupports* aSource,
|
IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext,
|
||||||
nsIScriptContext* aScriptContext,
|
nsPIDOMWindow* aOwner)
|
||||||
nsPIDOMWindow* aOwner,
|
|
||||||
IDBTransaction* aTransaction)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
@ -368,10 +364,8 @@ IDBVersionChangeRequest::Create(nsISupports* aSource,
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<IDBVersionChangeRequest> request(new IDBVersionChangeRequest());
|
nsRefPtr<IDBOpenDBRequest> request(new IDBOpenDBRequest());
|
||||||
|
|
||||||
request->mSource = aSource;
|
|
||||||
request->mTransaction = aTransaction;
|
|
||||||
request->mScriptContext = aScriptContext;
|
request->mScriptContext = aScriptContext;
|
||||||
request->mOwner = aOwner;
|
request->mOwner = aOwner;
|
||||||
|
|
||||||
|
@ -379,52 +373,50 @@ IDBVersionChangeRequest::Create(nsISupports* aSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBVersionChangeRequest::RootResultVal()
|
IDBOpenDBRequest::SetTransaction(IDBTransaction* aTransaction)
|
||||||
|
{
|
||||||
|
mTransaction = aTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBOpenDBRequest::RootResultVal()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!mResultValRooted, "This should be false!");
|
NS_ASSERTION(!mResultValRooted, "This should be false!");
|
||||||
NS_HOLD_JS_OBJECTS(this, IDBVersionChangeRequest);
|
NS_HOLD_JS_OBJECTS(this, IDBOpenDBRequest);
|
||||||
mResultValRooted = true;
|
mResultValRooted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IDBVersionChangeRequest::UnrootResultVal()
|
IDBOpenDBRequest::UnrootResultVal()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mResultValRooted, "This should be true!");
|
NS_ASSERTION(mResultValRooted, "This should be true!");
|
||||||
NS_DROP_JS_OBJECTS(this, IDBVersionChangeRequest);
|
NS_DROP_JS_OBJECTS(this, IDBOpenDBRequest);
|
||||||
mResultValRooted = false;
|
mResultValRooted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, blocked)
|
||||||
IDBVersionChangeRequest::SetOnblocked(nsIDOMEventListener* aBlockedListener)
|
NS_IMPL_EVENT_HANDLER(IDBOpenDBRequest, upgradeneeded)
|
||||||
{
|
|
||||||
return RemoveAddEventListener(NS_LITERAL_STRING(BLOCKED_EVT_STR),
|
|
||||||
mOnBlockedListener, aBlockedListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBOpenDBRequest)
|
||||||
IDBVersionChangeRequest::GetOnblocked(nsIDOMEventListener** aBlockedListener)
|
|
||||||
{
|
|
||||||
return GetInnerEventListener(mOnBlockedListener, aBlockedListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBVersionChangeRequest)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBOpenDBRequest,
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBVersionChangeRequest,
|
|
||||||
IDBRequest)
|
IDBRequest)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnBlockedListener)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnupgradeneededListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnblockedListener)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBVersionChangeRequest,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBOpenDBRequest,
|
||||||
IDBRequest)
|
IDBRequest)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnBlockedListener)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnupgradeneededListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnblockedListener)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBVersionChangeRequest)
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBOpenDBRequest)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIIDBVersionChangeRequest)
|
NS_INTERFACE_MAP_ENTRY(nsIIDBOpenDBRequest)
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBVersionChangeRequest)
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBOpenDBRequest)
|
||||||
NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
|
NS_INTERFACE_MAP_END_INHERITING(IDBRequest)
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(IDBVersionChangeRequest, IDBRequest)
|
NS_IMPL_ADDREF_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||||
NS_IMPL_RELEASE_INHERITED(IDBVersionChangeRequest, IDBRequest)
|
NS_IMPL_RELEASE_INHERITED(IDBOpenDBRequest, IDBRequest)
|
||||||
|
|
||||||
DOMCI_DATA(IDBVersionChangeRequest, IDBVersionChangeRequest)
|
DOMCI_DATA(IDBOpenDBRequest, IDBOpenDBRequest)
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||||
|
|
||||||
#include "nsIIDBRequest.h"
|
#include "nsIIDBRequest.h"
|
||||||
#include "nsIIDBVersionChangeRequest.h"
|
#include "nsIIDBOpenDBRequest.h"
|
||||||
|
|
||||||
#include "nsDOMEventTargetHelper.h"
|
#include "nsDOMEventTargetWrapperCache.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
|
||||||
class nsIScriptContext;
|
class nsIScriptContext;
|
||||||
|
@ -54,7 +54,7 @@ class nsPIDOMWindow;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
class AsyncConnectionHelper;
|
class HelperBase;
|
||||||
class IDBTransaction;
|
class IDBTransaction;
|
||||||
|
|
||||||
class IDBRequest : public nsDOMEventTargetHelper,
|
class IDBRequest : public nsDOMEventTargetHelper,
|
||||||
|
@ -82,7 +82,15 @@ public:
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
nsresult SetDone(AsyncConnectionHelper* aHelper);
|
nsresult NotifyHelperCompleted(HelperBase* aHelper);
|
||||||
|
|
||||||
|
void SetError(nsresult rv)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_FAILED(rv), "Er, what?");
|
||||||
|
NS_ASSERTION(mErrorCode == NS_OK, "Already have an error?");
|
||||||
|
|
||||||
|
mErrorCode = rv;
|
||||||
|
}
|
||||||
|
|
||||||
nsIScriptContext* ScriptContext()
|
nsIScriptContext* ScriptContext()
|
||||||
{
|
{
|
||||||
|
@ -116,30 +124,31 @@ protected:
|
||||||
bool mHaveResultOrErrorCode;
|
bool mHaveResultOrErrorCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDBVersionChangeRequest : public IDBRequest,
|
class IDBOpenDBRequest : public IDBRequest,
|
||||||
public nsIIDBVersionChangeRequest
|
public nsIIDBOpenDBRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS_INHERITED
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
NS_FORWARD_NSIIDBREQUEST(IDBRequest::)
|
NS_FORWARD_NSIIDBREQUEST(IDBRequest::)
|
||||||
NS_DECL_NSIIDBVERSIONCHANGEREQUEST
|
NS_DECL_NSIIDBOPENDBREQUEST
|
||||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBVersionChangeRequest,
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBOpenDBRequest,
|
||||||
IDBRequest)
|
IDBRequest)
|
||||||
|
|
||||||
~IDBVersionChangeRequest();
|
|
||||||
|
|
||||||
static
|
static
|
||||||
already_AddRefed<IDBVersionChangeRequest>
|
already_AddRefed<IDBOpenDBRequest>
|
||||||
Create(nsISupports* aSource,
|
Create(nsIScriptContext* aScriptContext,
|
||||||
nsIScriptContext* aScriptContext,
|
nsPIDOMWindow* aOwner);
|
||||||
nsPIDOMWindow* aOwner,
|
|
||||||
IDBTransaction* aTransaction);
|
void SetTransaction(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
virtual void RootResultVal();
|
virtual void RootResultVal();
|
||||||
virtual void UnrootResultVal();
|
virtual void UnrootResultVal();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsRefPtr<nsDOMEventListenerWrapper> mOnBlockedListener;
|
~IDBOpenDBRequest();
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMEventListenerWrapper> mOnblockedListener;
|
||||||
|
nsRefPtr<nsDOMEventListenerWrapper> mOnupgradeneededListener;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_INDEXEDDB_NAMESPACE
|
END_INDEXEDDB_NAMESPACE
|
||||||
|
|
|
@ -182,6 +182,14 @@ IDBTransaction::OnRequestFinished()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
IDBTransaction::SetTransactionListener(IDBTransactionListener* aListener)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ASSERTION(!mListener, "Shouldn't already have a listener!");
|
||||||
|
mListener = aListener;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
IDBTransaction::CommitOrRollback()
|
IDBTransaction::CommitOrRollback()
|
||||||
{
|
{
|
||||||
|
@ -190,7 +198,7 @@ IDBTransaction::CommitOrRollback()
|
||||||
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
TransactionThreadPool* pool = TransactionThreadPool::GetOrCreate();
|
||||||
NS_ENSURE_STATE(pool);
|
NS_ENSURE_STATE(pool);
|
||||||
|
|
||||||
nsRefPtr<CommitHelper> helper(new CommitHelper(this));
|
nsRefPtr<CommitHelper> helper(new CommitHelper(this, mListener));
|
||||||
|
|
||||||
mCachedStatements.Enumerate(DoomCachedStatements, helper);
|
mCachedStatements.Enumerate(DoomCachedStatements, helper);
|
||||||
NS_ASSERTION(!mCachedStatements.Count(), "Statements left!");
|
NS_ASSERTION(!mCachedStatements.Count(), "Statements left!");
|
||||||
|
@ -775,8 +783,13 @@ IDBTransaction::Abort()
|
||||||
mAborted = true;
|
mAborted = true;
|
||||||
mReadyState = nsIIDBTransaction::DONE;
|
mReadyState = nsIIDBTransaction::DONE;
|
||||||
|
|
||||||
|
if (Mode() == nsIIDBTransaction::VERSION_CHANGE) {
|
||||||
|
// If a version change transaction is aborted, the db must be closed
|
||||||
|
mDatabase->Close();
|
||||||
|
}
|
||||||
|
|
||||||
// Fire the abort event if there are no outstanding requests. Otherwise the
|
// Fire the abort event if there are no outstanding requests. Otherwise the
|
||||||
// abort event will be fired when all outdtanding requests finish.
|
// abort event will be fired when all outstanding requests finish.
|
||||||
if (needToCommitOrRollback) {
|
if (needToCommitOrRollback) {
|
||||||
return CommitOrRollback();
|
return CommitOrRollback();
|
||||||
}
|
}
|
||||||
|
@ -908,8 +921,10 @@ IDBTransaction::AfterProcessNextEvent(nsIThreadInternal* aThread,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommitHelper::CommitHelper(IDBTransaction* aTransaction)
|
CommitHelper::CommitHelper(IDBTransaction* aTransaction,
|
||||||
|
IDBTransactionListener* aListener)
|
||||||
: mTransaction(aTransaction),
|
: mTransaction(aTransaction),
|
||||||
|
mListener(aListener),
|
||||||
mAborted(!!aTransaction->mAborted),
|
mAborted(!!aTransaction->mAborted),
|
||||||
mHaveMetadata(false)
|
mHaveMetadata(false)
|
||||||
{
|
{
|
||||||
|
@ -965,7 +980,14 @@ CommitHelper::Run()
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
mTransaction->mFiredCompleteOrAbort = true;
|
mTransaction->mFiredCompleteOrAbort = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Tell the listener (if we have one) that we're done
|
||||||
|
if (mListener) {
|
||||||
|
mListener->NotifyTransactionComplete(mTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
mTransaction = nsnull;
|
mTransaction = nsnull;
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,7 +1016,7 @@ CommitHelper::Run()
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
IDBFactory::LoadDatabaseInformation(mConnection,
|
IDBFactory::LoadDatabaseInformation(mConnection,
|
||||||
mTransaction->Database()->Id(),
|
mTransaction->Database()->Id(),
|
||||||
mOldVersion, mOldObjectStores);
|
&mOldVersion, mOldObjectStores);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
mHaveMetadata = true;
|
mHaveMetadata = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,15 @@ class CommitHelper;
|
||||||
struct ObjectStoreInfo;
|
struct ObjectStoreInfo;
|
||||||
class TransactionThreadPool;
|
class TransactionThreadPool;
|
||||||
|
|
||||||
|
class IDBTransactionListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD_(nsrefcnt) AddRef() = 0;
|
||||||
|
NS_IMETHOD_(nsrefcnt) Release() = 0;
|
||||||
|
|
||||||
|
virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class IDBTransaction : public nsDOMEventTargetHelper,
|
class IDBTransaction : public nsDOMEventTargetHelper,
|
||||||
public nsIIDBTransaction,
|
public nsIIDBTransaction,
|
||||||
public nsIThreadObserver
|
public nsIThreadObserver
|
||||||
|
@ -95,6 +104,8 @@ public:
|
||||||
void OnNewRequest();
|
void OnNewRequest();
|
||||||
void OnRequestFinished();
|
void OnRequestFinished();
|
||||||
|
|
||||||
|
void SetTransactionListener(IDBTransactionListener* aListener);
|
||||||
|
|
||||||
bool StartSavepoint();
|
bool StartSavepoint();
|
||||||
nsresult ReleaseSavepoint();
|
nsresult ReleaseSavepoint();
|
||||||
void RollbackSavepoint();
|
void RollbackSavepoint();
|
||||||
|
@ -189,6 +200,8 @@ private:
|
||||||
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
|
nsInterfaceHashtable<nsCStringHashKey, mozIStorageStatement>
|
||||||
mCachedStatements;
|
mCachedStatements;
|
||||||
|
|
||||||
|
nsRefPtr<IDBTransactionListener> mListener;
|
||||||
|
|
||||||
// Only touched on the database thread.
|
// Only touched on the database thread.
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
nsCOMPtr<mozIStorageConnection> mConnection;
|
||||||
|
|
||||||
|
@ -211,7 +224,8 @@ public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIRUNNABLE
|
NS_DECL_NSIRUNNABLE
|
||||||
|
|
||||||
CommitHelper(IDBTransaction* aTransaction);
|
CommitHelper(IDBTransaction* aTransaction,
|
||||||
|
IDBTransactionListener* aListener);
|
||||||
~CommitHelper();
|
~CommitHelper();
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -229,10 +243,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<IDBTransaction> mTransaction;
|
nsRefPtr<IDBTransaction> mTransaction;
|
||||||
|
nsRefPtr<IDBTransactionListener> mListener;
|
||||||
nsCOMPtr<mozIStorageConnection> mConnection;
|
nsCOMPtr<mozIStorageConnection> mConnection;
|
||||||
nsAutoTArray<nsCOMPtr<nsISupports>, 10> mDoomedObjects;
|
nsAutoTArray<nsCOMPtr<nsISupports>, 10> mDoomedObjects;
|
||||||
|
|
||||||
nsString mOldVersion;
|
PRUint64 mOldVersion;
|
||||||
nsTArray<nsAutoPtr<ObjectStoreInfo> > mOldObjectStores;
|
nsTArray<nsAutoPtr<ObjectStoreInfo> > mOldObjectStores;
|
||||||
|
|
||||||
bool mAborted;
|
bool mAborted;
|
||||||
|
|
|
@ -51,6 +51,8 @@
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
#define DB_SCHEMA_VERSION 5
|
||||||
|
|
||||||
#define BEGIN_INDEXEDDB_NAMESPACE \
|
#define BEGIN_INDEXEDDB_NAMESPACE \
|
||||||
namespace mozilla { namespace dom { namespace indexedDB {
|
namespace mozilla { namespace dom { namespace indexedDB {
|
||||||
|
|
||||||
|
|
|
@ -149,14 +149,20 @@ class DelayedSetVersion : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DelayedSetVersion(IDBDatabase* aDatabase,
|
DelayedSetVersion(IDBDatabase* aDatabase,
|
||||||
IDBVersionChangeRequest* aRequest,
|
IDBOpenDBRequest* aRequest,
|
||||||
const nsAString& aVersion,
|
PRInt64 aOldVersion,
|
||||||
|
PRInt64 aNewVersion,
|
||||||
AsyncConnectionHelper* aHelper)
|
AsyncConnectionHelper* aHelper)
|
||||||
: mDatabase(aDatabase),
|
: mDatabase(aDatabase),
|
||||||
mRequest(aRequest),
|
mRequest(aRequest),
|
||||||
mVersion(aVersion),
|
mOldVersion(aOldVersion),
|
||||||
|
mNewVersion(aNewVersion),
|
||||||
mHelper(aHelper)
|
mHelper(aHelper)
|
||||||
{ }
|
{
|
||||||
|
NS_ASSERTION(aDatabase, "Null database!");
|
||||||
|
NS_ASSERTION(aRequest, "Null request!");
|
||||||
|
NS_ASSERTION(aHelper, "Null helper!");
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHOD Run()
|
NS_IMETHOD Run()
|
||||||
{
|
{
|
||||||
|
@ -165,7 +171,8 @@ public:
|
||||||
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
NS_ASSERTION(mgr, "This should never be null!");
|
NS_ASSERTION(mgr, "This should never be null!");
|
||||||
|
|
||||||
nsresult rv = mgr->SetDatabaseVersion(mDatabase, mRequest, mVersion,
|
nsresult rv = mgr->SetDatabaseVersion(mDatabase, mRequest,
|
||||||
|
mOldVersion, mNewVersion,
|
||||||
mHelper);
|
mHelper);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
@ -174,8 +181,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<IDBDatabase> mDatabase;
|
nsRefPtr<IDBDatabase> mDatabase;
|
||||||
nsRefPtr<IDBVersionChangeRequest> mRequest;
|
nsRefPtr<IDBOpenDBRequest> mRequest;
|
||||||
nsString mVersion;
|
PRInt64 mOldVersion;
|
||||||
|
PRInt64 mNewVersion;
|
||||||
nsRefPtr<AsyncConnectionHelper> mHelper;
|
nsRefPtr<AsyncConnectionHelper> mHelper;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,12 +195,14 @@ class VersionChangeEventsRunnable : public nsRunnable
|
||||||
public:
|
public:
|
||||||
VersionChangeEventsRunnable(
|
VersionChangeEventsRunnable(
|
||||||
IDBDatabase* aRequestingDatabase,
|
IDBDatabase* aRequestingDatabase,
|
||||||
IDBVersionChangeRequest* aRequest,
|
IDBOpenDBRequest* aRequest,
|
||||||
nsTArray<nsRefPtr<IDBDatabase> >& aWaitingDatabases,
|
nsTArray<nsRefPtr<IDBDatabase> >& aWaitingDatabases,
|
||||||
const nsAString& aVersion)
|
PRInt64 aOldVersion,
|
||||||
|
PRInt64 aNewVersion)
|
||||||
: mRequestingDatabase(aRequestingDatabase),
|
: mRequestingDatabase(aRequestingDatabase),
|
||||||
mRequest(aRequest),
|
mRequest(aRequest),
|
||||||
mVersion(aVersion)
|
mOldVersion(aOldVersion),
|
||||||
|
mNewVersion(aNewVersion)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(aRequestingDatabase, "Null pointer!");
|
NS_ASSERTION(aRequestingDatabase, "Null pointer!");
|
||||||
|
@ -230,7 +240,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise fire a versionchange event.
|
// Otherwise fire a versionchange event.
|
||||||
nsCOMPtr<nsIDOMEvent> event(IDBVersionChangeEvent::Create(mVersion));
|
nsRefPtr<nsDOMEvent> event =
|
||||||
|
IDBVersionChangeEvent::Create(mOldVersion, mNewVersion);
|
||||||
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
bool dummy;
|
bool dummy;
|
||||||
|
@ -241,8 +252,8 @@ public:
|
||||||
// then fire the blocked event.
|
// then fire the blocked event.
|
||||||
for (PRUint32 index = 0; index < mWaitingDatabases.Length(); index++) {
|
for (PRUint32 index = 0; index < mWaitingDatabases.Length(); index++) {
|
||||||
if (!mWaitingDatabases[index]->IsClosed()) {
|
if (!mWaitingDatabases[index]->IsClosed()) {
|
||||||
nsCOMPtr<nsIDOMEvent> event =
|
nsRefPtr<nsDOMEvent> event =
|
||||||
IDBVersionChangeEvent::CreateBlocked(mVersion);
|
IDBVersionChangeEvent::CreateBlocked(mOldVersion, mNewVersion);
|
||||||
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
bool dummy;
|
bool dummy;
|
||||||
|
@ -257,9 +268,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<IDBDatabase> mRequestingDatabase;
|
nsRefPtr<IDBDatabase> mRequestingDatabase;
|
||||||
nsRefPtr<IDBVersionChangeRequest> mRequest;
|
nsRefPtr<IDBOpenDBRequest> mRequest;
|
||||||
nsTArray<nsRefPtr<IDBDatabase> > mWaitingDatabases;
|
nsTArray<nsRefPtr<IDBDatabase> > mWaitingDatabases;
|
||||||
nsString mVersion;
|
PRInt64 mOldVersion;
|
||||||
|
PRInt64 mNewVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -512,8 +524,9 @@ IndexedDatabaseManager::IsShuttingDown()
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
IndexedDatabaseManager::SetDatabaseVersion(IDBDatabase* aDatabase,
|
IndexedDatabaseManager::SetDatabaseVersion(IDBDatabase* aDatabase,
|
||||||
IDBVersionChangeRequest* aRequest,
|
IDBOpenDBRequest* aRequest,
|
||||||
const nsAString& aVersion,
|
PRInt64 aOldVersion,
|
||||||
|
PRInt64 aNewVersion,
|
||||||
AsyncConnectionHelper* aHelper)
|
AsyncConnectionHelper* aHelper)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
@ -530,7 +543,8 @@ IndexedDatabaseManager::SetDatabaseVersion(IDBDatabase* aDatabase,
|
||||||
// Same database, just queue this call to run after the current
|
// Same database, just queue this call to run after the current
|
||||||
// SetVersion transaction completes.
|
// SetVersion transaction completes.
|
||||||
nsRefPtr<DelayedSetVersion> delayed =
|
nsRefPtr<DelayedSetVersion> delayed =
|
||||||
new DelayedSetVersion(aDatabase, aRequest, aVersion, aHelper);
|
new DelayedSetVersion(aDatabase, aRequest, aOldVersion, aNewVersion,
|
||||||
|
aHelper);
|
||||||
if (!runnable->mDelayedRunnables.AppendElement(delayed)) {
|
if (!runnable->mDelayedRunnables.AppendElement(delayed)) {
|
||||||
NS_WARNING("Out of memory!");
|
NS_WARNING("Out of memory!");
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
@ -600,7 +614,7 @@ IndexedDatabaseManager::SetDatabaseVersion(IDBDatabase* aDatabase,
|
||||||
|
|
||||||
nsRefPtr<VersionChangeEventsRunnable> eventsRunnable =
|
nsRefPtr<VersionChangeEventsRunnable> eventsRunnable =
|
||||||
new VersionChangeEventsRunnable(aDatabase, aRequest, waitingDatabases,
|
new VersionChangeEventsRunnable(aDatabase, aRequest, waitingDatabases,
|
||||||
aVersion);
|
aOldVersion, aNewVersion);
|
||||||
|
|
||||||
rv = NS_DispatchToCurrentThread(eventsRunnable);
|
rv = NS_DispatchToCurrentThread(eventsRunnable);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
|
@ -97,8 +97,9 @@ public:
|
||||||
|
|
||||||
// Begins the process of setting a database version.
|
// Begins the process of setting a database version.
|
||||||
nsresult SetDatabaseVersion(IDBDatabase* aDatabase,
|
nsresult SetDatabaseVersion(IDBDatabase* aDatabase,
|
||||||
IDBVersionChangeRequest* aRequest,
|
IDBOpenDBRequest* aRequest,
|
||||||
const nsAString& aVersion,
|
PRInt64 aOldVersion,
|
||||||
|
PRInt64 aNewVersion,
|
||||||
AsyncConnectionHelper* aHelper);
|
AsyncConnectionHelper* aHelper);
|
||||||
|
|
||||||
// Called when a window is being purged from the bfcache or the user leaves
|
// Called when a window is being purged from the bfcache or the user leaves
|
||||||
|
|
|
@ -67,6 +67,7 @@ CPPSRCS = \
|
||||||
IDBFactory.cpp \
|
IDBFactory.cpp \
|
||||||
IndexedDatabaseManager.cpp \
|
IndexedDatabaseManager.cpp \
|
||||||
LazyIdleThread.cpp \
|
LazyIdleThread.cpp \
|
||||||
|
OpenDatabaseHelper.cpp \
|
||||||
TransactionThreadPool.cpp \
|
TransactionThreadPool.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ XPIDLSRCS = \
|
||||||
nsIIDBRequest.idl \
|
nsIIDBRequest.idl \
|
||||||
nsIIDBTransaction.idl \
|
nsIIDBTransaction.idl \
|
||||||
nsIIDBVersionChangeEvent.idl \
|
nsIIDBVersionChangeEvent.idl \
|
||||||
nsIIDBVersionChangeRequest.idl \
|
nsIIDBOpenDBRequest.idl \
|
||||||
nsIIndexedDatabaseManager.idl \
|
nsIIndexedDatabaseManager.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,981 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Indexed Database.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* The Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com>
|
||||||
|
* Kyle Huey <me@kylehuey.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "OpenDatabaseHelper.h"
|
||||||
|
#include "IDBEvents.h"
|
||||||
|
#include "IDBFactory.h"
|
||||||
|
#include "IndexedDatabaseManager.h"
|
||||||
|
|
||||||
|
#include "mozilla/storage.h"
|
||||||
|
#include "nsIFile.h"
|
||||||
|
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsEscape.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
|
USING_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
|
const extern PRUint32 kDefaultDatabaseTimeoutSeconds = 30;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
GetDatabaseFile(const nsACString& aASCIIOrigin,
|
||||||
|
const nsAString& aName,
|
||||||
|
nsIFile** aDatabaseFile)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!aASCIIOrigin.IsEmpty() && !aName.IsEmpty(), "Bad arguments!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> dbFile;
|
||||||
|
nsresult rv = IDBFactory::GetDirectory(getter_AddRefs(dbFile));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
NS_ConvertASCIItoUTF16 originSanitized(aASCIIOrigin);
|
||||||
|
originSanitized.ReplaceChar(":/", '+');
|
||||||
|
|
||||||
|
rv = dbFile->Append(originSanitized);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsAutoString filename;
|
||||||
|
filename.AppendInt(HashString(aName));
|
||||||
|
|
||||||
|
nsCString escapedName;
|
||||||
|
if (!NS_Escape(NS_ConvertUTF16toUTF8(aName), escapedName, url_XPAlphas)) {
|
||||||
|
NS_WARNING("Can't escape database name!");
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* forwardIter = escapedName.BeginReading();
|
||||||
|
const char* backwardIter = escapedName.EndReading() - 1;
|
||||||
|
|
||||||
|
nsCString substring;
|
||||||
|
while (forwardIter <= backwardIter && substring.Length() < 21) {
|
||||||
|
if (substring.Length() % 2) {
|
||||||
|
substring.Append(*backwardIter--);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
substring.Append(*forwardIter++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename.Append(NS_ConvertASCIItoUTF16(substring));
|
||||||
|
filename.AppendLiteral(".sqlite");
|
||||||
|
|
||||||
|
rv = dbFile->Append(filename);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
dbFile.forget(aDatabaseFile);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
CreateTables(mozIStorageConnection* aDBConn)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(!NS_IsMainThread(),
|
||||||
|
"Creating tables on the main thread!");
|
||||||
|
NS_PRECONDITION(aDBConn, "Passing a null database connection!");
|
||||||
|
|
||||||
|
// Table `database`
|
||||||
|
nsresult rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE database ("
|
||||||
|
"name TEXT NOT NULL, "
|
||||||
|
"version INTEGER NOT NULL DEFAULT 0, "
|
||||||
|
"dataVersion INTEGER NOT NULL"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `object_store`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE object_store ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"name TEXT NOT NULL, "
|
||||||
|
"key_path TEXT NOT NULL, "
|
||||||
|
"auto_increment INTEGER NOT NULL DEFAULT 0, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"UNIQUE (name)"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `object_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE object_data ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"object_store_id INTEGER NOT NULL, "
|
||||||
|
"data BLOB NOT NULL, "
|
||||||
|
"key_value DEFAULT NULL, " // NONE affinity
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE UNIQUE INDEX key_index "
|
||||||
|
"ON object_data (key_value, object_store_id);"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `ai_object_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE ai_object_data ("
|
||||||
|
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
"object_store_id INTEGER NOT NULL, "
|
||||||
|
"data BLOB NOT NULL, "
|
||||||
|
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE UNIQUE INDEX ai_key_index "
|
||||||
|
"ON ai_object_data (id, object_store_id);"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `index`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE object_store_index ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"object_store_id INTEGER NOT NULL, "
|
||||||
|
"name TEXT NOT NULL, "
|
||||||
|
"key_path TEXT NOT NULL, "
|
||||||
|
"unique_index INTEGER NOT NULL, "
|
||||||
|
"object_store_autoincrement INTERGER NOT NULL, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"UNIQUE (object_store_id, name), "
|
||||||
|
"FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `index_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE index_data ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"index_id INTEGER NOT NULL, "
|
||||||
|
"object_data_id INTEGER NOT NULL, "
|
||||||
|
"object_data_key NOT NULL, " // NONE affinity
|
||||||
|
"value NOT NULL, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||||
|
"CASCADE, "
|
||||||
|
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE INDEX value_index "
|
||||||
|
"ON index_data (index_id, value);"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `unique_index_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE unique_index_data ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"index_id INTEGER NOT NULL, "
|
||||||
|
"object_data_id INTEGER NOT NULL, "
|
||||||
|
"object_data_key NOT NULL, " // NONE affinity
|
||||||
|
"value NOT NULL, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"UNIQUE (index_id, value), "
|
||||||
|
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||||
|
"CASCADE "
|
||||||
|
"FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `ai_index_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE ai_index_data ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"index_id INTEGER NOT NULL, "
|
||||||
|
"ai_object_data_id INTEGER NOT NULL, "
|
||||||
|
"value NOT NULL, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||||
|
"CASCADE, "
|
||||||
|
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE INDEX ai_value_index "
|
||||||
|
"ON ai_index_data (index_id, value);"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Table `ai_unique_index_data`
|
||||||
|
rv = aDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE ai_unique_index_data ("
|
||||||
|
"id INTEGER, "
|
||||||
|
"index_id INTEGER NOT NULL, "
|
||||||
|
"ai_object_data_id INTEGER NOT NULL, "
|
||||||
|
"value NOT NULL, "
|
||||||
|
"PRIMARY KEY (id), "
|
||||||
|
"UNIQUE (index_id, value), "
|
||||||
|
"FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE "
|
||||||
|
"CASCADE, "
|
||||||
|
"FOREIGN KEY (ai_object_data_id) REFERENCES ai_object_data(id) ON DELETE "
|
||||||
|
"CASCADE"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDBConn->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
CreateMetaData(mozIStorageConnection* aConnection,
|
||||||
|
const nsAString& aName)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_PRECONDITION(aConnection, "Null database!");
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
|
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"INSERT OR REPLACE INTO database (name, dataVersion) "
|
||||||
|
"VALUES (:name, :dataVersion)"
|
||||||
|
), getter_AddRefs(stmt));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->BindStringByName(NS_LITERAL_CSTRING("name"), aName);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("dataVersion"),
|
||||||
|
JS_STRUCTURED_CLONE_VERSION);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return stmt->Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
UpgradeSchemaFrom4To5(mozIStorageConnection* aConnection)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
mozStorageTransaction transaction(aConnection, false,
|
||||||
|
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||||
|
|
||||||
|
// All we changed is the type of the version column, so lets try to
|
||||||
|
// convert that to an integer, and if we fail, set it to 0.
|
||||||
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
|
rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"SELECT name, version, dataVersion "
|
||||||
|
"FROM database"
|
||||||
|
), getter_AddRefs(stmt));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsString name;
|
||||||
|
PRInt32 intVersion;
|
||||||
|
PRInt64 dataVersion;
|
||||||
|
|
||||||
|
{
|
||||||
|
mozStorageStatementScoper scoper(stmt);
|
||||||
|
|
||||||
|
bool hasResults;
|
||||||
|
rv = stmt->ExecuteStep(&hasResults);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
NS_ENSURE_TRUE(hasResults, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsString version;
|
||||||
|
rv = stmt->GetString(1, version);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
intVersion = version.ToInteger(&rv, 10);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
intVersion = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = stmt->GetString(0, name);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->GetInt64(2, &dataVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"DROP TABLE database"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"CREATE TABLE database ("
|
||||||
|
"name TEXT NOT NULL, "
|
||||||
|
"version INTEGER NOT NULL DEFAULT 0, "
|
||||||
|
"dataVersion INTEGER NOT NULL"
|
||||||
|
");"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"INSERT INTO database (name, version, dataVersion) "
|
||||||
|
"VALUES (:name, :version, :dataVersion)"
|
||||||
|
), getter_AddRefs(stmt));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
{
|
||||||
|
mozStorageStatementScoper scoper(stmt);
|
||||||
|
|
||||||
|
rv = stmt->BindStringParameter(0, name);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->BindInt32Parameter(1, intVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->BindInt64Parameter(2, dataVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = stmt->Execute();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = aConnection->SetSchemaVersion(DB_SCHEMA_VERSION);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = transaction.Commit();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
CreateDatabaseConnection(const nsAString& aName,
|
||||||
|
nsIFile* aDBFile,
|
||||||
|
mozIStorageConnection** aConnection)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> dbDirectory;
|
||||||
|
nsresult rv = aDBFile->GetParent(getter_AddRefs(dbDirectory));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
bool exists;
|
||||||
|
rv = aDBFile->Exists(&exists);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
NS_NAMED_LITERAL_CSTRING(quotaVFSName, "quota");
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageServiceQuotaManagement> ss =
|
||||||
|
do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(ss, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageConnection> connection;
|
||||||
|
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||||
|
getter_AddRefs(connection));
|
||||||
|
if (rv == NS_ERROR_FILE_CORRUPTED) {
|
||||||
|
// Nuke the database file. The web services can recreate their data.
|
||||||
|
rv = aDBFile->Remove(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
exists = false;
|
||||||
|
|
||||||
|
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||||
|
getter_AddRefs(connection));
|
||||||
|
}
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Check to make sure that the database schema is correct.
|
||||||
|
PRInt32 schemaVersion;
|
||||||
|
rv = connection->GetSchemaVersion(&schemaVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (schemaVersion != DB_SCHEMA_VERSION) {
|
||||||
|
// This logic needs to change next time we change the schema!
|
||||||
|
PR_STATIC_ASSERT(DB_SCHEMA_VERSION == 5);
|
||||||
|
if (schemaVersion == 4) {
|
||||||
|
rv = UpgradeSchemaFrom4To5(connection);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Nuke it from orbit, it's the only way to be sure.
|
||||||
|
if (exists) {
|
||||||
|
// If the connection is not at the right schema version, nuke it.
|
||||||
|
rv = aDBFile->Remove(false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = ss->OpenDatabaseWithVFS(aDBFile, quotaVFSName,
|
||||||
|
getter_AddRefs(connection));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
mozStorageTransaction transaction(connection, false,
|
||||||
|
mozIStorageConnection::TRANSACTION_IMMEDIATE);
|
||||||
|
rv = CreateTables(connection);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = CreateMetaData(connection, aName);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = transaction.Commit();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to make sure that the database schema is correct again.
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(connection->GetSchemaVersion(&schemaVersion)) &&
|
||||||
|
schemaVersion == DB_SCHEMA_VERSION,
|
||||||
|
"CreateTables failed!");
|
||||||
|
|
||||||
|
// Turn on foreign key constraints.
|
||||||
|
rv = connection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||||
|
"PRAGMA foreign_keys = ON;"
|
||||||
|
));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
connection.forget(aConnection);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SetVersionHelper : public AsyncConnectionHelper,
|
||||||
|
public IDBTransactionListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SetVersionHelper(IDBTransaction* aTransaction,
|
||||||
|
IDBOpenDBRequest* aRequest,
|
||||||
|
OpenDatabaseHelper* aHelper,
|
||||||
|
PRUint64 aRequestedVersion,
|
||||||
|
PRUint64 aCurrentVersion)
|
||||||
|
: AsyncConnectionHelper(aTransaction, aRequest),
|
||||||
|
mOpenRequest(aRequest), mOpenHelper(aHelper),
|
||||||
|
mRequestedVersion(aRequestedVersion),
|
||||||
|
mCurrentVersion(aCurrentVersion)
|
||||||
|
{
|
||||||
|
mTransaction->SetTransactionListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
|
||||||
|
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
|
||||||
|
nsresult GetSuccessResult(JSContext* aCx,
|
||||||
|
jsval* aVal);
|
||||||
|
|
||||||
|
// SetVersionHelper never fires an error event at the request. It hands that
|
||||||
|
// responsibility back to the OpenDatabaseHelper
|
||||||
|
void OnError() { }
|
||||||
|
|
||||||
|
// Need an upgradeneeded event here.
|
||||||
|
already_AddRefed<nsDOMEvent> CreateSuccessEvent();
|
||||||
|
|
||||||
|
nsresult NotifyTransactionComplete(IDBTransaction* aTransaction);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// In-params
|
||||||
|
nsRefPtr<OpenDatabaseHelper> mOpenHelper;
|
||||||
|
nsRefPtr<IDBOpenDBRequest> mOpenRequest;
|
||||||
|
PRUint64 mRequestedVersion;
|
||||||
|
PRUint64 mCurrentVersion;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
NS_IMPL_THREADSAFE_ISUPPORTS1(OpenDatabaseHelper, nsIRunnable);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::Dispatch(nsIEventTarget* aTarget)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mState == eCreated, "We've already been dispatched?");
|
||||||
|
mState = eDBWork;
|
||||||
|
|
||||||
|
return aTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::RunImmediately()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mState == eCreated, "We've already been dispatched?");
|
||||||
|
NS_ASSERTION(NS_FAILED(mResultCode),
|
||||||
|
"Should only be short-circuiting if we failed!");
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "All hell is about to break lose!");
|
||||||
|
|
||||||
|
mState = eFiringEvents;
|
||||||
|
return this->Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::DoDatabaseWork()
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
bool correctThread;
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(IndexedDatabaseManager::Get()->IOThread()->
|
||||||
|
IsOnCurrentThread(&correctThread)) &&
|
||||||
|
correctThread,
|
||||||
|
"Running on the wrong thread!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (IndexedDatabaseManager::IsShuttingDown()) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> dbFile;
|
||||||
|
nsresult rv = GetDatabaseFile(mASCIIOrigin, mName, getter_AddRefs(dbFile));
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
rv = dbFile->GetPath(mDatabaseFilePath);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIFile> dbDirectory;
|
||||||
|
rv = dbFile->GetParent(getter_AddRefs(dbDirectory));
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
bool exists;
|
||||||
|
rv = dbDirectory->Exists(&exists);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
bool isDirectory;
|
||||||
|
rv = dbDirectory->IsDirectory(&isDirectory);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
NS_ENSURE_TRUE(isDirectory, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rv = dbDirectory->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
|
NS_ASSERTION(mgr, "This should never be null!");
|
||||||
|
|
||||||
|
rv = mgr->EnsureQuotaManagementForDirectory(dbDirectory);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageConnection> connection;
|
||||||
|
rv = CreateDatabaseConnection(mName, dbFile, getter_AddRefs(connection));
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
// Get the data version.
|
||||||
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
|
rv = connection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"SELECT dataVersion "
|
||||||
|
"FROM database"
|
||||||
|
), getter_AddRefs(stmt));
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
bool hasResult;
|
||||||
|
rv = stmt->ExecuteStep(&hasResult);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
if (!hasResult) {
|
||||||
|
NS_ERROR("Database has no dataVersion!");
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt64 dataVersion;
|
||||||
|
rv = stmt->GetInt64(0, &dataVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
if (dataVersion > JS_STRUCTURED_CLONE_VERSION) {
|
||||||
|
NS_ERROR("Bad data version!");
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataVersion < JS_STRUCTURED_CLONE_VERSION) {
|
||||||
|
// Need to upgrade the database, here, before returning to the main thread.
|
||||||
|
NS_NOTYETIMPLEMENTED("Implement me!");
|
||||||
|
}
|
||||||
|
|
||||||
|
mDatabaseId = HashString(mDatabaseFilePath);
|
||||||
|
NS_ASSERTION(mDatabaseId, "HashString gave us 0?!");
|
||||||
|
|
||||||
|
rv = IDBFactory::LoadDatabaseInformation(connection, mDatabaseId, &mCurrentVersion,
|
||||||
|
mObjectStores);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
for (PRUint32 i = 0; i < mObjectStores.Length(); i++) {
|
||||||
|
nsAutoPtr<ObjectStoreInfo>& objectStoreInfo = mObjectStores[i];
|
||||||
|
for (PRUint32 j = 0; j < objectStoreInfo->indexes.Length(); j++) {
|
||||||
|
IndexInfo& indexInfo = objectStoreInfo->indexes[j];
|
||||||
|
mLastIndexId = NS_MAX(indexInfo.id, mLastIndexId);
|
||||||
|
}
|
||||||
|
mLastObjectStoreId = NS_MAX(objectStoreInfo->id, mLastObjectStoreId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we need to do a VERSION_CHANGE transaction
|
||||||
|
if (mCurrentVersion > mRequestedVersion) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_VERSION_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
mState = mCurrentVersion != mRequestedVersion ?
|
||||||
|
eSetVersionPending :
|
||||||
|
eFiringEvents;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::StartSetVersion()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mState == eSetVersionPending, "Why are we here?");
|
||||||
|
|
||||||
|
// In case we fail, fire error events
|
||||||
|
mState = eFiringEvents;
|
||||||
|
|
||||||
|
nsresult rv = EnsureSuccessResult();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsTArray<nsString> storesToOpen;
|
||||||
|
nsRefPtr<IDBTransaction> transaction =
|
||||||
|
IDBTransaction::Create(mDatabase, storesToOpen,
|
||||||
|
IDBTransaction::VERSION_CHANGE,
|
||||||
|
kDefaultDatabaseTimeoutSeconds, true);
|
||||||
|
NS_ENSURE_TRUE(transaction, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
nsRefPtr<SetVersionHelper> helper =
|
||||||
|
new SetVersionHelper(transaction, mOpenDBRequest, this, mRequestedVersion,
|
||||||
|
mCurrentVersion);
|
||||||
|
|
||||||
|
IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get();
|
||||||
|
NS_ASSERTION(mgr, "This should never be null!");
|
||||||
|
|
||||||
|
rv = mgr->SetDatabaseVersion(mDatabase, mOpenDBRequest, mCurrentVersion,
|
||||||
|
mRequestedVersion, helper);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
// The SetVersionHelper is responsible for dispatching us back to the
|
||||||
|
// main thread again and changing the state to eSetVersionCompleted.
|
||||||
|
mState = eSetVersionPending;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
OpenDatabaseHelper::Run()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mState != eCreated, "Dispatch was not called?!?");
|
||||||
|
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
// If we need to queue up a SetVersionHelper, do that here.
|
||||||
|
if (mState == eSetVersionPending) {
|
||||||
|
nsresult rv = StartSetVersion();
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetError(rv);
|
||||||
|
// fall through and run the default error processing
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've done whatever work we need to do on the DB thread, and any
|
||||||
|
// SetVersion stuff is done by now.
|
||||||
|
NS_ASSERTION(mState == eFiringEvents ||
|
||||||
|
mState == eSetVersionCompleted, "Why are we here?");
|
||||||
|
|
||||||
|
if (mState == eSetVersionCompleted) {
|
||||||
|
mState = eFiringEvents;
|
||||||
|
} else {
|
||||||
|
// Notify the request that we're done, but only if we didn't just finish
|
||||||
|
// a SetVersionHelper. In the SetVersionHelper case, that helper tells
|
||||||
|
// the request that it is done, and we avoid calling NotifyHandlerCompleted
|
||||||
|
// twice.
|
||||||
|
|
||||||
|
nsresult rv = mOpenDBRequest->NotifyHelperCompleted(this);
|
||||||
|
if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
|
||||||
|
mResultCode = rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(mState == eFiringEvents, "Why are we here?");
|
||||||
|
|
||||||
|
if (NS_FAILED(mResultCode)) {
|
||||||
|
DispatchErrorEvent();
|
||||||
|
} else {
|
||||||
|
DispatchSuccessEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're on the DB thread, do that
|
||||||
|
NS_ASSERTION(mState == eDBWork, "Why are we here?");
|
||||||
|
mResultCode = DoDatabaseWork();
|
||||||
|
NS_ASSERTION(mState != eDBWork, "We should be doing something else now.");
|
||||||
|
|
||||||
|
return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::EnsureSuccessResult()
|
||||||
|
{
|
||||||
|
DatabaseInfo* dbInfo;
|
||||||
|
if (DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
|
||||||
|
NS_ASSERTION(dbInfo->referenceCount, "Bad reference count!");
|
||||||
|
++dbInfo->referenceCount;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
NS_ASSERTION(dbInfo->name == mName &&
|
||||||
|
dbInfo->version == mCurrentVersion &&
|
||||||
|
dbInfo->id == mDatabaseId &&
|
||||||
|
dbInfo->filePath == mDatabaseFilePath,
|
||||||
|
"Metadata mismatch!");
|
||||||
|
|
||||||
|
PRUint32 objectStoreCount = mObjectStores.Length();
|
||||||
|
for (PRUint32 index = 0; index < objectStoreCount; index++) {
|
||||||
|
nsAutoPtr<ObjectStoreInfo>& info = mObjectStores[index];
|
||||||
|
NS_ASSERTION(info->databaseId == mDatabaseId, "Huh?!");
|
||||||
|
|
||||||
|
ObjectStoreInfo* otherInfo;
|
||||||
|
NS_ASSERTION(ObjectStoreInfo::Get(mDatabaseId, info->name, &otherInfo),
|
||||||
|
"ObjectStore not known!");
|
||||||
|
|
||||||
|
NS_ASSERTION(info->name == otherInfo->name &&
|
||||||
|
info->id == otherInfo->id &&
|
||||||
|
info->keyPath == otherInfo->keyPath &&
|
||||||
|
info->autoIncrement == otherInfo->autoIncrement &&
|
||||||
|
info->databaseId == otherInfo->databaseId,
|
||||||
|
"Metadata mismatch!");
|
||||||
|
NS_ASSERTION(dbInfo->ContainsStoreName(info->name),
|
||||||
|
"Object store names out of date!");
|
||||||
|
NS_ASSERTION(info->indexes.Length() == otherInfo->indexes.Length(),
|
||||||
|
"Bad index length!");
|
||||||
|
|
||||||
|
PRUint32 indexCount = info->indexes.Length();
|
||||||
|
for (PRUint32 indexIndex = 0; indexIndex < indexCount; indexIndex++) {
|
||||||
|
const IndexInfo& indexInfo = info->indexes[indexIndex];
|
||||||
|
const IndexInfo& otherIndexInfo = otherInfo->indexes[indexIndex];
|
||||||
|
NS_ASSERTION(indexInfo.id == otherIndexInfo.id,
|
||||||
|
"Bad index id!");
|
||||||
|
NS_ASSERTION(indexInfo.name == otherIndexInfo.name,
|
||||||
|
"Bad index name!");
|
||||||
|
NS_ASSERTION(indexInfo.keyPath == otherIndexInfo.keyPath,
|
||||||
|
"Bad index keyPath!");
|
||||||
|
NS_ASSERTION(indexInfo.unique == otherIndexInfo.unique,
|
||||||
|
"Bad index unique value!");
|
||||||
|
NS_ASSERTION(indexInfo.autoIncrement == otherIndexInfo.autoIncrement,
|
||||||
|
"Bad index autoIncrement value!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nsAutoPtr<DatabaseInfo> newInfo(new DatabaseInfo());
|
||||||
|
|
||||||
|
newInfo->name = mName;
|
||||||
|
newInfo->id = mDatabaseId;
|
||||||
|
newInfo->filePath = mDatabaseFilePath;
|
||||||
|
newInfo->referenceCount = 1;
|
||||||
|
|
||||||
|
if (!DatabaseInfo::Put(newInfo)) {
|
||||||
|
NS_ERROR("Failed to add to hash!");
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbInfo = newInfo.forget();
|
||||||
|
|
||||||
|
nsresult rv = IDBFactory::UpdateDatabaseMetadata(dbInfo, mCurrentVersion,
|
||||||
|
mObjectStores);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
NS_ASSERTION(mObjectStores.IsEmpty(), "Should have swapped!");
|
||||||
|
}
|
||||||
|
|
||||||
|
dbInfo->nextObjectStoreId = mLastObjectStoreId + 1;
|
||||||
|
dbInfo->nextIndexId = mLastIndexId + 1;
|
||||||
|
|
||||||
|
nsRefPtr<IDBDatabase> database =
|
||||||
|
IDBDatabase::Create(mOpenDBRequest->ScriptContext(),
|
||||||
|
mOpenDBRequest->Owner(), dbInfo, mASCIIOrigin);
|
||||||
|
if (!database) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(!mDatabase, "Shouldn't have a database yet!");
|
||||||
|
mDatabase.swap(database);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::GetSuccessResult(JSContext* aCx,
|
||||||
|
jsval* aVal)
|
||||||
|
{
|
||||||
|
// Be careful not to load the database twice.
|
||||||
|
if (!mDatabase) {
|
||||||
|
nsresult rv = EnsureSuccessResult();
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WrapNative(aCx, NS_ISUPPORTS_CAST(nsIDOMEventTarget*, mDatabase),
|
||||||
|
aVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
OpenDatabaseHelper::NotifySetVersionFinished()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
|
||||||
|
NS_ASSERTION(mState = eSetVersionPending, "How did we get here?");
|
||||||
|
|
||||||
|
mState = eSetVersionCompleted;
|
||||||
|
|
||||||
|
// Dispatch ourself back to the main thread
|
||||||
|
return NS_DispatchToCurrentThread(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenDatabaseHelper::DispatchSuccessEvent()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mDatabase, "Doesn't seem very successful to me.");
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMEvent> event =
|
||||||
|
CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
|
||||||
|
if (!event) {
|
||||||
|
NS_ERROR("Failed to create event!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dummy;
|
||||||
|
mOpenDBRequest->DispatchEvent(event, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenDatabaseHelper::DispatchErrorEvent()
|
||||||
|
{
|
||||||
|
nsRefPtr<nsDOMEvent> event =
|
||||||
|
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR));
|
||||||
|
if (!event) {
|
||||||
|
NS_ERROR("Failed to create event!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRUint16 errorCode = 0;
|
||||||
|
DebugOnly<nsresult> rv =
|
||||||
|
mOpenDBRequest->GetErrorCode(&errorCode);
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "This shouldn't be failing at this point!");
|
||||||
|
if (!errorCode) {
|
||||||
|
mOpenDBRequest->SetError(mResultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dummy;
|
||||||
|
mOpenDBRequest->DispatchEvent(event, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED0(SetVersionHelper, AsyncConnectionHelper);
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aConnection, "Passing a null connection!");
|
||||||
|
|
||||||
|
nsCOMPtr<mozIStorageStatement> stmt;
|
||||||
|
nsresult rv = aConnection->CreateStatement(NS_LITERAL_CSTRING(
|
||||||
|
"UPDATE database "
|
||||||
|
"SET version = :version"
|
||||||
|
), getter_AddRefs(stmt));
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
rv = stmt->BindInt64ByName(NS_LITERAL_CSTRING("version"),
|
||||||
|
mRequestedVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
if (NS_FAILED(stmt->Execute())) {
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetVersionHelper::GetSuccessResult(JSContext* aCx,
|
||||||
|
jsval* aVal)
|
||||||
|
{
|
||||||
|
DatabaseInfo* info;
|
||||||
|
if (!DatabaseInfo::Get(mDatabase->Id(), &info)) {
|
||||||
|
NS_ERROR("This should never fail!");
|
||||||
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
}
|
||||||
|
info->version = mRequestedVersion;
|
||||||
|
|
||||||
|
NS_ASSERTION(mTransaction, "Better have a transaction!");
|
||||||
|
|
||||||
|
mOpenRequest->SetTransaction(mTransaction);
|
||||||
|
|
||||||
|
return WrapNative(aCx, NS_ISUPPORTS_CAST(nsIDOMEventTarget*, mDatabase),
|
||||||
|
aVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsDOMEvent>
|
||||||
|
SetVersionHelper::CreateSuccessEvent()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mCurrentVersion < mRequestedVersion, "Huh?");
|
||||||
|
|
||||||
|
return IDBVersionChangeEvent::CreateUpgradeNeeded(mCurrentVersion,
|
||||||
|
mRequestedVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetVersionHelper::NotifyTransactionComplete(IDBTransaction* aTransaction)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ASSERTION(aTransaction, "This is unexpected.");
|
||||||
|
NS_ASSERTION(mOpenRequest, "Why don't we have a request?");
|
||||||
|
|
||||||
|
// If we hit an error, the OpenDatabaseHelper needs to get that error too.
|
||||||
|
nsresult rv = GetResultCode();
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
mOpenHelper->SetError(rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the transaction was aborted, we should throw an error message.
|
||||||
|
if (aTransaction->IsAborted()) {
|
||||||
|
mOpenHelper->SetError(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
mOpenRequest->SetTransaction(nsnull);
|
||||||
|
|
||||||
|
rv = mOpenHelper->NotifySetVersionFinished();
|
||||||
|
mOpenHelper = nsnull;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Indexed Database.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* The Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Ben Turner <bent.mozilla@gmail.com>
|
||||||
|
* Kyle Huey <me@kylehuey.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_indexeddb_opendatabasehelper_h__
|
||||||
|
#define mozilla_dom_indexeddb_opendatabasehelper_h__
|
||||||
|
|
||||||
|
#include "AsyncConnectionHelper.h"
|
||||||
|
#include "DatabaseInfo.h"
|
||||||
|
#include "IDBDatabase.h"
|
||||||
|
#include "IDBRequest.h"
|
||||||
|
|
||||||
|
#include "nsIRunnable.h"
|
||||||
|
|
||||||
|
class mozIStorageConnection;
|
||||||
|
|
||||||
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
|
class OpenDatabaseHelper : public HelperBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenDatabaseHelper(IDBOpenDBRequest* aRequest,
|
||||||
|
const nsAString& aName,
|
||||||
|
const nsACString& aASCIIOrigin,
|
||||||
|
PRUint64 aRequestedVersion)
|
||||||
|
: HelperBase(aRequest), mOpenDBRequest(aRequest), mName(aName),
|
||||||
|
mASCIIOrigin(aASCIIOrigin), mRequestedVersion(aRequestedVersion),
|
||||||
|
mCurrentVersion(0), mDataVersion(DB_SCHEMA_VERSION), mDatabaseId(0),
|
||||||
|
mLastObjectStoreId(0), mLastIndexId(0), mState(eCreated),
|
||||||
|
mResultCode(NS_OK)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
|
||||||
|
nsresult Dispatch(nsIEventTarget* aDatabaseThread);
|
||||||
|
nsresult RunImmediately();
|
||||||
|
|
||||||
|
void SetError(nsresult rv)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_FAILED(rv), "Why are you telling me?");
|
||||||
|
mResultCode = rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult GetResultCode()
|
||||||
|
{
|
||||||
|
return mResultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult NotifySetVersionFinished();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Methods only called on the main thread
|
||||||
|
nsresult EnsureSuccessResult();
|
||||||
|
nsresult StartSetVersion();
|
||||||
|
nsresult GetSuccessResult(JSContext* aCx,
|
||||||
|
jsval* aVal);
|
||||||
|
void DispatchSuccessEvent();
|
||||||
|
void DispatchErrorEvent();
|
||||||
|
|
||||||
|
// Methods only called on the DB thread
|
||||||
|
nsresult DoDatabaseWork();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// In-params.
|
||||||
|
nsRefPtr<IDBOpenDBRequest> mOpenDBRequest;
|
||||||
|
nsString mName;
|
||||||
|
nsCString mASCIIOrigin;
|
||||||
|
PRUint64 mRequestedVersion;
|
||||||
|
|
||||||
|
// Out-params.
|
||||||
|
nsTArray<nsAutoPtr<ObjectStoreInfo> > mObjectStores;
|
||||||
|
PRUint64 mCurrentVersion;
|
||||||
|
PRUint32 mDataVersion;
|
||||||
|
nsString mDatabaseFilePath;
|
||||||
|
PRUint32 mDatabaseId;
|
||||||
|
PRInt64 mLastObjectStoreId;
|
||||||
|
PRInt64 mLastIndexId;
|
||||||
|
nsRefPtr<IDBDatabase> mDatabase;
|
||||||
|
|
||||||
|
// State variables
|
||||||
|
enum OpenDatabaseState {
|
||||||
|
eCreated = 0, // Not yet dispatched to the DB thread
|
||||||
|
eDBWork, // Waiting to do/doing work on the DB thread
|
||||||
|
eFiringEvents, // Waiting to fire/firing events on the main thread
|
||||||
|
eSetVersionPending, // Waiting on a SetVersionHelper
|
||||||
|
eSetVersionCompleted, // SetVersionHelper is done
|
||||||
|
};
|
||||||
|
OpenDatabaseState mState;
|
||||||
|
nsresult mResultCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
|
#endif // mozilla_dom_indexeddb_opendatabasehelper_h__
|
|
@ -51,12 +51,12 @@ interface nsIDOMEventListener;
|
||||||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
|
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(42b38d02-1a29-45f0-99ef-04fd5b441270)]
|
[scriptable, uuid(ac14faa5-261c-4a84-9616-a700fd606f83)]
|
||||||
interface nsIIDBDatabase : nsISupports
|
interface nsIIDBDatabase : nsISupports
|
||||||
{
|
{
|
||||||
readonly attribute DOMString name;
|
readonly attribute DOMString name;
|
||||||
|
|
||||||
readonly attribute DOMString version;
|
readonly attribute unsigned long long version;
|
||||||
|
|
||||||
readonly attribute nsIDOMDOMStringList objectStoreNames;
|
readonly attribute nsIDOMDOMStringList objectStoreNames;
|
||||||
|
|
||||||
|
@ -76,10 +76,6 @@ interface nsIIDBDatabase : nsISupports
|
||||||
void
|
void
|
||||||
deleteObjectStore(in AString name);
|
deleteObjectStore(in AString name);
|
||||||
|
|
||||||
[implicit_jscontext]
|
|
||||||
nsIIDBRequest
|
|
||||||
setVersion(in AString version);
|
|
||||||
|
|
||||||
[optional_argc, implicit_jscontext]
|
[optional_argc, implicit_jscontext]
|
||||||
nsIIDBTransaction
|
nsIIDBTransaction
|
||||||
transaction(in nsIVariant storeNames, // js array of strings
|
transaction(in nsIVariant storeNames, // js array of strings
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "nsISupports.idl"
|
#include "nsISupports.idl"
|
||||||
|
|
||||||
interface nsIIDBKeyRange;
|
interface nsIIDBKeyRange;
|
||||||
interface nsIIDBRequest;
|
interface nsIIDBOpenDBRequest;
|
||||||
interface nsIVariant;
|
interface nsIVariant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,10 +49,10 @@ interface nsIVariant;
|
||||||
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
|
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(137d17a5-fac5-4788-87b5-bc3806d7cfaf)]
|
[scriptable, uuid(4b23254a-ce6d-4442-8c90-9d8744d3c633)]
|
||||||
interface nsIIDBFactory : nsISupports
|
interface nsIIDBFactory : nsISupports
|
||||||
{
|
{
|
||||||
[implicit_jscontext]
|
[implicit_jscontext]
|
||||||
nsIIDBRequest
|
nsIIDBOpenDBRequest
|
||||||
open(in AString name);
|
open(in AString name, in long long version);
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
interface nsIDOMEventListener;
|
interface nsIDOMEventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IDBReqeust interface. See
|
* IDBOpenDBRequest interface. See
|
||||||
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
|
* http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBOpenDBRequest
|
||||||
* information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(aeaabb0d-594a-4c58-ac5e-68ef3bff927d)]
|
[scriptable, uuid(91010fbe-1dfb-435d-852e-288d2804c0a7)]
|
||||||
interface nsIIDBVersionChangeRequest : nsISupports
|
interface nsIIDBOpenDBRequest : nsISupports
|
||||||
{
|
{
|
||||||
attribute nsIDOMEventListener onblocked;
|
attribute nsIDOMEventListener onblocked;
|
||||||
|
attribute nsIDOMEventListener onupgradeneeded;
|
||||||
};
|
};
|
|
@ -39,8 +39,9 @@
|
||||||
|
|
||||||
#include "nsIDOMEvent.idl"
|
#include "nsIDOMEvent.idl"
|
||||||
|
|
||||||
[scriptable, uuid(6a232c30-1bc4-4d5b-9ce0-6e7c08934755)]
|
[scriptable, uuid(2c5159dc-7d71-4fc6-a3b3-884ed7586456)]
|
||||||
interface nsIIDBVersionChangeEvent : nsIDOMEvent
|
interface nsIIDBVersionChangeEvent : nsIDOMEvent
|
||||||
{
|
{
|
||||||
readonly attribute AString version;
|
readonly attribute unsigned long long oldVersion;
|
||||||
|
readonly attribute unsigned long long newVersion;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script>
|
<script>
|
||||||
mozIndexedDB.open(parent.location).onsuccess = function(e) {
|
var request = mozIndexedDB.open(parent.location, 1);
|
||||||
var db = e.target.result;
|
request.onupgradeneeded = function(e) {
|
||||||
// This should never be called
|
var db = e.target.result;
|
||||||
db.onversionchange = function(e) {
|
// This should never be called
|
||||||
db.transaction(["mystore"]).objectStore("mystore").put({ hello: "fail" }, 42);
|
db.onversionchange = function(e) {
|
||||||
}
|
db.transaction(["mystore"]).objectStore("mystore").put({ hello: "fail" }, 42);
|
||||||
db.setVersion("1.0").onsuccess = function(e) {
|
}
|
||||||
trans = e.target.transaction;
|
var trans = e.target.transaction;
|
||||||
if (db.objectStoreNames.contains("mystore")) {
|
if (db.objectStoreNames.contains("mystore")) {
|
||||||
db.deleteObjectStore("mystore");
|
db.deleteObjectStore("mystore");
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ mozIndexedDB.open(parent.location).onsuccess = function(e) {
|
||||||
parent.postMessage("go", "http://mochi.test:8888");
|
parent.postMessage("go", "http://mochi.test:8888");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -2,26 +2,24 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<script>
|
<script>
|
||||||
var res = {};
|
var res = {};
|
||||||
mozIndexedDB.open(parent.location).onsuccess = function(e) {
|
var request = mozIndexedDB.open(parent.location, 2);
|
||||||
var db = e.target.result;
|
request.onblocked = function() {
|
||||||
res.version = db.version;
|
|
||||||
res.storeCount = db.objectStoreNames.length;
|
|
||||||
|
|
||||||
req = db.setVersion("2.0");
|
|
||||||
req.onblocked = function() {
|
|
||||||
res.blockedFired = true;
|
res.blockedFired = true;
|
||||||
}
|
}
|
||||||
req.onsuccess = function(e) {
|
request.onupgradeneeded = function(e) {
|
||||||
var trans = req.transaction;
|
var db = e.target.result;
|
||||||
|
res.version = db.version;
|
||||||
|
res.storeCount = db.objectStoreNames.length;
|
||||||
|
|
||||||
|
var trans = request.transaction;
|
||||||
trans.objectStore("mystore").get(42).onsuccess = function(e) {
|
trans.objectStore("mystore").get(42).onsuccess = function(e) {
|
||||||
res.value = JSON.stringify(e.target.result);
|
res.value = JSON.stringify(e.target.result);
|
||||||
}
|
}
|
||||||
trans.oncomplete = function() {
|
trans.oncomplete = function() {
|
||||||
parent.postMessage(JSON.stringify(res), "http://mochi.test:8888");
|
parent.postMessage(JSON.stringify(res), "http://mochi.test:8888");
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -33,7 +33,7 @@ function test1()
|
||||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
setFinishedCallback(function(result, exception) {
|
setFinishedCallback(function(result, exception) {
|
||||||
ok(result == "11", "Set version on database in " + testPageURL1);
|
ok(result == 11, "Set version on database in " + testPageURL1);
|
||||||
ok(!exception, "No exception");
|
ok(!exception, "No exception");
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ function test2()
|
||||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
setFinishedCallback(function(result, exception) {
|
setFinishedCallback(function(result, exception) {
|
||||||
ok(result == "11", "Set version on database in " + testPageURL2);
|
ok(result == 11, "Set version on database in " + testPageURL2);
|
||||||
ok(!exception, "No exception");
|
ok(!exception, "No exception");
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ function test4()
|
||||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
setFinishedCallback(function(result, exception) {
|
setFinishedCallback(function(result, exception) {
|
||||||
ok(result == "11", "Got correct version on database in " + testPageURL3);
|
ok(result == 11, "Got correct version on database in " + testPageURL3);
|
||||||
ok(!exception, "No exception");
|
ok(!exception, "No exception");
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
@ -97,7 +97,9 @@ function test5()
|
||||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
setFinishedCallback(function(result, exception) {
|
setFinishedCallback(function(result, exception) {
|
||||||
ok(result == "", "Got correct version on database in " + testPageURL4);
|
// XXXkhuey this isn't really testing anything until we get the default
|
||||||
|
// version behavior implemented ...
|
||||||
|
ok(result == 11, "Got correct version on database in " + testPageURL4);
|
||||||
ok(!exception, "No exception");
|
ok(!exception, "No exception");
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open("browser_forgetThisSite.js");
|
let request = mozIndexedDB.open("browser_forgetThisSite.js", 11);
|
||||||
request.onerror = grabEventAndContinueHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
if (event.type == "error") {
|
if (event.type == "error") {
|
||||||
|
@ -20,17 +20,7 @@
|
||||||
else {
|
else {
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("11");
|
testResult = db.version;
|
||||||
request.onerror = grabEventAndContinueHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
if (event.type == "error") {
|
|
||||||
testException = event.target.errorCode;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
testResult = db.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = finishTest;
|
event.target.transaction.oncomplete = finishTest;
|
||||||
yield;
|
yield;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open("browser_forgetThisSite.js");
|
let request = mozIndexedDB.open("browser_forgetThisSite.js", 11);
|
||||||
request.onerror = grabEventAndContinueHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = grabEventAndContinueHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
|
const READ_WRITE = Components.interfaces.nsIIDBTransaction.READ_WRITE;
|
||||||
|
|
||||||
let db;
|
let db;
|
||||||
|
let version = window.location.href.charAt(window.location.href.length - 1);
|
||||||
|
|
||||||
function onAddMore() {
|
function onAddMore() {
|
||||||
let transaction = db.transaction("foo", READ_WRITE);
|
let transaction = db.transaction("foo", READ_WRITE);
|
||||||
|
@ -36,10 +37,11 @@
|
||||||
window.removeEventListener("indexedDB-addMore", onAddMore, true);
|
window.removeEventListener("indexedDB-addMore", onAddMore, true);
|
||||||
window.removeEventListener("indexedDB-done", onDone, true);
|
window.removeEventListener("indexedDB-done", onDone, true);
|
||||||
|
|
||||||
let request = db.setVersion("2");
|
let request = mozIndexedDB.open(window.location.pathname, version++);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = function(event) {
|
request.onupgradeneeded = function(event) {
|
||||||
db.deleteObjectStore("foo");
|
db.deleteObjectStore("foo");
|
||||||
|
db.onversionchange = function () { db.close(); };
|
||||||
request.transaction.oncomplete = function(event) {
|
request.transaction.oncomplete = function(event) {
|
||||||
testResult = "finished";
|
testResult = "finished";
|
||||||
testException = undefined;
|
testException = undefined;
|
||||||
|
@ -56,17 +58,14 @@
|
||||||
window.addEventListener("indexedDB-addMore", onAddMore, true);
|
window.addEventListener("indexedDB-addMore", onAddMore, true);
|
||||||
window.addEventListener("indexedDB-done", onDone, true);
|
window.addEventListener("indexedDB-done", onDone, true);
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, version++, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
db = event.target.result;
|
db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
db.onversionchange = function () { db.close(); };
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ function test1()
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
info("loading test page: " + testPageURL);
|
info("loading test page: " + testPageURL);
|
||||||
content.location = testPageURL;
|
content.location = testPageURL + "?v=1";
|
||||||
}
|
}
|
||||||
|
|
||||||
function test2()
|
function test2()
|
||||||
|
@ -136,5 +136,5 @@ function test2()
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
info("loading test page: " + testPageURL);
|
info("loading test page: " + testPageURL);
|
||||||
content.location = testPageURL;
|
content.location = testPageURL + "?v=3";
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ function test1()
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
info("loading test page: " + testPageURL);
|
info("loading test page: " + testPageURL);
|
||||||
content.location = testPageURL;
|
content.location = testPageURL + "?v=5";
|
||||||
}
|
}
|
||||||
|
|
||||||
function test2()
|
function test2()
|
||||||
|
@ -145,5 +145,5 @@ function test2()
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
info("loading test page: " + testPageURL);
|
info("loading test page: " + testPageURL);
|
||||||
content.location = testPageURL;
|
content.location = testPageURL + "?v=7";
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,27 +56,20 @@
|
||||||
.add(uri, "indexedDB",
|
.add(uri, "indexedDB",
|
||||||
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onsuccess = unexpectedSuccessHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
is(db.version, "", "Correct version");
|
is(db.version, 1, "Correct version");
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
||||||
|
|
||||||
let request = db.setVersion("1");
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = unexpectedSuccessHandler;
|
event.target.transaction.oncomplete = unexpectedSuccessHandler;
|
||||||
event.target.transaction.onabort = grabEventAndContinueHandler;
|
event.target.transaction.onabort = grabEventAndContinueHandler;
|
||||||
|
|
||||||
is(db.version, "1", "Correct version");
|
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
|
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
||||||
|
@ -95,13 +88,21 @@
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
is(event.type, "abort", "Got a transaction abort event");
|
is(event.type, "abort", "Got a transaction abort event");
|
||||||
is(db.version, "", "Correct version");
|
//todo(db.version, 1, "Correct version");
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
event = yield;
|
event = yield;
|
||||||
|
is(event.type, "error", "Got request error event");
|
||||||
|
is(event.target.errorCode, IDBDatabaseException.ABORT_ERR, "Right error code");
|
||||||
|
|
||||||
|
db.close();
|
||||||
|
|
||||||
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
|
request.onerror = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||||
event.target.transaction.onabort = unexpectedSuccessHandler;
|
event.target.transaction.onabort = unexpectedSuccessHandler;
|
||||||
|
|
|
@ -95,20 +95,15 @@
|
||||||
.add(uri, "indexedDB",
|
.add(uri, "indexedDB",
|
||||||
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorEventCounter;
|
db.onerror = errorEventCounter;
|
||||||
db.addEventListener("error", errorEventCounter, true);
|
db.addEventListener("error", errorEventCounter, true);
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
|
@ -59,9 +59,25 @@
|
||||||
.add(uri, "indexedDB",
|
.add(uri, "indexedDB",
|
||||||
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = errorHandler;
|
||||||
|
request.onupgradeneeded = function () {
|
||||||
|
throw "STOP";
|
||||||
|
};
|
||||||
|
|
||||||
|
let event = yield;
|
||||||
|
|
||||||
|
is(event.type, "error",
|
||||||
|
"Throwing during an upgradeneeded event should fire an error.");
|
||||||
|
ok(event.target.result instanceof IDBDatabase, "Should have a DB");
|
||||||
|
event.target.result.close();
|
||||||
|
|
||||||
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
|
request.onerror = grabEventAndContinueHandler;
|
||||||
|
request.onblocked = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
let openrequest = request;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
@ -69,16 +85,10 @@
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
is(db.version, "", "Correct version");
|
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = unexpectedSuccessHandler;
|
event.target.transaction.oncomplete = unexpectedSuccessHandler;
|
||||||
event.target.transaction.onabort = grabEventAndContinueHandler;
|
event.target.transaction.onabort = grabEventAndContinueHandler;
|
||||||
|
|
||||||
is(db.version, "1", "Correct version");
|
is(db.version, 1, "Correct version");
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
|
@ -95,6 +105,11 @@
|
||||||
|
|
||||||
is(event.type, "abort", "Got transaction abort event");
|
is(event.type, "abort", "Got transaction abort event");
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
|
||||||
|
is(event.type, "error", "Got IDBOpenDBRequest error event");
|
||||||
|
is(event.target, openrequest, "Right event target");
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
yield;
|
yield;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,15 @@
|
||||||
<script>
|
<script>
|
||||||
var db;
|
var db;
|
||||||
function startDBWork() {
|
function startDBWork() {
|
||||||
mozIndexedDB.open(parent.location).onsuccess = function(e) {
|
mozIndexedDB.open(parent.location, 1).onupgradeneeded = function(e) {
|
||||||
db = e.target.result;
|
db = e.target.result;
|
||||||
db.setVersion("1.0").onsuccess = function(e) {
|
var trans = e.target.transaction;
|
||||||
var trans = e.target.transaction;
|
if (db.objectStoreNames.contains("mystore")) {
|
||||||
if (db.objectStoreNames.contains("mystore")) {
|
db.deleteObjectStore("mystore");
|
||||||
db.deleteObjectStore("mystore");
|
}
|
||||||
}
|
var store = db.createObjectStore("mystore");
|
||||||
var store = db.createObjectStore("mystore");
|
store.add({ hello: "world" }, 42);
|
||||||
store.add({ hello: "world" }, 42);
|
trans.oncomplete = madeMod;
|
||||||
trans.oncomplete = madeMod;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,18 +15,13 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = request.result;
|
let db = request.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
ok(event.target === request, "Good event target");
|
ok(event.target === request, "Good event target");
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "" });
|
||||||
|
|
|
@ -12,17 +12,14 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = request.result;
|
let db = request.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "id",
|
let objectStore = db.createObjectStore("foo", { keyPath: "id",
|
||||||
autoIncrement: true });
|
autoIncrement: true });
|
||||||
objectStore.createIndex("first","first");
|
objectStore.createIndex("first","first");
|
||||||
|
|
|
@ -15,18 +15,13 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = request.result;
|
let db = request.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "keyPath" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "keyPath" });
|
||||||
|
|
||||||
request = objectStore.add({keyPath:"foo"});
|
request = objectStore.add({keyPath:"foo"});
|
||||||
|
@ -36,6 +31,7 @@
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request = objectStore.add({});
|
request = objectStore.add({});
|
||||||
|
ok(false, "Shouldn't get here!");
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
is(e.code, IDBDatabaseException.DATA_ERR, "Good error");
|
is(e.code, IDBDatabaseException.DATA_ERR, "Good error");
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
iframe.src = "bfcache_iframe2.html";
|
iframe.src = "bfcache_iframe2.html";
|
||||||
res = JSON.parse((yield).data);
|
res = JSON.parse((yield).data);
|
||||||
is(res.version, "1.0", "version was set correctly");
|
is(res.version, 2, "version was set correctly");
|
||||||
is(res.storeCount, 1, "correct set of stores");
|
is(res.storeCount, 1, "correct set of stores");
|
||||||
ok(!("blockedFired" in res), "blocked shouldn't fire");
|
ok(!("blockedFired" in res), "blocked shouldn't fire");
|
||||||
is(res.value, JSON.stringify({ hello: "world" }),
|
is(res.value, JSON.stringify({ hello: "world" }),
|
||||||
|
|
|
@ -18,18 +18,13 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const entryCount = 1000;
|
const entryCount = 1000;
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = request.result;
|
let db = request.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
|
@ -27,17 +27,12 @@
|
||||||
{ name: "3", keyPath: "value", options: { unique: false } },
|
{ name: "3", keyPath: "value", options: { unique: false } },
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||||
let info = objectStoreInfo[i];
|
let info = objectStoreInfo[i];
|
||||||
let objectStore = info.hasOwnProperty("options") ?
|
let objectStore = info.hasOwnProperty("options") ?
|
||||||
|
|
|
@ -15,26 +15,29 @@
|
||||||
const data = { id: new Date().getTime(),
|
const data = { id: new Date().getTime(),
|
||||||
num: parseInt(Math.random() * 1000) };
|
num: parseInt(Math.random() * 1000) };
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
|
|
||||||
// Make object store, add data.
|
// Make object store, add data.
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "id" });
|
||||||
objectStore.add(data);
|
objectStore.add(data);
|
||||||
yield;
|
yield;
|
||||||
|
db.close();
|
||||||
|
|
||||||
db.setVersion("2").onsuccess = grabEventAndContinueHandler;
|
let request = mozIndexedDB.open(window.location.pathname, 2);
|
||||||
event = yield;
|
request.onerror = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
let event = yield;
|
||||||
|
|
||||||
|
let db2 = event.target.result;
|
||||||
|
db2.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
|
|
||||||
|
@ -46,8 +49,8 @@
|
||||||
let seenCount = 0;
|
let seenCount = 0;
|
||||||
|
|
||||||
|
|
||||||
db.transaction("foo").objectStore("foo").index("foo")
|
db2.transaction("foo").objectStore("foo").index("foo")
|
||||||
.openKeyCursor().onsuccess = function(event) {
|
.openKeyCursor().onsuccess = function(event) {
|
||||||
let cursor = event.target.result;
|
let cursor = event.target.result;
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
is(cursor.key, data.num, "Good key");
|
is(cursor.key, data.num, "Good key");
|
||||||
|
|
|
@ -31,25 +31,16 @@
|
||||||
{ name: "11", options: { keyPath: "foo", autoIncrement: true } }
|
{ name: "11", options: { keyPath: "foo", autoIncrement: true } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
ok(event.target.source === mozIndexedDB,
|
|
||||||
"event.target.source is correct");
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
let count = db.objectStoreNames.length;
|
let count = db.objectStoreNames.length;
|
||||||
is(count, 0, "correct objectStoreNames length");
|
is(count, 0, "correct objectStoreNames length");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
ok(event.target.source === db, "event.target.source is correct");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
db.createObjectStore(null);
|
db.createObjectStore(null);
|
||||||
ok(false, "createObjectStore with null name should throw");
|
ok(false, "createObjectStore with null name should throw");
|
||||||
|
|
|
@ -29,16 +29,12 @@
|
||||||
// Post-add and post-remove data ordered by name.
|
// Post-add and post-remove data ordered by name.
|
||||||
const objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ];
|
const objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
|
||||||
|
|
|
@ -30,23 +30,18 @@
|
||||||
entry: { data: START_DATA } },
|
entry: { data: START_DATA } },
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
let db = event.target.result;
|
|
||||||
|
|
||||||
for (let i = 0; i < objectStoreInfo.length; i++) {
|
for (let i = 0; i < objectStoreInfo.length; i++) {
|
||||||
// Create our object stores.
|
// Create our object stores.
|
||||||
let info = objectStoreInfo[i];
|
let info = objectStoreInfo[i];
|
||||||
|
|
||||||
ok(true, "1");
|
ok(true, "1");
|
||||||
request = db.setVersion("1");
|
request = mozIndexedDB.open(name, i + 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
ok(true, "2");
|
ok(true, "2");
|
||||||
let objectStore = info.hasOwnProperty("options") ?
|
let objectStore = info.hasOwnProperty("options") ?
|
||||||
db.createObjectStore(info.name, info.options) :
|
db.createObjectStore(info.name, info.options) :
|
||||||
|
@ -99,6 +94,7 @@
|
||||||
ok(true, "7");
|
ok(true, "7");
|
||||||
SimpleTest.ok(obj.data, event.target.result.data,
|
SimpleTest.ok(obj.data, event.target.result.data,
|
||||||
"Unique index was properly updated.");
|
"Unique index was properly updated.");
|
||||||
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
|
|
|
@ -19,18 +19,13 @@
|
||||||
|
|
||||||
is(keys.length, sortedKeys.length, "Good key setup");
|
is(keys.length, sortedKeys.length, "Good key setup");
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("autoIncrement",
|
let objectStore = db.createObjectStore("autoIncrement",
|
||||||
{ autoIncrement: true });
|
{ autoIncrement: true });
|
||||||
|
|
||||||
|
|
|
@ -16,22 +16,14 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const objectStoreName = "Objects";
|
const objectStoreName = "Objects";
|
||||||
|
|
||||||
var request = mozIndexedDB.open(name, description);
|
var request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
var event = yield;
|
var event = yield;
|
||||||
|
|
||||||
ok(event.target.source === mozIndexedDB, "correct event.target.source");
|
is(event.target.source, null, "correct event.target.source");
|
||||||
|
|
||||||
var db = event.target.result;
|
var db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
ok(event.target.source === db, "correct event.target.source");
|
|
||||||
|
|
||||||
var objectStore = db.createObjectStore(objectStoreName,
|
var objectStore = db.createObjectStore(objectStoreName,
|
||||||
{ autoIncrement: true });
|
{ autoIncrement: true });
|
||||||
request = objectStore.add({});
|
request = objectStore.add({});
|
||||||
|
|
|
@ -17,18 +17,13 @@
|
||||||
|
|
||||||
const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
|
const values = [ "a", "1", 1, "foo", 300, true, false, 4.5, null ];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
request = objectStore.getAll();
|
request = objectStore.getAll();
|
||||||
|
|
|
@ -17,18 +17,13 @@
|
||||||
const objectStore = { name: "Objects",
|
const objectStore = { name: "Objects",
|
||||||
options: { keyPath: "id", autoIncrement: true } };
|
options: { keyPath: "id", autoIncrement: true } };
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db1 = event.target.result;
|
let db1 = event.target.result;
|
||||||
|
|
||||||
request = db1.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
is(db1.objectStoreNames.length, 0, "No objectStores in db1");
|
is(db1.objectStoreNames.length, 0, "No objectStores in db1");
|
||||||
|
|
||||||
db1.createObjectStore(objectStore.name, objectStore.options);
|
db1.createObjectStore(objectStore.name, objectStore.options);
|
||||||
|
@ -36,7 +31,7 @@
|
||||||
continueToNextStep();
|
continueToNextStep();
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
request = mozIndexedDB.open(name, description);
|
request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
|
@ -57,18 +57,13 @@
|
||||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName);
|
let objectStore = db.createObjectStore(objectStoreName);
|
||||||
|
|
||||||
// First, add all our data to the object store.
|
// First, add all our data to the object store.
|
||||||
|
|
|
@ -57,18 +57,13 @@
|
||||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName, {});
|
let objectStore = db.createObjectStore(objectStoreName, {});
|
||||||
|
|
||||||
// First, add all our data to the object store.
|
// First, add all our data to the object store.
|
||||||
|
|
|
@ -29,18 +29,15 @@
|
||||||
{ ss: "237-23-7733", name: "Bob", height: 65 }
|
{ ss: "237-23-7733", name: "Bob", height: 65 }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.result.oncomplete = continueToNextStep;
|
|
||||||
|
|
||||||
for (let objectStoreIndex in objectStoreData) {
|
for (let objectStoreIndex in objectStoreData) {
|
||||||
const objectStoreInfo = objectStoreData[objectStoreIndex];
|
const objectStoreInfo = objectStoreData[objectStoreIndex];
|
||||||
|
|
|
@ -68,18 +68,13 @@
|
||||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName, { keyPath: "" });
|
let objectStore = db.createObjectStore(objectStoreName, { keyPath: "" });
|
||||||
|
|
||||||
// First, add all our data to the object store.
|
// First, add all our data to the object store.
|
||||||
|
|
|
@ -48,18 +48,13 @@
|
||||||
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
{ key: "237-23-7734", value: { name: "Ron", height: 73, weight: 180 } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName, { } );
|
let objectStore = db.createObjectStore(objectStoreName, { } );
|
||||||
|
|
||||||
let addedData = 0;
|
let addedData = 0;
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
@ -25,11 +25,6 @@
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
request = objectStore.add({});
|
request = objectStore.add({});
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
is(iframe.contentWindow.location.href, "about:blank",
|
is(iframe.contentWindow.location.href, "about:blank",
|
||||||
"should nagivate to about:blank");
|
"should nagivate to about:blank");
|
||||||
|
|
||||||
let request = mozIndexedDB.open(location);
|
let request = mozIndexedDB.open(location, 1);
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
|
|
@ -25,19 +25,15 @@
|
||||||
{ name: "b", options: { unique: true } }
|
{ name: "b", options: { unique: true } }
|
||||||
];
|
];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
var j = 0;
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
let db = event.target.result;
|
|
||||||
|
|
||||||
for (let i in objectStores) {
|
for (let i in objectStores) {
|
||||||
request = db.setVersion("1");
|
let request = mozIndexedDB.open(name, ++j, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
let objectStore =
|
let objectStore =
|
||||||
db.createObjectStore(objectStores[i].name,
|
db.createObjectStore(objectStores[i].name,
|
||||||
{ keyPath: "id",
|
{ keyPath: "id",
|
||||||
|
@ -58,12 +54,18 @@
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
ok(event.target.result == 1 || event.target.result == 2, "Good id");
|
ok(event.target.result == 1 || event.target.result == 2, "Good id");
|
||||||
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.executeSoon(function() { testGenerator.next(); });
|
SimpleTest.executeSoon(function() { testGenerator.next(); });
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
let objectStore = event.target.result;
|
let request = mozIndexedDB.open(name, j, description);
|
||||||
|
request.onerror = errorHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
for (let i in objectStores) {
|
for (let i in objectStores) {
|
||||||
for (let j in indexes) {
|
for (let j in indexes) {
|
||||||
|
|
|
@ -18,9 +18,9 @@ function testSteps()
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
var request = mozIndexedDB.open(name, description);
|
var request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
var event = yield;
|
var event = yield;
|
||||||
|
|
||||||
var db = event.target.result;
|
var db = event.target.result;
|
||||||
|
@ -32,11 +32,6 @@ function testSteps()
|
||||||
keyName: "id",
|
keyName: "id",
|
||||||
};
|
};
|
||||||
|
|
||||||
let request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(test.name,
|
let objectStore = db.createObjectStore(test.name,
|
||||||
{ keyPath: test.keyName,
|
{ keyPath: test.keyName,
|
||||||
autoIncrement: test.autoIncrement });
|
autoIncrement: test.autoIncrement });
|
||||||
|
|
|
@ -18,13 +18,6 @@ function testSteps()
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
var request = mozIndexedDB.open(name, description);
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
var event = yield;
|
|
||||||
|
|
||||||
var db = event.target.result;
|
|
||||||
|
|
||||||
var data = [
|
var data = [
|
||||||
{ name: "inline key; key generator",
|
{ name: "inline key; key generator",
|
||||||
autoIncrement: true,
|
autoIncrement: true,
|
||||||
|
@ -55,11 +48,12 @@ function testSteps()
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < data.length; i++) {
|
||||||
let test = data[i];
|
let test = data[i];
|
||||||
|
|
||||||
|
let request = mozIndexedDB.open(name, i+1, description);
|
||||||
let request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(test.name,
|
let objectStore = db.createObjectStore(test.name,
|
||||||
{ keyPath: test.keyName,
|
{ keyPath: test.keyName,
|
||||||
|
@ -92,6 +86,7 @@ function testSteps()
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
ok(event.target.result === undefined, "Object was deleted");
|
ok(event.target.result === undefined, "Object was deleted");
|
||||||
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
|
|
|
@ -12,18 +12,12 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open(window.location.pathname, "");
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let transaction = event.target.transaction;
|
let transaction = event.target.transaction;
|
||||||
|
|
||||||
let objectStore1 = db.createObjectStore("foo");
|
let objectStore1 = db.createObjectStore("foo");
|
||||||
|
|
|
@ -14,25 +14,17 @@
|
||||||
{
|
{
|
||||||
const data = { key: 5, index: 10 };
|
const data = { key: 5, index: 10 };
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db;
|
let db = event.target.result;
|
||||||
setTimeout(function() {
|
|
||||||
db = request.result;
|
|
||||||
continueToNextStep();
|
|
||||||
}, 0);
|
|
||||||
yield;
|
|
||||||
|
|
||||||
ok(db instanceof IDBDatabase, "Got a real database");
|
ok(db instanceof IDBDatabase, "Got a real database");
|
||||||
|
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { keyPath: "key",
|
let objectStore = db.createObjectStore("foo", { keyPath: "key",
|
||||||
autoIncrement: true });
|
autoIncrement: true });
|
||||||
let index = objectStore.createIndex("foo", "index");
|
let index = objectStore.createIndex("foo", "index");
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
let request;
|
let request;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request = mozIndexedDB.open("", "");
|
request = mozIndexedDB.open("", 1);
|
||||||
ok(false, "Open with empty name should have thrown!");
|
ok(false, "Open with empty name should have thrown!");
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
request = mozIndexedDB.open(null, "");
|
request = mozIndexedDB.open(null, 1);
|
||||||
ok(false, "Open with null name should have thrown!");
|
ok(false, "Open with null name should have thrown!");
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
is(request, undefined, "Shouldn't be set to anything");
|
is(request, undefined, "Shouldn't be set to anything");
|
||||||
}
|
}
|
||||||
|
|
||||||
request = mozIndexedDB.open(name, description);
|
request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.name, name, "Bad name");
|
is(db.name, name, "Bad name");
|
||||||
is(db.version, "", "Bad version");
|
is(db.version, 1, "Bad version");
|
||||||
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
||||||
|
|
||||||
is(db.name, request.result.name, "Bad name");
|
is(db.name, request.result.name, "Bad name");
|
||||||
|
|
|
@ -17,21 +17,14 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const objectStoreName = "Objects";
|
const objectStoreName = "Objects";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
is(db.objectStoreNames.length, 0, "Bad objectStores list");
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName,
|
let objectStore = db.createObjectStore(objectStoreName,
|
||||||
{ keyPath: "foo" });
|
{ keyPath: "foo" });
|
||||||
|
|
||||||
|
|
|
@ -18,23 +18,19 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const objectStores = [ "foo", "bar" ];
|
const objectStores = [ "foo", "bar" ];
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||||
request.onerror = errorHandler;
|
for (let i in objectStores) {
|
||||||
request.onsuccess = function(event) {
|
db.createObjectStore(objectStores[i], { autoIncrement: true });
|
||||||
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
}
|
||||||
for (let i in objectStores) {
|
let event = yield;
|
||||||
db.createObjectStore(objectStores[i], { autoIncrement: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
yield;
|
|
||||||
|
|
||||||
is(db.objectStoreNames.length, objectStores.length,
|
is(db.objectStoreNames.length, objectStores.length,
|
||||||
"Correct objectStoreNames list");
|
"Correct objectStoreNames list");
|
||||||
|
|
|
@ -19,18 +19,13 @@
|
||||||
let testString = { key: 0, value: "testString" };
|
let testString = { key: 0, value: "testString" };
|
||||||
let testInt = { key: 1, value: 1002 };
|
let testInt = { key: 1, value: 1002 };
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName,
|
let objectStore = db.createObjectStore(objectStoreName,
|
||||||
{ autoIncrement: 0 });
|
{ autoIncrement: 0 });
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,13 @@
|
||||||
let testString = { value: "testString" };
|
let testString = { value: "testString" };
|
||||||
let testInt = { value: 1002 };
|
let testInt = { value: 1002 };
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName,
|
let objectStore = db.createObjectStore(objectStoreName,
|
||||||
{ autoIncrement: 1 });
|
{ autoIncrement: 1 });
|
||||||
|
|
||||||
|
|
|
@ -19,19 +19,14 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const osName = "foo";
|
const osName = "foo";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
db.createObjectStore(osName, { autoIncrement: "true" });
|
db.createObjectStore(osName, { autoIncrement: "true" });
|
||||||
|
|
||||||
let key1, key2;
|
let key1, key2;
|
||||||
|
|
|
@ -18,19 +18,14 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const indexName = "My Test Index";
|
const indexName = "My Test Index";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("test store", { keyPath: "foo" });
|
let objectStore = db.createObjectStore("test store", { keyPath: "foo" });
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
||||||
is(db.objectStoreNames.item(0), objectStore.name, "Correct name");
|
is(db.objectStoreNames.item(0), objectStore.name, "Correct name");
|
||||||
|
|
|
@ -20,19 +20,14 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
const objectStoreName = "Objects";
|
const objectStoreName = "Objects";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore(objectStoreName,
|
let objectStore = db.createObjectStore(objectStoreName,
|
||||||
{ keyPath: "foo" });
|
{ keyPath: "foo" });
|
||||||
|
|
||||||
|
@ -52,10 +47,14 @@
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames list");
|
||||||
is(db.objectStoreNames.item(0), objectStoreName, "Correct name");
|
is(db.objectStoreNames.item(0), objectStoreName, "Correct name");
|
||||||
|
|
||||||
request = db.setVersion("2");
|
db.close();
|
||||||
|
|
||||||
|
let request = mozIndexedDB.open(name, 2, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
db.deleteObjectStore(objectStore.name);
|
db.deleteObjectStore(objectStore.name);
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStores list");
|
is(db.objectStoreNames.length, 0, "Correct objectStores list");
|
||||||
|
@ -78,10 +77,14 @@
|
||||||
continueToNextStep();
|
continueToNextStep();
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
request = db.setVersion("3");
|
db.close();
|
||||||
|
|
||||||
|
let request = mozIndexedDB.open(name, 3, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
objectStore = db.createObjectStore(objectStoreName, { keyPath: "foo" });
|
objectStore = db.createObjectStore(objectStoreName, { keyPath: "foo" });
|
||||||
|
|
||||||
|
|
|
@ -18,26 +18,17 @@
|
||||||
const LOADING = Components.interfaces.nsIIDBRequest.LOADING;
|
const LOADING = Components.interfaces.nsIIDBRequest.LOADING;
|
||||||
const DONE = Components.interfaces.nsIIDBRequest.DONE;
|
const DONE = Components.interfaces.nsIIDBRequest.DONE;
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
is(request.readyState, LOADING, "Correct readyState");
|
is(request.readyState, LOADING, "Correct readyState");
|
||||||
|
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
is(request.readyState, DONE, "Correct readyState");
|
is(request.readyState, DONE, "Correct readyState");
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
is(request.readyState, LOADING, "Correct readyState");
|
|
||||||
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
is(request.readyState, DONE, "Correct readyState");
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
let key = 10;
|
let key = 10;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ function testSteps()
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
@ -27,26 +27,31 @@ function testSteps()
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
// Check default state.
|
// Check default state.
|
||||||
is(db.version, "", "Correct default version for a new database.");
|
is(db.version, 1, "Correct default version for a new database.");
|
||||||
|
|
||||||
const versions = [
|
const versions = [
|
||||||
"1.0",
|
7,
|
||||||
"",
|
42,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
db.close();
|
||||||
|
|
||||||
for (let i = 0; i < versions.length; i++) {
|
for (let i = 0; i < versions.length; i++) {
|
||||||
let version = versions[i];
|
let version = versions[i];
|
||||||
|
|
||||||
request = db.setVersion(version);
|
let request = mozIndexedDB.open(name, version, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
event = yield;
|
let event = yield;
|
||||||
|
|
||||||
|
let db = event.target.result;
|
||||||
|
|
||||||
is(db.version, version, "Database version number updated correctly");
|
is(db.version, version, "Database version number updated correctly");
|
||||||
is(event.target.transaction.mode, VERSION_CHANGE, "Correct mode");
|
is(event.target.transaction.mode, VERSION_CHANGE, "Correct mode");
|
||||||
|
|
||||||
SimpleTest.executeSoon(function() { testGenerator.next(); });
|
SimpleTest.executeSoon(function() { testGenerator.next(); });
|
||||||
yield;
|
yield;
|
||||||
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
|
|
|
@ -19,34 +19,37 @@ function testSteps()
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
let index = objectStore.createIndex("bar", "baz");
|
let index = objectStore.createIndex("bar", "baz");
|
||||||
|
|
||||||
is(db.version, "1", "Correct version");
|
is(db.version, 1, "Correct version");
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
||||||
is(objectStore.indexNames.length, 1, "Correct indexNames length");
|
is(objectStore.indexNames.length, 1, "Correct indexNames length");
|
||||||
|
|
||||||
event.target.transaction.oncomplete = unexpectedSuccessHandler;
|
let transaction = event.target.transaction;
|
||||||
event.target.transaction.onabort = grabEventAndContinueHandler;
|
transaction.oncomplete = unexpectedSuccessHandler;
|
||||||
event.target.transaction.abort();
|
transaction.onabort = grabEventAndContinueHandler;
|
||||||
|
transaction.abort();
|
||||||
|
|
||||||
event = yield;
|
event = yield;
|
||||||
|
is(event.type, "abort", "Got transaction abort event");
|
||||||
|
is(event.target, transaction, "Right target");
|
||||||
|
|
||||||
is(db.version, "", "Correct version");
|
todo(db.version, 1, "Correct version");
|
||||||
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
is(event.type, "error", "Got request error event");
|
||||||
|
is(event.target, request, "Right target");
|
||||||
|
|
||||||
finishTest();
|
finishTest();
|
||||||
yield;
|
yield;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,21 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
// Open a datbase for the first time.
|
||||||
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
ok(request instanceof IDBRequest, "Request should be an IDBRequest");
|
||||||
|
ok(request instanceof IDBOpenDBRequest, "Request should be an IDBOpenDBRequest");
|
||||||
|
ok(request instanceof EventTarget, "Request should be an EventTarget");
|
||||||
|
is(request.source, null, "Request should have no source");
|
||||||
|
try {
|
||||||
|
request.result;
|
||||||
|
ok(false, "Getter should have thrown!");
|
||||||
|
} catch (e if e.result == 0x80660006 /* NS_ERROR_DOM_INDEXEDDB_NOTALLOWED_ERR */) {
|
||||||
|
ok(true, "Getter threw the right exception");
|
||||||
|
}
|
||||||
|
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
@ -26,65 +40,111 @@
|
||||||
db1 = event.target.result;
|
db1 = event.target.result;
|
||||||
db1.addEventListener("versionchange", function(event) {
|
db1.addEventListener("versionchange", function(event) {
|
||||||
ok(true, "Got version change event");
|
ok(true, "Got version change event");
|
||||||
|
ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
|
||||||
is(event.target.source, null, "Correct source");
|
is(event.target.source, null, "Correct source");
|
||||||
is(event.target, db1, "Correct target");
|
is(event.target, db1, "Correct target");
|
||||||
is(event.target.version, "", "Correct db version");
|
is(event.target.version, 1, "Correct db version");
|
||||||
is(event.version, "1", "Correct event version");
|
is(event.oldVersion, 1, "Correct event oldVersion");
|
||||||
|
is(event.newVersion, 2, "Correct event newVersion");
|
||||||
is(versionChangeEventCount++, 0, "Correct count");
|
is(versionChangeEventCount++, 0, "Correct count");
|
||||||
db1.close();
|
db1.close();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
request = mozIndexedDB.open(name, description);
|
// Open the database again and trigger an upgrade that should succeed
|
||||||
|
request = mozIndexedDB.open(name, 2, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
|
request.onsuccess = errorHandler;
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onblocked = errorHandler;
|
||||||
|
event = yield;
|
||||||
|
|
||||||
|
// Test the upgradeneeded event.
|
||||||
|
ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
|
||||||
|
ok(event.target.result instanceof IDBDatabase, "Good result");
|
||||||
|
db2 = event.target.result;
|
||||||
|
is(event.target.transaction.mode, IDBTransaction.VERSION_CHANGE,
|
||||||
|
"Correct mode");
|
||||||
|
is(db2.version, 2, "Correct db version");
|
||||||
|
is(event.oldVersion, 1, "Correct event oldVersion");
|
||||||
|
is(event.newVersion, 2, "Correct event newVersion");
|
||||||
|
|
||||||
|
request.onupgradeneeded = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
db2 = event.target.result;
|
|
||||||
db2.addEventListener("versionchange", function(event) {
|
db2.addEventListener("versionchange", function(event) {
|
||||||
ok(true, "Got version change event");
|
ok(true, "Got version change event");
|
||||||
|
ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
|
||||||
is(event.target.source, null, "Correct source");
|
is(event.target.source, null, "Correct source");
|
||||||
is(event.target, db2, "Correct target");
|
is(event.target, db2, "Correct target");
|
||||||
is(event.target.version, "1", "Correct db version");
|
is(event.target.version, 2, "Correct db version");
|
||||||
is(event.version, "2", "Correct event version");
|
is(event.oldVersion, 2, "Correct event oldVersion");
|
||||||
|
is(event.newVersion, 3, "Correct event newVersion");
|
||||||
is(versionChangeEventCount++, 1, "Correct count");
|
is(versionChangeEventCount++, 1, "Correct count");
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
request = db2.setVersion("1");
|
// Test opening the existing version again
|
||||||
|
request = mozIndexedDB.open(name, 2, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
request.onblocked = errorHandler;
|
request.onblocked = errorHandler;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
ok(event.target.result === event.target.transaction, "Good result");
|
db3 = event.target.result;
|
||||||
is(event.target.transaction.mode, IDBTransaction.VERSION_CHANGE,
|
|
||||||
"Correct mode");
|
|
||||||
is(db2.version, "1", "Correct db version");
|
|
||||||
|
|
||||||
request = mozIndexedDB.open(name, description);
|
// Test an upgrade that should fail
|
||||||
|
request = mozIndexedDB.open(name, 3, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
|
request.onsuccess = errorHandler;
|
||||||
|
request.onupgradeneeded = errorHandler;
|
||||||
|
request.onblocked = grabEventAndContinueHandler;
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
ok(true, "Got version change blocked event");
|
||||||
|
ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
|
||||||
|
is(event.target.source, null, "Correct source");
|
||||||
|
is(event.target.transaction, null, "Correct transaction");
|
||||||
|
is(event.target, request, "Correct target");
|
||||||
|
is(db3.version, 2, "Correct db version");
|
||||||
|
is(event.oldVersion, 2, "Correct event oldVersion");
|
||||||
|
is(event.newVersion, 3, "Correct event newVersion");
|
||||||
|
versionChangeEventCount++;
|
||||||
|
db2.close();
|
||||||
|
db3.close();
|
||||||
|
|
||||||
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
||||||
|
event = yield;
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
db3 = event.target.result;
|
db3 = event.target.result;
|
||||||
|
db3.close();
|
||||||
|
|
||||||
request = db3.setVersion("2");
|
// Test another upgrade that should succeed.
|
||||||
|
request = mozIndexedDB.open(name, 4);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = errorHandler;
|
||||||
request.onblocked = function(event) {
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
ok(true, "Got version change blocked event");
|
request.onblocked = errorHandler;
|
||||||
is(event.target.source, db3, "Correct source");
|
|
||||||
is(event.target, request, "Correct target");
|
|
||||||
is(event.target.source.version, "1", "Correct db version");
|
|
||||||
is(event.version, "2", "Correct event version");
|
|
||||||
versionChangeEventCount++;
|
|
||||||
db2.close();
|
|
||||||
};
|
|
||||||
event = yield;
|
event = yield;
|
||||||
|
|
||||||
ok(event.target.result === event.target.transaction, "Good result");
|
ok(event instanceof IDBVersionChangeEvent, "Event is of the right type");
|
||||||
|
ok(event.target.result instanceof IDBDatabase, "Good result");
|
||||||
is(event.target.transaction.mode, IDBTransaction.VERSION_CHANGE,
|
is(event.target.transaction.mode, IDBTransaction.VERSION_CHANGE,
|
||||||
"Correct mode");
|
"Correct mode");
|
||||||
is(db3.version, "2", "Correct db version");
|
is(event.oldVersion, 3, "Correct event oldVersion");
|
||||||
|
is(event.newVersion, 4, "Correct event newVersion");
|
||||||
|
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
ok(event.target.result instanceof IDBDatabase, "Expect a database here");
|
||||||
|
is(event.target.result.version, 4, "Right version");
|
||||||
|
todo_is(db3.version, 3, "After closing the version should not change!");
|
||||||
|
todo_is(db2.version, 2, "After closing the version should not change!");
|
||||||
|
todo_is(db1.version, 1, "After closing the version should not change!");
|
||||||
|
|
||||||
is(versionChangeEventCount, 3, "Saw all expected events");
|
is(versionChangeEventCount, 3, "Saw all expected events");
|
||||||
|
|
||||||
|
|
|
@ -12,19 +12,14 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
let request = db.setVersion("1");
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.result.oncomplete = continueToNextStep;
|
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo");
|
let objectStore = db.createObjectStore("foo");
|
||||||
objectStore.add({}, 1).onerror = errorHandler;
|
objectStore.add({}, 1).onerror = errorHandler;
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
@ -36,11 +36,6 @@
|
||||||
let transaction;
|
let transaction;
|
||||||
let objectStore;
|
let objectStore;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
transaction = event.target.transaction;
|
transaction = event.target.transaction;
|
||||||
objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,14 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
|
@ -12,17 +12,14 @@
|
||||||
<script type="text/javascript;version=1.7">
|
<script type="text/javascript;version=1.7">
|
||||||
function testSteps()
|
function testSteps()
|
||||||
{
|
{
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
|
|
||||||
event = yield;
|
|
||||||
|
|
||||||
event.target.transaction.oncomplete = continueToNextStep;
|
event.target.transaction.oncomplete = continueToNextStep;
|
||||||
db.createObjectStore("foo");
|
db.createObjectStore("foo");
|
||||||
yield;
|
yield;
|
||||||
|
|
|
@ -20,18 +20,13 @@
|
||||||
const name = window.location.pathname;
|
const name = window.location.pathname;
|
||||||
const description = "My Test Database";
|
const description = "My Test Database";
|
||||||
|
|
||||||
let request = mozIndexedDB.open(name, description);
|
let request = mozIndexedDB.open(name, 1, description);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
|
|
||||||
request = db.setVersion("1");
|
|
||||||
request.onerror = errorHandler;
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
|
||||||
let event = yield;
|
|
||||||
|
|
||||||
is(event.target.transaction.mode, VERSION_CHANGE, "Correct mode");
|
is(event.target.transaction.mode, VERSION_CHANGE, "Correct mode");
|
||||||
|
|
||||||
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
function runIndexedDBTest() {
|
function runIndexedDBTest() {
|
||||||
try {
|
try {
|
||||||
let request = mozIndexedDB.open(window.location.pathname);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onsuccess = function(event) {
|
request.onsuccess = function(event) {
|
||||||
report(!!(event.target.result instanceof IDBDatabase));
|
report(!!(event.target.result instanceof IDBDatabase));
|
||||||
}
|
}
|
||||||
|
|
|
@ -452,8 +452,8 @@ members = [
|
||||||
'nsIIDBRequest.*',
|
'nsIIDBRequest.*',
|
||||||
'nsIIDBTransaction.*',
|
'nsIIDBTransaction.*',
|
||||||
'nsIIDBFactory.*',
|
'nsIIDBFactory.*',
|
||||||
|
'nsIIDBOpenDBRequest.*',
|
||||||
'nsIIDBVersionChangeEvent.*',
|
'nsIIDBVersionChangeEvent.*',
|
||||||
'nsIIDBVersionChangeRequest.*',
|
|
||||||
'nsIIndexedDatabaseUsageCallback.*',
|
'nsIIndexedDatabaseUsageCallback.*',
|
||||||
'nsIIndexedDatabaseManager.*',
|
'nsIIndexedDatabaseManager.*',
|
||||||
]
|
]
|
||||||
|
|
|
@ -663,7 +663,7 @@ resultConvTemplates = {
|
||||||
" return xpc_qsInt32ToJsval(cx, result, ${jsvalPtr});\n",
|
" return xpc_qsInt32ToJsval(cx, result, ${jsvalPtr});\n",
|
||||||
|
|
||||||
'long long':
|
'long long':
|
||||||
" return xpc_qsInt64ToJsval(cx, result, ${jsvalPtr};\n",
|
" return xpc_qsInt64ToJsval(cx, result, ${jsvalPtr});\n",
|
||||||
|
|
||||||
'unsigned short':
|
'unsigned short':
|
||||||
" ${jsvalRef} = INT_TO_JSVAL((int32) result);\n"
|
" ${jsvalRef} = INT_TO_JSVAL((int32) result);\n"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче