Bug 914070 - Part 1 - Remove native connection getters from Storage connection. r=asuth

This commit is contained in:
Marco Bonardo 2014-04-24 11:54:09 +02:00
parent 52bc49c1b2
commit 089b484230
13 changed files with 91 additions and 53 deletions

View File

@ -194,8 +194,8 @@ StorageBaseStatementInternal::ExecuteAsync(
NS_ENSURE_TRUE(stmts.AppendElement(data), NS_ERROR_OUT_OF_MEMORY);
// Dispatch to the background
return AsyncExecuteStatements::execute(stmts, mDBConnection, aCallback,
_stmt);
return AsyncExecuteStatements::execute(stmts, mDBConnection,
mNativeConnection, aCallback, _stmt);
}
NS_IMETHODIMP

View File

@ -11,6 +11,7 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
struct sqlite3;
struct sqlite3_stmt;
class mozIStorageError;
class mozIStorageBindingParamsArray;
@ -97,6 +98,7 @@ protected: // mix-in bits are protected
StorageBaseStatementInternal();
nsRefPtr<Connection> mDBConnection;
sqlite3 *mNativeConnection;
/**
* Our asynchronous statement.

View File

@ -131,13 +131,14 @@ AsyncStatement::AsyncStatement()
nsresult
AsyncStatement::initialize(Connection *aDBConnection,
sqlite3 *aNativeConnection,
const nsACString &aSQLStatement)
{
NS_ASSERTION(aDBConnection, "No database connection given!");
NS_ASSERTION(aDBConnection->GetNativeConnection(),
"We should never be called with a null sqlite3 database!");
MOZ_ASSERT(aDBConnection, "No database connection given!");
MOZ_ASSERT(aNativeConnection, "No native connection given!");
mDBConnection = aDBConnection;
mNativeConnection = aNativeConnection;
mSQLString = aSQLStatement;
PR_LOG(gStorageLog, PR_LOG_NOTICE, ("Inited async statement '%s' (0x%p)",
@ -304,7 +305,7 @@ AsyncStatement::getAsyncStatement(sqlite3_stmt **_stmt)
if (rc != SQLITE_OK) {
PR_LOG(gStorageLog, PR_LOG_ERROR,
("Sqlite statement prepare error: %d '%s'", rc,
::sqlite3_errmsg(mDBConnection->GetNativeConnection())));
::sqlite3_errmsg(mNativeConnection)));
PR_LOG(gStorageLog, PR_LOG_ERROR,
("Statement was: '%s'", mSQLString.get()));
*_stmt = nullptr;

View File

@ -45,10 +45,13 @@ public:
*
* @param aDBConnection
* The Connection object this statement is associated with.
* @param aNativeConnection
* The native Sqlite connection this statement is associated with.
* @param aSQLStatement
* The SQL statement to prepare that this object will represent.
*/
nsresult initialize(Connection *aDBConnection,
sqlite3 *aNativeConnection,
const nsACString &aSQLStatement);
/**

View File

@ -163,12 +163,14 @@ private:
nsresult
AsyncExecuteStatements::execute(StatementDataArray &aStatements,
Connection *aConnection,
sqlite3 *aNativeConnection,
mozIStorageStatementCallback *aCallback,
mozIStoragePendingStatement **_stmt)
{
// Create our event to run in the background
nsRefPtr<AsyncExecuteStatements> event =
new AsyncExecuteStatements(aStatements, aConnection, aCallback);
new AsyncExecuteStatements(aStatements, aConnection, aNativeConnection,
aCallback);
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
// Dispatch it to the background
@ -194,8 +196,10 @@ AsyncExecuteStatements::execute(StatementDataArray &aStatements,
AsyncExecuteStatements::AsyncExecuteStatements(StatementDataArray &aStatements,
Connection *aConnection,
sqlite3 *aNativeConnection,
mozIStorageStatementCallback *aCallback)
: mConnection(aConnection)
, mNativeConnection(aNativeConnection)
, mTransactionManager(nullptr)
, mCallback(aCallback)
, mCallingThread(::do_GetCurrentThread())
@ -364,8 +368,9 @@ AsyncExecuteStatements::executeStatement(sqlite3_stmt *aStatement)
// Construct the error message before giving up the mutex (which we cannot
// hold during the call to notifyError).
sqlite3 *db = mConnection->GetNativeConnection();
nsCOMPtr<mozIStorageError> errorObj(new Error(rc, ::sqlite3_errmsg(db)));
nsCOMPtr<mozIStorageError> errorObj(
new Error(rc, ::sqlite3_errmsg(mNativeConnection))
);
// We cannot hold the DB mutex while calling notifyError.
SQLiteMutexAutoUnlock unlockedScope(mDBMutex);
(void)notifyError(errorObj);
@ -592,9 +597,8 @@ AsyncExecuteStatements::Run()
mState = ERROR;
// Build the error object; can't call notifyError with the lock held
sqlite3 *db = mConnection->GetNativeConnection();
nsCOMPtr<mozIStorageError> errorObj(
new Error(rc, ::sqlite3_errmsg(db))
new Error(rc, ::sqlite3_errmsg(mNativeConnection))
);
{
// We cannot hold the DB mutex and call notifyError.

View File

@ -66,6 +66,8 @@ public:
* Ownership is transfered from the caller.
* @param aConnection
* The connection that created the statements to execute.
* @param aNativeConnection
* The native Sqlite connection that created the statements to execute.
* @param aCallback
* The callback that is notified of results, completion, and errors.
* @param _stmt
@ -73,6 +75,7 @@ public:
*/
static nsresult execute(StatementDataArray &aStatements,
Connection *aConnection,
sqlite3 *aNativeConnection,
mozIStorageStatementCallback *aCallback,
mozIStoragePendingStatement **_stmt);
@ -90,6 +93,7 @@ public:
private:
AsyncExecuteStatements(StatementDataArray &aStatements,
Connection *aConnection,
sqlite3 *aNativeConnection,
mozIStorageStatementCallback *aCallback);
/**
@ -187,6 +191,7 @@ private:
StatementDataArray mStatements;
nsRefPtr<Connection> mConnection;
sqlite3 *mNativeConnection;
mozStorageAsyncTransaction *mTransactionManager;
mozIStorageStatementCallback *mCallback;
nsCOMPtr<nsIThread> mCallingThread;

View File

@ -519,6 +519,18 @@ NS_IMETHODIMP_(MozExternalRefCountType) Connection::Release(void)
return count;
}
int32_t
Connection::getSqliteRuntimeStatus(int32_t aStatusOption, int32_t* aMaxValue)
{
MOZ_ASSERT(mDBConn, "A connection must exist at this point");
int curr = 0, max = 0;
DebugOnly<int> rc = ::sqlite3_db_status(mDBConn, aStatusOption, &curr, &max, 0);
MOZ_ASSERT(NS_SUCCEEDED(convertResultCode(rc)));
if (aMaxValue)
*aMaxValue = max;
return curr;
}
nsIEventTarget *
Connection::getAsyncExecutionTarget()
{
@ -1335,7 +1347,7 @@ Connection::CreateStatement(const nsACString &aSQLStatement,
nsRefPtr<Statement> statement(new Statement());
NS_ENSURE_TRUE(statement, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = statement->initialize(this, aSQLStatement);
nsresult rv = statement->initialize(this, mDBConn, aSQLStatement);
NS_ENSURE_SUCCESS(rv, rv);
Statement *rawPtr;
@ -1354,7 +1366,7 @@ Connection::CreateAsyncStatement(const nsACString &aSQLStatement,
nsRefPtr<AsyncStatement> statement(new AsyncStatement());
NS_ENSURE_TRUE(statement, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = statement->initialize(this, aSQLStatement);
nsresult rv = statement->initialize(this, mDBConn, aSQLStatement);
NS_ENSURE_SUCCESS(rv, rv);
AsyncStatement *rawPtr;
@ -1396,7 +1408,8 @@ Connection::ExecuteAsync(mozIStorageBaseStatement **aStatements,
}
// Dispatch to the background
return AsyncExecuteStatements::execute(stmts, this, aCallback, _handle);
return AsyncExecuteStatements::execute(stmts, this, mDBConn, aCallback,
_handle);
}
NS_IMETHODIMP

View File

@ -96,9 +96,29 @@ public:
*/
nsresult initialize(nsIFileURL *aFileURL);
// fetch the native handle
sqlite3 *GetNativeConnection() { return mDBConn; }
operator sqlite3 *() const { return mDBConn; }
/**
* Fetches runtime status information for this connection.
*
* @param aStatusOption One of the SQLITE_DBSTATUS options defined at
* http://www.sqlite.org/c3ref/c_dbstatus_options.html
* @param [optional] aMaxValue if provided, will be set to the highest
* istantaneous value.
* @return the current value for the specified option.
*/
int32_t getSqliteRuntimeStatus(int32_t aStatusOption,
int32_t* aMaxValue=nullptr);
/**
* Registers/unregisters a commit hook callback.
*
* @param aCallbackFn a callback function to be invoked on transactions
* commit. Pass nullptr to unregister the current callback.
* @param [optional] aData if provided, will be passed to the callback.
* @see http://sqlite.org/c3ref/commit_hook.html
*/
void setCommitHook(int (*aCallbackFn)(void *) , void *aData=nullptr) {
MOZ_ASSERT(mDBConn, "A connection must exist at this point");
::sqlite3_commit_hook(mDBConn, aCallbackFn, aData);
};
/**
* Lazily creates and returns a background execution thread. In the future,
@ -262,19 +282,19 @@ private:
/**
* Tracks if we have a transaction in progress or not. Access protected by
* mDBMutex.
* sharedDBMutex.
*/
bool mTransactionInProgress;
/**
* Stores the mapping of a given function by name to its instance. Access is
* protected by mDBMutex.
* protected by sharedDBMutex.
*/
nsDataHashtable<nsCStringHashKey, FunctionInfo> mFunctions;
/**
* Stores the registered progress handler for the database connection. Access
* is protected by mDBMutex.
* is protected by sharedDBMutex.
*/
nsCOMPtr<mozIStorageProgressHandler> mProgressHandler;

