@mikro-orm/knex 6.1.13-dev.9 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/AbstractSqlConnection.js +8 -2
  2. package/AbstractSqlDriver.d.ts +5 -5
  3. package/AbstractSqlDriver.js +21 -10
  4. package/MonkeyPatchable.d.ts +5 -0
  5. package/MonkeyPatchable.js +15 -0
  6. package/README.md +17 -11
  7. package/SqlEntityManager.d.ts +1 -1
  8. package/SqlEntityManager.js +1 -2
  9. package/dialects/index.d.ts +4 -0
  10. package/dialects/index.js +20 -0
  11. package/dialects/mssql/MsSqlColumnCompiler.d.ts +4 -0
  12. package/dialects/mssql/MsSqlColumnCompiler.js +10 -0
  13. package/dialects/mssql/MsSqlKnexDialect.d.ts +6 -0
  14. package/dialects/mssql/MsSqlKnexDialect.js +22 -0
  15. package/dialects/mssql/MsSqlQueryCompiler.d.ts +12 -0
  16. package/dialects/mssql/MsSqlQueryCompiler.js +94 -0
  17. package/dialects/mssql/MsSqlTableCompiler.d.ts +9 -0
  18. package/dialects/mssql/MsSqlTableCompiler.js +40 -0
  19. package/dialects/mssql/index.d.ts +1 -0
  20. package/dialects/mssql/index.js +17 -0
  21. package/dialects/mysql/MariaDbKnexDialect.d.ts +6 -0
  22. package/dialects/mysql/MariaDbKnexDialect.js +16 -0
  23. package/dialects/mysql/MySqlColumnCompiler.d.ts +9 -0
  24. package/dialects/mysql/MySqlColumnCompiler.js +19 -0
  25. package/dialects/mysql/MySqlConnection.d.ts +8 -0
  26. package/dialects/mysql/MySqlConnection.js +43 -0
  27. package/dialects/mysql/MySqlExceptionConverter.d.ts +9 -0
  28. package/dialects/mysql/MySqlExceptionConverter.js +83 -0
  29. package/dialects/mysql/MySqlKnexDialect.d.ts +5 -0
  30. package/dialects/mysql/MySqlKnexDialect.js +21 -0
  31. package/dialects/mysql/MySqlPlatform.d.ts +31 -0
  32. package/dialects/mysql/MySqlPlatform.js +88 -0
  33. package/dialects/mysql/MySqlQueryCompiler.d.ts +5 -0
  34. package/dialects/mysql/MySqlQueryCompiler.js +23 -0
  35. package/dialects/mysql/MySqlSchemaHelper.d.ts +43 -0
  36. package/dialects/mysql/MySqlSchemaHelper.js +297 -0
  37. package/dialects/mysql/index.d.ts +6 -0
  38. package/dialects/mysql/index.js +22 -0
  39. package/dialects/postgresql/PostgreSqlKnexDialect.d.ts +6 -0
  40. package/dialects/postgresql/PostgreSqlKnexDialect.js +19 -0
  41. package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +11 -0
  42. package/dialects/postgresql/PostgreSqlTableCompiler.js +89 -0
  43. package/dialects/postgresql/index.d.ts +1 -0
  44. package/dialects/postgresql/index.js +17 -0
  45. package/dialects/sqlite/BaseSqliteConnection.d.ts +10 -0
  46. package/dialects/sqlite/BaseSqliteConnection.js +56 -0
  47. package/dialects/sqlite/BaseSqlitePlatform.d.ts +49 -0
  48. package/dialects/sqlite/BaseSqlitePlatform.js +78 -0
  49. package/dialects/sqlite/BaseSqliteSchemaHelper.d.ts +27 -0
  50. package/dialects/sqlite/BaseSqliteSchemaHelper.js +172 -0
  51. package/dialects/sqlite/BetterSqliteKnexDialect.d.ts +5 -0
  52. package/dialects/sqlite/BetterSqliteKnexDialect.js +15 -0
  53. package/dialects/sqlite/LibSqlKnexDialect.d.ts +6 -0
  54. package/dialects/sqlite/LibSqlKnexDialect.js +18 -0
  55. package/dialects/sqlite/SqliteKnexDialect.d.ts +8 -0
  56. package/dialects/sqlite/SqliteKnexDialect.js +67 -0
  57. package/dialects/sqlite/SqliteTableCompiler.d.ts +5 -0
  58. package/dialects/sqlite/SqliteTableCompiler.js +45 -0
  59. package/dialects/sqlite/index.d.ts +7 -0
  60. package/dialects/sqlite/index.js +23 -0
  61. package/index.d.ts +1 -0
  62. package/index.js +1 -0
  63. package/index.mjs +16 -0
  64. package/package.json +3 -3
  65. package/query/QueryBuilder.d.ts +59 -41
  66. package/query/QueryBuilder.js +61 -23
  67. package/query/QueryBuilderHelper.js +8 -3
  68. package/schema/DatabaseTable.js +16 -4
  69. package/schema/SchemaComparator.js +13 -3
  70. package/schema/SchemaHelper.d.ts +5 -1
  71. package/schema/SchemaHelper.js +19 -2
  72. package/schema/SqlSchemaGenerator.d.ts +12 -4
  73. package/schema/SqlSchemaGenerator.js +51 -29
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PostgreSqlKnexDialect = void 0;
7
+ // @ts-ignore
8
+ const postgres_1 = __importDefault(require("knex/lib/dialects/postgres"));
9
+ const PostgreSqlTableCompiler_1 = require("./PostgreSqlTableCompiler");
10
+ class PostgreSqlKnexDialect extends postgres_1.default {
11
+ ormConfig;
12
+ tableCompiler() {
13
+ // eslint-disable-next-line prefer-rest-params
14
+ const tableCompiler = new PostgreSqlTableCompiler_1.PostgreSqlTableCompiler(this, ...arguments);
15
+ tableCompiler.ormConfig = this.ormConfig;
16
+ return tableCompiler;
17
+ }
18
+ }
19
+ exports.PostgreSqlKnexDialect = PostgreSqlKnexDialect;
@@ -0,0 +1,11 @@
1
+ import PostgresDialectTableCompiler from 'knex/lib/dialects/postgres/schema/pg-tablecompiler';
2
+ import type { Configuration, Dictionary } from '@mikro-orm/core';
3
+ export declare class PostgreSqlTableCompiler extends PostgresDialectTableCompiler {
4
+ ormConfig: Configuration;
5
+ alterColumnsPrefix: string;
6
+ addColumns(columns: Dictionary[], prefix: string, colCompilers: Dictionary[]): any;
7
+ private addColumn;
8
+ private alterColumnNullable;
9
+ private addColumnDefault;
10
+ private dropColumnDefault;
11
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PostgreSqlTableCompiler = void 0;
7
+ // @ts-ignore
8
+ const pg_tablecompiler_1 = __importDefault(require("knex/lib/dialects/postgres/schema/pg-tablecompiler"));
9
+ // @ts-ignore
10
+ const tablecompiler_1 = __importDefault(require("knex/lib/schema/tablecompiler"));
11
+ class PostgreSqlTableCompiler extends pg_tablecompiler_1.default {
12
+ ormConfig;
13
+ addColumns(columns, prefix, colCompilers) {
14
+ if (prefix !== this.alterColumnsPrefix) {
15
+ // base class implementation for normal add
16
+ return tablecompiler_1.default.prototype.addColumns.call(this, columns, prefix);
17
+ }
18
+ // alter columns
19
+ for (const col of colCompilers) {
20
+ this.addColumn(col);
21
+ }
22
+ }
23
+ addColumn(col) {
24
+ const options = this.ormConfig.get('schemaGenerator');
25
+ const quotedTableName = this.tableName();
26
+ const type = col.getColumnType();
27
+ const colName = this.client.wrapIdentifier(col.getColumnName(), col.columnBuilder.queryContext());
28
+ const constraintName = `${this.tableNameRaw.replace(/^.*\.(.*)$/, '$1')}_${col.getColumnName()}_check`;
29
+ const useNative = col.args?.[2]?.useNative;
30
+ const alterType = col.columnBuilder.alterType;
31
+ const alterNullable = col.columnBuilder.alterNullable;
32
+ const defaultTo = col.modified.defaultTo;
33
+ if (defaultTo != null) {
34
+ this.dropColumnDefault(col, colName);
35
+ }
36
+ /* istanbul ignore next */
37
+ if (col.type === 'enu' && !useNative) {
38
+ if (alterType) {
39
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} type text using (${colName}::text)`, bindings: [] });
40
+ }
41
+ /* istanbul ignore else */
42
+ if (options.createForeignKeyConstraints && alterNullable) {
43
+ this.pushQuery({ sql: `alter table ${quotedTableName} add constraint "${constraintName}" ${type.replace(/^text /, '')}`, bindings: [] });
44
+ }
45
+ }
46
+ else if (type === 'uuid') {
47
+ // we need to drop the default as it would be invalid
48
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} drop default`, bindings: [] });
49
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}::text::uuid)`, bindings: [] });
50
+ }
51
+ else if (alterType) {
52
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} type ${type} using (${colName}::${type})`, bindings: [] });
53
+ }
54
+ this.addColumnDefault(col, colName);
55
+ this.alterColumnNullable(col, colName);
56
+ }
57
+ alterColumnNullable(col, colName) {
58
+ const quotedTableName = this.tableName();
59
+ const nullable = col.modified.nullable;
60
+ if (!nullable) {
61
+ return;
62
+ }
63
+ if (nullable[0] === false) {
64
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} set not null`, bindings: [] });
65
+ }
66
+ else {
67
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} drop not null`, bindings: [] });
68
+ }
69
+ }
70
+ addColumnDefault(col, colName) {
71
+ const quotedTableName = this.tableName();
72
+ const defaultTo = col.modified.defaultTo;
73
+ if (!defaultTo) {
74
+ return;
75
+ }
76
+ if (defaultTo[0] !== null) {
77
+ const modifier = col.defaultTo(...defaultTo);
78
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} set ${modifier}`, bindings: [] });
79
+ }
80
+ }
81
+ dropColumnDefault(col, colName) {
82
+ const quotedTableName = this.tableName();
83
+ const defaultTo = col.modified.defaultTo;
84
+ if (defaultTo?.[0] == null) {
85
+ this.pushQuery({ sql: `alter table ${quotedTableName} alter column ${colName} drop default`, bindings: [] });
86
+ }
87
+ }
88
+ }
89
+ exports.PostgreSqlTableCompiler = PostgreSqlTableCompiler;
@@ -0,0 +1 @@
1
+ export * from './PostgreSqlKnexDialect';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./PostgreSqlKnexDialect"), exports);
@@ -0,0 +1,10 @@
1
+ import type { Knex } from 'knex';
2
+ import { AbstractSqlConnection } from '../../AbstractSqlConnection';
3
+ export declare abstract class BaseSqliteConnection extends AbstractSqlConnection {
4
+ connect(): Promise<void>;
5
+ getDefaultClientUrl(): string;
6
+ getClientUrl(): string;
7
+ loadFile(path: string): Promise<void>;
8
+ protected getKnexOptions(type: string): Knex.Config;
9
+ protected transformRawResult<T>(res: any, method: 'all' | 'get' | 'run'): T;
10
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseSqliteConnection = void 0;
4
+ const fs_extra_1 = require("fs-extra");
5
+ const path_1 = require("path");
6
+ const AbstractSqlConnection_1 = require("../../AbstractSqlConnection");
7
+ const core_1 = require("@mikro-orm/core");
8
+ class BaseSqliteConnection extends AbstractSqlConnection_1.AbstractSqlConnection {
9
+ async connect() {
10
+ this.createKnex();
11
+ await (0, fs_extra_1.ensureDir)((0, path_1.dirname)(this.config.get('dbName')));
12
+ await this.client.raw('pragma foreign_keys = on');
13
+ }
14
+ getDefaultClientUrl() {
15
+ return '';
16
+ }
17
+ getClientUrl() {
18
+ return '';
19
+ }
20
+ async loadFile(path) {
21
+ const conn = await this.client.client.acquireConnection();
22
+ await conn.exec((await (0, fs_extra_1.readFile)(path)).toString());
23
+ await this.client.client.releaseConnection(conn);
24
+ }
25
+ getKnexOptions(type) {
26
+ return core_1.Utils.mergeConfig({
27
+ client: type,
28
+ connection: {
29
+ filename: this.config.get('dbName'),
30
+ },
31
+ pool: this.config.get('pool'),
32
+ useNullAsDefault: true,
33
+ }, this.config.get('driverOptions'));
34
+ }
35
+ transformRawResult(res, method) {
36
+ if (method === 'get') {
37
+ return res[0];
38
+ }
39
+ if (method === 'all') {
40
+ return res;
41
+ }
42
+ if (Array.isArray(res)) {
43
+ return {
44
+ insertId: res[res.length - 1]?.id ?? 0,
45
+ affectedRows: res.length,
46
+ row: res[0],
47
+ rows: res,
48
+ };
49
+ }
50
+ return {
51
+ insertId: res.lastInsertRowid,
52
+ affectedRows: res.changes,
53
+ };
54
+ }
55
+ }
56
+ exports.BaseSqliteConnection = BaseSqliteConnection;
@@ -0,0 +1,49 @@
1
+ import { AbstractSqlPlatform } from '../../AbstractSqlPlatform';
2
+ export declare abstract class BaseSqlitePlatform extends AbstractSqlPlatform {
3
+ usesDefaultKeyword(): boolean;
4
+ usesReturningStatement(): boolean;
5
+ getCurrentTimestampSQL(length: number): string;
6
+ getDateTimeTypeDeclarationSQL(column: {
7
+ length: number;
8
+ }): string;
9
+ getEnumTypeDeclarationSQL(column: {
10
+ items?: unknown[];
11
+ fieldNames: string[];
12
+ length?: number;
13
+ unsigned?: boolean;
14
+ autoincrement?: boolean;
15
+ }): string;
16
+ getTinyIntTypeDeclarationSQL(column: {
17
+ length?: number;
18
+ unsigned?: boolean;
19
+ autoincrement?: boolean;
20
+ }): string;
21
+ getSmallIntTypeDeclarationSQL(column: {
22
+ length?: number;
23
+ unsigned?: boolean;
24
+ autoincrement?: boolean;
25
+ }): string;
26
+ getIntegerTypeDeclarationSQL(column: {
27
+ length?: number;
28
+ unsigned?: boolean;
29
+ autoincrement?: boolean;
30
+ }): string;
31
+ getFloatDeclarationSQL(): string;
32
+ getBooleanTypeDeclarationSQL(): string;
33
+ getVarcharTypeDeclarationSQL(column: {
34
+ length?: number;
35
+ }): string;
36
+ convertsJsonAutomatically(): boolean;
37
+ allowsComparingTuples(): boolean;
38
+ /**
39
+ * This is used to narrow the value of Date properties as they will be stored as timestamps in sqlite.
40
+ * We use this method to convert Dates to timestamps when computing the changeset, so we have the right
41
+ * data type in the payload as well as in original entity data. Without that, we would end up with diffs
42
+ * including all Date properties, as we would be comparing Date object with timestamp.
43
+ */
44
+ processDateProperty(value: unknown): string | number | Date;
45
+ getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence'): string;
46
+ getDefaultPrimaryName(tableName: string, columns: string[]): string;
47
+ supportsDownMigrations(): boolean;
48
+ getFullTextWhereClause(): string;
49
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseSqlitePlatform = void 0;
4
+ const core_1 = require("@mikro-orm/core");
5
+ const AbstractSqlPlatform_1 = require("../../AbstractSqlPlatform");
6
+ class BaseSqlitePlatform extends AbstractSqlPlatform_1.AbstractSqlPlatform {
7
+ usesDefaultKeyword() {
8
+ return false;
9
+ }
10
+ usesReturningStatement() {
11
+ return true;
12
+ }
13
+ getCurrentTimestampSQL(length) {
14
+ return super.getCurrentTimestampSQL(0);
15
+ }
16
+ getDateTimeTypeDeclarationSQL(column) {
17
+ return 'datetime';
18
+ }
19
+ getEnumTypeDeclarationSQL(column) {
20
+ if (column.items?.every(item => core_1.Utils.isString(item))) {
21
+ return 'text';
22
+ }
23
+ /* istanbul ignore next */
24
+ return this.getTinyIntTypeDeclarationSQL(column);
25
+ }
26
+ getTinyIntTypeDeclarationSQL(column) {
27
+ return this.getIntegerTypeDeclarationSQL(column);
28
+ }
29
+ getSmallIntTypeDeclarationSQL(column) {
30
+ return this.getIntegerTypeDeclarationSQL(column);
31
+ }
32
+ getIntegerTypeDeclarationSQL(column) {
33
+ return 'integer';
34
+ }
35
+ getFloatDeclarationSQL() {
36
+ return 'real';
37
+ }
38
+ getBooleanTypeDeclarationSQL() {
39
+ return 'integer';
40
+ }
41
+ getVarcharTypeDeclarationSQL(column) {
42
+ return 'text';
43
+ }
44
+ convertsJsonAutomatically() {
45
+ return false;
46
+ }
47
+ allowsComparingTuples() {
48
+ return false;
49
+ }
50
+ /**
51
+ * This is used to narrow the value of Date properties as they will be stored as timestamps in sqlite.
52
+ * We use this method to convert Dates to timestamps when computing the changeset, so we have the right
53
+ * data type in the payload as well as in original entity data. Without that, we would end up with diffs
54
+ * including all Date properties, as we would be comparing Date object with timestamp.
55
+ */
56
+ processDateProperty(value) {
57
+ if (value instanceof Date) {
58
+ return +value;
59
+ }
60
+ return value;
61
+ }
62
+ getIndexName(tableName, columns, type) {
63
+ if (type === 'primary') {
64
+ return this.getDefaultPrimaryName(tableName, columns);
65
+ }
66
+ return super.getIndexName(tableName, columns, type);
67
+ }
68
+ getDefaultPrimaryName(tableName, columns) {
69
+ return 'primary';
70
+ }
71
+ supportsDownMigrations() {
72
+ return false;
73
+ }
74
+ getFullTextWhereClause() {
75
+ return `:column: match :query`;
76
+ }
77
+ }
78
+ exports.BaseSqlitePlatform = BaseSqlitePlatform;
@@ -0,0 +1,27 @@
1
+ import type { Connection, Dictionary } from '@mikro-orm/core';
2
+ import type { AbstractSqlConnection } from '../../AbstractSqlConnection';
3
+ import { SchemaHelper } from '../../schema/SchemaHelper';
4
+ import type { CheckDef, Column, IndexDef } from '../../typings';
5
+ export declare abstract class BaseSqliteSchemaHelper extends SchemaHelper {
6
+ disableForeignKeysSQL(): string;
7
+ enableForeignKeysSQL(): string;
8
+ supportsSchemaConstraints(): boolean;
9
+ getListTablesSQL(): string;
10
+ getDropDatabaseSQL(name: string): string;
11
+ getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
12
+ private parseTableDefinition;
13
+ getColumns(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<any[]>;
14
+ getEnumDefinitions(connection: AbstractSqlConnection, checks: CheckDef[], tableName: string, schemaName: string): Promise<Dictionary<string[]>>;
15
+ getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[], tableName: string, schemaName?: string): Promise<string[]>;
16
+ getIndexes(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<IndexDef[]>;
17
+ getChecks(connection: AbstractSqlConnection, tableName: string, schemaName?: string): Promise<CheckDef[]>;
18
+ getForeignKeysSQL(tableName: string): string;
19
+ mapForeignKeys(fks: any[], tableName: string): Dictionary;
20
+ getManagementDbName(): string;
21
+ getCreateDatabaseSQL(name: string): string;
22
+ databaseExists(connection: Connection, name: string): Promise<boolean>;
23
+ /**
24
+ * Implicit indexes will be ignored when diffing
25
+ */
26
+ isImplicitIndex(name: string): boolean;
27
+ }
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseSqliteSchemaHelper = void 0;
4
+ const SchemaHelper_1 = require("../../schema/SchemaHelper");
5
+ class BaseSqliteSchemaHelper extends SchemaHelper_1.SchemaHelper {
6
+ disableForeignKeysSQL() {
7
+ return 'pragma foreign_keys = off;';
8
+ }
9
+ enableForeignKeysSQL() {
10
+ return 'pragma foreign_keys = on;';
11
+ }
12
+ supportsSchemaConstraints() {
13
+ return false;
14
+ }
15
+ getListTablesSQL() {
16
+ return `select name as table_name from sqlite_master where type = 'table' and name != 'sqlite_sequence' and name != 'geometry_columns' and name != 'spatial_ref_sys' `
17
+ + `union all select name as table_name from sqlite_temp_master where type = 'table' order by name`;
18
+ }
19
+ getDropDatabaseSQL(name) {
20
+ if (name === ':memory:') {
21
+ return '';
22
+ }
23
+ /* istanbul ignore next */
24
+ return `drop database if exists ${this.platform.quoteIdentifier(name)}`;
25
+ }
26
+ getDropColumnsSQL(tableName, columns, schemaName) {
27
+ /* istanbul ignore next */
28
+ const name = this.platform.quoteIdentifier((schemaName && schemaName !== this.platform.getDefaultSchemaName() ? schemaName + '.' : '') + tableName);
29
+ return columns.map(column => {
30
+ return `alter table ${name} drop column ${this.platform.quoteIdentifier(column.name)}`;
31
+ }).join(';\n');
32
+ }
33
+ parseTableDefinition(sql, cols) {
34
+ const columns = {};
35
+ // extract all columns definitions
36
+ let columnsDef = sql.replaceAll('\n', '').match(new RegExp(`create table [\`"']?.*?[\`"']? \\((.*)\\)`, 'i'))?.[1];
37
+ /* istanbul ignore else */
38
+ if (columnsDef) {
39
+ for (let i = cols.length - 1; i >= 0; i--) {
40
+ const col = cols[i];
41
+ const re = ` *, *[\`"']?${col.name}[\`"']? (.*)`;
42
+ const columnDef = columnsDef.match(new RegExp(re, 'i'));
43
+ /* istanbul ignore else */
44
+ if (columnDef) {
45
+ columns[col.name] = { name: col.name, definition: columnDef[1] };
46
+ columnsDef = columnsDef.substring(0, columnDef.index);
47
+ }
48
+ }
49
+ }
50
+ return columns;
51
+ }
52
+ async getColumns(connection, tableName, schemaName) {
53
+ const columns = await connection.execute(`pragma table_xinfo('${tableName}')`);
54
+ const sql = `select sql from sqlite_master where type = ? and name = ?`;
55
+ const tableDefinition = await connection.execute(sql, ['table', tableName], 'get');
56
+ const composite = columns.reduce((count, col) => count + (col.pk ? 1 : 0), 0) > 1;
57
+ // there can be only one, so naive check like this should be enough
58
+ const hasAutoincrement = tableDefinition.sql.toLowerCase().includes('autoincrement');
59
+ const columnDefinitions = this.parseTableDefinition(tableDefinition.sql, columns);
60
+ return columns.map(col => {
61
+ const mappedType = connection.getPlatform().getMappedType(col.type);
62
+ let generated;
63
+ if (col.hidden > 1) {
64
+ /* istanbul ignore next */
65
+ const storage = col.hidden === 2 ? 'virtual' : 'stored';
66
+ const re = `(generated always)? as \\((.*)\\)( ${storage})?$`;
67
+ const match = columnDefinitions[col.name].definition.match(re);
68
+ if (match) {
69
+ generated = `${match[2]} ${storage}`;
70
+ }
71
+ }
72
+ return {
73
+ name: col.name,
74
+ type: col.type,
75
+ default: col.dflt_value,
76
+ nullable: !col.notnull,
77
+ primary: !!col.pk,
78
+ mappedType,
79
+ unsigned: false,
80
+ autoincrement: !composite && col.pk && this.platform.isNumericColumn(mappedType) && hasAutoincrement,
81
+ generated,
82
+ };
83
+ });
84
+ }
85
+ async getEnumDefinitions(connection, checks, tableName, schemaName) {
86
+ const sql = `select sql from sqlite_master where type = ? and name = ?`;
87
+ const tableDefinition = await connection.execute(sql, ['table', tableName], 'get');
88
+ const checkConstraints = [...tableDefinition.sql.match(/[`["'][^`\]"']+[`\]"'] text check \(.*?\)/gi) ?? []];
89
+ return checkConstraints.reduce((o, item) => {
90
+ // check constraints are defined as (note that last closing paren is missing):
91
+ // `type` text check (`type` in ('local', 'global')
92
+ const match = item.match(/[`["']([^`\]"']+)[`\]"'] text check \(.* \((.*)\)/i);
93
+ /* istanbul ignore else */
94
+ if (match) {
95
+ o[match[1]] = match[2].split(',').map((item) => item.trim().match(/^\(?'(.*)'/)[1]);
96
+ }
97
+ return o;
98
+ }, {});
99
+ }
100
+ async getPrimaryKeys(connection, indexes, tableName, schemaName) {
101
+ const sql = `pragma table_info(\`${tableName}\`)`;
102
+ const cols = await connection.execute(sql);
103
+ return cols.filter(col => !!col.pk).map(col => col.name);
104
+ }
105
+ async getIndexes(connection, tableName, schemaName) {
106
+ const sql = `pragma table_info(\`${tableName}\`)`;
107
+ const cols = await connection.execute(sql);
108
+ const indexes = await connection.execute(`pragma index_list(\`${tableName}\`)`);
109
+ const ret = [];
110
+ for (const col of cols.filter(c => c.pk)) {
111
+ ret.push({
112
+ columnNames: [col.name],
113
+ keyName: 'primary',
114
+ constraint: true,
115
+ unique: true,
116
+ primary: true,
117
+ });
118
+ }
119
+ for (const index of indexes.filter(index => !this.isImplicitIndex(index.name))) {
120
+ const res = await connection.execute(`pragma index_info(\`${index.name}\`)`);
121
+ ret.push(...res.map(row => ({
122
+ columnNames: [row.name],
123
+ keyName: index.name,
124
+ unique: !!index.unique,
125
+ constraint: !!index.unique,
126
+ primary: false,
127
+ })));
128
+ }
129
+ return this.mapIndexes(ret);
130
+ }
131
+ async getChecks(connection, tableName, schemaName) {
132
+ // Not supported at the moment.
133
+ return [];
134
+ }
135
+ getForeignKeysSQL(tableName) {
136
+ return `pragma foreign_key_list(\`${tableName}\`)`;
137
+ }
138
+ mapForeignKeys(fks, tableName) {
139
+ return fks.reduce((ret, fk) => {
140
+ ret[fk.from] = {
141
+ constraintName: this.platform.getIndexName(tableName, [fk.from], 'foreign'),
142
+ columnName: fk.from,
143
+ columnNames: [fk.from],
144
+ localTableName: tableName,
145
+ referencedTableName: fk.table,
146
+ referencedColumnName: fk.to,
147
+ referencedColumnNames: [fk.to],
148
+ updateRule: fk.on_update.toLowerCase(),
149
+ deleteRule: fk.on_delete.toLowerCase(),
150
+ };
151
+ return ret;
152
+ }, {});
153
+ }
154
+ getManagementDbName() {
155
+ return '';
156
+ }
157
+ getCreateDatabaseSQL(name) {
158
+ return '';
159
+ }
160
+ async databaseExists(connection, name) {
161
+ const tables = await connection.execute(this.getListTablesSQL());
162
+ return tables.length > 0;
163
+ }
164
+ /**
165
+ * Implicit indexes will be ignored when diffing
166
+ */
167
+ isImplicitIndex(name) {
168
+ // Ignore indexes with reserved names, e.g. autoindexes
169
+ return name.startsWith('sqlite_');
170
+ }
171
+ }
172
+ exports.BaseSqliteSchemaHelper = BaseSqliteSchemaHelper;
@@ -0,0 +1,5 @@
1
+ import { MonkeyPatchable } from '../../MonkeyPatchable';
2
+ export declare class BetterSqliteKnexDialect extends MonkeyPatchable.BetterSqlite3Dialect {
3
+ _driver(): any;
4
+ tableCompiler(): any;
5
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BetterSqliteKnexDialect = void 0;
4
+ const SqliteTableCompiler_1 = require("./SqliteTableCompiler");
5
+ const MonkeyPatchable_1 = require("../../MonkeyPatchable");
6
+ class BetterSqliteKnexDialect extends MonkeyPatchable_1.MonkeyPatchable.BetterSqlite3Dialect {
7
+ _driver() {
8
+ return require('better-sqlite3');
9
+ }
10
+ tableCompiler() {
11
+ // eslint-disable-next-line prefer-rest-params
12
+ return new SqliteTableCompiler_1.SqliteTableCompiler(this, ...arguments);
13
+ }
14
+ }
15
+ exports.BetterSqliteKnexDialect = BetterSqliteKnexDialect;
@@ -0,0 +1,6 @@
1
+ import { MonkeyPatchable } from '../../MonkeyPatchable';
2
+ export declare class LibSqlKnexDialect extends MonkeyPatchable.BetterSqlite3Dialect {
3
+ get driverName(): string;
4
+ _driver(): any;
5
+ tableCompiler(): any;
6
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LibSqlKnexDialect = void 0;
4
+ const SqliteTableCompiler_1 = require("./SqliteTableCompiler");
5
+ const MonkeyPatchable_1 = require("../../MonkeyPatchable");
6
+ class LibSqlKnexDialect extends MonkeyPatchable_1.MonkeyPatchable.BetterSqlite3Dialect {
7
+ get driverName() {
8
+ return 'libsql';
9
+ }
10
+ _driver() {
11
+ return require('libsql');
12
+ }
13
+ tableCompiler() {
14
+ // eslint-disable-next-line prefer-rest-params
15
+ return new SqliteTableCompiler_1.SqliteTableCompiler(this, ...arguments);
16
+ }
17
+ }
18
+ exports.LibSqlKnexDialect = LibSqlKnexDialect;
@@ -0,0 +1,8 @@
1
+ import { MonkeyPatchable } from '../../MonkeyPatchable';
2
+ export declare class SqliteKnexDialect extends MonkeyPatchable.Sqlite3Dialect {
3
+ tableCompiler(): any;
4
+ processResponse(obj: any, runner: any): any;
5
+ _query(connection: any, obj: any): Promise<unknown>;
6
+ private getCallMethod;
7
+ private isRunQuery;
8
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqliteKnexDialect = void 0;
4
+ const SqliteTableCompiler_1 = require("./SqliteTableCompiler");
5
+ const MonkeyPatchable_1 = require("../../MonkeyPatchable");
6
+ class SqliteKnexDialect extends MonkeyPatchable_1.MonkeyPatchable.Sqlite3Dialect {
7
+ tableCompiler() {
8
+ // eslint-disable-next-line prefer-rest-params
9
+ return new SqliteTableCompiler_1.SqliteTableCompiler(this, ...arguments);
10
+ }
11
+ processResponse(obj, runner) {
12
+ if (obj.method === 'raw' && this.isRunQuery(obj.sql)) {
13
+ return obj.response ?? obj.context;
14
+ }
15
+ return super.processResponse(obj, runner);
16
+ }
17
+ _query(connection, obj) {
18
+ const callMethod = this.getCallMethod(obj);
19
+ return new Promise((resolve, reject) => {
20
+ /* istanbul ignore if */
21
+ if (!connection?.[callMethod]) {
22
+ return reject(new Error(`Error calling ${callMethod} on connection.`));
23
+ }
24
+ connection[callMethod](obj.sql, obj.bindings, function (err, response) {
25
+ if (err) {
26
+ return reject(err);
27
+ }
28
+ obj.response = response;
29
+ obj.context = this;
30
+ return resolve(obj);
31
+ });
32
+ });
33
+ }
34
+ getCallMethod(obj) {
35
+ if (obj.method === 'raw') {
36
+ const query = obj.sql.trim().toLowerCase();
37
+ if ((query.startsWith('insert into') || query.startsWith('update ')) && query.includes(' returning ')) {
38
+ return 'all';
39
+ }
40
+ if (this.isRunQuery(query)) {
41
+ return 'run';
42
+ }
43
+ }
44
+ /* istanbul ignore next */
45
+ switch (obj.method) {
46
+ case 'insert':
47
+ case 'update':
48
+ return obj.returning ? 'all' : 'run';
49
+ case 'counter':
50
+ case 'del':
51
+ return 'run';
52
+ default:
53
+ return 'all';
54
+ }
55
+ }
56
+ isRunQuery(query) {
57
+ query = query.trim().toLowerCase();
58
+ if ((query.startsWith('insert into') || query.startsWith('update ')) && query.includes(' returning ')) {
59
+ return false;
60
+ }
61
+ return query.startsWith('insert into') ||
62
+ query.startsWith('update') ||
63
+ query.startsWith('delete') ||
64
+ query.startsWith('truncate');
65
+ }
66
+ }
67
+ exports.SqliteKnexDialect = SqliteKnexDialect;