UNPKG

24.8 kBTypeScriptView Raw
1/// <reference path="querybuilder.d.ts" />
2/// <reference types="@adonisjs/events/build/adonis-typings" />
3/// <reference types="@adonisjs/profiler/build/adonis-typings/profiler" />
4/// <reference types="node" />
5/// <reference types="@adonisjs/logger/build/adonis-typings/logger" />
6declare module '@ioc:Adonis/Lucid/Database' {
7 import { Knex } from 'knex';
8 import { Pool } from 'tarn';
9 import { EventEmitter } from 'events';
10 import { ConnectionOptions } from 'tls';
11 import { EmitterContract } from '@ioc:Adonis/Core/Event';
12 import { MacroableConstructorContract } from 'macroable';
13 import { LoggerContract } from '@ioc:Adonis/Core/Logger';
14 import { HealthReportEntry } from '@ioc:Adonis/Core/HealthCheck';
15 import { LucidModel, ModelQueryBuilderContract } from '@ioc:Adonis/Lucid/Orm';
16 import { ProfilerRowContract, ProfilerContract } from '@ioc:Adonis/Core/Profiler';
17 /**
18 * Same as knex. Need to redefine, as knex doesn't export this
19 * type
20 */
21 export type IsolationLevels = 'read uncommitted' | 'read committed' | 'snapshot' | 'repeatable read' | 'serializable';
22 /**
23 * Migration node returned by the migration source
24 * implementation
25 */
26 export type FileNode<T> = {
27 filename?: string;
28 absPath: string;
29 name: string;
30 getSource: () => T;
31 };
32 /**
33 * Dialect specfic methods
34 */
35 export interface DialectContract {
36 readonly name: 'mssql' | 'mysql' | 'oracledb' | 'postgres' | 'redshift' | 'sqlite3';
37 readonly version?: string;
38 readonly supportsAdvisoryLocks: boolean;
39 readonly dateTimeFormat: string;
40 getAllTables(schemas?: string[]): Promise<string[]>;
41 dropAllTables(schemas?: string[]): Promise<void>;
42 truncate(table: string, cascade?: boolean): Promise<void>;
43 getAdvisoryLock(key: string | number, timeout?: number): Promise<boolean>;
44 releaseAdvisoryLock(key: string | number): Promise<boolean>;
45 }
46 /**
47 * Shape of the transaction function to create a new transaction
48 */
49 export interface TransactionFn {
50 <T>(callback: (trx: TransactionClientContract) => Promise<T>, options?: {
51 isolationLevel?: IsolationLevels;
52 }): Promise<T>;
53 (options?: {
54 isolationLevel?: IsolationLevels;
55 }): Promise<TransactionClientContract>;
56 }
57 /**
58 * Shape of the query client, that is used to retrive instances
59 * of query builder
60 */
61 export interface QueryClientContract {
62 emitter: EmitterContract;
63 /**
64 * Custom profiler to time queries
65 */
66 profiler?: ProfilerRowContract | ProfilerContract;
67 /**
68 * Tells if client is a transaction client or not
69 */
70 readonly isTransaction: boolean;
71 /**
72 * The database dialect in use
73 */
74 readonly dialect: DialectContract;
75 /**
76 * The client mode in which it is execute queries
77 */
78 readonly mode: 'dual' | 'write' | 'read';
79 /**
80 * The name of the connnection from which the client
81 * was originated
82 */
83 readonly connectionName: string;
84 /**
85 * Is debug enabled on the connnection or not. Also opens up the API to
86 * disable debug for a given client
87 */
88 debug: boolean;
89 /**
90 * Returns schema instance for the write client
91 */
92 schema: Knex.SchemaBuilder;
93 /**
94 * Returns the read and write clients
95 */
96 getReadClient(): Knex<any, any>;
97 getWriteClient(): Knex<any, any>;
98 /**
99 * Returns the query builder for a given model
100 */
101 modelQuery<T extends LucidModel, Result = T>(model: T): ModelQueryBuilderContract<T, Result>;
102 /**
103 * Returns the knex query builder instance
104 */
105 knexQuery(): Knex.QueryBuilder;
106 /**
107 * Returns the knex raw query builder instance
108 */
109 knexRawQuery(sql: string, bindings?: RawQueryBindings): Knex.Raw;
110 /**
111 * Get new query builder instance for select, update and
112 * delete calls
113 */
114 query<Result = any>(): DatabaseQueryBuilderContract<Result>;
115 /**
116 * Get new query builder instance inserts
117 */
118 insertQuery<ReturnColumns = any>(): InsertQueryBuilderContract<ReturnColumns[]>;
119 /**
120 * Get raw query builder instance
121 */
122 rawQuery<Result = any>(sql: string, bindings?: RawQueryBindings): RawQueryBuilderContract<Result>;
123 /**
124 * Returns instance of reference builder
125 */
126 ref(reference: string): ReferenceBuilderContract;
127 /**
128 * Returns instance of raw builder
129 */
130 raw(sql: string, bindings?: RawQueryBindings): RawBuilderContract;
131 /**
132 * Truncate a given table
133 */
134 truncate(table: string, cascade?: boolean): Promise<void>;
135 /**
136 * Returns columns info for a given table
137 */
138 columnsInfo(table: string): Promise<{
139 [column: string]: Knex.ColumnInfo;
140 }>;
141 columnsInfo(table: string, column: string): Promise<Knex.ColumnInfo>;
142 /**
143 * Get all tables of the database
144 */
145 getAllTables(schemas?: string[]): Promise<string[]>;
146 /**
147 * Same as `query()`, but also selects the table for the query. The `from` method
148 * doesn't allow defining the return type and one must use `query` to define
149 * that.
150 */
151 from: FromTable<DatabaseQueryBuilderContract<any>>;
152 /**
153 * Same as `insertQuery()`, but also selects the table for the query.
154 * The `table` method doesn't allow defining the return type and
155 * one must use `insertQuery` to define that.
156 */
157 table: (table: string) => InsertQueryBuilderContract<any>;
158 /**
159 * Get instance of transaction client
160 */
161 transaction: TransactionFn;
162 /**
163 * Work with advisory locks
164 */
165 getAdvisoryLock(key: string | number, timeout?: number): Promise<boolean>;
166 releaseAdvisoryLock(key: string | number): Promise<boolean>;
167 }
168 /**
169 * The shape of transaction client to run queries under a given
170 * transaction on a single connection
171 */
172 export interface TransactionClientContract extends QueryClientContract, EventEmitter {
173 knexClient: Knex.Transaction;
174 /**
175 * Custom profiler to time queries
176 */
177 profiler?: ProfilerRowContract;
178 /**
179 * Is transaction completed or not
180 */
181 isCompleted: boolean;
182 /**
183 * Commit transaction
184 */
185 commit(): Promise<void>;
186 /**
187 * Rollback transaction
188 */
189 rollback(): Promise<void>;
190 /**
191 * Returns the read and write transaction clients
192 */
193 getReadClient(): Knex.Transaction<any, any>;
194 getWriteClient(): Knex.Transaction<any, any>;
195 /**
196 * Transaction named events
197 */
198 on(event: 'commit', handler: (client: this) => void): this;
199 on(event: 'rollback', handler: (client: this) => void): this;
200 once(event: 'commit', handler: (client: this) => void): this;
201 once(event: 'rollback', handler: (client: this) => void): this;
202 after(event: 'rollback' | 'commit', handler: () => void | Promise<void>): this;
203 }
204 /**
205 * Connection node used by majority of database
206 * clients
207 */
208 type SharedConnectionNode = {
209 host?: string;
210 user?: string;
211 password?: string;
212 database?: string;
213 port?: number;
214 };
215 /**
216 * Shape of the report node for the database connection report
217 */
218 export type ReportNode = {
219 connection: string;
220 message: string;
221 error: any;
222 };
223 /**
224 * Migrations config
225 */
226 export type MigratorConfig = {
227 disableTransactions?: boolean;
228 paths?: string[];
229 tableName?: string;
230 disableRollbacksInProduction?: boolean;
231 naturalSort?: boolean;
232 };
233 /**
234 * Seeders config
235 */
236 export type SeedersConfig = {
237 paths: string[];
238 };
239 /**
240 * Shared config options for all clients
241 */
242 type SharedConfigNode = {
243 useNullAsDefault?: boolean;
244 debug?: boolean;
245 asyncStackTraces?: boolean;
246 revision?: number;
247 healthCheck?: boolean;
248 migrations?: MigratorConfig;
249 seeders?: SeedersConfig;
250 pool?: {
251 afterCreate?: (conn: any, done: any) => void;
252 min?: number;
253 max?: number;
254 acquireTimeoutMillis?: number;
255 createTimeoutMillis?: number;
256 idleTimeoutMillis?: number;
257 createRetryIntervalMillis?: number;
258 reapIntervalMillis?: number;
259 log?: (msg: string) => any;
260 validate?: (resource: any) => boolean;
261 propagateCreateError?: boolean;
262 };
263 };
264 /**
265 * The Sqlite specific config options are taken directly from the
266 * driver. https://github.com/mapbox/node-sqlite3/wiki/API#new-sqlite3databasefilename-mode-callback
267 *
268 * Knex forwards all config options to the driver directly. So feel
269 * free to define them (let us know, in case any options are missing)
270 */
271 export type SqliteConfig = SharedConfigNode & {
272 client: 'sqlite' | 'sqlite3';
273 connection: {
274 filename: string;
275 flags?: string[];
276 debug?: boolean;
277 mode?: any;
278 };
279 replicas?: never;
280 };
281 /**
282 * The MYSQL specific config options are taken directly from the
283 * driver. https://www.npmjs.com/package/mysql#connection-options
284 *
285 * Knex forwards all config options to the driver directly. So feel
286 * free to define them (let us know, in case any options are missing)
287 */
288 type MysqlConnectionNode = {
289 socketPath?: string;
290 localAddress?: string;
291 charset?: string;
292 timezone?: string;
293 stringifyObjects?: boolean;
294 insecureAuth?: boolean;
295 typeCast?: boolean;
296 supportBigNumbers?: boolean;
297 bigNumberStrings?: boolean;
298 dateStrings?: boolean | string[];
299 flags?: string;
300 ssl?: any;
301 };
302 export type MysqlConfig = SharedConfigNode & {
303 client: 'mysql' | 'mysql2';
304 version?: string;
305 connection?: SharedConnectionNode & MysqlConnectionNode;
306 replicas?: {
307 write: {
308 connection: MysqlConfig['connection'];
309 pool?: MysqlConfig['pool'];
310 };
311 read: {
312 connection: MysqlConfig['connection'][];
313 pool?: MysqlConfig['pool'];
314 };
315 };
316 };
317 /**
318 * Config is picked from PostgreSQL driver, just refer their docs
319 * https://node-postgres.com/features/connecting#programmatic.
320 *
321 * - `returning` is added by knex and not driver.
322 * - `searchPath` is also added by Knex.
323 *
324 * Knex forwards all config options to the driver directly. So feel
325 * free to define them (let us know, in case any options are missing)
326 */
327 type PostgresConnectionNode = {
328 ssl?: boolean | ConnectionOptions;
329 };
330 export type PostgreConfig = SharedConfigNode & {
331 client: 'pg' | 'postgres' | 'postgresql';
332 version?: string;
333 returning?: string;
334 connection?: string | (SharedConnectionNode & PostgresConnectionNode);
335 replicas?: {
336 write: {
337 connection: PostgreConfig['connection'];
338 pool?: PostgreConfig['pool'];
339 };
340 read: {
341 connection: PostgreConfig['connection'][];
342 pool?: PostgreConfig['pool'];
343 };
344 };
345 searchPath?: string[];
346 };
347 /**
348 * Redshift uses `pg` driver. So config options are same as Postgres.
349 * https://node-postgres.com/features/connecting#programmatic.
350 *
351 * Knex forwards all config options to the driver directly. So feel
352 * free to define them (let us know, in case any options are missing)
353 */
354 export type RedshiftConfig = PostgreConfig & {
355 client: 'redshift';
356 };
357 /**
358 * Please install `oracledb` driver and not the `oracle`. The later is
359 * deprecated. Config is only allowed for `oracledb`.
360 *
361 * Please refer to the driver configuration docs to learn more about the
362 * config values.
363 * https://oracle.github.io/node-oracledb/doc/api.html#oracledbproperties
364 */
365 type OracleConnectionNode = {
366 autoCommit?: boolean;
367 connectionClass?: string;
368 edition?: string;
369 externalAuth?: boolean;
370 fetchArraySize?: number;
371 fetchAsBuffer?: any[];
372 lobPrefetchSize?: number;
373 maxRows?: number;
374 oracleClientVersion?: number;
375 };
376 export type OracleConfig = SharedConfigNode & {
377 client: 'oracledb';
378 connection?: SharedConnectionNode & OracleConnectionNode;
379 replicas?: {
380 write: {
381 connection: OracleConfig['connection'];
382 pool?: OracleConfig['pool'];
383 };
384 read: {
385 connection: OracleConfig['connection'][];
386 pool?: OracleConfig['pool'];
387 };
388 };
389 fetchAsString?: any[];
390 };
391 /**
392 * Config values are taken directly from the driver config.
393 * https://www.npmjs.com/package/mssql#config.
394 *
395 * Knex forwards all config options to the driver directly. So feel
396 * free to define them (let us know, in case any options are missing)
397 */
398 type MssqlConnectionNode = {
399 server: string;
400 domain?: string;
401 connectionTimeout?: number;
402 requestTimeout?: number;
403 parseJSON?: boolean;
404 options?: {
405 encrypt?: boolean;
406 useUTC?: boolean;
407 tdsVersion?: string;
408 appName?: string;
409 abortTransactionOnError?: boolean;
410 trustedConnection?: boolean;
411 enableArithAbort?: boolean;
412 isolationLevel?: 'READ_UNCOMMITTED' | 'READ_COMMITTED' | 'REPEATABLE_READ' | 'SERIALIZABLE' | 'SNAPSHOT';
413 maxRetriesOnTransientErrors?: number;
414 multiSubnetFailover?: boolean;
415 packetSize?: number;
416 trustServerCertificate?: boolean;
417 };
418 };
419 export type MssqlConfig = SharedConfigNode & {
420 client: 'mssql';
421 version?: string;
422 connection?: SharedConnectionNode & MssqlConnectionNode;
423 replicas?: {
424 write: {
425 connection: MssqlConfig['connection'];
426 pool?: MssqlConfig['pool'];
427 };
428 read: {
429 connection: MssqlConfig['connection'][];
430 pool?: MssqlConfig['pool'];
431 };
432 };
433 };
434 /**
435 * Connection config must be the config from one of the
436 * available dialects
437 */
438 export type ConnectionConfig = SqliteConfig | MysqlConfig | PostgreConfig | OracleConfig | RedshiftConfig | MssqlConfig;
439 /**
440 * Shape of config inside the database config file
441 */
442 export type DatabaseConfig = {
443 connection: string;
444 connections: {
445 [key: string]: ConnectionConfig;
446 };
447 };
448 /**
449 * The shape of a connection within the connection manager
450 */
451 export type ConnectionNode = {
452 name: string;
453 config: ConnectionConfig;
454 connection?: ConnectionContract;
455 state: 'registered' | 'migrating' | 'open' | 'closing' | 'closed';
456 };
457 /**
458 * Connection manager to manage one or more database
459 * connections.
460 */
461 export interface ConnectionManagerContract {
462 /**
463 * List of registered connection. You must check the connection state
464 * to understand, if it is connected or not
465 */
466 connections: Map<string, ConnectionNode>;
467 /**
468 * Add a new connection to the list of managed connection. You must call
469 * connect seperately to instantiate a connection instance
470 */
471 add(connectionName: string, config: ConnectionConfig): void;
472 /**
473 * Instantiate a connection. It is a noop, when connection for the given
474 * name is already instantiated
475 */
476 connect(connectionName: string): void;
477 /**
478 * Get connection node
479 */
480 get(connectionName: string): ConnectionNode | undefined;
481 /**
482 * Find if a connection name is managed by the manager or not
483 */
484 has(connectionName: string): boolean;
485 /**
486 * Patch the existing connection config. This triggers the disconnect on the
487 * old connection
488 */
489 patch(connectionName: string, config: ConnectionConfig): void;
490 /**
491 * Find if a managed connection is instantiated or not
492 */
493 isConnected(connectionName: string): boolean;
494 /**
495 * Close a given connection. This is also kill the underlying knex connection
496 * pool
497 */
498 close(connectionName: string, release?: boolean): Promise<void>;
499 /**
500 * Close all managed connections
501 */
502 closeAll(release?: boolean): Promise<void>;
503 /**
504 * Release a given connection. Releasing a connection means, you will have to
505 * re-add it using the `add` method
506 */
507 release(connectionName: string): Promise<void>;
508 /**
509 * Returns the health check report for registered connections
510 */
511 report(): Promise<HealthReportEntry & {
512 meta: ReportNode[];
513 }>;
514 }
515 /**
516 * Connection represents a single knex instance with inbuilt
517 * pooling capabilities.
518 */
519 export interface ConnectionContract extends EventEmitter {
520 client?: Knex;
521 readClient?: Knex;
522 readonly dialectName: 'mssql' | 'mysql' | 'mysql2' | 'oracledb' | 'postgres' | 'redshift' | 'sqlite3';
523 /**
524 * Property to find if explicit read/write is enabled
525 */
526 readonly hasReadWriteReplicas: boolean;
527 /**
528 * Read/write connection pools
529 */
530 pool: null | Pool<any>;
531 readPool: null | Pool<any>;
532 /**
533 * Name of the connection
534 */
535 readonly name: string;
536 /**
537 * Find if connection is ready or not
538 */
539 readonly ready: boolean;
540 /**
541 * Untouched config
542 */
543 config: ConnectionConfig;
544 /**
545 * List of emitted events
546 */
547 on(event: 'connect', callback: (connection: ConnectionContract) => void): this;
548 on(event: 'error', callback: (error: Error, connection: ConnectionContract) => void): this;
549 on(event: 'disconnect', callback: (connection: ConnectionContract) => void): this;
550 on(event: 'disconnect:error', callback: (error: Error, connection: ConnectionContract) => void): this;
551 /**
552 * Make knex connection
553 */
554 connect(): void;
555 /**
556 * Disconnect knex
557 */
558 disconnect(): Promise<void>;
559 /**
560 * Returns the connection report
561 */
562 getReport(): Promise<ReportNode>;
563 }
564 /**
565 * Options when retrieving new query client from the database
566 * query builder
567 */
568 export type DatabaseClientOptions = Partial<{
569 mode: 'read' | 'write';
570 profiler: ProfilerRowContract | ProfilerContract;
571 }>;
572 /**
573 * Shape of the data emitted by the `db:query event`
574 */
575 export type DbQueryEventNode = {
576 connection: string;
577 model?: string;
578 ddl?: boolean;
579 duration?: [number, number];
580 method: string;
581 sql: string;
582 bindings?: any[];
583 inTransaction?: boolean;
584 };
585 /**
586 * Database contract serves as the main API to interact with multiple
587 * database connections
588 */
589 export interface DatabaseContract {
590 Database: MacroableConstructorContract<DatabaseContract> & {
591 new (config: DatabaseConfig, logger: LoggerContract, profiler: ProfilerContract, emitter: EmitterContract): DatabaseContract;
592 };
593 DatabaseQueryBuilder: MacroableConstructorContract<DatabaseQueryBuilderContract>;
594 InsertQueryBuilder: MacroableConstructorContract<InsertQueryBuilderContract>;
595 ModelQueryBuilder: MacroableConstructorContract<ModelQueryBuilderContract<any, any>>;
596 SimplePaginator: {
597 namingStrategy: {
598 paginationMetaKeys(): SimplePaginatorMetaKeys;
599 };
600 new <Row>(total: number, perPage: number, currentPage: number, ...rows: Row[]): SimplePaginatorContract<Row>;
601 };
602 hasHealthChecksEnabled: boolean;
603 /**
604 * Pretty print query logs
605 */
606 prettyPrint: (queryLog: DbQueryEventNode) => void;
607 /**
608 * Name of the primary connection defined inside `config/database.ts`
609 * file
610 */
611 primaryConnectionName: string;
612 /**
613 * Reference to the connection manager
614 */
615 manager: ConnectionManagerContract;
616 /**
617 * Returns the raw connection instance
618 */
619 getRawConnection: ConnectionManagerContract['get'];
620 /**
621 * Get query client for a given connection. Optionally one can also define
622 * the mode of the connection and profiler row
623 */
624 connection(connectionName?: string, options?: DatabaseClientOptions): QueryClientContract;
625 /**
626 * Returns the knex query builder instance
627 */
628 knexQuery(): Knex.QueryBuilder;
629 /**
630 * Returns the knex raw query builder instance
631 */
632 knexRawQuery(sql: string, bindings?: RawQueryBindings): Knex.Raw;
633 /**
634 * Returns the query builder for a given model
635 */
636 modelQuery<T extends LucidModel, Result = T>(model: T, options?: DatabaseClientOptions): ModelQueryBuilderContract<T, Result>;
637 /**
638 * Get query builder instance for a given connection.
639 */
640 query<Result = any>(options?: DatabaseClientOptions): DatabaseQueryBuilderContract<Result>;
641 /**
642 * Get insert query builder instance for a given connection.
643 */
644 insertQuery<ReturnColumns = any>(options?: DatabaseClientOptions): InsertQueryBuilderContract<ReturnColumns[]>;
645 /**
646 * Get raw query builder instance
647 */
648 rawQuery<Result = any>(sql: string, bindings?: RawQueryBindings, options?: DatabaseClientOptions): RawQueryBuilderContract<Result>;
649 /**
650 * Returns instance of reference builder
651 */
652 ref(reference: string): ReferenceBuilderContract;
653 /**
654 * Returns instance of raw builder
655 */
656 raw(sql: string, bindings?: RawQueryBindings): RawBuilderContract;
657 /**
658 * Selects a table on the default connection by instantiating a new query
659 * builder instance. This method provides no control over the client
660 * mode and one must use `query` for that
661 */
662 from: QueryClientContract['from'];
663 /**
664 * Selects a table on the default connection by instantiating a new query
665 * builder instance. This method provides no control over the client
666 * mode and one must use `insertQuery` for that
667 */
668 table: QueryClientContract['table'];
669 /**
670 * Start a new transaction
671 */
672 transaction: TransactionFn;
673 /**
674 * Returns the health check report for registered connections
675 */
676 report(): Promise<HealthReportEntry & {
677 meta: ReportNode[];
678 }>;
679 /**
680 * Begin a new global transaction. Multiple calls to this
681 * method is a noop
682 */
683 beginGlobalTransaction(connectionName?: string, options?: Exclude<DatabaseClientOptions, 'mode'>): Promise<TransactionClientContract>;
684 /**
685 * Commit an existing global transaction
686 */
687 commitGlobalTransaction(connectionName?: string): Promise<void>;
688 /**
689 * Rollback an existing global transaction
690 */
691 rollbackGlobalTransaction(connectionName?: string): Promise<void>;
692 }
693 const Database: DatabaseContract;
694 export default Database;
695}