From c925b4583f5d90fab58bd60c6684d1d8cbf15a7a Mon Sep 17 00:00:00 2001 From: Harminder virk Date: Mon, 6 Jan 2020 11:43:58 +0530 Subject: [PATCH] refactor: remove _ prefix from all private properties --- adonis-typings/database.ts | 8 +- adonis-typings/migrator.ts | 2 +- adonis-typings/model.txt | 90 ------------- src/Connection/Logger.ts | 4 + src/Connection/Manager.ts | 25 ++-- src/Connection/index.ts | 86 ++++++------- src/Database/QueryBuilder/Chainable.ts | 38 +++--- src/Database/QueryBuilder/Database.ts | 8 +- src/Database/index.ts | 22 ++-- src/Dialects/Mssql.ts | 2 +- src/Dialects/Mysql.ts | 8 +- src/Dialects/Oracle.ts | 2 +- src/Dialects/Pg.ts | 8 +- src/Dialects/Redshift.ts | 2 +- src/Dialects/Sqlite.ts | 2 +- src/Migrator/MigrationSource.ts | 16 +-- src/Migrator/index.ts | 142 ++++++++++----------- src/Orm/Adapter/index.ts | 4 +- src/Orm/Hooks/index.ts | 24 ++-- src/Orm/QueryBuilder/index.ts | 24 ++-- src/QueryClient/index.ts | 30 +++-- src/Schema/index.ts | 34 ++--- src/Traits/Executable.ts | 20 +-- src/TransactionClient/index.ts | 14 ++ test/connection/connection-manager.spec.ts | 2 +- 25 files changed, 278 insertions(+), 339 deletions(-) delete mode 100644 adonis-typings/model.txt diff --git a/adonis-typings/database.ts b/adonis-typings/database.ts index 270beeac..95d228ce 100644 --- a/adonis-typings/database.ts +++ b/adonis-typings/database.ts @@ -48,7 +48,7 @@ declare module '@ioc:Adonis/Lucid/Database' { */ export interface DialectContract { readonly name: string - supportsAdvisoryLocks: boolean + readonly supportsAdvisoryLocks: boolean getAdvisoryLock (key: string | number, timeout?: number): Promise releaseAdvisoryLock (key: string | number): Promise } @@ -155,6 +155,12 @@ declare module '@ioc:Adonis/Lucid/Database' { * Get instance of transaction client */ transaction (): Promise, + + /** + * Work with advisory locks + */ + getAdvisoryLock (key: string | number, timeout?: number): Promise + releaseAdvisoryLock (key: string | number): Promise } /** diff --git a/adonis-typings/migrator.ts b/adonis-typings/migrator.ts index 32ef9ce5..ac3446a1 100644 --- a/adonis-typings/migrator.ts +++ b/adonis-typings/migrator.ts @@ -8,8 +8,8 @@ */ declare module '@ioc:Adonis/Lucid/Migrator' { - import { SchemaConstructorContract } from '@ioc:Adonis/Lucid/Schema' import { EventEmitter } from 'events' + import { SchemaConstructorContract } from '@ioc:Adonis/Lucid/Schema' /** * Migration node returned by the migration source diff --git a/adonis-typings/model.txt b/adonis-typings/model.txt deleted file mode 100644 index e7859dca..00000000 --- a/adonis-typings/model.txt +++ /dev/null @@ -1,90 +0,0 @@ - /** - * Save the related model. - */ - save (model: T, wrapInTransaction?: boolean): Promise - - /** - * Save the related model. - */ - saveMany (model: T[], wrapInTransaction?: boolean): Promise - - /** - * Create the related model instance - */ - create (values: ModelObject, wrapInTransaction?: boolean): Promise - - /** - * Create many of the related model instance - */ - createMany (values: ModelObject[], wrapInTransaction?: boolean): Promise - - /** - * Update the relationship or create a new one - */ - updateOrCreate ( - search: ModelObject, - updatePayload: ModelObject, - wrapInTransaction?: boolean, - ): Promise - - - - - /** - * Associate related model. - */ - associate (model: T, wrapInTransaction?: boolean): Promise - - /** - * Dissociate all relationships. - */ - dissociate (): Promise - - - - - - - - - /** - * Save related model - */ - save (model: T, wrapInTransaction?: boolean, checkExisting?: boolean): Promise - - /** - * Save related many - */ - saveMany (model: T[], wrapInTransaction?: boolean, checkExisting?: boolean): Promise - - /** - * Create the related model instance - */ - create (values: ModelObject, wrapInTransaction?: boolean, checkExisting?: boolean): Promise - - /** - * Create many of the related model instance - */ - createMany (values: ModelObject, wrapInTransaction?: boolean, checkExisting?: boolean): Promise - - /** - * Attach related - */ - attach ( - ids: (string | number)[] | { [key: string]: ModelObject }, - checkExisting?: boolean, - ): Promise - - /** - * Detach from pivot table - */ - detach (ids: (string | number)[]): Promise - - /** - * Sync related ids - */ - sync ( - ids: (string | number)[] | { [key: string]: ModelObject }, - wrapInTransaction?: boolean, - checkExisting?: boolean, - ): Promise diff --git a/src/Connection/Logger.ts b/src/Connection/Logger.ts index b5e5b07c..ab186642 100644 --- a/src/Connection/Logger.ts +++ b/src/Connection/Logger.ts @@ -9,6 +9,10 @@ import { LoggerContract } from '@ioc:Adonis/Core/Logger' +/** + * Custom knex logger that uses adonisjs logger under the + * hood. + */ export class Logger { public warn = function (message: any) { this.adonisLogger.warn(message) diff --git a/src/Connection/Manager.ts b/src/Connection/Manager.ts index a5408f95..cd2a5bfc 100644 --- a/src/Connection/Manager.ts +++ b/src/Connection/Manager.ts @@ -35,16 +35,16 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager * Connections for which the config was patched. They must get removed * overtime, unless application is behaving unstable. */ - private _orphanConnections: Set = new Set() + private orphanConnections: Set = new Set() - constructor (private _logger: LoggerContract) { + constructor (private logger: LoggerContract) { super() } /** * Monitors a given connection by listening for lifecycle events */ - private _monitorConnection (connection: ConnectionContract): void { + private monitorConnection (connection: ConnectionContract): void { /** * Listens for disconnect to set the connection state and cleanup * memory @@ -54,11 +54,11 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager * We received the close event on the orphan connection and not the connection * that is in use */ - if (this._orphanConnections.has($connection)) { - this._orphanConnections.delete($connection) + if (this.orphanConnections.has($connection)) { + this.orphanConnections.delete($connection) this.emit('disconnect', $connection) - this._logger.trace({ connection: $connection.name }, 'disconnecting connection inside manager') + this.logger.trace({ connection: $connection.name }, 'disconnecting connection inside manager') return } @@ -73,7 +73,7 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager } this.emit('disconnect', $connection) - this._logger.trace({ connection: $connection.name }, 'disconnecting connection inside manager') + this.logger.trace({ connection: $connection.name }, 'disconnecting connection inside manager') delete internalConnection.connection internalConnection.state = 'closed' @@ -113,7 +113,7 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager return } - this._logger.trace({ connection: connectionName }, 'adding new connection to the manager') + this.logger.trace({ connection: connectionName }, 'adding new connection to the manager') this.connections.set(connectionName, { name: connectionName, config: config, @@ -144,8 +144,8 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager /** * Create a new connection and monitor it's state */ - connection.connection = new Connection(connection.name, connection.config, this._logger) - this._monitorConnection(connection.connection) + connection.connection = new Connection(connection.name, connection.config, this.logger) + this.monitorConnection(connection.connection) connection.connection.connect() } @@ -168,12 +168,13 @@ export class ConnectionManager extends EventEmitter implements ConnectionManager * they cleanup after some time */ if (connection.connection) { - this._orphanConnections.add(connection.connection) + this.orphanConnections.add(connection.connection) connection.connection.disconnect() } /** - * Updating config and state. Next call to connect will use this + * Updating config and state. Next call to connect will use the + * new config */ connection.state = 'migrating' connection.config = config diff --git a/src/Connection/index.ts b/src/Connection/index.ts index 51164dad..6151bf61 100644 --- a/src/Connection/index.ts +++ b/src/Connection/index.ts @@ -51,27 +51,27 @@ export class Connection extends EventEmitter implements ConnectionContract { * Config for one or more read replicas. Only exists, when replicas are * defined */ - private _readReplicas: any[] = [] + private readReplicas: any[] = [] /** * The round robin counter for reading config */ - private _roundRobinCounter = 0 + private roundRobinCounter = 0 constructor ( public readonly name: string, public config: ConnectionConfigContract, - private _logger: LoggerContract, + private logger: LoggerContract, ) { super() - this._validateConfig() + this.validateConfig() } /** * Validates the config to ensure that read/write replicas are defined * properly. */ - private _validateConfig (): void { + private validateConfig (): void { if (this.config.replicas) { if (!this.config.replicas.read || !this.config.replicas.write) { throw new Exception( @@ -94,11 +94,11 @@ export class Connection extends EventEmitter implements ConnectionContract { /** * Cleanup references */ - private _cleanup (): void { + private cleanup (): void { this.client = undefined this.readClient = undefined - this._readReplicas = [] - this._roundRobinCounter = 0 + this.readReplicas = [] + this.roundRobinCounter = 0 } /** @@ -106,22 +106,22 @@ export class Connection extends EventEmitter implements ConnectionContract { * For the same of simplicity, we get rid of both read and write * clients, when anyone of them disconnects. */ - private _monitorPoolResources (): void { + private monitorPoolResources (): void { /** * Pool has destroyed and hence we must cleanup resources * as well. */ this.pool!.on('poolDestroySuccess', () => { - this._logger.trace({ connection: this.name }, 'pool destroyed, cleaning up resource') - this._cleanup() + this.logger.trace({ connection: this.name }, 'pool destroyed, cleaning up resource') + this.cleanup() this.emit('disconnect', this) this.removeAllListeners() }) if (this.readPool !== this.pool) { - this._logger.trace({ connection: this.name }, 'pool destroyed, cleaning up resource') + this.logger.trace({ connection: this.name }, 'pool destroyed, cleaning up resource') this.readPool!.on('poolDestroySuccess', () => { - this._cleanup() + this.cleanup() this.emit('disconnect', this) this.removeAllListeners() }) @@ -132,7 +132,7 @@ export class Connection extends EventEmitter implements ConnectionContract { * Returns normalized config object for write replica to be * used by knex */ - private _getWriteConfig (): knex.Config { + private getWriteConfig (): knex.Config { if (!this.config.replicas) { return this.config } @@ -163,7 +163,7 @@ export class Connection extends EventEmitter implements ConnectionContract { /** * Returns the config for read replicas. */ - private _getReadConfig (): knex.Config { + private getReadConfig (): knex.Config { if (!this.config.replicas) { return this.config } @@ -174,7 +174,7 @@ export class Connection extends EventEmitter implements ConnectionContract { * Reading replicas and storing them as a reference, so that we * can pick a config from replicas as round robin. */ - this._readReplicas = (replicas.read.connection as Array).map((one) => { + this.readReplicas = (replicas.read.connection as Array).map((one) => { if (typeof (one) === 'string' || typeof (config.connection) === 'string') { return one } else { @@ -187,7 +187,7 @@ export class Connection extends EventEmitter implements ConnectionContract { * internally */ config.connection = { - database: this._readReplicas[0].database, + database: this.readReplicas[0].database, } /** @@ -204,58 +204,58 @@ export class Connection extends EventEmitter implements ConnectionContract { /** * Resolves connection config for the writer connection */ - private _writeConfigResolver (originalConfig: ConnectionConfigContract) { + private writeConfigResolver (originalConfig: ConnectionConfigContract) { return originalConfig.connection } /** * Resolves connection config for the reader connection */ - private _readConfigResolver (originalConfig: ConnectionConfigContract) { - if (!this._readReplicas.length) { + private readConfigResolver (originalConfig: ConnectionConfigContract) { + if (!this.readReplicas.length) { return originalConfig.connection } - const index = this._roundRobinCounter++ % this._readReplicas.length - this._logger.trace({ connection: this.name }, `round robin using host at ${index} index`) - return this._readReplicas[index] + const index = this.roundRobinCounter++ % this.readReplicas.length + this.logger.trace({ connection: this.name }, `round robin using host at ${index} index`) + return this.readReplicas[index] } /** * Creates the write connection */ - private _setupWriteConnection () { - this.client = knex(Object.assign({ log: new Logger(this._logger) }, this._getWriteConfig())) - patchKnex(this.client, this._writeConfigResolver.bind(this)) + private setupWriteConnection () { + this.client = knex(Object.assign({ log: new Logger(this.logger) }, this.getWriteConfig())) + patchKnex(this.client, this.writeConfigResolver.bind(this)) } /** * Creates the read connection. If there aren't any replicas in use, then * it will use reference the write client */ - private _setupReadConnection () { + private setupReadConnection () { if (!this.hasReadWriteReplicas) { this.readClient = this.client return } - this._logger.trace({ connection: this.name }, 'setting up read/write replicas') + this.logger.trace({ connection: this.name }, 'setting up read/write replicas') - this.readClient = knex(Object.assign({ log: new Logger(this._logger) }, this._getReadConfig())) - patchKnex(this.readClient, this._readConfigResolver.bind(this)) + this.readClient = knex(Object.assign({ log: new Logger(this.logger) }, this.getReadConfig())) + patchKnex(this.readClient, this.readConfigResolver.bind(this)) } /** * Checks all the read hosts by running a query on them. Stops * after first error. */ - private async _checkReadHosts () { - const configCopy = Object.assign({ log: new Logger(this._logger) }, this.config) + private async checkReadHosts () { + const configCopy = Object.assign({ log: new Logger(this.logger) }, this.config) let error: any = null - for (let _replica of this._readReplicas) { - configCopy.connection = this._readConfigResolver(this.config) - this._logger.trace({ connection: this.name }, 'spawing health check read connection') + for (let _ of this.readReplicas) { + configCopy.connection = this.readConfigResolver(this.config) + this.logger.trace({ connection: this.name }, 'spawing health check read connection') const client = knex(configCopy) try { @@ -268,7 +268,7 @@ export class Connection extends EventEmitter implements ConnectionContract { * Cleanup client connection */ await client.destroy() - this._logger.trace({ connection: this.name }, 'destroying health check read connection') + this.logger.trace({ connection: this.name }, 'destroying health check read connection') /** * Return early when there is an error @@ -284,7 +284,7 @@ export class Connection extends EventEmitter implements ConnectionContract { /** * Checks for the write host */ - private async _checkWriteHost () { + private async checkWriteHost () { try { await this.client!.raw('SELECT 1 + 1 AS result') } catch (error) { @@ -320,9 +320,9 @@ export class Connection extends EventEmitter implements ConnectionContract { */ public connect () { try { - this._setupWriteConnection() - this._setupReadConnection() - this._monitorPoolResources() + this.setupWriteConnection() + this.setupReadConnection() + this.monitorPoolResources() this.emit('connect', this) } catch (error) { this.emit('error', error, this) @@ -338,7 +338,7 @@ export class Connection extends EventEmitter implements ConnectionContract { * by the `close` event. */ public async disconnect (): Promise { - this._logger.trace({ connection: this.name }, 'destroying connection') + this.logger.trace({ connection: this.name }, 'destroying connection') /** * Disconnect write client @@ -368,11 +368,11 @@ export class Connection extends EventEmitter implements ConnectionContract { * Returns the healthcheck report for the connection */ public async getReport (): Promise { - const error = await this._checkWriteHost() + const error = await this.checkWriteHost() let readError: Error | undefined if (!error && this.hasReadWriteReplicas) { - readError = await this._checkReadHosts() + readError = await this.checkReadHosts() } return { diff --git a/src/Database/QueryBuilder/Chainable.ts b/src/Database/QueryBuilder/Chainable.ts index 2e34298e..82b08948 100644 --- a/src/Database/QueryBuilder/Chainable.ts +++ b/src/Database/QueryBuilder/Chainable.ts @@ -24,7 +24,7 @@ import { RawQueryBuilder } from './Raw' export abstract class Chainable extends Macroable implements ChainableContract { constructor ( public $knexBuilder: knex.QueryBuilder, // Needs to be public for Executable trait - private _queryCallback: DBQueryCallback, + private queryCallback: DBQueryCallback, ) { super() } @@ -32,7 +32,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { /** * Returns the value pair for the `whereBetween` clause */ - private _getBetweenPair (value: any[]): any { + private getBetweenPair (value: any[]): any { const [lhs, rhs] = value if (!lhs || !rhs) { throw new Error('Invalid array for whereBetween value') @@ -45,7 +45,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Normalizes the columns aggregates functions to something * knex can process. */ - private _normalizeAggregateColumns (columns: any, alias?: any): any { + private normalizeAggregateColumns (columns: any, alias?: any): any { if (columns.constructor === Object) { return Object.keys(columns).reduce((result, key) => { result[key] = this.$transformValue(columns[key]) @@ -87,7 +87,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { */ protected $transformCallback (value: any) { if (typeof (value) === 'function') { - return this._queryCallback(value) + return this.queryCallback(value) } return value @@ -358,7 +358,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Add where between clause */ public whereBetween (key: any, value: [any, any]): this { - this.$knexBuilder.whereBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.whereBetween(key, this.getBetweenPair(value)) return this } @@ -366,7 +366,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Add where between clause */ public orWhereBetween (key: any, value: any): this { - this.$knexBuilder.orWhereBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.orWhereBetween(key, this.getBetweenPair(value)) return this } @@ -381,7 +381,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Add where between clause */ public whereNotBetween (key: any, value: any): this { - this.$knexBuilder.whereNotBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.whereNotBetween(key, this.getBetweenPair(value)) return this } @@ -389,7 +389,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Add where between clause */ public orWhereNotBetween (key: any, value: any): this { - this.$knexBuilder.orWhereNotBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.orWhereNotBetween(key, this.getBetweenPair(value)) return this } @@ -766,7 +766,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Adding `having between` clause */ public havingBetween (key: any, value: any): this { - this.$knexBuilder.havingBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.havingBetween(key, this.getBetweenPair(value)) return this } @@ -774,7 +774,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Adding `or having between` clause */ public orHavingBetween (key: any, value: any): this { - this.$knexBuilder.orHavingBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.orHavingBetween(key, this.getBetweenPair(value)) return this } @@ -789,7 +789,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Adding `having not between` clause */ public havingNotBetween (key: any, value: any): this { - this.$knexBuilder.havingNotBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.havingNotBetween(key, this.getBetweenPair(value)) return this } @@ -797,7 +797,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Adding `or having not between` clause */ public orHavingNotBetween (key: any, value: any): this { - this.$knexBuilder.orHavingNotBetween(key, this._getBetweenPair(value)) + this.$knexBuilder.orHavingNotBetween(key, this.getBetweenPair(value)) return this } @@ -1047,7 +1047,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Count rows for the current query */ public count (columns: any, alias?: any): this { - this.$knexBuilder.count(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.count(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1055,7 +1055,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Count distinct rows for the current query */ public countDistinct (columns: any, alias?: any): this { - this.$knexBuilder.countDistinct(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.countDistinct(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1063,7 +1063,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Make use of `min` aggregate function */ public min (columns: any, alias?: any): this { - this.$knexBuilder.min(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.min(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1071,7 +1071,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Make use of `max` aggregate function */ public max (columns: any, alias?: any): this { - this.$knexBuilder.max(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.max(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1079,7 +1079,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Make use of `avg` aggregate function */ public avg (columns: any, alias?: any): this { - this.$knexBuilder.avg(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.avg(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1087,7 +1087,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Make use of distinct `avg` aggregate function */ public avgDistinct (columns: any, alias?: any): this { - this.$knexBuilder.avgDistinct(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.avgDistinct(this.normalizeAggregateColumns(columns, alias)) return this } @@ -1095,7 +1095,7 @@ export abstract class Chainable extends Macroable implements ChainableContract { * Make use of `sum` aggregate function */ public sum (columns: any, alias?: any): this { - this.$knexBuilder.sum(this._normalizeAggregateColumns(columns, alias)) + this.$knexBuilder.sum(this.normalizeAggregateColumns(columns, alias)) return this } } diff --git a/src/Database/QueryBuilder/Database.ts b/src/Database/QueryBuilder/Database.ts index 2722520f..0729205a 100644 --- a/src/Database/QueryBuilder/Database.ts +++ b/src/Database/QueryBuilder/Database.ts @@ -58,7 +58,7 @@ export class DatabaseQueryBuilder extends Chainable implements DatabaseQueryBuil * Ensures that we are not executing `update` or `del` when using read only * client */ - private _ensureCanPerformWrites () { + private ensureCanPerformWrites () { if (this.client && this.client.mode === 'read') { throw new Exception('Updates and deletes cannot be performed in read mode') } @@ -68,7 +68,7 @@ export class DatabaseQueryBuilder extends Chainable implements DatabaseQueryBuil * Delete rows under the current query */ public del (): this { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.del() return this } @@ -117,7 +117,7 @@ export class DatabaseQueryBuilder extends Chainable implements DatabaseQueryBuil * Perform update */ public update (columns: any): this { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.update(columns) return this } @@ -144,7 +144,7 @@ export class DatabaseQueryBuilder extends Chainable implements DatabaseQueryBuil * Use write client for updates and deletes */ if (['update', 'del'].includes(this.$knexBuilder['_method'])) { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() return this.client!.getWriteClient().client } diff --git a/src/Database/index.ts b/src/Database/index.ts index 88e0581f..4434d653 100644 --- a/src/Database/index.ts +++ b/src/Database/index.ts @@ -40,7 +40,7 @@ export class Database implements DatabaseContract { /** * Primary connection name */ - public primaryConnectionName = this._config.connection + public primaryConnectionName = this.config.connection /** * Reference to query builders @@ -50,21 +50,21 @@ export class Database implements DatabaseContract { public ModelQueryBuilder = ModelQueryBuilder constructor ( - private _config: DatabaseConfigContract, - private _logger: LoggerContract, - private _profiler: ProfilerContract, + private config: DatabaseConfigContract, + private logger: LoggerContract, + private profiler: ProfilerContract, ) { - this.manager = new ConnectionManager(this._logger) - this._registerConnections() + this.manager = new ConnectionManager(this.logger) + this.registerConnections() } /** * Registering all connections with the manager, so that we can fetch * and connect with them whenver required. */ - private _registerConnections () { - Object.keys(this._config.connections).forEach((name) => { - this.manager.add(name, this._config.connections[name]) + private registerConnections () { + Object.keys(this.config.connections).forEach((name) => { + this.manager.add(name, this.config.connections[name]) }) } @@ -85,7 +85,7 @@ export class Database implements DatabaseContract { options = options || {} if (!options.profiler) { - options.profiler = this._profiler + options.profiler = this.profiler } /** @@ -109,7 +109,7 @@ export class Database implements DatabaseContract { * Generating query client for a given connection and setting appropriate * mode on it */ - this._logger.trace({ connection }, 'creating query client in %s mode', [options.mode || 'dual']) + this.logger.trace({ connection }, 'creating query client in %s mode', [options.mode || 'dual']) const queryClient = options.mode ? new QueryClient(options.mode, rawConnection) : new QueryClient('dual', rawConnection) diff --git a/src/Dialects/Mssql.ts b/src/Dialects/Mssql.ts index f3de992d..6904b1c1 100644 --- a/src/Dialects/Mssql.ts +++ b/src/Dialects/Mssql.ts @@ -13,7 +13,7 @@ import { DialectContract } from '@ioc:Adonis/Lucid/Database' export class MssqlDialect implements DialectContract { public readonly name = 'mssql' - public supportsAdvisoryLocks = false + public readonly supportsAdvisoryLocks = false public getAdvisoryLock (): Promise { throw new Error('Support for advisory locks is not implemented for mssql. Create a PR to add the feature') diff --git a/src/Dialects/Mysql.ts b/src/Dialects/Mysql.ts index e6304e55..979dd28d 100644 --- a/src/Dialects/Mysql.ts +++ b/src/Dialects/Mysql.ts @@ -13,9 +13,9 @@ import { DialectContract, QueryClientContract } from '@ioc:Adonis/Lucid/Database export class MysqlDialect implements DialectContract { public readonly name = 'mysql' - public supportsAdvisoryLocks = true + public readonly supportsAdvisoryLocks = true - constructor (private _client: QueryClientContract) { + constructor (private client: QueryClientContract) { } /** @@ -23,7 +23,7 @@ export class MysqlDialect implements DialectContract { * returns it's status. */ public async getAdvisoryLock (key: string, timeout: number = 0): Promise { - const response = await this._client.raw(`SELECT GET_LOCK('${key}', ${timeout}) as lock_status;`) + const response = await this.client.raw(`SELECT GET_LOCK('${key}', ${timeout}) as lock_status;`) return response[0] && response[0][0] && response[0][0].lock_status === 1 } @@ -31,7 +31,7 @@ export class MysqlDialect implements DialectContract { * Releases the advisory lock */ public async releaseAdvisoryLock (key: string): Promise { - const response = await this._client.raw(`SELECT RELEASE_LOCK('${key}') as lock_status;`) + const response = await this.client.raw(`SELECT RELEASE_LOCK('${key}') as lock_status;`) return response[0] && response[0][0] && response[0][0].lock_status === 1 } } diff --git a/src/Dialects/Oracle.ts b/src/Dialects/Oracle.ts index a1102b9f..75fe6f00 100644 --- a/src/Dialects/Oracle.ts +++ b/src/Dialects/Oracle.ts @@ -13,7 +13,7 @@ import { DialectContract } from '@ioc:Adonis/Lucid/Database' export class OracleDialect implements DialectContract { public readonly name = 'oracledb' - public supportsAdvisoryLocks = false + public readonly supportsAdvisoryLocks = false public getAdvisoryLock (): Promise { throw new Error('Support for advisory locks is not implemented for oracledb. Create a PR to add the feature') diff --git a/src/Dialects/Pg.ts b/src/Dialects/Pg.ts index 5dd51390..95dee536 100644 --- a/src/Dialects/Pg.ts +++ b/src/Dialects/Pg.ts @@ -13,9 +13,9 @@ import { DialectContract, QueryClientContract } from '@ioc:Adonis/Lucid/Database export class PgDialect implements DialectContract { public readonly name = 'postgres' - public supportsAdvisoryLocks = true + public readonly supportsAdvisoryLocks = true - constructor (private _client: QueryClientContract) { + constructor (private client: QueryClientContract) { } /** @@ -23,7 +23,7 @@ export class PgDialect implements DialectContract { * returns it's status. */ public async getAdvisoryLock (key: string): Promise { - const response = await this._client.raw(`SELECT PG_TRY_ADVISORY_LOCK('${key}') as lock_status;`) + const response = await this.client.raw(`SELECT PG_TRY_ADVISORY_LOCK('${key}') as lock_status;`) return response.rows[0] && response.rows[0].lock_status === true } @@ -31,7 +31,7 @@ export class PgDialect implements DialectContract { * Releases the advisory lock */ public async releaseAdvisoryLock (key: string): Promise { - const response = await this._client.raw(`SELECT PG_ADVISORY_UNLOCK('${key}') as lock_status;`) + const response = await this.client.raw(`SELECT PG_ADVISORY_UNLOCK('${key}') as lock_status;`) return response.rows[0] && response.rows[0].lock_status === true } } diff --git a/src/Dialects/Redshift.ts b/src/Dialects/Redshift.ts index e5cfe400..d0e99d57 100644 --- a/src/Dialects/Redshift.ts +++ b/src/Dialects/Redshift.ts @@ -13,7 +13,7 @@ import { DialectContract } from '@ioc:Adonis/Lucid/Database' export class RedshiftDialect implements DialectContract { public readonly name = 'redshift' - public supportsAdvisoryLocks = false + public readonly supportsAdvisoryLocks = false /** * Redshift doesn't support advisory locks. Learn more: diff --git a/src/Dialects/Sqlite.ts b/src/Dialects/Sqlite.ts index 1f3087df..ae0517ea 100644 --- a/src/Dialects/Sqlite.ts +++ b/src/Dialects/Sqlite.ts @@ -13,7 +13,7 @@ import { DialectContract } from '@ioc:Adonis/Lucid/Database' export class SqliteDialect implements DialectContract { public readonly name = 'sqlite3' - public supportsAdvisoryLocks = false + public readonly supportsAdvisoryLocks = false /** * Attempts to add advisory lock to the database and diff --git a/src/Migrator/MigrationSource.ts b/src/Migrator/MigrationSource.ts index 9a305b0d..cb626dd9 100644 --- a/src/Migrator/MigrationSource.ts +++ b/src/Migrator/MigrationSource.ts @@ -23,16 +23,16 @@ import { isJavaScriptFile } from '../utils' */ export class MigrationSource { constructor ( - private _config: ConnectionConfigContract, - private _app: ApplicationContract, + private config: ConnectionConfigContract, + private app: ApplicationContract, ) {} /** * Returns an array of files inside a given directory. Relative * paths are resolved from the project root */ - private _getDirectoryFiles (directoryPath: string): Promise { - const basePath = this._app.appRoot + private getDirectoryFiles (directoryPath: string): Promise { + const basePath = this.app.appRoot return new Promise((resolve, reject) => { const path = isAbsolute(directoryPath) ? directoryPath : join(basePath, directoryPath) @@ -59,8 +59,8 @@ export class MigrationSource { * Returns an array of migrations paths for a given connection. If paths * are not defined, then `database/migrations` fallback is used */ - private _getMigrationsPath (): string[] { - const directories = (this._config.migrations || {}).paths + private getMigrationsPath (): string[] { + const directories = (this.config.migrations || {}).paths return directories && directories.length ? directories : ['database/migrations'] } @@ -68,9 +68,9 @@ export class MigrationSource { * Returns an array of files for all defined directories */ public async getMigrations () { - const migrationPaths = this._getMigrationsPath().sort() + const migrationPaths = this.getMigrationsPath().sort() const directories = await Promise.all(migrationPaths.map((directoryPath) => { - return this._getDirectoryFiles(directoryPath) + return this.getDirectoryFiles(directoryPath) })) return directories.reduce((result, directory) => { diff --git a/src/Migrator/index.ts b/src/Migrator/index.ts index 40ae2b5b..2d2ee45e 100644 --- a/src/Migrator/index.ts +++ b/src/Migrator/index.ts @@ -34,26 +34,26 @@ import { MigrationSource } from './MigrationSource' * for a given connection at a time. */ export class Migrator extends EventEmitter implements MigratorContract { - private _client = this._db.connection(this._options.connectionName || this._db.primaryConnectionName) - private _config = this._db.getRawConnection(this._client.connectionName)!.config + private client = this.db.connection(this.options.connectionName || this.db.primaryConnectionName) + private config = this.db.getRawConnection(this.client.connectionName)!.config /** * Reference to the migrations config for the given connection */ - private _migrationsConfig = Object.assign({ + private migrationsConfig = Object.assign({ tableName: 'adonis_schema', disableTransactions: false, - }, this._config.migrations) + }, this.config.migrations) /** * Whether or not the migrator has been booted */ - private _booted: boolean = false + private booted: boolean = false /** * Migration source to collect schema files from the disk */ - private _migrationSource = new MigrationSource(this._config, this._app) + private migrationSource = new MigrationSource(this.config, this.app) /** * Mode decides in which mode the migrator is executing migrations. The migrator @@ -61,12 +61,12 @@ export class Migrator extends EventEmitter implements MigratorContract { * * The value is set when `migrate` or `rollback` method is invoked */ - public direction: 'up' | 'down' = this._options.direction + public direction: 'up' | 'down' = this.options.direction /** * Instead of executing migrations, just return the generated SQL queries */ - public dryRun: boolean = !!this._options.dryRun + public dryRun: boolean = !!this.options.dryRun /** * An array of files we have successfully migrated. The files are @@ -83,7 +83,7 @@ export class Migrator extends EventEmitter implements MigratorContract { * Current status of the migrator */ public get status () { - return !this._booted + return !this.booted ? 'pending' : ( this.error @@ -93,9 +93,9 @@ export class Migrator extends EventEmitter implements MigratorContract { } constructor ( - private _db: DatabaseContract, - private _app: ApplicationContract, - private _options: MigratorOptions, + private db: DatabaseContract, + private app: ApplicationContract, + private options: MigratorOptions, ) { super() } @@ -104,7 +104,7 @@ export class Migrator extends EventEmitter implements MigratorContract { * Returns the client for a given schema file. Schema instructions are * wrapped in a transaction unless transaction is not disabled */ - private async _getClient (disableTransactions: boolean) { + private async getClient (disableTransactions: boolean) { /** * We do not create a transaction when * @@ -114,19 +114,19 @@ export class Migrator extends EventEmitter implements MigratorContract { */ if ( disableTransactions || - this._migrationsConfig.disableTransactions || + this.migrationsConfig.disableTransactions || this.dryRun ) { - return this._client + return this.client } - return this._client.transaction() + return this.client.transaction() } /** * Roll back the transaction when it's client is a transaction client */ - private async _rollback (client: QueryClientContract) { + private async rollback (client: QueryClientContract) { if (client.isTransaction) { await (client as TransactionClientContract).rollback() } @@ -135,7 +135,7 @@ export class Migrator extends EventEmitter implements MigratorContract { /** * Commits a transaction when it's client is a transaction client */ - private async _commit (client: QueryClientContract) { + private async commit (client: QueryClientContract) { if (client.isTransaction) { await (client as TransactionClientContract).commit() } @@ -145,7 +145,7 @@ export class Migrator extends EventEmitter implements MigratorContract { * Writes the migrated file to the migrations table. This ensures that * we are not re-running the same migration again */ - private async _recordMigrated ( + private async recordMigrated ( client: QueryClientContract, name: string, executionResponse: boolean | string[], @@ -155,7 +155,7 @@ export class Migrator extends EventEmitter implements MigratorContract { return } - await client.insertQuery().table(this._migrationsConfig.tableName).insert({ + await client.insertQuery().table(this.migrationsConfig.tableName).insert({ name, batch: this.migratedFiles[name].batch, }) @@ -165,7 +165,7 @@ export class Migrator extends EventEmitter implements MigratorContract { * Removes the migrated file from the migrations table. This allows re-running * the migration */ - private async _recordRollback ( + private async recordRollback ( client: QueryClientContract, name: string, executionResponse: boolean | string[], @@ -175,15 +175,15 @@ export class Migrator extends EventEmitter implements MigratorContract { return } - await client.query().from(this._migrationsConfig.tableName).where({ name }).del() + await client.query().from(this.migrationsConfig.tableName).where({ name }).del() } /** * Executes a given migration node and cleans up any created transactions * in case of failure */ - private async _executeMigration (migration: MigrationNode) { - const client = await this._getClient(migration.source.disableTransactions) + private async executeMigration (migration: MigrationNode) { + const client = await this.getClient(migration.source.disableTransactions) try { const schema = new migration.source(client, migration.name, this.dryRun) @@ -191,13 +191,13 @@ export class Migrator extends EventEmitter implements MigratorContract { if (this.direction === 'up') { const response = await schema.execUp() // Handles dry run itself - await this._recordMigrated(client, migration.name, response) // Handles dry run itself + await this.recordMigrated(client, migration.name, response) // Handles dry run itself } else if (this.direction === 'down') { const response = await schema.execDown() // Handles dry run itself - await this._recordRollback(client, migration.name, response) // Handles dry run itself + await this.recordRollback(client, migration.name, response) // Handles dry run itself } - await this._commit(client) + await this.commit(client) this.migratedFiles[migration.name].status = 'completed' this.emit('migration:completed', this.migratedFiles[migration.name]) } catch (error) { @@ -205,7 +205,7 @@ export class Migrator extends EventEmitter implements MigratorContract { this.migratedFiles[migration.name].status = 'error' this.emit('migration:error', this.migratedFiles[migration.name]) - await this._rollback(client) + await this.rollback(client) throw error } } @@ -220,12 +220,12 @@ export class Migrator extends EventEmitter implements MigratorContract { * Locks are always acquired in dry run too, since we want to stay close * to the real execution cycle */ - private async _acquireLock () { - if (!this._client.dialect.supportsAdvisoryLocks) { + private async acquireLock () { + if (!this.client.dialect.supportsAdvisoryLocks) { return } - const acquired = await this._client.dialect.getAdvisoryLock(1) + const acquired = await this.client.dialect.getAdvisoryLock(1) if (!acquired) { throw new Exception('Unable to acquire lock. Concurrent migrations are not allowed') } @@ -236,12 +236,12 @@ export class Migrator extends EventEmitter implements MigratorContract { * Release a lock once complete the migration process. Only works with * `Mysql`, `PostgreSQL` and `MariaDb` for now. */ - private async _releaseLock () { - if (!this._client.dialect.supportsAdvisoryLocks) { + private async releaseLock () { + if (!this.client.dialect.supportsAdvisoryLocks) { return } - const released = await this._client.dialect.releaseAdvisoryLock(1) + const released = await this.client.dialect.releaseAdvisoryLock(1) if (!released) { throw new Exception('Migration completed, but unable to release database lock') } @@ -253,16 +253,16 @@ export class Migrator extends EventEmitter implements MigratorContract { * we always reads from the schema table to find which migrations files to * execute and that cannot done without missing table. */ - private async _makeMigrationsTable () { - const client = this._client + private async makeMigrationsTable () { + const client = this.client - const hasTable = await client.schema.hasTable(this._migrationsConfig.tableName) + const hasTable = await client.schema.hasTable(this.migrationsConfig.tableName) if (hasTable) { return } this.emit('create:schema:table') - await client.schema.createTable(this._migrationsConfig.tableName, (table) => { + await client.schema.createTable(this.migrationsConfig.tableName, (table) => { table.increments().notNullable() table.string('name').notNullable() table.integer('batch').notNullable() @@ -274,9 +274,9 @@ export class Migrator extends EventEmitter implements MigratorContract { * Returns the latest batch from the migrations * table */ - private async _getLatestBatch () { - const rows = await this._client - .from(this._migrationsConfig.tableName) + private async getLatestBatch () { + const rows = await this.client + .from(this.migrationsConfig.tableName) .max('batch as batch') return Number(rows[0].batch) @@ -285,10 +285,10 @@ export class Migrator extends EventEmitter implements MigratorContract { /** * Returns an array of files migrated till now */ - private async _getMigratedFiles () { - const rows = await this._client + private async getMigratedFiles () { + const rows = await this.client .query<{ name: string }[]>() - .from(this._migrationsConfig.tableName) + .from(this.migrationsConfig.tableName) .select('name') return new Set(rows.map(({ name }) => name)) @@ -298,10 +298,10 @@ export class Migrator extends EventEmitter implements MigratorContract { * Returns an array of files migrated till now. The latest * migrations are on top */ - private async _getMigratedFilesTillBatch (batch: number) { - return this._client + private async getMigratedFilesTillBatch (batch: number) { + return this.client .query<{ name: string, batch: number, migration_time: Date }[]>() - .from(this._migrationsConfig.tableName) + .from(this.migrationsConfig.tableName) .select('name', 'batch', 'migration_time') .where('batch', '>', batch) .orderBy('id', 'desc') @@ -311,27 +311,27 @@ export class Migrator extends EventEmitter implements MigratorContract { * Boot the migrator to perform actions. All boot methods must * work regardless of dryRun is enabled or not. */ - private async _boot () { + private async boot () { this.emit('start') - this._booted = true - await this._acquireLock() - await this._makeMigrationsTable() + this.booted = true + await this.acquireLock() + await this.makeMigrationsTable() } /** * Shutdown gracefully */ - private async _shutdown () { - await this._releaseLock() + private async shutdown () { + await this.releaseLock() } /** * Migrate up */ - private async _runUp () { - const batch = await this._getLatestBatch() - const existing = await this._getMigratedFiles() - const collected = await this._migrationSource.getMigrations() + private async runUp () { + const batch = await this.getLatestBatch() + const existing = await this.getMigratedFiles() + const collected = await this.migrationSource.getMigrations() /** * Upfront collecting the files to be executed @@ -349,20 +349,20 @@ export class Migrator extends EventEmitter implements MigratorContract { const filesToMigrate = Object.keys(this.migratedFiles) for (let name of filesToMigrate) { - await this._executeMigration(this.migratedFiles[name].migration) + await this.executeMigration(this.migratedFiles[name].migration) } } /** * Migrate down (aka rollback) */ - private async _runDown (batch?: number) { + private async runDown (batch?: number) { if (batch === undefined) { - batch = await this._getLatestBatch() - 1 + batch = await this.getLatestBatch() - 1 } - const existing = await this._getMigratedFilesTillBatch(batch) - const collected = await this._migrationSource.getMigrations() + const existing = await this.getMigratedFilesTillBatch(batch) + const collected = await this.migrationSource.getMigrations() /** * Finding schema files for migrations to rollback. We do not perform @@ -388,7 +388,7 @@ export class Migrator extends EventEmitter implements MigratorContract { const filesToMigrate = Object.keys(this.migratedFiles) for (let name of filesToMigrate) { - await this._executeMigration(this.migratedFiles[name].migration) + await this.executeMigration(this.migratedFiles[name].migration) } } @@ -408,8 +408,8 @@ export class Migrator extends EventEmitter implements MigratorContract { */ public async getList (): Promise { const existingCollected: Set = new Set() - const existing = await this._getMigratedFilesTillBatch(0) - const collected = await this._migrationSource.getMigrations() + const existing = await this.getMigratedFilesTillBatch(0) + const collected = await this.migrationSource.getMigrations() const list: MigrationListNode[] = collected.map((migration) => { const migrated = existing.find(({ name }) => migration.name === name) @@ -452,24 +452,24 @@ export class Migrator extends EventEmitter implements MigratorContract { */ public async run () { try { - await this._boot() + await this.boot() if (this.direction === 'up') { - await this._runUp() - } else if (this._options.direction === 'down') { - await this._runDown(this._options.batch) + await this.runUp() + } else if (this.options.direction === 'down') { + await this.runDown(this.options.batch) } } catch (error) { this.error = error } - await this._shutdown() + await this.shutdown() } /** * Close database connections */ public async close () { - await this._db.manager.closeAll(true) + await this.db.manager.closeAll(true) } } diff --git a/src/Orm/Adapter/index.ts b/src/Orm/Adapter/index.ts index b92ee515..2beccb6a 100644 --- a/src/Orm/Adapter/index.ts +++ b/src/Orm/Adapter/index.ts @@ -22,7 +22,7 @@ import { * model instances from it. */ export class Adapter implements AdapterContract { - constructor (private _db: DatabaseContract) { + constructor (private db: DatabaseContract) { } /** @@ -38,7 +38,7 @@ export class Adapter implements AdapterContract { const connection = options && options.connection || modelConstructor.$connection const profiler = options && options.profiler - return this._db.connection(connection, { profiler }) + return this.db.connection(connection, { profiler }) } /** diff --git a/src/Orm/Hooks/index.ts b/src/Orm/Hooks/index.ts index dec70569..a1e11526 100644 --- a/src/Orm/Hooks/index.ts +++ b/src/Orm/Hooks/index.ts @@ -16,7 +16,7 @@ import { IocContract, IocResolverContract, IocResolverLookupNode } from '@adonis * A generic class to implement before and after lifecycle hooks */ export class Hooks { - private _hooks: { + private hooks: { [event: string]: { before: Set, string> | IocResolverLookupNode>, after: Set, string> | IocResolverLookupNode>, @@ -26,17 +26,17 @@ export class Hooks { /** * Resolver to resolve IoC container bindings */ - private _resolver: IocResolverContract + private resolver: IocResolverContract constructor (container: IocContract) { - this._resolver = container.getResolver(undefined, 'modelHooks', 'App/Models/Hooks') + this.resolver = container.getResolver(undefined, 'modelHooks', 'App/Models/Hooks') } /** * Add hook for a given event and lifecycle */ public add (lifecycle: 'before' | 'after', event: EventsList, handler: HooksHandler) { - this._hooks[event] = this._hooks[event] || { before: new Set(), after: new Set() } + this.hooks[event] = this.hooks[event] || { before: new Set(), after: new Set() } let resolvedHook @@ -44,12 +44,12 @@ export class Hooks { * If hook is a string, then resolve it from the container */ if (typeof (handler) === 'string') { - resolvedHook = this._resolver.resolve(handler) + resolvedHook = this.resolver.resolve(handler) } else { resolvedHook = handler } - this._hooks[event][lifecycle].add(resolvedHook) + this.hooks[event][lifecycle].add(resolvedHook) return this } @@ -57,15 +57,15 @@ export class Hooks { * Execute hooks for a given event and lifecycle */ public async execute (lifecycle: 'before' | 'after', event: EventsList, payload: any): Promise { - if (!this._hooks[event]) { + if (!this.hooks[event]) { return } - for (let hook of this._hooks[event][lifecycle]) { + for (let hook of this.hooks[event][lifecycle]) { if (typeof (hook) === 'function') { await hook(payload) } else { - await this._resolver.call(hook, undefined, [payload]) + await this.resolver.call(hook, undefined, [payload]) } } } @@ -74,17 +74,17 @@ export class Hooks { * Remove hooks for a given event */ public clear (event: EventsList): void { - if (!this._hooks[event]) { + if (!this.hooks[event]) { return } - delete this._hooks[event] + delete this.hooks[event] } /** * Remove all hooks */ public clearAll (): void { - this._hooks = {} + this.hooks = {} } } diff --git a/src/Orm/QueryBuilder/index.ts b/src/Orm/QueryBuilder/index.ts index 9b23098f..9ea1e803 100644 --- a/src/Orm/QueryBuilder/index.ts +++ b/src/Orm/QueryBuilder/index.ts @@ -39,7 +39,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * or not, since we don't transform return types of non-select * queries */ - private _isSelectQuery: boolean = true + private isSelectQuery: boolean = true /** * Sideloaded attributes that will be passed to the model instances @@ -49,7 +49,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon /** * A copy of defined preloads on the model instance */ - private _preloader = new Preloader(this.model) + private preloader = new Preloader(this.model) /** * Required by macroable @@ -84,7 +84,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Ensures that we are not executing `update` or `del` when using read only * client */ - private _ensureCanPerformWrites () { + private ensureCanPerformWrites () { if (this.client && this.client.mode === 'read') { throw new Exception('Updates and deletes cannot be performed in read mode') } @@ -95,7 +95,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon */ public async beforeExecute () { if (['update', 'del'].includes(this.$knexBuilder['_method'])) { - this._isSelectQuery = false + this.isSelectQuery = false } } @@ -104,7 +104,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Executable trait. */ public async afterExecute (rows: any[]): Promise { - if (!this._isSelectQuery) { + if (!this.isSelectQuery) { return Array.isArray(rows) ? rows : [rows] } @@ -114,7 +114,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon this.clientOptions, ) - await this._preloader.sideload(this.sideloaded).processAllForMany(modelInstances, this.client) + await this.preloader.sideload(this.sideloaded).processAllForMany(modelInstances, this.client) return modelInstances } @@ -159,7 +159,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Define a relationship to be preloaded */ public preload (relationName: any, userCallback?: any): this { - this._preloader.preload(relationName, userCallback) + this.preloader.preload(relationName, userCallback) return this } @@ -172,7 +172,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Use write client for updates and deletes */ if (['update', 'del'].includes(this.$knexBuilder['_method'])) { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() return this.client!.getWriteClient().client } @@ -199,7 +199,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * can be clubbed with `update` as well */ public increment (column: any, counter?: any): any { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.increment(column, counter) return this } @@ -209,7 +209,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * can be clubbed with `update` as well */ public decrement (column: any, counter?: any): any { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.decrement(column, counter) return this } @@ -218,7 +218,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Perform update */ public update (columns: any): any { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.update(columns) return this } @@ -227,7 +227,7 @@ export class ModelQueryBuilder extends Chainable implements ModelQueryBuilderCon * Delete rows under the current query */ public del (): any { - this._ensureCanPerformWrites() + this.ensureCanPerformWrites() this.$knexBuilder.del() return this } diff --git a/src/QueryClient/index.ts b/src/QueryClient/index.ts index 3e57234d..2b1bf834 100644 --- a/src/QueryClient/index.ts +++ b/src/QueryClient/index.ts @@ -36,17 +36,15 @@ import { dialects } from '../Dialects' * it doesn't real matter what are the return types from this class */ export class QueryClient implements QueryClientContract { - private _dialect: DialectContract - /** * Not a transaction client */ public readonly isTransaction = false /** - * The name of the dialect in use + * The dialect in use */ - public dialect = new (dialects[resolveClientNameWithAliases(this._connection.config.client)])(this) + public dialect: DialectContract = new (dialects[resolveClientNameWithAliases(this.connection.config.client)])(this) /** * The profiler to be used for profiling queries @@ -56,11 +54,11 @@ export class QueryClient implements QueryClientContract { /** * Name of the connection in use */ - public readonly connectionName = this._connection.name + public readonly connectionName = this.connection.name constructor ( public readonly mode: 'dual' | 'write' | 'read', - private _connection: ConnectionContract, + private connection: ConnectionContract, ) { } @@ -77,10 +75,10 @@ export class QueryClient implements QueryClientContract { */ public getReadClient (): knex { if (this.mode === 'read' || this.mode === 'dual') { - return this._connection.readClient! + return this.connection.readClient! } - return this._connection.client! + return this.connection.client! } /** @@ -88,7 +86,7 @@ export class QueryClient implements QueryClientContract { */ public getWriteClient (): knex { if (this.mode === 'write' || this.mode === 'dual') { - return this._connection.client! + return this.connection.client! } throw new Exception( @@ -134,7 +132,7 @@ export class QueryClient implements QueryClientContract { * Returns the knex query builder instance */ public knexQuery (): knex.QueryBuilder { - return this._connection.client!.queryBuilder() + return this.connection.client!.queryBuilder() } /** @@ -165,7 +163,7 @@ export class QueryClient implements QueryClientContract { * Returns instance of raw query builder */ public raw (sql: any, bindings?: any): any { - return new RawQueryBuilder(this._connection.client!.raw(sql, bindings), this) + return new RawQueryBuilder(this.connection.client!.raw(sql, bindings), this) } /** @@ -183,11 +181,17 @@ export class QueryClient implements QueryClientContract { return this.insertQuery().table(table) } + /** + * Get advisory lock on the selected connection + */ public getAdvisoryLock (key: string, timeout?: number): any { - return this._dialect.getAdvisoryLock(key, timeout) + return this.dialect.getAdvisoryLock(key, timeout) } + /** + * Release advisory lock + */ public releaseAdvisoryLock (key: string): any { - return this._dialect.releaseAdvisoryLock(key) + return this.dialect.releaseAdvisoryLock(key) } } diff --git a/src/Schema/index.ts b/src/Schema/index.ts index a36282e1..98d85a77 100644 --- a/src/Schema/index.ts +++ b/src/Schema/index.ts @@ -23,12 +23,12 @@ export class Schema implements SchemaContract { * All calls to `schema` and `defer` are tracked to be * executed later */ - private _trackedCalls: (SchemaBuilder | DeferCallback)[] = [] + private trackedCalls: (SchemaBuilder | DeferCallback)[] = [] /** - * The lifecycle method that was invoked + * The state of the schema. It cannot be re-executed after completion */ - private _isFresh: boolean = true + private state: 'pending' | 'completed' = 'pending' /** * Enable/disable transactions for this schema @@ -40,7 +40,7 @@ export class Schema implements SchemaContract { */ public get schema () { const schema = this.db.schema - this._trackedCalls.push(schema) + this.trackedCalls.push(schema) return schema } @@ -53,8 +53,8 @@ export class Schema implements SchemaContract { /** * Returns schema queries sql without executing them */ - private _getQueries (): string[] { - return this._trackedCalls + private getQueries (): string[] { + return this.trackedCalls .filter((schema) => typeof (schema['toQuery']) === 'function') .map((schema) => (schema as SchemaBuilder).toQuery()) } @@ -62,8 +62,8 @@ export class Schema implements SchemaContract { /** * Executes schema queries and defer calls in sequence */ - private async _executeQueries () { - for (let trackedCall of this._trackedCalls) { + private async executeQueries () { + for (let trackedCall of this.trackedCalls) { if (typeof (trackedCall) === 'function') { await trackedCall(this.db) } else { @@ -87,7 +87,7 @@ export class Schema implements SchemaContract { * schema is invoked to return the SQL queries */ public defer (cb: DeferCallback): void { - this._trackedCalls.push(cb) + this.trackedCalls.push(cb) } /** @@ -95,18 +95,18 @@ export class Schema implements SchemaContract { * when `dryRun` is set to true */ public async execUp () { - if (!this._isFresh) { + if (this.state === 'completed') { throw new Exception('Cannot execute a given schema twice') } await this.up() - this._isFresh = false + this.state = 'completed' if (this.dryRun) { - return this._getQueries() + return this.getQueries() } - await this._executeQueries() + await this.executeQueries() return true } @@ -115,18 +115,18 @@ export class Schema implements SchemaContract { * when `dryRun` is set to true */ public async execDown () { - if (!this._isFresh) { + if (this.state === 'completed') { throw new Exception('Cannot execute a given schema twice') } await this.down() - this._isFresh = false + this.state = 'completed' if (this.dryRun) { - return this._getQueries() + return this.getQueries() } - await this._executeQueries() + await this.executeQueries() return true } diff --git a/src/Traits/Executable.ts b/src/Traits/Executable.ts index 5205d8e2..3163794b 100644 --- a/src/Traits/Executable.ts +++ b/src/Traits/Executable.ts @@ -46,7 +46,7 @@ export class Executable implements ExcutableQueryBuilderContract { /** * Ends the profile action */ - private _endProfilerAction (action: null | ProfilerActionContract, error?: any) { + private endProfilerAction (action: null | ProfilerActionContract, error?: any) { if (!action) { return } @@ -57,15 +57,15 @@ export class Executable implements ExcutableQueryBuilderContract { /** * Executes the knex query builder */ - private async _executeQuery () { + private async executeQuery () { const action = this.getProfilerAction() try { const result = await this.$knexBuilder - this._endProfilerAction(action) + this.endProfilerAction(action) return result } catch (error) { - this._endProfilerAction(action, error) + this.endProfilerAction(action, error) throw error } } @@ -74,7 +74,7 @@ export class Executable implements ExcutableQueryBuilderContract { * Executes the query by acquiring a connection from a custom * knex client */ - private async _executeQueryWithCustomConnection (knexClient: knex) { + private async executeQueryWithCustomConnection (knexClient: knex) { const action = this.getProfilerAction() /** @@ -94,10 +94,10 @@ export class Executable implements ExcutableQueryBuilderContract { */ try { queryResult = await this.$knexBuilder - this._endProfilerAction(action) + this.endProfilerAction(action) } catch (error) { queryError = error - this._endProfilerAction(action, error) + this.endProfilerAction(action, error) } /** @@ -179,13 +179,13 @@ export class Executable implements ExcutableQueryBuilderContract { || this.client.isTransaction || this.$knexBuilder['client'].transacting ) { - result = await this._executeQuery() + result = await this.executeQuery() } else { const knexClient = this.getQueryClient() if (knexClient) { - result = await this._executeQueryWithCustomConnection(knexClient) + result = await this.executeQueryWithCustomConnection(knexClient) } else { - result = await this._executeQuery() + result = await this.executeQuery() } } diff --git a/src/TransactionClient/index.ts b/src/TransactionClient/index.ts index 0b5be9f4..83c52cd0 100644 --- a/src/TransactionClient/index.ts +++ b/src/TransactionClient/index.ts @@ -187,4 +187,18 @@ export class TransactionClient extends EventEmitter implements TransactionClient throw error } } + + /** + * Get advisory lock on the selected connection + */ + public getAdvisoryLock (key: string, timeout?: number): any { + return this.dialect.getAdvisoryLock(key, timeout) + } + + /** + * Release advisory lock + */ + public releaseAdvisoryLock (key: string): any { + return this.dialect.releaseAdvisoryLock(key) + } } diff --git a/test/connection/connection-manager.spec.ts b/test/connection/connection-manager.spec.ts index 366bfb02..443cf080 100644 --- a/test/connection/connection-manager.spec.ts +++ b/test/connection/connection-manager.spec.ts @@ -167,7 +167,7 @@ test.group('ConnectionManager', (group) => { manager.on('disconnect', async (connection) => { try { assert.deepEqual(connection, connections[0]) - assert.equal(manager['_orphanConnections'].size, 0) + assert.equal(manager['orphanConnections'].size, 0) assert.deepEqual(mapToObj(manager.connections), { primary: { config: connection.config,