View File

@ -94,28 +94,24 @@ StorageSQLiteDistinguishedAmount()
nsresult
ReportConn(nsIHandleReportCallback *aHandleReport,
nsISupports *aData,
sqlite3 *aConn,
Connection *aConn,
const nsACString &aPathHead,
const nsACString &aKind,
const nsACString &aDesc,
int aOption,
int32_t aOption,
size_t *aTotal)
{
nsCString path(aPathHead);
path.Append(aKind);
path.AppendLiteral("-used");
int curr = 0, max = 0;
int rc = ::sqlite3_db_status(aConn, aOption, &curr, &max, 0);
nsresult rv = convertResultCode(rc);
int32_t val = aConn->getSqliteRuntimeStatus(aOption);
nsresult rv = aHandleReport->Callback(EmptyCString(), path,
nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES,
int64_t(val), aDesc, aData);
NS_ENSURE_SUCCESS(rv, rv);
rv = aHandleReport->Callback(EmptyCString(), path,
nsIMemoryReporter::KIND_HEAP,
nsIMemoryReporter::UNITS_BYTES, int64_t(curr),
aDesc, aData);
NS_ENSURE_SUCCESS(rv, rv);
*aTotal += curr;
*aTotal += val;
return NS_OK;
}
@ -155,7 +151,7 @@ Service::CollectReports(nsIHandleReportCallback *aHandleReport,
NS_NAMED_LITERAL_CSTRING(stmtDesc,
"Memory (approximate) used by all prepared statements used by "
"connections to this database.");
rv = ReportConn(aHandleReport, aData, *conn.get(), pathHead,
rv = ReportConn(aHandleReport, aData, conn, pathHead,
NS_LITERAL_CSTRING("stmt"), stmtDesc,
SQLITE_DBSTATUS_STMT_USED, &totalConnSize);
NS_ENSURE_SUCCESS(rv, rv);
@ -163,7 +159,7 @@ Service::CollectReports(nsIHandleReportCallback *aHandleReport,
NS_NAMED_LITERAL_CSTRING(cacheDesc,
"Memory (approximate) used by all pager caches used by connections "
"to this database.");
rv = ReportConn(aHandleReport, aData, *conn.get(), pathHead,
rv = ReportConn(aHandleReport, aData, conn, pathHead,
NS_LITERAL_CSTRING("cache"), cacheDesc,
SQLITE_DBSTATUS_CACHE_USED, &totalConnSize);
NS_ENSURE_SUCCESS(rv, rv);
@ -171,7 +167,7 @@ Service::CollectReports(nsIHandleReportCallback *aHandleReport,
NS_NAMED_LITERAL_CSTRING(schemaDesc,
"Memory (approximate) used to store the schema for all databases "
"associated with connections to this database.");
rv = ReportConn(aHandleReport, aData, *conn.get(), pathHead,
rv = ReportConn(aHandleReport, aData, conn, pathHead,
NS_LITERAL_CSTRING("schema"), schemaDesc,
SQLITE_DBSTATUS_SCHEMA_USED, &totalConnSize);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -135,20 +135,19 @@ Statement::Statement()
nsresult
Statement::initialize(Connection *aDBConnection,
sqlite3 *aNativeConnection,
const nsACString &aSQLStatement)
{
NS_ASSERTION(aDBConnection, "No database connection given!");
NS_ASSERTION(!mDBStatement, "Statement already initialized!");
DebugOnly<sqlite3 *> db = aDBConnection->GetNativeConnection();
NS_ASSERTION(db, "We should never be called with a null sqlite3 database!");
MOZ_ASSERT(aDBConnection, "No database connection given!");
MOZ_ASSERT(!mDBStatement, "Statement already initialized!");
MOZ_ASSERT(aNativeConnection, "No native connection given!");
int srv = aDBConnection->prepareStatement(PromiseFlatCString(aSQLStatement),
&mDBStatement);
if (srv != SQLITE_OK) {
PR_LOG(gStorageLog, PR_LOG_ERROR,
("Sqlite statement prepare error: %d '%s'", srv,
::sqlite3_errmsg(db)));
::sqlite3_errmsg(aNativeConnection)));
PR_LOG(gStorageLog, PR_LOG_ERROR,
("Statement was: '%s'", PromiseFlatCString(aSQLStatement).get()));
return NS_ERROR_FAILURE;
@ -159,6 +158,7 @@ Statement::initialize(Connection *aDBConnection,
mDBStatement));
mDBConnection = aDBConnection;
mNativeConnection = aNativeConnection;
mParamCount = ::sqlite3_bind_parameter_count(mDBStatement);
mResultColumnCount = ::sqlite3_column_count(mDBStatement);
mColumnNames.Clear();
@ -335,7 +335,7 @@ Statement::Clone(mozIStorageStatement **_statement)
NS_ENSURE_TRUE(statement, NS_ERROR_OUT_OF_MEMORY);
nsAutoCString sql(::sqlite3_sql(mDBStatement));
nsresult rv = statement->initialize(mDBConnection, sql);
nsresult rv = statement->initialize(mDBConnection, mNativeConnection, sql);
NS_ENSURE_SUCCESS(rv, rv);
statement.forget(_statement);

View File

@ -47,10 +47,13 @@ public:
*
* @param aDBConnection
* The Connection object this statement is associated with.
* @param aNativeConnection
* The native Sqlite connection this statement is associated with.
* @param aSQLStatement
* The SQL statement to prepare that this object will represent.
*/
nsresult initialize(Connection *aDBConnection,
sqlite3* aNativeConnection,
const nsACString &aSQLStatement);

View File

@ -71,15 +71,6 @@ public:
operator BindingParamsArray *() const { return mParamsArray; }
/**
* Provide the ability to coerce back to a sqlite3 * connection for purposes
* of getting an error message out of it.
*/
operator sqlite3 *() const
{
return mStatementOwner->getOwner()->GetNativeConnection();
}
/**
* NULLs out our sqlite3_stmt (it is held by the owner) after reseting it and
* clear all bindings to it. This is expected to occur on the async thread.

View File

@ -48,7 +48,7 @@ check_transaction(mozIStorageConnection *aDB,
{
// -- install a transaction commit hook.
int commit = 0;
::sqlite3_commit_hook(*static_cast<Connection *>(aDB), commit_hook, &commit);
static_cast<Connection *>(aDB)->setCommitHook(commit_hook, &commit);
nsRefPtr<AsyncStatementSpinner> asyncSpin(new AsyncStatementSpinner());
nsCOMPtr<mozIStoragePendingStatement> asyncPend;
@ -60,7 +60,7 @@ check_transaction(mozIStorageConnection *aDB,
asyncSpin->SpinUntilCompleted();
// -- uninstall the transaction commit hook.
::sqlite3_commit_hook(*static_cast<Connection *>(aDB), nullptr, nullptr);
static_cast<Connection *>(aDB)->setCommitHook(nullptr);
// -- check transaction
do_check_eq(aTransactionExpected, !!commit);