mirror of
https://github.com/arthur-pbty/portfolio2023.git
synced 2026-06-05 00:06:20 +02:00
330 lines
9.7 KiB
JavaScript
330 lines
9.7 KiB
JavaScript
"use strict";
|
|
/*
|
|
* @adonisjs/lucid
|
|
*
|
|
* (c) Harminder Virk <virk@adonisjs.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.TransactionClient = void 0;
|
|
const events_1 = require("events");
|
|
const hooks_1 = require("@poppinss/hooks");
|
|
const QueryBuilder_1 = require("../Orm/QueryBuilder");
|
|
const Raw_1 = require("../Database/StaticBuilder/Raw");
|
|
const Raw_2 = require("../Database/QueryBuilder/Raw");
|
|
const Insert_1 = require("../Database/QueryBuilder/Insert");
|
|
const Reference_1 = require("../Database/StaticBuilder/Reference");
|
|
const Database_1 = require("../Database/QueryBuilder/Database");
|
|
/**
|
|
* Transaction uses a dedicated connection from the connection pool
|
|
* and executes queries inside a given transaction.
|
|
*/
|
|
class TransactionClient extends events_1.EventEmitter {
|
|
constructor(knexClient, dialect, connectionName, debug, emitter) {
|
|
super();
|
|
Object.defineProperty(this, "knexClient", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: knexClient
|
|
});
|
|
Object.defineProperty(this, "dialect", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: dialect
|
|
});
|
|
Object.defineProperty(this, "connectionName", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: connectionName
|
|
});
|
|
Object.defineProperty(this, "debug", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: debug
|
|
});
|
|
Object.defineProperty(this, "emitter", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: emitter
|
|
});
|
|
/**
|
|
* Always true
|
|
*/
|
|
Object.defineProperty(this, "isTransaction", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: true
|
|
});
|
|
/**
|
|
* Transactions are always in write mode, since they always needs
|
|
* the primary connection
|
|
*/
|
|
Object.defineProperty(this, "mode", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: 'dual'
|
|
});
|
|
/**
|
|
* The profiler to be used for profiling queries
|
|
*/
|
|
Object.defineProperty(this, "profiler", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
Object.defineProperty(this, "hooks", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: new hooks_1.Hooks()
|
|
});
|
|
/**
|
|
* Lucid models listens for transaction events to delete the reference. During
|
|
* testing, it is common to generate more than 10 model instances and hence
|
|
* the max listeners limit needs to be removed
|
|
*/
|
|
this.setMaxListeners(Infinity);
|
|
}
|
|
/**
|
|
* Whether or not transaction has been completed
|
|
*/
|
|
get isCompleted() {
|
|
return this.knexClient.isCompleted();
|
|
}
|
|
/**
|
|
* Returns schema instance for the write client
|
|
*/
|
|
get schema() {
|
|
return this.getWriteClient().schema;
|
|
}
|
|
/**
|
|
* Returns the read client. Which is just a single client in case
|
|
* of transactions
|
|
*/
|
|
getReadClient() {
|
|
return this.knexClient;
|
|
}
|
|
/**
|
|
* Returns the write client. Which is just a single client in case
|
|
* of transactions
|
|
*/
|
|
getWriteClient() {
|
|
return this.knexClient;
|
|
}
|
|
/**
|
|
* Truncate tables inside a transaction
|
|
*/
|
|
async truncate(table, cascade = false) {
|
|
await this.dialect.truncate(table, cascade);
|
|
}
|
|
/**
|
|
* Get columns info inside a transaction. You won't need it here, however
|
|
* added for API compatibility with the [[QueryClient]] class
|
|
*/
|
|
async columnsInfo(table, column) {
|
|
const query = this.knexClient.select(table);
|
|
const result = await (column ? query.columnInfo(column) : query.columnInfo());
|
|
return result;
|
|
}
|
|
/**
|
|
* Returns an array of table names
|
|
*/
|
|
async getAllTables(schemas) {
|
|
return this.dialect.getAllTables(schemas);
|
|
}
|
|
/**
|
|
* Returns an array of all views names
|
|
*/
|
|
async getAllViews(schemas) {
|
|
return this.dialect.getAllViews(schemas);
|
|
}
|
|
/**
|
|
* Returns an array of all types names
|
|
*/
|
|
async getAllTypes(schemas) {
|
|
return this.dialect.getAllTypes(schemas);
|
|
}
|
|
/**
|
|
* Drop all tables inside database
|
|
*/
|
|
async dropAllTables(schemas) {
|
|
return this.dialect.dropAllTables(schemas || ['public']);
|
|
}
|
|
/**
|
|
* Drop all views inside the database
|
|
*/
|
|
async dropAllViews(schemas) {
|
|
return this.dialect.dropAllViews(schemas || ['public']);
|
|
}
|
|
/**
|
|
* Drop all custom types inside the database
|
|
*/
|
|
async dropAllTypes(schemas) {
|
|
return this.dialect.dropAllTypes(schemas || ['public']);
|
|
}
|
|
/**
|
|
* Get a new query builder instance
|
|
*/
|
|
knexQuery() {
|
|
return this.knexClient.queryBuilder();
|
|
}
|
|
/**
|
|
* Returns the knex raw query builder instance. The query builder is always
|
|
* created from the `write` client, so before executing the query, you
|
|
* may want to decide which client to use.
|
|
*/
|
|
knexRawQuery(sql, bindings) {
|
|
return bindings ? this.knexClient.raw(sql, bindings) : this.knexClient.raw(sql);
|
|
}
|
|
/**
|
|
* Returns a query builder instance for a given model. The `connection`
|
|
* and `profiler` is passed down to the model, so that it continue
|
|
* using the same options
|
|
*/
|
|
modelQuery(model) {
|
|
return new QueryBuilder_1.ModelQueryBuilder(this.knexQuery(), model, this);
|
|
}
|
|
/**
|
|
* Get a new query builder instance
|
|
*/
|
|
query() {
|
|
return new Database_1.DatabaseQueryBuilder(this.knexQuery(), this);
|
|
}
|
|
/**
|
|
* Get a new insert query builder instance
|
|
*/
|
|
insertQuery() {
|
|
return new Insert_1.InsertQueryBuilder(this.knexQuery(), this);
|
|
}
|
|
/**
|
|
* Execute raw query on transaction
|
|
*/
|
|
rawQuery(sql, bindings) {
|
|
return new Raw_2.RawQueryBuilder(this.knexClient.raw(sql, bindings), this);
|
|
}
|
|
/**
|
|
* Returns an instance of raw builder. This raw builder queries
|
|
* cannot be executed. Use `rawQuery`, if you want to execute
|
|
* queries raw queries.
|
|
*/
|
|
raw(sql, bindings) {
|
|
return new Raw_1.RawBuilder(sql, bindings);
|
|
}
|
|
/**
|
|
* Returns reference builder.
|
|
*/
|
|
ref(reference) {
|
|
return new Reference_1.ReferenceBuilder(reference, this.knexClient.client);
|
|
}
|
|
/**
|
|
* Returns another instance of transaction with save point
|
|
*/
|
|
async transaction(callback, options) {
|
|
const trx = await this.knexClient.transaction(options);
|
|
const transaction = new TransactionClient(trx, this.dialect, this.connectionName, this.debug, this.emitter);
|
|
/**
|
|
* Always make sure to pass the profiler down the chain
|
|
*/
|
|
transaction.profiler = this.profiler?.create('trx:begin', { state: 'begin' });
|
|
/**
|
|
* Self managed transaction
|
|
*/
|
|
if (typeof callback === 'function') {
|
|
try {
|
|
const response = await callback(transaction);
|
|
!transaction.isCompleted && (await transaction.commit());
|
|
return response;
|
|
}
|
|
catch (error) {
|
|
await transaction.rollback();
|
|
throw error;
|
|
}
|
|
}
|
|
return transaction;
|
|
}
|
|
/**
|
|
* Same as [[Transaction.query]] but also selects the table
|
|
*/
|
|
from(table) {
|
|
return this.query().from(table);
|
|
}
|
|
/**
|
|
* Same as [[Transaction.insertTable]] but also selects the table
|
|
*/
|
|
table(table) {
|
|
return this.insertQuery().table(table);
|
|
}
|
|
/**
|
|
* Register after commit or rollback hook
|
|
*/
|
|
after(event, handler) {
|
|
this.hooks.add('after', event, handler);
|
|
return this;
|
|
}
|
|
/**
|
|
* Commit the transaction
|
|
*/
|
|
async commit() {
|
|
try {
|
|
await this.knexClient.commit();
|
|
this.profiler?.end({ state: 'commit' });
|
|
this.emit('commit', this);
|
|
this.removeAllListeners();
|
|
}
|
|
catch (error) {
|
|
this.profiler?.end({ state: 'commit' });
|
|
this.removeAllListeners();
|
|
throw error;
|
|
}
|
|
try {
|
|
await this.hooks.exec('after', 'commit');
|
|
this.hooks.clear('after');
|
|
}
|
|
catch { }
|
|
}
|
|
/**
|
|
* Rollback the transaction
|
|
*/
|
|
async rollback() {
|
|
try {
|
|
await this.knexClient.rollback();
|
|
this.profiler?.end({ state: 'rollback' });
|
|
this.emit('rollback', this);
|
|
this.removeAllListeners();
|
|
}
|
|
catch (error) {
|
|
this.profiler?.end({ state: 'rollback' });
|
|
this.removeAllListeners();
|
|
throw error;
|
|
}
|
|
try {
|
|
await this.hooks.exec('after', 'rollback');
|
|
this.hooks.clear('after');
|
|
}
|
|
catch { }
|
|
}
|
|
/**
|
|
* Get advisory lock on the selected connection
|
|
*/
|
|
getAdvisoryLock(key, timeout) {
|
|
return this.dialect.getAdvisoryLock(key, timeout);
|
|
}
|
|
/**
|
|
* Release advisory lock
|
|
*/
|
|
releaseAdvisoryLock(key) {
|
|
return this.dialect.releaseAdvisoryLock(key);
|
|
}
|
|
}
|
|
exports.TransactionClient = TransactionClient;
|