UNPKG

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