Bug 1380606 - Add `mozIStorageAsyncConnection::createDeterministicFunction`. r?mak
According to the SQLite docs, the `eTextRep` parameter can be ORed with
`SQLITE_DETERMINISTIC` as a hint to the query planner, to indicate that
the function returns the same result for the same arguments.
MozReview-Commit-ID: 1Ib5yO8lK1P
--- a/dom/cache/Connection.cpp
+++ b/dom/cache/Connection.cpp
@@ -112,16 +112,25 @@ Connection::CreateFunction(const nsACStr
int32_t aNumArguments,
mozIStorageFunction* aFunction)
{
// async methods are not supported
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
+Connection::CreateDeterministicFunction(const nsACString& aFunctionName,
+ int32_t aNumArguments,
+ mozIStorageFunction* aFunction)
+{
+ // async methods are not supported
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
Connection::CreateAggregateFunction(const nsACString& aFunctionName,
int32_t aNumArguments,
mozIStorageAggregateFunction* aFunction)
{
return mBase->CreateAggregateFunction(aFunctionName, aNumArguments,
aFunction);
}
--- a/storage/mozIStorageAsyncConnection.idl
+++ b/storage/mozIStorageAsyncConnection.idl
@@ -191,16 +191,20 @@ interface mozIStorageAsyncConnection : n
* @param aFunction
* The instance of mozIStorageFunction, which implements the function
* in question.
*/
void createFunction(in AUTF8String aFunctionName,
in long aNumArguments,
in mozIStorageFunction aFunction);
+ void createDeterministicFunction(in AUTF8String aFunctionName,
+ in long aNumArguments,
+ in mozIStorageFunction aFunction);
+
/**
* Create a new SQL aggregate function. If you use your connection on
* multiple threads, your function needs to be threadsafe, or it should only
* be called on one thread.
*
* @param aFunctionName
* The name of aggregate function to create, as seen in SQL.
* @param aNumArguments
--- a/storage/mozStorageConnection.cpp
+++ b/storage/mozStorageConnection.cpp
@@ -1933,47 +1933,72 @@ Connection::CreateTable(const char *aTab
return NS_ERROR_OUT_OF_MEMORY;
int srv = executeSql(mDBConn, buf.get());
return convertResultCode(srv);
}
NS_IMETHODIMP
-Connection::CreateFunction(const nsACString &aFunctionName,
- int32_t aNumArguments,
- mozIStorageFunction *aFunction)
+Connection::createFunctionInternal(const nsACString &aFunctionName,
+ int32_t aNumArguments,
+ bool aIsDeterministic,
+ mozIStorageFunction *aFunction)
{
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
// Check to see if this function is already defined. We only check the name
// because a function can be defined with the same body but different names.
SQLiteMutexAutoLock lockedScope(sharedDBMutex);
NS_ENSURE_FALSE(mFunctions.Get(aFunctionName, nullptr), NS_ERROR_FAILURE);
+ int textRep = SQLITE_ANY;
+ if (aIsDeterministic) {
+ textRep |= SQLITE_DETERMINISTIC;
+ }
int srv = ::sqlite3_create_function(mDBConn,
nsPromiseFlatCString(aFunctionName).get(),
aNumArguments,
- SQLITE_ANY,
+ textRep,
aFunction,
basicFunctionHelper,
nullptr,
nullptr);
if (srv != SQLITE_OK)
return convertResultCode(srv);
FunctionInfo info = { aFunction,
Connection::FunctionInfo::SIMPLE,
aNumArguments };
mFunctions.Put(aFunctionName, info);
return NS_OK;
}
NS_IMETHODIMP
+Connection::CreateFunction(const nsACString &aFunctionName,
+ int32_t aNumArguments,
+ mozIStorageFunction *aFunction)
+{
+ return createFunctionInternal(aFunctionName, aNumArguments,
+ /* aIsDeterministic */ false,
+ aFunction);
+}
+
+NS_IMETHODIMP
+Connection::CreateDeterministicFunction(const nsACString &aFunctionName,
+ int32_t aNumArguments,
+ mozIStorageFunction *aFunction)
+{
+ return createFunctionInternal(aFunctionName, aNumArguments,
+ /* aIsDeterministic */ true,
+ aFunction);
+}
+
+NS_IMETHODIMP
Connection::CreateAggregateFunction(const nsACString &aFunctionName,
int32_t aNumArguments,
mozIStorageAggregateFunction *aFunction)
{
if (!mDBConn) return NS_ERROR_NOT_INITIALIZED;
// Check to see if this function name is already defined.
SQLiteMutexAutoLock lockedScope(sharedDBMutex);
--- a/storage/mozStorageConnection.h
+++ b/storage/mozStorageConnection.h
@@ -222,16 +222,21 @@ public:
*
* @see BeginTransactionAs, CommitTransaction, RollbackTransaction.
*/
nsresult beginTransactionInternal(sqlite3 *aNativeConnection,
int32_t aTransactionType=TRANSACTION_DEFERRED);
nsresult commitTransactionInternal(sqlite3 *aNativeConnection);
nsresult rollbackTransactionInternal(sqlite3 *aNativeConnection);
+ nsresult createFunctionInternal(const nsACString &aFunctionName,
+ int32_t aNumArguments,
+ bool aIsDeterministic,
+ mozIStorageFunction *aFunction);
+
bool connectionReady();
/**
* Thread-aware version of connectionReady, results per caller's thread are:
* - owner thread: Same as connectionReady(). True means we have a valid,
* un-closed database connection and it's not going away until you invoke
* Close() or AsyncClose().
* - async thread: Returns true at all times because you can't schedule