diff --git a/storage/public/mozIStorageStatement.idl b/storage/public/mozIStorageStatement.idl index f74eacbec9d4..4af59ac2441c 100644 --- a/storage/public/mozIStorageStatement.idl +++ b/storage/public/mozIStorageStatement.idl @@ -264,44 +264,61 @@ interface mozIStorageStatement : mozIStorageBaseStatement { */ inline PRInt32 AsInt32(PRUint32 idx) { - PRInt32 v; - GetInt32(idx, &v); + PRInt32 v = 0; + nsresult rv = GetInt32(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline PRInt64 AsInt64(PRUint32 idx) { - PRInt64 v; - GetInt64(idx, &v); + PRInt64 v = 0; + nsresult rv = GetInt64(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline double AsDouble(PRUint32 idx) { - double v; - GetDouble(idx, &v); + double v = 0.0; + nsresult rv = GetDouble(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline const char* AsSharedUTF8String(PRUint32 idx, PRUint32 *len) { const char *str = nsnull; - GetSharedUTF8String(idx, len, &str); + *len = 0; + nsresult rv = GetSharedUTF8String(idx, len, &str); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return str; } inline const PRUnichar* AsSharedWString(PRUint32 idx, PRUint32 *len) { const PRUnichar *str = nsnull; - GetSharedString(idx, len, &str); + *len = 0; + nsresult rv = GetSharedString(idx, len, &str); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return str; } inline const PRUint8* AsSharedBlob(PRUint32 idx, PRUint32 *len) { const PRUint8 *blob = nsnull; - GetSharedBlob(idx, len, &blob); + *len = 0; + nsresult rv = GetSharedBlob(idx, len, &blob); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return blob; } inline PRBool IsNull(PRUint32 idx) { PRBool b = PR_FALSE; - GetIsNull(idx, &b); + nsresult rv = GetIsNull(idx, &b); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), + "Getting value failed, wrong column index?"); return b; } diff --git a/storage/public/mozIStorageValueArray.idl b/storage/public/mozIStorageValueArray.idl index c43b9466465a..69f3bf85fe0d 100644 --- a/storage/public/mozIStorageValueArray.idl +++ b/storage/public/mozIStorageValueArray.idl @@ -110,44 +110,61 @@ interface mozIStorageValueArray : nsISupports { */ inline PRInt32 AsInt32(PRUint32 idx) { - PRInt32 v; - GetInt32(idx, &v); + PRInt32 v = 0; + nsresult rv = GetInt32(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline PRInt64 AsInt64(PRUint32 idx) { - PRInt64 v; - GetInt64(idx, &v); + PRInt64 v = 0; + nsresult rv = GetInt64(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline double AsDouble(PRUint32 idx) { - double v; - GetDouble(idx, &v); + double v = 0.0; + nsresult rv = GetDouble(idx, &v); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return v; } inline const char* AsSharedUTF8String(PRUint32 idx, PRUint32 *len) { const char *str = nsnull; - GetSharedUTF8String(idx, len, &str); + *len = 0; + nsresult rv = GetSharedUTF8String(idx, len, &str); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return str; } inline const PRUnichar* AsSharedWString(PRUint32 idx, PRUint32 *len) { const PRUnichar *str = nsnull; - GetSharedString(idx, len, &str); + *len = 0; + nsresult rv = GetSharedString(idx, len, &str); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return str; } inline const PRUint8* AsSharedBlob(PRUint32 idx, PRUint32 *len) { const PRUint8 *blob = nsnull; - GetSharedBlob(idx, len, &blob); + *len = 0; + nsresult rv = GetSharedBlob(idx, len, &blob); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) || IsNull(idx), + "Getting value failed, wrong column index?"); return blob; } inline PRBool IsNull(PRUint32 idx) { PRBool b = PR_FALSE; - GetIsNull(idx, &b); + nsresult rv = GetIsNull(idx, &b); + NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), + "Getting value failed, wrong column index?"); return b; } diff --git a/storage/test/Makefile.in b/storage/test/Makefile.in index 194b97abc05d..389102e6cb50 100644 --- a/storage/test/Makefile.in +++ b/storage/test/Makefile.in @@ -56,6 +56,7 @@ CPP_UNIT_TESTS = \ test_true_async.cpp \ test_unlock_notify.cpp \ test_service_init_background_thread.cpp \ + test_AsXXX_helpers.cpp \ $(NULL) ifdef MOZ_DEBUG diff --git a/storage/test/storage_test_harness.h b/storage/test/storage_test_harness.h index 571da9774e0e..a54c6b56b08d 100644 --- a/storage/test/storage_test_harness.h +++ b/storage/test/storage_test_harness.h @@ -43,6 +43,14 @@ #include "nsDirectoryServiceDefs.h" #include "mozIStorageService.h" #include "mozIStorageConnection.h" +#include "mozIStorageStatementCallback.h" +#include "mozIStorageCompletionCallback.h" +#include "mozIStorageBindingParamsArray.h" +#include "mozIStorageBindingParams.h" +#include "mozIStorageAsyncStatement.h" +#include "mozIStorageStatement.h" +#include "mozIStoragePendingStatement.h" +#include "nsThreadUtils.h" static int gTotalTests = 0; static int gPassedTests = 0; @@ -109,3 +117,73 @@ getDatabase() do_check_success(rv); return conn.forget(); } + + +class AsyncStatementSpinner : public mozIStorageStatementCallback + , public mozIStorageCompletionCallback +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_MOZISTORAGESTATEMENTCALLBACK + NS_DECL_MOZISTORAGECOMPLETIONCALLBACK + + AsyncStatementSpinner(); + + void SpinUntilCompleted(); + + PRUint16 completionReason; + +protected: + ~AsyncStatementSpinner() {} + volatile bool mCompleted; +}; + +NS_IMPL_ISUPPORTS2(AsyncStatementSpinner, + mozIStorageStatementCallback, + mozIStorageCompletionCallback) + +AsyncStatementSpinner::AsyncStatementSpinner() +: completionReason(0) +, mCompleted(false) +{ +} + +NS_IMETHODIMP +AsyncStatementSpinner::HandleResult(mozIStorageResultSet *aResultSet) +{ + return NS_OK; +} + +NS_IMETHODIMP +AsyncStatementSpinner::HandleError(mozIStorageError *aError) +{ + return NS_OK; +} + +NS_IMETHODIMP +AsyncStatementSpinner::HandleCompletion(PRUint16 aReason) +{ + completionReason = aReason; + mCompleted = true; + return NS_OK; +} + +NS_IMETHODIMP +AsyncStatementSpinner::Complete() +{ + mCompleted = true; + return NS_OK; +} + +void AsyncStatementSpinner::SpinUntilCompleted() +{ + nsCOMPtr thread(::do_GetCurrentThread()); + nsresult rv = NS_OK; + PRBool processed = PR_TRUE; + while (!mCompleted && NS_SUCCEEDED(rv)) { + rv = thread->ProcessNextEvent(true, &processed); + } +} + +#define NS_DECL_ASYNCSTATEMENTSPINNER \ + NS_IMETHOD HandleResult(mozIStorageResultSet *aResultSet); diff --git a/storage/test/test_AsXXX_helpers.cpp b/storage/test/test_AsXXX_helpers.cpp new file mode 100644 index 000000000000..897dac93c0b8 --- /dev/null +++ b/storage/test/test_AsXXX_helpers.cpp @@ -0,0 +1,123 @@ +/* + *Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +#include "storage_test_harness.h" +#include "mozIStorageRow.h" +#include "mozIStorageResultSet.h" + +/** + * This file tests AsXXX (AsInt32, AsInt64, ...) helpers. + */ + +//////////////////////////////////////////////////////////////////////////////// +//// Event Loop Spinning + +class Spinner : public AsyncStatementSpinner +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_ASYNCSTATEMENTSPINNER + Spinner() {} +}; + +NS_IMPL_ISUPPORTS_INHERITED0(Spinner, + AsyncStatementSpinner) + +NS_IMETHODIMP +Spinner::HandleResult(mozIStorageResultSet *aResultSet) +{ + nsCOMPtr row; + do_check_true(NS_SUCCEEDED(aResultSet->GetNextRow(getter_AddRefs(row))) && row); + + do_check_eq(row->AsInt32(0), 0); + do_check_eq(row->AsInt64(0), 0); + do_check_eq(row->AsDouble(0), 0.0); + + PRUint32 len = 100; + do_check_eq(row->AsSharedUTF8String(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(row->AsSharedWString(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(row->AsSharedBlob(0, &len), nsnull); + do_check_eq(len, 0); + + do_check_eq(row->IsNull(0), PR_TRUE); + return NS_OK; +} + +void +test_NULLFallback() +{ + nsCOMPtr db(getMemoryDatabase()); + + nsCOMPtr stmt; + (void)db->CreateStatement(NS_LITERAL_CSTRING( + "SELECT NULL" + ), getter_AddRefs(stmt)); + + nsCOMPtr valueArray = do_QueryInterface(stmt); + do_check_true(valueArray); + + PRBool hasMore; + do_check_true(NS_SUCCEEDED(stmt->ExecuteStep(&hasMore)) && hasMore); + + do_check_eq(stmt->AsInt32(0), 0); + do_check_eq(stmt->AsInt64(0), 0); + do_check_eq(stmt->AsDouble(0), 0.0); + PRUint32 len = 100; + do_check_eq(stmt->AsSharedUTF8String(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(stmt->AsSharedWString(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(stmt->AsSharedBlob(0, &len), nsnull); + do_check_eq(len, 0); + do_check_eq(stmt->IsNull(0), PR_TRUE); + + do_check_eq(valueArray->AsInt32(0), 0); + do_check_eq(valueArray->AsInt64(0), 0); + do_check_eq(valueArray->AsDouble(0), 0.0); + len = 100; + do_check_eq(valueArray->AsSharedUTF8String(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(valueArray->AsSharedWString(0, &len), nsnull); + do_check_eq(len, 0); + len = 100; + do_check_eq(valueArray->AsSharedBlob(0, &len), nsnull); + do_check_eq(len, 0); + do_check_eq(valueArray->IsNull(0), PR_TRUE); +} + +void +test_asyncNULLFallback() +{ + nsCOMPtr db(getMemoryDatabase()); + + nsCOMPtr stmt; + (void)db->CreateStatement(NS_LITERAL_CSTRING( + "SELECT NULL" + ), getter_AddRefs(stmt)); + + nsRefPtr asyncSpin(new Spinner()); + nsCOMPtr pendingStmt; + do_check_true(NS_SUCCEEDED(stmt->ExecuteAsync(asyncSpin, getter_AddRefs(pendingStmt)))); + do_check_true(pendingStmt); + asyncSpin->SpinUntilCompleted(); + +} + +void (*gTests[])(void) = { + test_NULLFallback +, test_asyncNULLFallback +}; + +const char *file = __FILE__; +#define TEST_NAME "AsXXX helpers" +#define TEST_FILE file +#include "storage_test_harness_tail.h" diff --git a/storage/test/test_true_async.cpp b/storage/test/test_true_async.cpp index ddb52c9930e7..f05018a4b177 100644 --- a/storage/test/test_true_async.cpp +++ b/storage/test/test_true_async.cpp @@ -38,22 +38,12 @@ #include "storage_test_harness.h" #include "prthread.h" -#include "nsIThread.h" -#include "nsThreadUtils.h" #include "nsIEventTarget.h" #include "sqlite3.h" #include "mozilla/Monitor.h" -#include "mozIStorageStatementCallback.h" -#include "mozIStorageCompletionCallback.h" -#include "mozIStorageBindingParamsArray.h" -#include "mozIStorageBindingParams.h" -#include "mozIStorageAsyncStatement.h" -#include "mozIStorageStatement.h" -#include "mozIStoragePendingStatement.h" - using mozilla::Monitor; using mozilla::MonitorAutoEnter; @@ -135,75 +125,6 @@ void watch_for_mutex_use_on_this_thread() } -//////////////////////////////////////////////////////////////////////////////// -//// Event Loop Spinning - -class AsyncStatementSpinner : public mozIStorageStatementCallback, - public mozIStorageCompletionCallback -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_MOZISTORAGESTATEMENTCALLBACK - NS_DECL_MOZISTORAGECOMPLETIONCALLBACK - - AsyncStatementSpinner(); - - void SpinUntilCompleted(); - - PRUint16 completionReason; - -private: - ~AsyncStatementSpinner() {} - volatile bool mCompleted; -}; - -NS_IMPL_ISUPPORTS2(AsyncStatementSpinner, - mozIStorageStatementCallback, - mozIStorageCompletionCallback) - -AsyncStatementSpinner::AsyncStatementSpinner() -: completionReason(0) -, mCompleted(false) -{ -} - -NS_IMETHODIMP -AsyncStatementSpinner::HandleResult(mozIStorageResultSet *aResultSet) -{ - return NS_OK; -} - -NS_IMETHODIMP -AsyncStatementSpinner::HandleError(mozIStorageError *aError) -{ - return NS_OK; -} - -NS_IMETHODIMP -AsyncStatementSpinner::HandleCompletion(PRUint16 aReason) -{ - completionReason = aReason; - mCompleted = true; - return NS_OK; -} - -NS_IMETHODIMP -AsyncStatementSpinner::Complete() -{ - mCompleted = true; - return NS_OK; -} - -void AsyncStatementSpinner::SpinUntilCompleted() -{ - nsCOMPtr thread(::do_GetCurrentThread()); - nsresult rv = NS_OK; - PRBool processed = PR_TRUE; - while (!mCompleted && NS_SUCCEEDED(rv)) { - rv = thread->ProcessNextEvent(true, &processed); - } -} - //////////////////////////////////////////////////////////////////////////////// //// Thread Wedgers