Bug 658303 - mozIStorageConnection::Clone() should copy over pragmas.

r=sdwilsh
This commit is contained in:
Marco Bonardo 2011-10-03 21:55:03 +02:00
Родитель 428a03bc2c
Коммит 7d8090e55d
3 изменённых файлов: 79 добавлений и 0 удалений

Просмотреть файл

@ -104,6 +104,10 @@ interface mozIStorageConnection : nsISupports {
* @note Due to a bug in SQLite, if you use the shared cache (openDatabase),
* you end up with the same privileges as the first connection opened
* regardless of what is specified in aReadOnly.
* @note The following pragmas are copied over to the new connection:
* cache_size (only if smaller than SQLITE_DEFAULT_CACHE_SIZE),
* foreign_keys, journal_size_limit, synchronous, temp_store,
* wal_autocheckpoint.
*
* @throws NS_ERROR_UNEXPECTED
* If this connection is a memory database.

Просмотреть файл

@ -882,6 +882,40 @@ Connection::Clone(bool aReadOnly,
nsresult rv = clone->initialize(mDatabaseFile);
NS_ENSURE_SUCCESS(rv, rv);
// Copy over pragmas from the original connection.
static const char * pragmas[] = {
"cache_size",
"foreign_keys",
"journal_size_limit",
"synchronous",
"temp_store",
"wal_autocheckpoint"
};
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(pragmas); ++i) {
nsCAutoString pragmaQuery("PRAGMA ");
pragmaQuery.Append(pragmas[i]);
nsCOMPtr<mozIStorageStatement> stmt;
rv = CreateStatement(pragmaQuery, getter_AddRefs(stmt));
MOZ_ASSERT(NS_SUCCEEDED(rv));
bool hasResult = PR_FALSE;
if (stmt && NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult) {
PRInt32 value = stmt->AsInt32(0);
// To preserve memory, override the cloned connection's cache_size value
// only if it's smaller than the default.
if (::strcmp(pragmas[i], "cache_size") == 0) {
(void)clone->CreateStatement(pragmaQuery, getter_AddRefs(stmt));
if (stmt && NS_SUCCEEDED(stmt->ExecuteStep(&hasResult)) && hasResult &&
value >= stmt->AsInt32(0)) {
continue;
}
}
pragmaQuery.AppendLiteral(" = ");
pragmaQuery.AppendInt(value);
rv = clone->ExecuteSimpleSQL(pragmaQuery);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
}
// Copy any functions that have been added to this connection.
(void)mFunctions.EnumerateRead(copyFunctionEnumerator, clone);

Просмотреть файл

@ -482,6 +482,47 @@ function test_clone_copies_overridden_functions()
run_next_test();
}
function test_clone_copies_pragmas()
{
const PRAGMAS = [
{ name: "cache_size", value: 500, copied: true },
{ name: "foreign_keys", value: 1, copied: true },
{ name: "journal_size_limit", value: 524288, copied: true },
{ name: "synchronous", value: 2, copied: true },
{ name: "temp_store", value: 2, copied: true },
{ name: "wal_autocheckpoint", value: 16, copied: true },
{ name: "ignore_check_constraints", value: 1, copied: false },
];
let db1 = getService().openUnsharedDatabase(getTestDB());
// Sanity check initial values are different from enforced ones.
PRAGMAS.forEach(function (pragma) {
let stmt = db1.createStatement("PRAGMA " + pragma.name);
do_check_true(stmt.executeStep());
do_check_neq(pragma.value, stmt.getInt32(0));
stmt.finalize();
});
// Execute pragmas.
PRAGMAS.forEach(function (pragma) {
db1.executeSimpleSQL("PRAGMA " + pragma.name + " = " + pragma.value);
});
let db2 = db1.clone(true);
do_check_true(db2.connectionReady);
// Check cloned connection inherited pragma values.
PRAGMAS.forEach(function (pragma) {
let stmt = db1.createStatement("PRAGMA " + pragma.name);
do_check_true(stmt.executeStep());
let validate = pragma.copied ? do_check_eq : do_check_neq;
validate(pragma.value, stmt.getInt32(0));
stmt.finalize();
});
run_next_test();
}
function test_getInterface()
{
let db = getOpenedDatabase();