mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 702559 - Adapting Sqlite.jsm to use mozIStorageAsyncConnection;r=mak
This commit is contained in:
parent
fed1e56a56
commit
4b9f52dd06
@ -26,7 +26,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
|
||||
// Counts the number of created connections per database basename(). This is
|
||||
// used for logging to distinguish connection instances.
|
||||
let connectionCounters = {};
|
||||
let connectionCounters = new Map();
|
||||
|
||||
|
||||
/**
|
||||
@ -89,34 +89,37 @@ function openConnection(options) {
|
||||
}
|
||||
|
||||
let file = FileUtils.File(path);
|
||||
let openDatabaseFn = sharedMemoryCache ?
|
||||
Services.storage.openDatabase :
|
||||
Services.storage.openUnsharedDatabase;
|
||||
|
||||
let basename = OS.Path.basename(path);
|
||||
let number = connectionCounters.get(basename) || 0;
|
||||
connectionCounters.set(basename, number + 1);
|
||||
|
||||
if (!connectionCounters[basename]) {
|
||||
connectionCounters[basename] = 1;
|
||||
}
|
||||
|
||||
let number = connectionCounters[basename]++;
|
||||
let identifier = basename + "#" + number;
|
||||
|
||||
log.info("Opening database: " + path + " (" + identifier + ")");
|
||||
try {
|
||||
let connection = openDatabaseFn(file);
|
||||
|
||||
if (!connection.connectionReady) {
|
||||
log.warn("Connection is not ready.");
|
||||
return Promise.reject(new Error("Connection is not ready."));
|
||||
}
|
||||
|
||||
return Promise.resolve(new OpenedConnection(connection, basename, number,
|
||||
openedOptions));
|
||||
} catch (ex) {
|
||||
log.warn("Could not open database: " + CommonUtils.exceptionStr(ex));
|
||||
return Promise.reject(ex);
|
||||
let deferred = Promise.defer();
|
||||
let options = null;
|
||||
if (!sharedMemoryCache) {
|
||||
options = Cc["@mozilla.org/hash-property-bag;1"].
|
||||
createInstance(Ci.nsIWritablePropertyBag);
|
||||
options.setProperty("shared", false);
|
||||
}
|
||||
Services.storage.openAsyncDatabase(file, options, function(status, connection) {
|
||||
if (!connection) {
|
||||
log.warn("Could not open connection: " + status);
|
||||
deferred.reject(new Error("Could not open connection: " + status));
|
||||
}
|
||||
log.warn("Connection opened");
|
||||
try {
|
||||
deferred.resolve(
|
||||
new OpenedConnection(connection.QueryInterface(Ci.mozIStorageAsyncConnection), basename, number,
|
||||
openedOptions));
|
||||
} catch (ex) {
|
||||
log.warn("Could not open database: " + CommonUtils.exceptionStr(ex));
|
||||
deferred.reject(ex);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
|
||||
@ -225,51 +228,32 @@ OpenedConnection.prototype = Object.freeze({
|
||||
|
||||
TRANSACTION_TYPES: ["DEFERRED", "IMMEDIATE", "EXCLUSIVE"],
|
||||
|
||||
get connectionReady() {
|
||||
return this._open && this._connection.connectionReady;
|
||||
},
|
||||
|
||||
/**
|
||||
* The row ID from the last INSERT operation.
|
||||
*
|
||||
* Because all statements are executed asynchronously, this could
|
||||
* return unexpected results if multiple statements are performed in
|
||||
* parallel. It is the caller's responsibility to schedule
|
||||
* appropriately.
|
||||
*
|
||||
* It is recommended to only use this within transactions (which are
|
||||
* handled as sequential statements via Tasks).
|
||||
*/
|
||||
get lastInsertRowID() {
|
||||
this._ensureOpen();
|
||||
return this._connection.lastInsertRowID;
|
||||
},
|
||||
|
||||
/**
|
||||
* The number of rows that were changed, inserted, or deleted by the
|
||||
* last operation.
|
||||
*
|
||||
* The same caveats regarding asynchronous execution for
|
||||
* `lastInsertRowID` also apply here.
|
||||
*/
|
||||
get affectedRows() {
|
||||
this._ensureOpen();
|
||||
return this._connection.affectedRows;
|
||||
},
|
||||
|
||||
/**
|
||||
* The integer schema version of the database.
|
||||
*
|
||||
* This is 0 if not schema version has been set.
|
||||
*
|
||||
* @return Promise<int>
|
||||
*/
|
||||
get schemaVersion() {
|
||||
this._ensureOpen();
|
||||
return this._connection.schemaVersion;
|
||||
getSchemaVersion: function() {
|
||||
let self = this;
|
||||
return this.execute("PRAGMA user_version").then(
|
||||
function onSuccess(result) {
|
||||
if (result == null) {
|
||||
return 0;
|
||||
}
|
||||
return JSON.stringify(result[0].getInt32(0));
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
set schemaVersion(value) {
|
||||
setSchemaVersion: function(value) {
|
||||
if (!Number.isInteger(value)) {
|
||||
// Guarding against accidental SQLi
|
||||
throw new TypeError("Schema version must be an integer. Got " + value);
|
||||
}
|
||||
this._ensureOpen();
|
||||
this._connection.schemaVersion = value;
|
||||
return this.execute("PRAGMA user_version = " + value);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -87,6 +87,34 @@ add_task(function test_get_dummy_database() {
|
||||
yield db.close();
|
||||
});
|
||||
|
||||
add_task(function test_schema_version() {
|
||||
let db = yield getDummyDatabase("schema_version");
|
||||
|
||||
let version = yield db.getSchemaVersion();
|
||||
do_check_eq(version, 0);
|
||||
|
||||
db.setSchemaVersion(14);
|
||||
version = yield db.getSchemaVersion();
|
||||
do_check_eq(version, 14);
|
||||
|
||||
for (let v of [0.5, "foobar", NaN]) {
|
||||
let success;
|
||||
try {
|
||||
yield db.setSchemaVersion(v);
|
||||
do_print("Schema version " + v + " should have been rejected");
|
||||
success = false;
|
||||
} catch (ex if ex.message.startsWith("Schema version must be an integer.")) {
|
||||
success = true;
|
||||
}
|
||||
do_check_true(success);
|
||||
|
||||
version = yield db.getSchemaVersion();
|
||||
do_check_eq(version, 14);
|
||||
}
|
||||
|
||||
yield db.close();
|
||||
});
|
||||
|
||||
add_task(function test_simple_insert() {
|
||||
let c = yield getDummyDatabase("simple_insert");
|
||||
|
||||
@ -109,8 +137,10 @@ add_task(function test_simple_bound_object() {
|
||||
let result = yield c.execute("INSERT INTO dirs VALUES (:id, :path)",
|
||||
{id: 1, path: "foo"});
|
||||
do_check_eq(result.length, 0);
|
||||
do_check_eq(c.lastInsertRowID, 1);
|
||||
do_check_eq(c.affectedRows, 1);
|
||||
result = yield c.execute("SELECT id, path FROM dirs");
|
||||
do_check_eq(result.length, 1);
|
||||
do_check_eq(result[0].getResultByName("id"), 1);
|
||||
do_check_eq(result[0].getResultByName("path"), "foo");
|
||||
yield c.close();
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user