From 40a355a42d4a9444dc753c04c6608dade2f06a23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:27 +0200 Subject: Adding upstream version 125.0.1. Signed-off-by: Daniel Baumann --- toolkit/modules/Sqlite.sys.mjs | 158 ++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 73 deletions(-) (limited to 'toolkit/modules/Sqlite.sys.mjs') diff --git a/toolkit/modules/Sqlite.sys.mjs b/toolkit/modules/Sqlite.sys.mjs index 2c9de0f438..b1f48c28be 100644 --- a/toolkit/modules/Sqlite.sys.mjs +++ b/toolkit/modules/Sqlite.sys.mjs @@ -23,11 +23,14 @@ import { setTimeout } from "resource://gre/modules/Timer.sys.mjs"; const lazy = {}; -ChromeUtils.defineESModuleGetters(lazy, { - AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs", - FileUtils: "resource://gre/modules/FileUtils.sys.mjs", - Log: "resource://gre/modules/Log.sys.mjs", -}); +ChromeUtils.defineESModuleGetters( + lazy, + { + AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs", + FileUtils: "resource://gre/modules/FileUtils.sys.mjs", + }, + { global: "contextual" } +); XPCOMUtils.defineLazyServiceGetter( lazy, @@ -306,6 +309,18 @@ function unregisterVacuumParticipant(connectionData) { } } +/** + * Create a ConsoleInstance logger with a given prefix. + * @param {string} prefix The prefix to use when logging. + * @returns {ConsoleInstance} a console logger. + */ +function createLoggerWithPrefix(prefix) { + return console.createInstance({ + prefix: `SQLite JSM (${prefix})`, + maxLogLevelPref: "toolkit.sqlitejsm.loglevel", + }); +} + /** * Connection data with methods necessary for closing the connection. * @@ -325,12 +340,8 @@ function unregisterVacuumParticipant(connectionData) { * dispatch its method calls here. */ function ConnectionData(connection, identifier, options = {}) { - this._log = lazy.Log.repository.getLoggerWithMessagePrefix( - "Sqlite.sys.mjs", - `Connection ${identifier}: ` - ); - this._log.manageLevelFromPref("toolkit.sqlitejsm.loglevel"); - this._log.debug("Opened"); + this._logger = createLoggerWithPrefix(`Connection ${identifier}`); + this._logger.debug("Opened"); this._dbConn = connection; @@ -410,25 +421,27 @@ function ConnectionData(connection, identifier, options = {}) { this._useIncrementalVacuum = !!options.incrementalVacuum; if (this._useIncrementalVacuum) { - this._log.debug("Set auto_vacuum INCREMENTAL"); + this._logger.debug("Set auto_vacuum INCREMENTAL"); this.execute("PRAGMA auto_vacuum = 2").catch(ex => { - this._log.error("Setting auto_vacuum to INCREMENTAL failed."); + this._logger.error("Setting auto_vacuum to INCREMENTAL failed."); console.error(ex); }); } this._expectedPageSize = options.pageSize ?? 0; if (this._expectedPageSize) { - this._log.debug("Set page_size to " + this._expectedPageSize); + this._logger.debug("Set page_size to " + this._expectedPageSize); this.execute("PRAGMA page_size = " + this._expectedPageSize).catch(ex => { - this._log.error(`Setting page_size to ${this._expectedPageSize} failed.`); + this._logger.error( + `Setting page_size to ${this._expectedPageSize} failed.` + ); console.error(ex); }); } this._vacuumOnIdle = options.vacuumOnIdle; if (this._vacuumOnIdle) { - this._log.debug("Register as vacuum participant"); + this._logger.debug("Register as vacuum participant"); this.QueryInterface = ChromeUtils.generateQI([ Ci.mozIStorageVacuumParticipant, ]); @@ -470,12 +483,12 @@ ConnectionData.prototype = Object.freeze({ onBeginVacuum() { let granted = !this.transactionInProgress; - this._log.debug("Begin Vacuum - " + granted ? "granted" : "denied"); + this._logger.debug("Begin Vacuum - " + granted ? "granted" : "denied"); return granted; }, onEndVacuum(succeeded) { - this._log.debug("End Vacuum - " + succeeded ? "success" : "failure"); + this._logger.debug("End Vacuum - " + succeeded ? "success" : "failure"); }, /** @@ -597,11 +610,11 @@ ConnectionData.prototype = Object.freeze({ return this._deferredClose.promise; } - this._log.debug("Request to close connection."); + this._logger.debug("Request to close connection."); this._clearIdleShrinkTimer(); if (this._vacuumOnIdle) { - this._log.debug("Unregister as vacuum participant"); + this._logger.debug("Unregister as vacuum participant"); unregisterVacuumParticipant(this); } @@ -616,7 +629,7 @@ ConnectionData.prototype = Object.freeze({ clone(readOnly = false) { this.ensureOpen(); - this._log.debug("Request to clone connection."); + this._logger.debug("Request to clone connection."); let options = { connection: this._dbConn, @@ -632,7 +645,7 @@ ConnectionData.prototype = Object.freeze({ return this._operationsCounter++; }, _finalize() { - this._log.debug("Finalizing connection."); + this._logger.debug("Finalizing connection."); // Cancel any pending statements. for (let [, /* k */ statement] of this._pendingStatements) { statement.cancel(); @@ -660,7 +673,7 @@ ConnectionData.prototype = Object.freeze({ // We must always close the connection at the Sqlite.sys.mjs-level, not // necessarily at the mozStorage-level. let markAsClosed = () => { - this._log.debug("Closed"); + this._logger.debug("Closed"); // Now that the connection is closed, no need to keep // a blocker for Barriers.connections. lazy.Barriers.connections.client.removeBlocker( @@ -673,7 +686,7 @@ ConnectionData.prototype = Object.freeze({ this._dbConn = null; markAsClosed(); } else { - this._log.debug("Calling asyncClose()."); + this._logger.debug("Calling asyncClose()."); try { this._dbConn.asyncClose(markAsClosed); } catch (ex) { @@ -770,7 +783,7 @@ ConnectionData.prototype = Object.freeze({ .pop() .match(/^([^@]*@).*\/([^\/:]+)[:0-9]*$/); caller = caller[1] + caller[2]; - this._log.debug(`Transaction (type ${type}) requested by: ${caller}`); + this._logger.debug(`Transaction (type ${type}) requested by: ${caller}`); if (type == OpenedConnection.prototype.TRANSACTION_DEFAULT) { type = this.defaultTransactionType; @@ -794,7 +807,7 @@ ConnectionData.prototype = Object.freeze({ // At this point we should never have an in progress transaction, since // they are enqueued. if (this._initiatedTransaction) { - this._log.error( + this._logger.error( "Unexpected transaction in progress when trying to start a new one." ); } @@ -802,7 +815,7 @@ ConnectionData.prototype = Object.freeze({ // We catch errors in statement execution to detect nested transactions. try { await this.execute("BEGIN " + type + " TRANSACTION"); - this._log.debug(`Begin transaction`); + this._logger.debug(`Begin transaction`); this._initiatedTransaction = true; } catch (ex) { // Unfortunately, if we are wrapping an existing connection, a @@ -811,12 +824,12 @@ ConnectionData.prototype = Object.freeze({ // The best we can do is proceed without a transaction and hope // things won't break. if (wrappedConnections.has(this._identifier)) { - this._log.warn( + this._logger.warn( "A new transaction could not be started cause the wrapped connection had one in progress", ex ); } else { - this._log.warn( + this._logger.warn( "A transaction was already in progress, likely a nested transaction", ex ); @@ -831,7 +844,7 @@ ConnectionData.prototype = Object.freeze({ // It's possible that the exception has been caused by trying to // close the connection in the middle of a transaction. if (this._closeRequested) { - this._log.warn( + this._logger.warn( "Connection closed while performing a transaction", ex ); @@ -845,12 +858,12 @@ ConnectionData.prototype = Object.freeze({ caller_module, 1 ); - this._log.error( + this._logger.error( `The transaction requested by ${caller} timed out. Rolling back`, ex ); } else { - this._log.error( + this._logger.error( `Error during transaction requested by ${caller}. Rolling back`, ex ); @@ -860,9 +873,9 @@ ConnectionData.prototype = Object.freeze({ try { await this.execute("ROLLBACK TRANSACTION"); this._initiatedTransaction = false; - this._log.debug(`Roll back transaction`); + this._logger.debug(`Roll back transaction`); } catch (inner) { - this._log.error("Could not roll back transaction", inner); + this._logger.error("Could not roll back transaction", inner); } } } @@ -872,7 +885,7 @@ ConnectionData.prototype = Object.freeze({ // See comment above about connection being closed during transaction. if (this._closeRequested) { - this._log.warn( + this._logger.warn( "Connection closed before committing the transaction." ); throw new Error( @@ -884,9 +897,9 @@ ConnectionData.prototype = Object.freeze({ if (this._initiatedTransaction) { try { await this.execute("COMMIT TRANSACTION"); - this._log.debug(`Commit transaction`); + this._logger.debug(`Commit transaction`); } catch (ex) { - this._log.warn("Error committing transaction", ex); + this._logger.warn("Error committing transaction", ex); throw ex; } } @@ -902,7 +915,7 @@ ConnectionData.prototype = Object.freeze({ // Atomically update the queue before anyone else has a chance to enqueue // further transactions. this._transactionQueue = promise.catch(ex => { - this._log.error(ex); + this._logger.error(ex); }); // Make sure that we do not shutdown the connection during a transaction. @@ -914,7 +927,7 @@ ConnectionData.prototype = Object.freeze({ }, shrinkMemory() { - this._log.debug("Shrinking memory usage."); + this._logger.debug("Shrinking memory usage."); return this.execute("PRAGMA shrink_memory").finally(() => { this._clearIdleShrinkTimer(); }); @@ -927,12 +940,12 @@ ConnectionData.prototype = Object.freeze({ statement.finalize(); } this._cachedStatements.clear(); - this._log.debug("Discarded " + count + " cached statements."); + this._logger.debug("Discarded " + count + " cached statements."); return count; }, interrupt() { - this._log.debug("Trying to interrupt."); + this._logger.debug("Trying to interrupt."); this.ensureOpen(); this._dbConn.interrupt(); }, @@ -1018,15 +1031,15 @@ ConnectionData.prototype = Object.freeze({ // Don't incur overhead for serializing params unless the messages go // somewhere. - if (this._log.level <= lazy.Log.Level.Trace) { + if (this._logger.shouldLog("Trace")) { let msg = "Stmt #" + index + " " + sql; if (params) { msg += " - " + JSON.stringify(params); } - this._log.trace(msg); + this._logger.trace(msg); } else { - this._log.debug("Stmt #" + index + " starting"); + this._logger.debug("Stmt #" + index + " starting"); } let self = this; @@ -1052,20 +1065,20 @@ ConnectionData.prototype = Object.freeze({ pending.cancel(); }); } catch (e) { - self._log.warn("Exception when calling onRow callback", e); + self._logger.warn("Exception when calling onRow callback", e); } } }, handleError(error) { - self._log.warn( + self._logger.warn( "Error when executing SQL (" + error.result + "): " + error.message ); errors.push(error); }, handleCompletion(reason) { - self._log.debug("Stmt #" + index + " finished."); + self._logger.debug("Stmt #" + index + " finished."); self._pendingStatements.delete(index); switch (reason) { @@ -1256,11 +1269,7 @@ ConnectionData.prototype = Object.freeze({ * @return Promise */ function openConnection(options) { - let log = lazy.Log.repository.getLoggerWithMessagePrefix( - "Sqlite.sys.mjs", - `ConnectionOpener: ` - ); - log.manageLevelFromPref("toolkit.sqlitejsm.loglevel"); + let logger = createLoggerWithPrefix("ConnectionOpener"); if (!options.path) { throw new Error("path not specified in connection options."); @@ -1350,7 +1359,7 @@ function openConnection(options) { let identifier = getIdentifierByFileName(PathUtils.filename(path)); - log.debug("Opening database: " + path + " (" + identifier + ")"); + logger.debug("Opening database: " + path + " (" + identifier + ")"); return new Promise((resolve, reject) => { let dbOpenOptions = Ci.mozIStorageService.OPEN_DEFAULT; @@ -1373,7 +1382,7 @@ function openConnection(options) { dbConnectionOptions, async (status, connection) => { if (!connection) { - log.error(`Could not open connection to ${path}: ${status}`); + logger.error(`Could not open connection to ${path}: ${status}`); let error = new Components.Exception( `Could not open connection to ${path}: ${status}`, status @@ -1381,7 +1390,7 @@ function openConnection(options) { reject(error); return; } - log.debug("Connection opened"); + logger.debug("Connection opened"); if (options.testDelayedOpenPromise) { await options.testDelayedOpenPromise; @@ -1407,7 +1416,7 @@ function openConnection(options) { ) ); } catch (ex) { - log.error("Could not open database", ex); + logger.error("Could not open database", ex); connection.asyncClose(); reject(ex); } @@ -1446,11 +1455,7 @@ function openConnection(options) { * @return Promise */ function cloneStorageConnection(options) { - let log = lazy.Log.repository.getLoggerWithMessagePrefix( - "Sqlite.sys.mjs", - `ConnectionCloner: ` - ); - log.manageLevelFromPref("toolkit.sqlitejsm.loglevel"); + let logger = createLoggerWithPrefix("ConnectionCloner"); let source = options && options.connection; if (!source) { @@ -1484,16 +1489,16 @@ function cloneStorageConnection(options) { let path = source.databaseFile.path; let identifier = getIdentifierByFileName(PathUtils.filename(path)); - log.debug("Cloning database: " + path + " (" + identifier + ")"); + logger.debug("Cloning database: " + path + " (" + identifier + ")"); return new Promise((resolve, reject) => { source.asyncClone(!!options.readOnly, (status, connection) => { if (!connection) { - log.error("Could not clone connection: " + status); + logger.error("Could not clone connection: " + status); reject(new Error("Could not clone connection: " + status)); return; } - log.debug("Connection cloned"); + logger.debug("Connection cloned"); if (isClosed()) { connection.QueryInterface(Ci.mozIStorageAsyncConnection).asyncClose(); @@ -1510,7 +1515,7 @@ function cloneStorageConnection(options) { let conn = connection.QueryInterface(Ci.mozIStorageAsyncConnection); resolve(new OpenedConnection(conn, identifier, openedOptions)); } catch (ex) { - log.error("Could not clone database", ex); + logger.error("Could not clone database", ex); connection.asyncClose(); reject(ex); } @@ -1537,11 +1542,7 @@ function cloneStorageConnection(options) { * @return Promise */ function wrapStorageConnection(options) { - let log = lazy.Log.repository.getLoggerWithMessagePrefix( - "Sqlite.sys.mjs", - `ConnectionCloner: ` - ); - log.manageLevelFromPref("toolkit.sqlitejsm.loglevel"); + let logger = createLoggerWithPrefix("ConnectionWrapper"); let connection = options && options.connection; if (!connection || !(connection instanceof Ci.mozIStorageAsyncConnection)) { @@ -1557,7 +1558,7 @@ function wrapStorageConnection(options) { let identifier = getIdentifierByFileName(connection.databaseFile.leafName); - log.debug("Wrapping database: " + identifier); + logger.debug("Wrapping database: " + identifier); return new Promise(resolve => { try { let conn = connection.QueryInterface(Ci.mozIStorageAsyncConnection); @@ -1567,7 +1568,7 @@ function wrapStorageConnection(options) { wrappedConnections.add(identifier); resolve(wrapper); } catch (ex) { - log.error("Could not wrap database", ex); + logger.error("Could not wrap database", ex); throw ex; } }); @@ -1687,12 +1688,23 @@ OpenedConnection.prototype = Object.freeze({ * Returns the maximum number of bound parameters for statements executed * on this connection. * - * @type {number} + * @returns {number} The bound parameters limit. */ get variableLimit() { return this.unsafeRawConnection.variableLimit; }, + /** + * Set the the maximum number of bound parameters for statements executed + * on this connection. If the passed-in value is higher than the maximum + * default value, it will be silently truncated. + * + * @param {number} newLimit The bound parameters limit. + */ + set variableLimit(newLimit) { + this.unsafeRawConnection.variableLimit = newLimit; + }, + /** * The integer schema version of the database. * -- cgit v1.2.3