--- a/storage/public/Makefile.in
+++ b/storage/public/Makefile.in
@@ -57,18 +57,16 @@ XPIDLSRCS = \
mozIStorageStatement.idl \
mozIStorageStatementWrapper.idl \
mozIStorageValueArray.idl \
mozIStorageResultSet.idl \
mozIStorageRow.idl \
mozIStorageError.idl \
mozIStorageStatementCallback.idl \
mozIStoragePendingStatement.idl \
- mozIStorageBindingParamsArray.idl \
- mozIStorageBindingParams.idl \
$(NULL)
EXPORTS_NAMESPACES = mozilla
EXPORTS = \
mozStorageHelper.h \
mozStorage.h \
$(NULL)
deleted file mode 100644
--- a/storage/public/mozIStorageBindingParams.idl
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 "nsISupports.idl"
-
-interface nsIVariant;
-
-[scriptable, uuid(a8d4827c-641c-45e3-a9ea-493570b4106b)]
-interface mozIStorageBindingParams : nsISupports {
- /**
- * Binds aValue to the parameter with the name aName.
- *
- * @param aName
- * The name of the parameter to bind aValue to.
- * @param aValue
- * The value to bind.
- */
- void bindByName(in AUTF8String aName,
- in nsIVariant aValue);
- [noscript] void bindUTF8StringByName(in AUTF8String aName,
- in AUTF8String aValue);
- [noscript] void bindStringByName(in AUTF8String aName,
- in AString aValue);
- [noscript] void bindDoubleByName(in AUTF8String aName,
- in double aValue);
- [noscript] void bindInt32ByName(in AUTF8String aName,
- in long aValue);
- [noscript] void bindInt64ByName(in AUTF8String aName,
- in long long aValue);
- [noscript] void bindNullByName(in AUTF8String aName);
- void bindBlobByName(in AUTF8String aName,
- [array, const, size_is(aValueSize)] in octet aValue,
- in unsigned long aValueSize);
-
- /**
- * Binds aValue to the parameter with the index aIndex.
- *
- * @param aIndex
- * The zero-based index of the parameter to bind aValue to.
- * @param aValue
- * The value to bind.
- */
- void bindByIndex(in unsigned long aIndex,
- in nsIVariant aValue);
- [noscript] void bindUTF8StringByIndex(in unsigned long aIndex,
- in AUTF8String aValue);
- [noscript] void bindStringByIndex(in unsigned long aIndex,
- in AString aValue);
- [noscript] void bindDoubleByIndex(in unsigned long aIndex,
- in double aValue);
- [noscript] void bindInt32ByIndex(in unsigned long aIndex,
- in long aValue);
- [noscript] void bindInt64ByIndex(in unsigned long aIndex,
- in long long aValue);
- [noscript] void bindNullByIndex(in unsigned long aIndex);
- void bindBlobByIndex(in unsigned long aIndex,
- [array, const, size_is(aValueSize)] in octet aValue,
- in unsigned long aValueSize);
-};
deleted file mode 100644
--- a/storage/public/mozIStorageBindingParamsArray.idl
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 "nsISupports.idl"
-
-interface mozIStorageBindingParams;
-
-[scriptable, uuid(e676e1a3-1dc6-4802-ac03-291fa9de7f93)]
-interface mozIStorageBindingParamsArray : nsISupports {
- /**
- * Creates a new mozIStorageBindingParams object that can be added to this
- * array.
- *
- * @returns a mozIStorageBindingParams object that can be used to specify
- * parameters that need to be bound.
- */
- mozIStorageBindingParams newBindingParams();
-
- /**
- * Adds the parameters to the end of this array.
- *
- * @param aParameters
- * The parameters to add to this array.
- */
- void addParams(in mozIStorageBindingParams aParameters);
-};
--- a/storage/public/mozIStorageStatement.idl
+++ b/storage/public/mozIStorageStatement.idl
@@ -38,19 +38,18 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "mozIStorageValueArray.idl"
interface mozIStorageConnection;
interface mozIStorageStatementCallback;
interface mozIStoragePendingStatement;
-interface mozIStorageBindingParamsArray;
-[scriptable, uuid(20c45bdd-51d4-4f07-b70e-5feaa6302197)]
+[scriptable, uuid(52d740cd-1c25-471f-a848-98d1a00a2963)]
interface mozIStorageStatement : mozIStorageValueArray {
/**
* Finalizes a statement so you can successfully close a database connection.
* This method does not need to be used from native callers since you can just
* set the statement to null, but is extremely useful to JS callers.
*/
void finalize();
@@ -126,34 +125,16 @@ interface mozIStorageStatement : mozISto
void bindInt32Parameter(in unsigned long aParamIndex, in long aValue);
void bindInt64Parameter(in unsigned long aParamIndex, in long long aValue);
void bindNullParameter(in unsigned long aParamIndex);
void bindBlobParameter(in unsigned long aParamIndex,
[array,const,size_is(aValueSize)] in octet aValue,
in unsigned long aValueSize);
/**
- * Binds the array of parameters to the statement. When executeAsync is
- * called, all the parameters in aParameters are bound and then executed.
- *
- * @param aParameters
- * The array of parameters to bind to the statement upon execution.
- */
- void bindParameters(in mozIStorageBindingParamsArray aParameters);
-
- /**
- * Creates a new mozIStorageBindingParamsArray that can be used to bind
- * multiple sets of data to a statement.
- *
- * @returns a mozIStorageBindingParamsArray that multiple sets of parameters
- * can be bound to.
- */
- mozIStorageBindingParamsArray newBindingParamsArray();
-
- /**
* Execute the query, ignoring any results. This is accomplished by
* calling step() once, and then calling reset().
*
* Error and last insert info, etc. are available from
* the mozStorageConnection.
*/
void execute();
--- a/storage/src/Makefile.in
+++ b/storage/src/Makefile.in
@@ -78,18 +78,16 @@ CPPSRCS = \
mozStorageArgValueArray.cpp \
mozStorageSQLFunctions.cpp \
mozStorageRow.cpp \
mozStorageResultSet.cpp \
mozStorageError.cpp \
mozStorageAsyncStatementExecution.cpp \
mozStorageStatementJSHelper.cpp \
mozStoragePrivateHelpers.cpp \
- mozStorageBindingParamsArray.cpp \
- mozStorageBindingParams.cpp \
$(NULL)
LOCAL_INCLUDES = \
$(SQLITE_CFLAGS)
# This is the default value. If we ever change it when compiling sqlite, we
# will need to change it here as well.
DEFINES += -DSQLITE_MAX_LIKE_PATTERN_LENGTH=50000
--- a/storage/src/mozStorageAsyncStatementExecution.cpp
+++ b/storage/src/mozStorageAsyncStatementExecution.cpp
@@ -38,24 +38,22 @@
* ***** END LICENSE BLOCK ***** */
#include "nsAutoPtr.h"
#include "prtime.h"
#include "sqlite3.h"
#include "mozIStorageStatementCallback.h"
-#include "mozStorageBindingParams.h"
#include "mozStorageHelper.h"
#include "mozStorageResultSet.h"
#include "mozStorageRow.h"
#include "mozStorageConnection.h"
#include "mozStorageError.h"
#include "mozStoragePrivateHelpers.h"
-#include "mozStorageStatementData.h"
#include "mozStorageAsyncStatementExecution.h"
namespace mozilla {
namespace storage {
/**
* The following constants help batch rows into result sets.
* MAX_MILLISECONDS_BETWEEN_RESULTS was chosen because any user-based task that
@@ -169,17 +167,17 @@ private:
} // anonymous namespace
////////////////////////////////////////////////////////////////////////////////
//// AsyncExecuteStatements
/* static */
nsresult
-AsyncExecuteStatements::execute(StatementDataArray &aStatements,
+AsyncExecuteStatements::execute(sqlite3_stmt_array &aStatements,
Connection *aConnection,
mozIStorageStatementCallback *aCallback,
mozIStoragePendingStatement **_stmt)
{
// Create our event to run in the background
nsRefPtr<AsyncExecuteStatements> event =
new AsyncExecuteStatements(aStatements, aConnection, aCallback);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
@@ -190,17 +188,17 @@ AsyncExecuteStatements::execute(Statemen
nsresult rv = target->Dispatch(event, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
// Return it as the pending statement object
NS_ADDREF(*_stmt = event);
return NS_OK;
}
-AsyncExecuteStatements::AsyncExecuteStatements(StatementDataArray &aStatements,
+AsyncExecuteStatements::AsyncExecuteStatements(sqlite3_stmt_array &aStatements,
Connection *aConnection,
mozIStorageStatementCallback *aCallback)
: mConnection(aConnection)
, mTransactionManager(nsnull)
, mCallback(aCallback)
, mCallingThread(::do_GetCurrentThread())
, mMaxIntervalWait(::PR_MicrosecondsToInterval(MAX_MILLISECONDS_BETWEEN_RESULTS))
, mIntervalStart(::PR_IntervalNow())
@@ -224,57 +222,16 @@ AsyncExecuteStatements::shouldNotify()
// We do not need to acquire mMutex here because it can only ever be written
// to on the calling thread, and the only thread that can call us is the
// calling thread, so we know that our access is serialized.
return !mCancelRequested;
}
bool
-AsyncExecuteStatements::bindExecuteAndProcessStatement(StatementData &aData,
- bool aLastStatement)
-{
- mMutex.AssertNotCurrentThreadOwns();
-
- sqlite3_stmt *stmt(aData);
- BindingParamsArray *paramsArray(aData);
-
- // Iterate through all of our parameters, bind them, and execute.
- bool continueProcessing = true;
- BindingParamsArray::iterator itr = paramsArray->begin();
- BindingParamsArray::iterator end = paramsArray->end();
- while (itr != end && continueProcessing) {
- // Bind the data to our statement.
- nsCOMPtr<mozIStorageError> error;
- error = (*itr)->bind(stmt);
- if (error) {
- // Set our error state.
- {
- MutexAutoLock mutex(mMutex);
- mState = ERROR;
- }
-
- // And notify.
- (void)notifyError(error);
- return false;
- }
-
- // Advance our iterator, execute, and then process the statement.
- itr++;
- bool lastStatement = aLastStatement && itr == end;
- continueProcessing = executeAndProcessStatement(stmt, lastStatement);
-
- // Always reset our statement.
- (void)::sqlite3_reset(stmt);
- }
-
- return continueProcessing;
-}
-
-bool
AsyncExecuteStatements::executeAndProcessStatement(sqlite3_stmt *aStatement,
bool aLastStatement)
{
mMutex.AssertNotCurrentThreadOwns();
// We need to hold the mutex for statement execution so we can properly
// reflect state in case we are canceled. We release the mutex in a few areas
// in order to allow for cancelation to occur.
@@ -415,18 +372,20 @@ AsyncExecuteStatements::notifyComplete()
{
mMutex.AssertNotCurrentThreadOwns();
NS_ASSERTION(mState != PENDING,
"Still in a pending state when calling Complete!");
// Finalize our statements before we try to commit or rollback. If we are
// canceling and have statements that think they have pending work, the
// rollback will fail.
- for (PRUint32 i = 0; i < mStatements.Length(); i++)
- mStatements[i].finalize();
+ for (PRUint32 i = 0; i < mStatements.Length(); i++) {
+ (void)::sqlite3_finalize(mStatements[i]);
+ mStatements[i] = NULL;
+ }
// Handle our transaction, if we have one
if (mTransactionManager) {
if (mState == COMPLETED) {
nsresult rv = mTransactionManager->Commit();
if (NS_FAILED(rv)) {
mState = ERROR;
(void)notifyError(mozIStorageError::ERROR,
@@ -462,29 +421,18 @@ AsyncExecuteStatements::notifyError(PRIn
mMutex.AssertNotCurrentThreadOwns();
if (!mCallback)
return NS_OK;
nsCOMPtr<mozIStorageError> errorObj(new Error(aErrorCode, aMessage));
NS_ENSURE_TRUE(errorObj, NS_ERROR_OUT_OF_MEMORY);
- return notifyError(errorObj);
-}
-
-nsresult
-AsyncExecuteStatements::notifyError(mozIStorageError *aError)
-{
- mMutex.AssertNotCurrentThreadOwns();
-
- if (!mCallback)
- return NS_OK;
-
nsRefPtr<ErrorNotifier> notifier =
- new ErrorNotifier(mCallback, aError, this);
+ new ErrorNotifier(mCallback, errorObj, this);
NS_ENSURE_TRUE(notifier, NS_ERROR_OUT_OF_MEMORY);
return mCallingThread->Dispatch(notifier, NS_DISPATCH_NORMAL);
}
nsresult
AsyncExecuteStatements::notifyResults()
{
@@ -557,37 +505,27 @@ AsyncExecuteStatements::Run()
mState = CANCELED;
}
if (cancelRequested)
return notifyComplete();
// If there is more than one statement, run it in a transaction. We assume
// that we have been given write statements since getting a batch of read
// statements doesn't make a whole lot of sense.
- // Additionally, if we have only one statement and it has parameters to be
- // bound, we assume that the consumer would want a transaction as well.
- if (mStatements.Length() > 1 || mStatements[0].hasParametersToBeBound()) {
+ if (mStatements.Length() > 1) {
// We don't error if this failed because it's not terrible if it does.
mTransactionManager = new mozStorageTransaction(mConnection, PR_FALSE,
mozIStorageConnection::TRANSACTION_IMMEDIATE);
}
// Execute each statement, giving the callback results if it returns any.
for (PRUint32 i = 0; i < mStatements.Length(); i++) {
- bool finished = (i == (mStatements.Length() - 1));
-
- // If we have parameters to bind, bind them, execute, and process.
- if (mStatements[i].hasParametersToBeBound()) {
- if (!bindExecuteAndProcessStatement(mStatements[i], finished))
- break;
- }
- // Otherwise, just execute and process the statement.
- else if (!executeAndProcessStatement(mStatements[i], finished)) {
+ PRBool finished = (i == (mStatements.Length() - 1));
+ if (!executeAndProcessStatement(mStatements[i], finished))
break;
- }
}
// If we still have results that we haven't notified about, take care of
// them now.
if (mResultSet)
(void)notifyResults();
// Notify about completion
--- a/storage/src/mozStorageAsyncStatementExecution.h
+++ b/storage/src/mozStorageAsyncStatementExecution.h
@@ -52,17 +52,16 @@
struct sqlite3_stmt;
class mozStorageTransaction;
namespace mozilla {
namespace storage {
class Connection;
class ResultSet;
-class StatementData;
class AsyncExecuteStatements : public nsIRunnable
, public mozIStoragePendingStatement
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIRUNNABLE
NS_DECL_MOZISTORAGEPENDINGSTATEMENT
@@ -72,69 +71,52 @@ public:
*/
enum ExecutionState {
PENDING = -1,
COMPLETED = mozIStorageStatementCallback::REASON_FINISHED,
CANCELED = mozIStorageStatementCallback::REASON_CANCELED,
ERROR = mozIStorageStatementCallback::REASON_ERROR
};
- typedef nsTArray<StatementData> StatementDataArray;
+ typedef nsTArray<sqlite3_stmt *> sqlite3_stmt_array;
/**
* Executes a statement in the background, and passes results back to the
* caller.
*
* @param aStatements
- * The statements to execute and possibly bind in the background.
- * Ownership is transfered from the caller.
+ * The SQLite statements to execute in the background. Ownership is
+ * transfered from the caller.
* @param aConnection
* The connection that created the statements to execute.
* @param aCallback
* The callback that is notified of results, completion, and errors.
* @param _stmt
* The handle to control the execution of the statements.
*/
- static nsresult execute(StatementDataArray &aStatements,
+ static nsresult execute(sqlite3_stmt_array &aStatements,
Connection *aConnection,
mozIStorageStatementCallback *aCallback,
mozIStoragePendingStatement **_stmt);
/**
* Indicates when events on the calling thread should run or not. Certain
* events posted back to the calling thread should call this see if they
* should run or not.
*
* @returns true if the event should notify still, false otherwise.
*/
bool shouldNotify();
private:
- AsyncExecuteStatements(StatementDataArray &aStatements,
+ AsyncExecuteStatements(sqlite3_stmt_array &aStatements,
Connection *aConnection,
mozIStorageStatementCallback *aCallback);
/**
- * Binds and then executes a given statement until completion, an error
- * occurs, or we are canceled. If aLastStatement is true, we should set
- * mState accordingly.
- *
- * @pre mMutex is not held
- *
- * @param aData
- * The StatementData to bind, execute, and then process.
- * @param aLastStatement
- * Indicates if this is the last statement or not. If it is, we have
- * to set the proper state.
- * @returns true if we should continue to process statements, false otherwise.
- */
- bool bindExecuteAndProcessStatement(StatementData &aData,
- bool aLastStatement);
-
- /**
* Executes a given statement until completion, an error occurs, or we are
* canceled. If aLastStatement is true, we should set mState accordingly.
*
* @pre mMutex is not held
*
* @param aStatement
* The statement to execute and then process.
* @param aLastStatement
@@ -178,30 +160,27 @@ private:
* Notifies callback about an error.
*
* @pre mMutex is not held
*
* @param aErrorCode
* The error code defined in mozIStorageError for the error.
* @param aMessage
* The error string, if any.
- * @param aError
- * The error object to notify the caller with.
*/
nsresult notifyError(PRInt32 aErrorCode, const char *aMessage);
- nsresult notifyError(mozIStorageError *aError);
/**
* Notifies the callback about a result set.
*
* @pre mMutex is not held
*/
nsresult notifyResults();
- StatementDataArray mStatements;
+ sqlite3_stmt_array mStatements;
nsRefPtr<Connection> mConnection;
mozStorageTransaction *mTransactionManager;
mozIStorageStatementCallback *mCallback;
nsCOMPtr<nsIThread> mCallingThread;
nsRefPtr<ResultSet> mResultSet;
/**
* The maximum amount of time we want to wait between results. Defined by
deleted file mode 100644
--- a/storage/src/mozStorageBindingParams.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 <limits.h>
-
-#include "nsString.h"
-
-#include "mozStorageError.h"
-#include "mozStoragePrivateHelpers.h"
-#include "mozStorageBindingParams.h"
-#include "mozStorageBindingParamsArray.h"
-#include "Variant.h"
-
-namespace mozilla {
-namespace storage {
-
-////////////////////////////////////////////////////////////////////////////////
-//// Local Helper Objects
-
-namespace {
-
-struct BindingColumnData
-{
- BindingColumnData(sqlite3_stmt *aStmt,
- int aColumn)
- : stmt(aStmt)
- , column(aColumn)
- {
- }
- sqlite3_stmt *stmt;
- int column;
-};
-
-} // anonymous namespace
-
-////////////////////////////////////////////////////////////////////////////////
-//// sqlite3_stmt Specialization Functions (varaintToSQLite3T)
-
-template < >
-int
-sqlite3_T_int(BindingColumnData aData,
- int aValue)
-{
- return ::sqlite3_bind_int(aData.stmt, aData.column + 1, aValue);
-}
-
-template < >
-int
-sqlite3_T_int64(BindingColumnData aData,
- sqlite3_int64 aValue)
-{
- return ::sqlite3_bind_int64(aData.stmt, aData.column + 1, aValue);
-}
-
-template < >
-int
-sqlite3_T_double(BindingColumnData aData,
- double aValue)
-{
- return ::sqlite3_bind_double(aData.stmt, aData.column + 1, aValue);
-}
-
-template < >
-int
-sqlite3_T_text16(BindingColumnData aData,
- nsString aValue)
-{
- return ::sqlite3_bind_text16(aData.stmt,
- aData.column + 1,
- PromiseFlatString(aValue).get(),
- aValue.Length() * 2, // Length in bytes!
- SQLITE_TRANSIENT);
-}
-
-template < >
-int
-sqlite3_T_null(BindingColumnData aData)
-{
- return ::sqlite3_bind_null(aData.stmt, aData.column + 1);
-}
-
-template < >
-int
-sqlite3_T_blob(BindingColumnData aData,
- const void *aBlob,
- int aSize)
-{
- return ::sqlite3_bind_blob(aData.stmt, aData.column + 1, aBlob, aSize,
- NS_Free);
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// BindingParams
-
-BindingParams::BindingParams(BindingParamsArray *aOwningArray,
- Statement *aOwningStatement)
-: mOwningArray(aOwningArray)
-, mOwningStatement(aOwningStatement)
-, mLocked(false)
-{
- (void)mOwningStatement->GetParameterCount(&mParamCount);
-}
-
-void
-BindingParams::lock()
-{
- NS_ASSERTION(mLocked == false, "Parameters have already been locked!");
- mLocked = true;
-
- // We no longer need to hold a reference to our statement or our owning array.
- // The array owns us at this point, and it will own a reference to the
- // statement.
- mOwningStatement = nsnull;
- mOwningArray = nsnull;
-}
-
-const BindingParamsArray *
-BindingParams::getOwner() const
-{
- return mOwningArray;
-}
-
-already_AddRefed<mozIStorageError>
-BindingParams::bind(sqlite3_stmt *aStatement)
-{
- // Iterate through all of our stored data, and bind it.
- for (PRInt32 i = 0; i < mParameters.Count(); i++) {
- int rc = variantToSQLiteT(BindingColumnData(aStatement, i), mParameters[i]);
- if (rc != SQLITE_OK) {
- // We had an error while trying to bind. Now we need to create an error
- // object with the right message. Note that we special case
- // SQLITE_MISMATCH, but otherwise get the message from SQLite.
- const char *msg = "Could not covert nsIVariant to SQLite type.";
- if (rc != SQLITE_MISMATCH)
- msg = ::sqlite3_errmsg(::sqlite3_db_handle(aStatement));
-
- nsCOMPtr<mozIStorageError> err(new Error(rc, msg));
- return err.forget();
- }
- }
-
- // No error occurred, so return null!
- return nsnull;
-}
-
-NS_IMPL_THREADSAFE_ISUPPORTS1(
- BindingParams,
- mozIStorageBindingParams
-)
-
-///////////////////////////////////////////////////////////////////////////////
-//// mozIStorageBindingParams
-
-NS_IMETHODIMP
-BindingParams::BindByName(const nsACString &aName,
- nsIVariant *aValue)
-{
- NS_ENSURE_FALSE(mLocked, NS_ERROR_UNEXPECTED);
-
- // Get the column index that we need to store this at.
- PRUint32 index;
- nsresult rv = mOwningStatement->GetParameterIndex(aName, &index);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return BindByIndex(index, aValue);
-}
-
-NS_IMETHODIMP
-BindingParams::BindUTF8StringByName(const nsACString &aName,
- const nsACString &aValue)
-{
- nsCOMPtr<nsIVariant> value(new UTF8TextVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindStringByName(const nsACString &aName,
- const nsAString &aValue)
-{
- nsCOMPtr<nsIVariant> value(new TextVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindDoubleByName(const nsACString &aName,
- double aValue)
-{
- nsCOMPtr<nsIVariant> value(new FloatVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindInt32ByName(const nsACString &aName,
- PRInt32 aValue)
-{
- nsCOMPtr<nsIVariant> value(new IntegerVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindInt64ByName(const nsACString &aName,
- PRInt64 aValue)
-{
- nsCOMPtr<nsIVariant> value(new IntegerVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindNullByName(const nsACString &aName)
-{
- nsCOMPtr<nsIVariant> value(new NullVariant());
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindBlobByName(const nsACString &aName,
- const PRUint8 *aValue,
- PRUint32 aValueSize)
-{
- NS_ENSURE_ARG_MAX(aValueSize, INT_MAX);
- std::pair<const void *, int> data(
- static_cast<const void *>(aValue),
- int(aValueSize)
- );
- nsCOMPtr<nsIVariant> value(new BlobVariant(data));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByName(aName, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindByIndex(PRUint32 aIndex,
- nsIVariant *aValue)
-{
- NS_ENSURE_FALSE(mLocked, NS_ERROR_UNEXPECTED);
- ENSURE_INDEX_VALUE(aIndex, mParamCount);
-
- // Store the variant for later use.
- NS_ENSURE_TRUE(mParameters.InsertObjectAt(aValue, aIndex),
- NS_ERROR_OUT_OF_MEMORY);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-BindingParams::BindUTF8StringByIndex(PRUint32 aIndex,
- const nsACString &aValue)
-{
- nsCOMPtr<nsIVariant> value(new UTF8TextVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindStringByIndex(PRUint32 aIndex,
- const nsAString &aValue)
-{
- nsCOMPtr<nsIVariant> value(new TextVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindDoubleByIndex(PRUint32 aIndex,
- double aValue)
-{
- nsCOMPtr<nsIVariant> value(new FloatVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindInt32ByIndex(PRUint32 aIndex,
- PRInt32 aValue)
-{
- nsCOMPtr<nsIVariant> value(new IntegerVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindInt64ByIndex(PRUint32 aIndex,
- PRInt64 aValue)
-{
- nsCOMPtr<nsIVariant> value(new IntegerVariant(aValue));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindNullByIndex(PRUint32 aIndex)
-{
- nsCOMPtr<nsIVariant> value(new NullVariant());
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-NS_IMETHODIMP
-BindingParams::BindBlobByIndex(PRUint32 aIndex,
- const PRUint8 *aValue,
- PRUint32 aValueSize)
-{
- NS_ENSURE_ARG_MAX(aValueSize, INT_MAX);
- std::pair<const void *, int> data(
- static_cast<const void *>(aValue),
- int(aValueSize)
- );
- nsCOMPtr<nsIVariant> value(new BlobVariant(data));
- NS_ENSURE_TRUE(value, NS_ERROR_OUT_OF_MEMORY);
-
- return BindByIndex(aIndex, value);
-}
-
-} // namespace storage
-} // namespace mozilla
deleted file mode 100644
--- a/storage/src/mozStorageBindingParams.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 _mozStorageBindingParams_h_
-#define _mozStorageBindingParams_h_
-
-#include "nsAutoPtr.h"
-#include "nsCOMArray.h"
-#include "nsIVariant.h"
-
-#include "mozStorageBindingParamsArray.h"
-#include "mozStorageStatement.h"
-#include "mozIStorageBindingParams.h"
-
-class mozIStorageError;
-struct sqlite3_stmt;
-
-namespace mozilla {
-namespace storage {
-
-class BindingParams : public mozIStorageBindingParams
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_MOZISTORAGEBINDINGPARAMS
-
- /**
- * Locks the parameters and prevents further modification to it (such as
- * binding more elements to it).
- */
- void lock();
-
- /**
- * @returns the pointer to the owning BindingParamsArray.
- */
- const BindingParamsArray *getOwner() const;
-
- /**
- * Binds our stored data to the statement.
- *
- * @param aStatement
- * The statement to bind our data to.
- * @returns nsnull on success, or a mozIStorageError object if an error
- * occurred.
- */
- already_AddRefed<mozIStorageError> bind(sqlite3_stmt *aStatement);
-
- BindingParams(BindingParamsArray *aOwningArray,
- Statement *aOwningStatement);
-
-private:
- nsRefPtr<BindingParamsArray> mOwningArray;
- Statement *mOwningStatement;
- nsCOMArray<nsIVariant> mParameters;
- PRUint32 mParamCount;
- bool mLocked;
-};
-
-} // namespace storage
-} // namespace mozilla
-
-#endif // _mozStorageBindingParams_h_
deleted file mode 100644
--- a/storage/src/mozStorageBindingParamsArray.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 "mozStorageBindingParamsArray.h"
-#include "mozStorageBindingParams.h"
-
-namespace mozilla {
-namespace storage {
-
-////////////////////////////////////////////////////////////////////////////////
-//// BindingParamsArray
-
-BindingParamsArray::BindingParamsArray(Statement *aOwningStatement)
-: mOwningStatement(aOwningStatement)
-, mLocked(false)
-{
-}
-
-void
-BindingParamsArray::lock()
-{
- NS_ASSERTION(mLocked == false, "Array has already been locked!");
- mLocked = true;
-
- // We also no longer need to hold a reference to our statement since it owns
- // us.
- mOwningStatement = nsnull;
-}
-
-const Statement *
-BindingParamsArray::getOwner() const
-{
- return mOwningStatement;
-}
-
-NS_IMPL_THREADSAFE_ISUPPORTS1(
- BindingParamsArray,
- mozIStorageBindingParamsArray
-)
-
-///////////////////////////////////////////////////////////////////////////////
-//// mozIStorageBindingParamsArray
-
-NS_IMETHODIMP
-BindingParamsArray::NewBindingParams(mozIStorageBindingParams **_params)
-{
- NS_ENSURE_FALSE(mLocked, NS_ERROR_UNEXPECTED);
-
- nsCOMPtr<mozIStorageBindingParams> params =
- new BindingParams(this, mOwningStatement);
- NS_ENSURE_TRUE(params, NS_ERROR_OUT_OF_MEMORY);
-
- params.forget(_params);
- return NS_OK;
-}
-
-NS_IMETHODIMP
-BindingParamsArray::AddParams(mozIStorageBindingParams *aParameters)
-{
- NS_ENSURE_FALSE(mLocked, NS_ERROR_UNEXPECTED);
-
- BindingParams *params = static_cast<BindingParams *>(aParameters);
-
- // Check to make sure that this set of parameters was created with us.
- if (params->getOwner() != this)
- return NS_ERROR_UNEXPECTED;
-
- NS_ENSURE_TRUE(mArray.AppendElement(params), NS_ERROR_OUT_OF_MEMORY);
-
- // Lock the parameters only after we've successfully added them.
- params->lock();
-
- return NS_OK;
-}
-
-} // namespace storage
-} // namespace mozilla
deleted file mode 100644
--- a/storage/src/mozStorageBindingParamsArray.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 _mozStorageBindingParamsArray_h_
-#define _mozStorageBindingParamsArray_h_
-
-#include "nsAutoPtr.h"
-#include "nsTArray.h"
-
-#include "mozIStorageBindingParamsArray.h"
-
-namespace mozilla {
-namespace storage {
-
-class BindingParams;
-class Statement;
-
-class BindingParamsArray : public mozIStorageBindingParamsArray
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_MOZISTORAGEBINDINGPARAMSARRAY
-
- BindingParamsArray(Statement *aOwningStatement);
-
- /**
- * Locks the array and prevents further modification to it (such as adding
- * more elements to it).
- */
- void lock();
-
- /**
- * @returns the pointer to the owning BindingParamsArray.
- */
- const Statement *getOwner() const;
-
- class iterator {
- public:
- iterator(BindingParamsArray *aArray,
- PRUint32 aIndex)
- : mArray(aArray)
- , mIndex(aIndex)
- {
- }
-
- iterator &operator++(int)
- {
- mIndex++;
- return *this;
- }
-
- bool operator==(const iterator &aOther) const
- {
- return mIndex == aOther.mIndex;
- }
- bool operator!=(const iterator &aOther) const
- {
- return !(*this == aOther);
- }
- BindingParams *operator*()
- {
- NS_ASSERTION(mIndex < mArray->mArray.Length(),
- "Dereferenceing an invalid value!");
- return mArray->mArray[mIndex].get();
- }
- private:
- void operator--() { }
- BindingParamsArray *mArray;
- PRUint32 mIndex;
- };
-
- /**
- * Obtains an iterator pointing to the beginning of the array.
- */
- inline iterator begin()
- {
- NS_ASSERTION(mLocked, "Obtaining an iterator when we are not locked!");
- return iterator(this, 0);
- }
-
- /**
- * Obtains an iterator pointing to the end of the array.
- */
- inline iterator end()
- {
- NS_ASSERTION(mLocked, "Obtaining an iterator when we are not locked!");
- return iterator(this, mArray.Length());
- }
-private:
- nsRefPtr<Statement> mOwningStatement;
- nsTArray< nsRefPtr<BindingParams> > mArray;
- bool mLocked;
-
- friend class iterator;
-};
-
-} // namespace storage
-} // namespace mozilla
-
-#endif // _mozStorageBindingParamsArray_h_
--- a/storage/src/mozStorageConnection.cpp
+++ b/storage/src/mozStorageConnection.cpp
@@ -57,17 +57,16 @@
#include "mozStorageAsyncStatementExecution.h"
#include "mozStorageSQLFunctions.h"
#include "mozStorageConnection.h"
#include "mozStorageService.h"
#include "mozStorageStatement.h"
#include "mozStorageArgValueArray.h"
#include "mozStoragePrivateHelpers.h"
-#include "mozStorageStatementData.h"
#include "prlog.h"
#include "prprf.h"
#ifdef PR_LOGGING
PRLogModuleInfo* gStorageLog = nsnull;
#endif
@@ -623,17 +622,17 @@ Connection::ExecuteSimpleSQL(const nsACS
nsresult
Connection::ExecuteAsync(mozIStorageStatement **aStatements,
PRUint32 aNumStatements,
mozIStorageStatementCallback *aCallback,
mozIStoragePendingStatement **_handle)
{
int rc = SQLITE_OK;
- nsTArray<StatementData> stmts(aNumStatements);
+ nsTArray<sqlite3_stmt *> stmts(aNumStatements);
for (PRUint32 i = 0; i < aNumStatements && rc == SQLITE_OK; i++) {
sqlite3_stmt *old_stmt =
static_cast<Statement *>(aStatements[i])->nativeStatement();
if (!old_stmt) {
rc = SQLITE_MISUSE;
break;
}
NS_ASSERTION(::sqlite3_db_handle(old_stmt) == mDBConn,
@@ -653,19 +652,17 @@ Connection::ExecuteAsync(mozIStorageStat
("Cloned statement 0x%p to 0x%p", old_stmt, new_stmt));
#endif
// Transfer the bindings
rc = sqlite3_transfer_bindings(old_stmt, new_stmt);
if (rc != SQLITE_OK)
break;
- Statement *storageStmt = static_cast<Statement *>(aStatements[i]);
- StatementData data(new_stmt, storageStmt->bindingParamsArray());
- if (!stmts.AppendElement(data)) {
+ if (!stmts.AppendElement(new_stmt)) {
rc = SQLITE_NOMEM;
break;
}
}
// Dispatch to the background
nsresult rv = NS_OK;
if (rc == SQLITE_OK)
--- a/storage/src/mozStorageStatement.cpp
+++ b/storage/src/mozStorageStatement.cpp
@@ -501,43 +501,16 @@ Statement::BindBlobParameter(PRUint32 aP
return NS_ERROR_NOT_INITIALIZED;
int srv = ::sqlite3_bind_blob(mDBStatement, aParamIndex + 1, aValue,
aValueSize, SQLITE_TRANSIENT);
return convertResultCode(srv);
}
NS_IMETHODIMP
-Statement::BindParameters(mozIStorageBindingParamsArray *aParameters)
-{
- if (!mDBStatement)
- return NS_ERROR_NOT_INITIALIZED;
-
- BindingParamsArray *array = static_cast<BindingParamsArray *>(aParameters);
- if (array->getOwner() != this)
- return NS_ERROR_UNEXPECTED;
-
- mParamsArray = array;
- mParamsArray->lock();
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-Statement::NewBindingParamsArray(mozIStorageBindingParamsArray **_array)
-{
- nsCOMPtr<mozIStorageBindingParamsArray> array =
- new BindingParamsArray(this);
- NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
-
- array.forget(_array);
- return NS_OK;
-}
-
-NS_IMETHODIMP
Statement::Execute()
{
if (!mDBStatement)
return NS_ERROR_NOT_INITIALIZED;
PRBool ret;
nsresult rv = ExecuteStep(&ret);
NS_ENSURE_SUCCESS(rv, rv);
--- a/storage/src/mozStorageStatement.h
+++ b/storage/src/mozStorageStatement.h
@@ -40,17 +40,16 @@
#ifndef _mozStorageStatement_h_
#define _mozStorageStatement_h_
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsTArray.h"
-#include "mozStorageBindingParamsArray.h"
#include "mozIStorageStatement.h"
class nsIXPConnectJSObjectHolder;
struct sqlite3_stmt;
namespace mozilla {
namespace storage {
class StatementJSHelper;
@@ -78,42 +77,27 @@ public:
const nsACString &aSQLStatement);
/**
* Obtains the native statement pointer.
*/
inline sqlite3_stmt *nativeStatement() { return mDBStatement; }
- /**
- * Obtains and transfers ownership of the array of parameters that are bound
- * to this statment. This can be null.
- */
- inline already_AddRefed<BindingParamsArray> bindingParamsArray()
- {
- return mParamsArray.forget();
- }
-
private:
~Statement();
nsRefPtr<Connection> mDBConnection;
sqlite3_stmt *mDBStatement;
PRUint32 mParamCount;
PRUint32 mResultColumnCount;
nsTArray<nsCString> mColumnNames;
bool mExecuting;
/**
- * Holds the array of parameters to bind to this statement when we execute
- * it asynchronously.
- */
- nsRefPtr<BindingParamsArray> mParamsArray;
-
- /**
* The following two members are only used with the JS helper. They cache
* the row and params objects.
*/
nsCOMPtr<nsIXPConnectJSObjectHolder> mStatementParamsHolder;
nsCOMPtr<nsIXPConnectJSObjectHolder> mStatementRowHolder;
friend class StatementJSHelper;
};
deleted file mode 100644
--- a/storage/src/mozStorageStatementData.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et
- * ***** 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 mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 _mozStorageStatementData_h_
-#define _mozStorageStatementData_h_
-
-#include "nsAutoPtr.h"
-#include "nsTArray.h"
-
-#include "mozStorageBindingParamsArray.h"
-
-struct sqlite3_stmt;
-
-namespace mozilla {
-namespace storage {
-
-class StatementData
-{
-public:
- StatementData(sqlite3_stmt *aStatement,
- already_AddRefed<BindingParamsArray> aParamsArray)
- : mStatement(aStatement)
- , mParamsArray(aParamsArray)
- {
- }
- StatementData(const StatementData &aSource)
- : mStatement(aSource.mStatement)
- , mParamsArray(aSource.mParamsArray)
- {
- }
- StatementData()
- {
- }
-
- operator sqlite3_stmt *() const
- {
- NS_ASSERTION(mStatement, "NULL sqlite3_stmt being handed off!");
- return mStatement;
- }
- operator BindingParamsArray *() const { return mParamsArray; }
-
- /**
- * Finalizes and NULLs out our sqlite3_stmt. Also releases our parameter
- * array since we'll no longer need it.
- */
- inline void finalize()
- {
- (void)::sqlite3_finalize(mStatement);
- mStatement = NULL;
- mParamsArray = nsnull;
- }
-
- /**
- * Indicates if this statement has parameters to be bound before it is
- * executed.
- *
- * @returns true if the statement has parameters to bind against, false
- * otherwise.
- */
- inline bool hasParametersToBeBound() const { return mParamsArray != nsnull; }
-
-private:
- sqlite3_stmt *mStatement;
- nsRefPtr<BindingParamsArray> mParamsArray;
-};
-
-} // namespace storage
-} // namespace mozilla
-
-#endif // _mozStorageStatementData_h_
--- a/storage/test/unit/test_connection_executeAsync.js
+++ b/storage/test/unit/test_connection_executeAsync.js
@@ -39,19 +39,21 @@
const INTEGER = 1;
const TEXT = "this is test text";
const REAL = 3.23;
const BLOB = [1, 2];
function test_create_and_add()
{
+ dump("test_create_and_add()\n");
+
getOpenedDatabase().executeSimpleSQL(
"CREATE TABLE test (" +
- "id INTEGER, " +
+ "id INTEGER PRIMARY KEY, " +
"string TEXT, " +
"number REAL, " +
"nuller NULL, " +
"blober BLOB" +
")"
);
let stmts = [];
@@ -66,16 +68,17 @@ function test_create_and_add()
stmts[1] = getOpenedDatabase().createStatement(
"INSERT INTO test (string, number, nuller, blober) VALUES (?, ?, ?, ?)"
);
stmts[1].bindStringParameter(0, TEXT);
stmts[1].bindDoubleParameter(1, REAL);
stmts[1].bindNullParameter(2);
stmts[1].bindBlobParameter(3, BLOB, BLOB.length);
+ do_test_pending();
getOpenedDatabase().executeAsync(stmts, stmts.length, {
handleResult: function(aResultSet)
{
dump("handleResult("+aResultSet+")\n");
do_throw("unexpected results obtained!");
},
handleError: function(aError)
{
@@ -115,153 +118,63 @@ function test_create_and_add()
try {
do_check_true(stmt.executeStep());
do_check_eq(2, stmt.getInt32(0));
}
finally {
stmt.finalize();
}
- // Run the next test.
- run_next_test();
+ do_test_finished();
}
});
stmts[0].finalize();
stmts[1].finalize();
}
function test_transaction_created()
{
+ dump("test_transaction_created()\n");
+
let stmts = [];
stmts[0] = getOpenedDatabase().createStatement(
"BEGIN"
);
stmts[1] = getOpenedDatabase().createStatement(
"SELECT * FROM test"
);
+ do_test_pending()
getOpenedDatabase().executeAsync(stmts, stmts.length, {
handleResult: function(aResultSet)
{
dump("handleResults("+aResultSet+")\n");
do_throw("unexpected results obtained!");
},
handleError: function(aError)
{
dump("handleError("+aError.result+")\n");
},
handleCompletion: function(aReason)
{
dump("handleCompletion("+aReason+")\n");
do_check_eq(Ci.mozIStorageStatementCallback.REASON_ERROR, aReason);
-
- // Run the next test.
- run_next_test();
+ do_test_finished();
}
});
stmts[0].finalize();
stmts[1].finalize();
}
-function test_multiple_bindings_on_statements()
-{
- // This tests to make sure that we pass all the statements multiply bound
- // parameters when we call executeAsync.
- const AMOUNT_TO_ADD = 5;
- const ITERATIONS = 5;
-
- let stmts = [];
- // We run the same statement twice, and should insert 2 * AMOUNT_TO_ADD.
- for (let i = 0; i < ITERATIONS; i++) {
- stmts[i] = getOpenedDatabase().createStatement(
- "INSERT INTO test (id, string, number, nuller, blober) " +
- "VALUES (:int, :text, :real, :null, :blob)"
- );
- let params = stmts[i].newBindingParamsArray()
- for (let j = 0; j < AMOUNT_TO_ADD; j++) {
- let bp = params.newBindingParams();
- bp.bindByName("int", INTEGER);
- bp.bindByName("text", TEXT);
- bp.bindByName("real", REAL);
- bp.bindByName("null", null);
- bp.bindBlobByName("blob", BLOB, BLOB.length);
- params.addParams(bp);
- }
- stmts[i].bindParameters(params);
- }
-
- // Get our current number of rows in the table.
- let currentRows = 0;
- let countStmt = getOpenedDatabase().createStatement(
- "SELECT COUNT(1) AS count FROM test"
- );
- try {
- do_check_true(countStmt.executeStep());
- currentRows = countStmt.row.count;
- }
- finally {
- countStmt.reset();
- }
-
- // Execute asynchronously.
- getOpenedDatabase().executeAsync(stmts, stmts.length, {
- handleResult: function(aResultSet)
- {
- do_throw("Unexpected call to handleResult!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("Unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_multiple_bindings_on_statements");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
-
- // Check to make sure we added all of our rows.
- try {
- do_check_true(countStmt.executeStep());
- do_check_eq(currentRows + (ITERATIONS * AMOUNT_TO_ADD),
- countStmt.row.count);
- }
- finally {
- countStmt.finalize();
- }
-
- // Run the next test.
- run_next_test();
- }
- });
- stmts.forEach(function(stmt) stmt.finalize());
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Runner
let tests =
[
test_create_and_add,
test_transaction_created,
- test_multiple_bindings_on_statements,
];
-let index = 0;
-
-function run_next_test()
-{
- if (index < tests.length) {
- do_test_pending();
- print("Running the next test: " + tests[index].name);
- tests[index++]();
- }
-
- do_test_finished();
-}
function run_test()
{
cleanup();
- do_test_pending();
- run_next_test();
+ for (let i = 0; i < tests.length; i++)
+ tests[i]();
}
deleted file mode 100644
--- a/storage/test/unit/test_statement_executeAsync.js
+++ /dev/null
@@ -1,1006 +0,0 @@
-/* ***** 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 Storage Test Code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2008
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
- *
- * 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 ***** */
-
-// This file tests the functionality of mozIStorageStatement::executeAsync
-
-const INTEGER = 1;
-const TEXT = "this is test text";
-const REAL = 3.23;
-const BLOB = [1, 2];
-
-function test_create_table()
-{
- // Ensure our table doesn't exists
- do_check_false(getOpenedDatabase().tableExists("test"));
-
- var stmt = getOpenedDatabase().createStatement(
- "CREATE TABLE test (" +
- "id INTEGER, " +
- "string TEXT, " +
- "number REAL, " +
- "nuller NULL, " +
- "blober BLOB" +
- ")"
- );
-
- stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- dump("handleResult("+aResultSet+");\n");
- do_throw("unexpected results obtained!");
- },
- handleError: function(aError)
- {
- print("error code " + aerror.result + " with message '" +
- aerror.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason + ") for test_create_table");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
-
- // Check that the table has been created
- do_check_true(getOpenedDatabase().tableExists("test"));
-
- // Verify that it's created correctly (this will throw if it wasn't)
- var stmt = getOpenedDatabase().createStatement(
- "SELECT id, string, number, nuller, blober FROM test"
- );
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_add_data()
-{
- var stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id, string, number, nuller, blober) " +
- "VALUES (?, ?, ?, ?, ?)"
- );
- stmt.bindInt32Parameter(0, INTEGER);
- stmt.bindStringParameter(1, TEXT);
- stmt.bindDoubleParameter(2, REAL);
- stmt.bindNullParameter(3);
- stmt.bindBlobParameter(4, BLOB, BLOB.length);
-
- stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- do_throw("unexpected results obtained!");
- },
- handleError: function(aError)
- {
- print("error code " + aerror.result + " with message '" +
- aerror.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason + ") for test_add_data");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
-
- // Check that the result is in the table
- var stmt = getOpenedDatabase().createStatement(
- "SELECT string, number, nuller, blober FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, INTEGER);
- try {
- do_check_true(stmt.executeStep());
- do_check_eq(TEXT, stmt.getString(0));
- do_check_eq(REAL, stmt.getDouble(1));
- do_check_true(stmt.getIsNull(2));
- var count = { value: 0 };
- var blob = { value: null };
- stmt.getBlob(3, count, blob);
- do_check_eq(BLOB.length, count.value);
- for (var i = 0; i < BLOB.length; i++)
- do_check_eq(BLOB[i], blob.value[i]);
- }
- finally {
- stmt.reset();
- stmt.finalize();
- }
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_get_data()
-{
- var stmt = getOpenedDatabase().createStatement(
- "SELECT string, number, nuller, blober, id FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, 1);
-
- stmt.executeAsync({
- resultObtained: false,
- handleResult: function(aResultSet)
- {
- dump("handleResult("+aResultSet+");\n");
- do_check_false(this.resultObtained);
- this.resultObtained = true;
-
- // Check that we have a result
- var tuple = aResultSet.getNextRow();
- do_check_neq(null, tuple);
-
- // Check that it's what we expect
- do_check_eq(tuple.getResultByName("string"), tuple.getResultByIndex(0));
- do_check_eq(TEXT, tuple.getResultByName("string"));
- do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_TEXT,
- tuple.getTypeOfIndex(0));
-
- do_check_eq(tuple.getResultByName("number"), tuple.getResultByIndex(1));
- do_check_eq(REAL, tuple.getResultByName("number"));
- do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT,
- tuple.getTypeOfIndex(1));
-
- do_check_eq(tuple.getResultByName("nuller"), tuple.getResultByIndex(2));
- do_check_eq(null, tuple.getResultByName("nuller"));
- do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_NULL,
- tuple.getTypeOfIndex(2));
-
- var blobByName = tuple.getResultByName("blober");
- do_check_eq(BLOB.length, blobByName.length);
- var blobByIndex = tuple.getResultByIndex(3);
- do_check_eq(BLOB.length, blobByIndex.length);
- for (var i = 0; i < BLOB.length; i++) {
- do_check_eq(BLOB[i], blobByName[i]);
- do_check_eq(BLOB[i], blobByIndex[i]);
- }
- var count = { value: 0 };
- var blob = { value: null };
- tuple.getBlob(3, count, blob);
- do_check_eq(BLOB.length, count.value);
- for (var i = 0; i < BLOB.length; i++)
- do_check_eq(BLOB[i], blob.value[i]);
- do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_BLOB,
- tuple.getTypeOfIndex(3));
-
- do_check_eq(tuple.getResultByName("id"), tuple.getResultByIndex(4));
- do_check_eq(INTEGER, tuple.getResultByName("id"));
- do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER,
- tuple.getTypeOfIndex(4));
-
- // check that we have no more results
- tuple = aResultSet.getNextRow();
- do_check_eq(null, tuple);
- },
- handleError: function(aError)
- {
- print("error code " + aerror.result + " with message '" +
- aerror.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason + ") for test_get_data");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
- do_check_true(this.resultObtained);
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_tuple_out_of_bounds()
-{
- var stmt = getOpenedDatabase().createStatement(
- "SELECT string FROM test"
- );
-
- stmt.executeAsync({
- resultObtained: false,
- handleResult: function(aResultSet)
- {
- dump("handleResult("+aResultSet+");\n");
- do_check_false(this.resultObtained);
- this.resultObtained = true;
-
- // Check that we have a result
- var tuple = aResultSet.getNextRow();
- do_check_neq(null, tuple);
-
- // Check all out of bounds - should throw
- var methods = [
- "getTypeOfIndex",
- "getInt32",
- "getInt64",
- "getDouble",
- "getUTF8String",
- "getString",
- "getIsNull",
- ];
- for (var i in methods) {
- try {
- tuple[methods[i]](tuple.numEntries);
- do_throw("did not throw :(");
- }
- catch (e) {
- do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
- }
- }
-
- // getBlob requires more args...
- try {
- var blob = { value: null };
- var size = { value: 0 };
- tuple.getBlob(tuple.numEntries, blob, size);
- do_throw("did not throw :(");
- }
- catch (e) {
- do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
- }
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_tuple_out_of_bounds");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
- do_check_true(this.resultObtained);
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_no_listener_works_on_success()
-{
- var stmt = getOpenedDatabase().createStatement(
- "DELETE FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, 0);
- stmt.executeAsync();
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_no_listener_works_on_results()
-{
- var stmt = getOpenedDatabase().createStatement(
- "SELECT ?"
- );
- stmt.bindInt32Parameter(0, 1);
- stmt.executeAsync();
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_no_listener_works_on_error()
-{
- // commit without a transaction will trigger an error
- var stmt = getOpenedDatabase().createStatement(
- "COMMIT"
- );
- stmt.executeAsync();
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_partial_listener_works()
-{
- var stmt = getOpenedDatabase().createStatement(
- "DELETE FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, 0);
- stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- }
- });
- stmt.executeAsync({
- handleError: function(aError)
- {
- }
- });
- stmt.executeAsync({
- handleCompletion: function(aReason)
- {
- }
- });
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_immediate_cancellation()
-{
- var stmt = getOpenedDatabase().createStatement(
- "DELETE FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, 0);
- let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
- var pendingStatement = stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- do_throw("unexpected result!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_immediate_cancellation");
- do_check_eq(reason, aReason);
-
- // Run the next test.
- run_next_test();
- }
- });
-
- // Cancel immediately
- if (!pendingStatement.cancel()) {
- // It is possible that we finished before we canceled
- reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
- }
-
- stmt.finalize();
-}
-
-function test_double_cancellation()
-{
- var stmt = getOpenedDatabase().createStatement(
- "DELETE FROM test WHERE id = ?"
- );
- stmt.bindInt32Parameter(0, 0);
- let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
- var pendingStatement = stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- do_throw("unexpected result!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_double_cancellation");
- do_check_eq(reason, aReason);
-
- // Run the next test.
- run_next_test();
- }
- });
-
- // Cancel immediately
- if (!pendingStatement.cancel()) {
- // It is possible that we finished before we canceled
- reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
- }
-
- // And cancel again - expect an exception
- try {
- pendingStatement.cancel();
- do_throw("function call should have thrown!");
- }
- catch (e) {
- do_check_eq(Cr.NS_ERROR_UNEXPECTED, e.result);
- }
-
- stmt.finalize();
-}
-
-function test_double_execute()
-{
- var stmt = getOpenedDatabase().createStatement(
- "SELECT * FROM test"
- );
-
- var listener = {
- _timesCompleted: 0,
- _hasResults: false,
- handleResult: function(aResultSet)
- {
- do_check_false(this._hasResults);
- this._hasResults = true;
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_double_execute (iteration " +
- (this._timesCompleted + 1) + ")");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
- do_check_true(this._hasResults);
- this._hasResults = false;
- this._timesCompleted++;
-
- // Run the next test.
- if (this._timesCompleted == 2)
- run_next_test();
- }
- }
- stmt.executeAsync(listener);
- stmt.executeAsync(listener);
- stmt.finalize();
-}
-
-function test_finalized_statement_does_not_crash()
-{
- var stmt = getOpenedDatabase().createStatement(
- "SELECT * FROM TEST"
- );
- stmt.finalize();
- // we are concerned about a crash here; an error is fine.
- try {
- stmt.executeAsync();
- }
- catch (ex) {}
-
- // Run the next test.
- run_next_test();
-}
-
-function test_bind_multiple_rows_by_index()
-{
- const AMOUNT_TO_ADD = 5;
- var stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id, string, number, nuller, blober) " +
- "VALUES (?, ?, ?, ?, ?)"
- );
- var array = stmt.newBindingParamsArray();
- for (let i = 0; i < AMOUNT_TO_ADD; i++) {
- let bp = array.newBindingParams();
- bp.bindByIndex(0, INTEGER);
- bp.bindByIndex(1, TEXT);
- bp.bindByIndex(2, REAL);
- bp.bindByIndex(3, null);
- bp.bindBlobByIndex(4, BLOB, BLOB.length);
- array.addParams(bp);
- }
- stmt.bindParameters(array);
-
- // Get our current number of rows in the table.
- var currentRows = 0;
- var countStmt = getOpenedDatabase().createStatement(
- "SELECT COUNT(1) AS count FROM test"
- );
- try {
- do_check_true(countStmt.executeStep());
- currentRows = countStmt.row.count;
- print("We have " + currentRows + " rows in test_bind_multiple_rows_by_index");
- }
- finally {
- countStmt.reset();
- }
-
- // Execute asynchronously.
- stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- do_throw("Unexpected call to handleResult!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_bind_multiple_rows_by_index");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
-
- // Check to make sure we added all of our rows.
- try {
- do_check_true(countStmt.executeStep());
- print("We now have " + currentRows +
- " rows in test_bind_multiple_rows_by_index");
- do_check_eq(currentRows + AMOUNT_TO_ADD, countStmt.row.count);
- }
- finally {
- countStmt.finalize();
- }
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_bind_multiple_rows_by_name()
-{
- const AMOUNT_TO_ADD = 5;
- var stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id, string, number, nuller, blober) " +
- "VALUES (:int, :text, :real, :null, :blob)"
- );
- var array = stmt.newBindingParamsArray();
- for (let i = 0; i < AMOUNT_TO_ADD; i++) {
- let bp = array.newBindingParams();
- bp.bindByName("int", INTEGER);
- bp.bindByName("text", TEXT);
- bp.bindByName("real", REAL);
- bp.bindByName("null", null);
- bp.bindBlobByName("blob", BLOB, BLOB.length);
- array.addParams(bp);
- }
- stmt.bindParameters(array);
-
- // Get our current number of rows in the table.
- var currentRows = 0;
- var countStmt = getOpenedDatabase().createStatement(
- "SELECT COUNT(1) AS count FROM test"
- );
- try {
- do_check_true(countStmt.executeStep());
- currentRows = countStmt.row.count;
- print("We have " + currentRows + " rows in test_bind_multiple_rows_by_name");
- }
- finally {
- countStmt.reset();
- }
-
- // Execute asynchronously.
- stmt.executeAsync({
- handleResult: function(aResultSet)
- {
- do_throw("Unexpected call to handleResult!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- do_throw("unexpected error!");
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_bind_multiple_rows_by_name");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
-
- // Check to make sure we added all of our rows.
- try {
- do_check_true(countStmt.executeStep());
- print("We now have " + currentRows +
- " rows in test_bind_multiple_rows_by_name");
- do_check_eq(currentRows + AMOUNT_TO_ADD, countStmt.row.count);
- }
- finally {
- countStmt.finalize();
- }
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_bind_out_of_bounds()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (?)"
- );
-
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
-
- // Check variant binding.
- let exceptionCaught = false;
- try {
- bp.bindByIndex(1, INTEGER);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Check blob binding.
- exceptionCaught = false;
- try {
- bp.bindBlobByIndex(1, BLOB, BLOB.length);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_bind_no_such_name()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:foo)"
- );
-
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
-
- // Check variant binding.
- let exceptionCaught = false;
- try {
- bp.bindByName("doesnotexist", INTEGER);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Check blob binding.
- exceptionCaught = false;
- try {
- bp.bindBlobByName("doesnotexist", BLOB, BLOB.length);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- stmt.finalize();
-
- // Run the next test.
- run_next_test();
-}
-
-function test_bind_bogus_type_by_index()
-{
- // We try to bind a JS Object here that should fail to bind.
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (blober) " +
- "VALUES (?)"
- );
-
- // We get an error after calling executeAsync, not when we bind.
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
- bp.bindByIndex(0, run_test);
- array.addParams(bp);
- stmt.bindParameters(array);
-
- stmt.executeAsync({
- _errorObtained: false,
- handleResult: function(aResultSet)
- {
- do_throw("Unexpected call to handleResult!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- this._errorObtained = true;
- do_check_eq(aError.result, Ci.mozIStorageError.MISMATCH);
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_bind_bogus_type_by_index");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_ERROR, aReason);
- do_check_true(this._errorObtained);
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_bind_bogus_type_by_name()
-{
- // We try to bind a JS Object here that should fail to bind.
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (blober) " +
- "VALUES (:blob)"
- );
-
- // We get an error after calling executeAsync, not when we bind.
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
- bp.bindByName("blob", run_test);
- array.addParams(bp);
- stmt.bindParameters(array);
-
- stmt.executeAsync({
- _errorObtained: false,
- handleResult: function(aResultSet)
- {
- do_throw("Unexpected call to handleResult!");
- },
- handleError: function(aError)
- {
- print("Error code " + aError.result + " with message '" +
- aError.message + "' returned.");
- this._errorObtained = true;
- do_check_eq(aError.result, Ci.mozIStorageError.MISMATCH);
- },
- handleCompletion: function(aReason)
- {
- print("handleCompletion(" + aReason +
- ") for test_bind_bogus_type_by_name");
- do_check_eq(Ci.mozIStorageStatementCallback.REASON_ERROR, aReason);
- do_check_true(this._errorObtained);
-
- // Run the next test.
- run_next_test();
- }
- });
- stmt.finalize();
-}
-
-function test_bind_params_already_locked()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
-
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
- bp.bindByName("int", INTEGER);
- array.addParams(bp);
-
- // We should get an error after we call addParams and try to bind again.
- let exceptionCaught = false;
- try {
- bp.bindByName("int", INTEGER);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Run the next test.
- run_next_test();
-}
-
-function test_bind_params_array_already_locked()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
-
- let array = stmt.newBindingParamsArray();
- let bp1 = array.newBindingParams();
- bp1.bindByName("int", INTEGER);
- array.addParams(bp1);
- let bp2 = array.newBindingParams();
- stmt.bindParameters(array);
- bp2.bindByName("int", INTEGER);
-
- // We should get an error after we have bound the array to the statement.
- let exceptionCaught = false;
- try {
- array.addParams(bp2);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Run the next test.
- run_next_test();
-}
-
-function test_no_binding_params_from_locked_array()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
-
- let array = stmt.newBindingParamsArray();
- let bp = array.newBindingParams();
- bp.bindByName("int", INTEGER);
- array.addParams(bp);
- stmt.bindParameters(array);
-
- // We should not be able to get a new BindingParams object after we have bound
- // to the statement.
- let exceptionCaught = false;
- try {
- bp = array.newBindingParams();
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Run the next test.
- run_next_test();
-}
-
-function test_not_right_owning_array()
-{
- let stmt = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
-
- let array1 = stmt.newBindingParamsArray();
- let array2 = stmt.newBindingParamsArray();
- let bp = array1.newBindingParams();
- bp.bindByName("int", INTEGER);
-
- // We should not be able to add bp to array2 since it was created from array1.
- let exceptionCaught = false;
- try {
- array2.addParams(bp);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Run the next test.
- run_next_test();
-}
-
-function test_not_right_owning_statement()
-{
- let stmt1 = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
- let stmt2 = getOpenedDatabase().createStatement(
- "INSERT INTO test (id) " +
- "VALUES (:int)"
- );
-
- let array1 = stmt1.newBindingParamsArray();
- let array2 = stmt2.newBindingParamsArray();
- let bp = array1.newBindingParams();
- bp.bindByName("int", INTEGER);
- array1.addParams(bp);
-
- // We should not be able to bind array1 since it was created from stmt1.
- let exceptionCaught = false;
- try {
- stmt2.bindParameters(array1);
- do_throw("we should have an exception!");
- }
- catch(e) {
- do_check_eq(e.result, Cr.NS_ERROR_UNEXPECTED);
- exceptionCaught = true;
- }
- do_check_true(exceptionCaught);
-
- // Run the next test.
- run_next_test();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Test Runner
-
-var tests =
-[
- test_create_table,
- test_add_data,
- test_get_data,
- test_tuple_out_of_bounds,
- test_no_listener_works_on_success,
- test_no_listener_works_on_results,
- test_no_listener_works_on_error,
- test_partial_listener_works,
- test_immediate_cancellation,
- test_double_cancellation,
- test_double_execute,
- test_finalized_statement_does_not_crash,
- test_bind_multiple_rows_by_index,
- test_bind_multiple_rows_by_name,
- test_bind_out_of_bounds,
- test_bind_no_such_name,
- test_bind_bogus_type_by_index,
- test_bind_bogus_type_by_name,
- test_bind_params_already_locked,
- test_bind_params_array_already_locked,
- test_no_binding_params_from_locked_array,
- test_not_right_owning_array,
- test_not_right_owning_statement,
-];
-let index = 0;
-
-function run_next_test()
-{
- if (index < tests.length) {
- do_test_pending();
- print("Running the next test: " + tests[index].name);
- tests[index++]();
- }
-
- do_test_finished();
-}
-
-function run_test()
-{
- cleanup();
-
- do_test_pending();
- run_next_test();
-}
new file mode 100644
--- /dev/null
+++ b/storage/test/unit/test_storage_statement_executeAsync.js
@@ -0,0 +1,521 @@
+/* ***** 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 Storage Test Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * 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 ***** */
+
+// This file tests the functionality of mozIStorageStatement::executeAsync
+
+const INTEGER = 1;
+const TEXT = "this is test text";
+const REAL = 3.23;
+const BLOB = [1, 2];
+
+function test_create_table()
+{
+ dump("test_create_table()\n");
+
+ // Ensure our table doesn't exists
+ do_check_false(getOpenedDatabase().tableExists("test"));
+
+ var stmt = getOpenedDatabase().createStatement(
+ "CREATE TABLE test (" +
+ "id INTEGER PRIMARY KEY, " +
+ "string TEXT, " +
+ "number REAL, " +
+ "nuller NULL, " +
+ "blober BLOB" +
+ ")"
+ );
+
+ do_test_pending();
+ stmt.executeAsync({
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_throw("unexpected results obtained!");
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
+
+ // Check that the table has been created
+ do_check_true(getOpenedDatabase().tableExists("test"));
+
+ // Verify that it's created correctly (this will throw if it wasn't)
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT id, string, number, nuller, blober FROM test"
+ );
+ stmt.finalize();
+
+ // Now we run the rest of the tests
+ for (var i = 0; i < tests.length; i++)
+ tests[i]();
+
+ do_test_finished();
+ }
+ });
+ stmt.finalize();
+}
+
+function test_add_data()
+{
+ dump("test_add_data()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "INSERT INTO test (id, string, number, nuller, blober) VALUES (?, ?, ?, ?, ?)"
+ );
+ stmt.bindInt32Parameter(0, INTEGER);
+ stmt.bindStringParameter(1, TEXT);
+ stmt.bindDoubleParameter(2, REAL);
+ stmt.bindNullParameter(3);
+ stmt.bindBlobParameter(4, BLOB, BLOB.length);
+
+ do_test_pending();
+ stmt.executeAsync({
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_throw("unexpected results obtained!");
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
+
+ // Check that the result is in the table
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT string, number, nuller, blober FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, INTEGER);
+ try {
+ do_check_true(stmt.executeStep());
+ do_check_eq(TEXT, stmt.getString(0));
+ do_check_eq(REAL, stmt.getDouble(1));
+ do_check_true(stmt.getIsNull(2));
+ var count = { value: 0 };
+ var blob = { value: null };
+ stmt.getBlob(3, count, blob);
+ do_check_eq(BLOB.length, count.value);
+ for (var i = 0; i < BLOB.length; i++)
+ do_check_eq(BLOB[i], blob.value[i]);
+ }
+ finally {
+ stmt.reset();
+ stmt.finalize();
+ }
+
+ do_test_finished();
+ }
+ });
+ stmt.finalize();
+}
+
+function test_get_data()
+{
+ dump("test_get_data()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT string, number, nuller, blober, id FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, 1);
+
+ do_test_pending();
+ stmt.executeAsync({
+ resultObtained: false,
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_check_false(this.resultObtained);
+ this.resultObtained = true;
+
+ // Check that we have a result
+ var tuple = aResultSet.getNextRow();
+ do_check_neq(null, tuple);
+
+ // Check that it's what we expect
+ do_check_eq(tuple.getResultByName("string"), tuple.getResultByIndex(0));
+ do_check_eq(TEXT, tuple.getResultByName("string"));
+ do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_TEXT,
+ tuple.getTypeOfIndex(0));
+
+ do_check_eq(tuple.getResultByName("number"), tuple.getResultByIndex(1));
+ do_check_eq(REAL, tuple.getResultByName("number"));
+ do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_FLOAT,
+ tuple.getTypeOfIndex(1));
+
+ do_check_eq(tuple.getResultByName("nuller"), tuple.getResultByIndex(2));
+ do_check_eq(null, tuple.getResultByName("nuller"));
+ do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_NULL,
+ tuple.getTypeOfIndex(2));
+
+ var blobByName = tuple.getResultByName("blober");
+ do_check_eq(BLOB.length, blobByName.length);
+ var blobByIndex = tuple.getResultByIndex(3);
+ do_check_eq(BLOB.length, blobByIndex.length);
+ for (var i = 0; i < BLOB.length; i++) {
+ do_check_eq(BLOB[i], blobByName[i]);
+ do_check_eq(BLOB[i], blobByIndex[i]);
+ }
+ var count = { value: 0 };
+ var blob = { value: null };
+ tuple.getBlob(3, count, blob);
+ do_check_eq(BLOB.length, count.value);
+ for (var i = 0; i < BLOB.length; i++)
+ do_check_eq(BLOB[i], blob.value[i]);
+ do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_BLOB,
+ tuple.getTypeOfIndex(3));
+
+ do_check_eq(tuple.getResultByName("id"), tuple.getResultByIndex(4));
+ do_check_eq(INTEGER, tuple.getResultByName("id"));
+ do_check_eq(Ci.mozIStorageValueArray.VALUE_TYPE_INTEGER,
+ tuple.getTypeOfIndex(4));
+
+ // check that we have no more results
+ tuple = aResultSet.getNextRow();
+ do_check_eq(null, tuple);
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
+ do_check_true(this.resultObtained);
+ do_test_finished();
+ }
+ });
+ stmt.finalize();
+}
+
+function test_tuple_out_of_bounds()
+{
+ dump("test_tuple_out_of_bounds()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT string FROM test"
+ );
+
+ do_test_pending();
+ stmt.executeAsync({
+ resultObtained: false,
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_check_false(this.resultObtained);
+ this.resultObtained = true;
+
+ // Check that we have a result
+ var tuple = aResultSet.getNextRow();
+ do_check_neq(null, tuple);
+
+ // Check all out of bounds - should throw
+ var methods = [
+ "getTypeOfIndex",
+ "getInt32",
+ "getInt64",
+ "getDouble",
+ "getUTF8String",
+ "getString",
+ "getIsNull",
+ ];
+ for (var i in methods) {
+ try {
+ tuple[methods[i]](tuple.numEntries);
+ do_throw("did not throw :(");
+ }
+ catch (e) {
+ do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
+ }
+ }
+
+ // getBlob requires more args...
+ try {
+ var blob = { value: null };
+ var size = { value: 0 };
+ tuple.getBlob(tuple.numEntries, blob, size);
+ do_throw("did not throw :(");
+ }
+ catch (e) {
+ do_check_eq(Cr.NS_ERROR_ILLEGAL_VALUE, e.result);
+ }
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
+ do_check_true(this.resultObtained);
+ do_test_finished();
+ }
+ });
+ stmt.finalize();
+}
+
+function test_no_listener_works_on_success()
+{
+ dump("test_no_listener_works_on_success()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "DELETE FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, 0);
+ stmt.executeAsync();
+ stmt.finalize();
+}
+
+function test_no_listener_works_on_results()
+{
+ dump("test_no_listener_works_on_results()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT ?"
+ );
+ stmt.bindInt32Parameter(0, 1);
+ stmt.executeAsync();
+ stmt.finalize();
+}
+
+function test_no_listener_works_on_error()
+{
+ return;
+ dump("test_no_listener_works_on_error()\n");
+
+ // commit without a transaction will trigger an error
+ var stmt = getOpenedDatabase().createStatement(
+ "COMMIT"
+ );
+ stmt.executeAsync();
+ stmt.finalize();
+}
+
+function test_partial_listener_works()
+{
+ dump("test_partial_listener_works()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "DELETE FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, 0);
+ stmt.executeAsync({
+ handleResult: function(aResultSet)
+ {
+ }
+ });
+ stmt.executeAsync({
+ handleError: function(aError)
+ {
+ }
+ });
+ stmt.executeAsync({
+ handleCompletion: function(aReason)
+ {
+ }
+ });
+ stmt.finalize();
+}
+
+function test_immediate_cancellation()
+{
+ dump("test_immediate_cancelation()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "DELETE FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, 0);
+ let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
+ var pendingStatement = stmt.executeAsync({
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_throw("unexpected result!");
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(reason, aReason);
+ do_test_finished();
+ }
+ });
+ do_test_pending();
+
+ // Cancel immediately
+ if (!pendingStatement.cancel()) {
+ // It is possible that we finished before we canceled
+ reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
+ }
+
+ stmt.finalize();
+}
+
+function test_double_cancellation()
+{
+ dump("test_double_cancelation()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "DELETE FROM test WHERE id = ?"
+ );
+ stmt.bindInt32Parameter(0, 0);
+ let reason = Ci.mozIStorageStatementCallback.REASON_CANCELED;
+ var pendingStatement = stmt.executeAsync({
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ do_throw("unexpected result!");
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(reason, aReason);
+ do_test_finished();
+ }
+ });
+ do_test_pending();
+
+ // Cancel immediately
+ if (!pendingStatement.cancel()) {
+ // It is possible that we finished before we canceled
+ reason = Ci.mozIStorageStatementCallback.REASON_FINISHED;
+ }
+
+ // And cancel again - expect an exception
+ try {
+ pendingStatement.cancel();
+ do_throw("function call should have thrown!");
+ }
+ catch (e) {
+ do_check_eq(Cr.NS_ERROR_UNEXPECTED, e.result);
+ }
+
+ stmt.finalize();
+}
+
+function test_double_execute()
+{
+ dump("test_double_execute()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT * FROM test"
+ );
+
+ var listener = {
+ handleResult: function(aResultSet)
+ {
+ dump("handleResult("+aResultSet+");\n");
+ },
+ handleError: function(aError)
+ {
+ dump("handleError("+aError+");\n");
+ do_throw("unexpected error!");
+ },
+ handleCompletion: function(aReason)
+ {
+ dump("handleCompletion("+aReason+");\n");
+ do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason);
+ do_test_finished();
+ }
+ }
+ do_test_pending();
+ stmt.executeAsync(listener);
+ do_test_pending();
+ stmt.executeAsync(listener);
+ stmt.finalize();
+}
+
+function test_finalized_statement_does_not_crash()
+{
+ dump("test_finalized_statement_does_not_crash()\n");
+
+ var stmt = getOpenedDatabase().createStatement(
+ "SELECT * FROM TEST"
+ );
+ stmt.finalize();
+ // we are concerned about a crash here; an error is fine.
+ try {
+ stmt.executeAsync();
+ }
+ catch (ex) {}
+}
+
+var tests =
+[
+ test_add_data,
+ test_get_data,
+ test_tuple_out_of_bounds,
+ test_no_listener_works_on_success,
+ test_no_listener_works_on_results,
+ test_no_listener_works_on_error,
+ test_partial_listener_works,
+ test_immediate_cancellation,
+ test_double_cancellation,
+ test_double_execute,
+ test_finalized_statement_does_not_crash,
+];
+
+function run_test()
+{
+ cleanup();
+
+ // This test has to run first and run to completion. When it is done, it will
+ // run the rest of the tests.
+ test_create_table();
+}