@mikro-orm/sql 7.0.0-dev.97 → 7.0.0-dev.99

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 (91) hide show
  1. package/AbstractSqlConnection.d.ts +57 -0
  2. package/AbstractSqlConnection.js +239 -0
  3. package/AbstractSqlDriver.d.ts +94 -0
  4. package/AbstractSqlDriver.js +1387 -0
  5. package/AbstractSqlPlatform.d.ts +38 -0
  6. package/AbstractSqlPlatform.js +104 -0
  7. package/LICENSE +21 -0
  8. package/PivotCollectionPersister.d.ts +22 -0
  9. package/PivotCollectionPersister.js +159 -0
  10. package/README.md +390 -0
  11. package/SqlEntityManager.d.ts +33 -0
  12. package/SqlEntityManager.js +44 -0
  13. package/SqlEntityRepository.d.ts +19 -0
  14. package/SqlEntityRepository.js +26 -0
  15. package/dialects/index.d.ts +4 -0
  16. package/dialects/index.js +4 -0
  17. package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +14 -0
  18. package/dialects/mssql/MsSqlNativeQueryBuilder.js +200 -0
  19. package/dialects/mssql/index.d.ts +1 -0
  20. package/dialects/mssql/index.js +1 -0
  21. package/dialects/mysql/MySqlExceptionConverter.d.ts +9 -0
  22. package/dialects/mysql/MySqlExceptionConverter.js +80 -0
  23. package/dialects/mysql/MySqlNativeQueryBuilder.d.ts +7 -0
  24. package/dialects/mysql/MySqlNativeQueryBuilder.js +77 -0
  25. package/dialects/mysql/MySqlPlatform.d.ts +45 -0
  26. package/dialects/mysql/MySqlPlatform.js +116 -0
  27. package/dialects/mysql/MySqlSchemaHelper.d.ts +36 -0
  28. package/dialects/mysql/MySqlSchemaHelper.js +269 -0
  29. package/dialects/mysql/index.d.ts +4 -0
  30. package/dialects/mysql/index.js +4 -0
  31. package/dialects/postgresql/PostgreSqlNativeQueryBuilder.d.ts +5 -0
  32. package/dialects/postgresql/PostgreSqlNativeQueryBuilder.js +8 -0
  33. package/dialects/postgresql/PostgreSqlTableCompiler.d.ts +1 -0
  34. package/dialects/postgresql/PostgreSqlTableCompiler.js +1 -0
  35. package/dialects/postgresql/index.d.ts +1 -0
  36. package/dialects/postgresql/index.js +1 -0
  37. package/dialects/sqlite/BaseSqliteConnection.d.ts +6 -0
  38. package/dialects/sqlite/BaseSqliteConnection.js +8 -0
  39. package/dialects/sqlite/BaseSqlitePlatform.d.ts +70 -0
  40. package/dialects/sqlite/BaseSqlitePlatform.js +104 -0
  41. package/dialects/sqlite/SqliteExceptionConverter.d.ts +9 -0
  42. package/dialects/sqlite/SqliteExceptionConverter.js +54 -0
  43. package/dialects/sqlite/SqliteNativeQueryBuilder.d.ts +6 -0
  44. package/dialects/sqlite/SqliteNativeQueryBuilder.js +11 -0
  45. package/dialects/sqlite/SqliteSchemaHelper.d.ts +38 -0
  46. package/dialects/sqlite/SqliteSchemaHelper.js +379 -0
  47. package/dialects/sqlite/index.d.ts +5 -0
  48. package/dialects/sqlite/index.js +5 -0
  49. package/index.d.ts +19 -0
  50. package/index.js +19 -0
  51. package/package.json +3 -3
  52. package/plugin/index.d.ts +53 -0
  53. package/plugin/index.js +42 -0
  54. package/plugin/transformer.d.ts +115 -0
  55. package/plugin/transformer.js +883 -0
  56. package/query/ArrayCriteriaNode.d.ts +11 -0
  57. package/query/ArrayCriteriaNode.js +24 -0
  58. package/query/CriteriaNode.d.ts +29 -0
  59. package/query/CriteriaNode.js +121 -0
  60. package/query/CriteriaNodeFactory.d.ts +12 -0
  61. package/query/CriteriaNodeFactory.js +90 -0
  62. package/query/NativeQueryBuilder.d.ts +108 -0
  63. package/query/NativeQueryBuilder.js +425 -0
  64. package/query/ObjectCriteriaNode.d.ts +19 -0
  65. package/query/ObjectCriteriaNode.js +249 -0
  66. package/query/QueryBuilder.d.ts +389 -0
  67. package/query/QueryBuilder.js +1558 -0
  68. package/query/QueryBuilderHelper.d.ts +73 -0
  69. package/query/QueryBuilderHelper.js +756 -0
  70. package/query/ScalarCriteriaNode.d.ts +10 -0
  71. package/query/ScalarCriteriaNode.js +49 -0
  72. package/query/enums.d.ts +18 -0
  73. package/query/enums.js +20 -0
  74. package/query/index.d.ts +10 -0
  75. package/query/index.js +10 -0
  76. package/query/raw.d.ts +59 -0
  77. package/query/raw.js +68 -0
  78. package/schema/DatabaseSchema.d.ts +45 -0
  79. package/schema/DatabaseSchema.js +185 -0
  80. package/schema/DatabaseTable.d.ts +68 -0
  81. package/schema/DatabaseTable.js +793 -0
  82. package/schema/SchemaComparator.d.ts +58 -0
  83. package/schema/SchemaComparator.js +577 -0
  84. package/schema/SchemaHelper.d.ts +76 -0
  85. package/schema/SchemaHelper.js +545 -0
  86. package/schema/SqlSchemaGenerator.d.ts +65 -0
  87. package/schema/SqlSchemaGenerator.js +375 -0
  88. package/schema/index.d.ts +5 -0
  89. package/schema/index.js +5 -0
  90. package/typings.d.ts +272 -0
  91. package/typings.js +1 -0
@@ -0,0 +1,269 @@
1
+ import { EnumType, StringType, TextType } from '@mikro-orm/core';
2
+ import { SchemaHelper } from '../../schema/SchemaHelper.js';
3
+ export class MySqlSchemaHelper extends SchemaHelper {
4
+ _cache = {};
5
+ static DEFAULT_VALUES = {
6
+ 'now()': ['now()', 'current_timestamp'],
7
+ 'current_timestamp(?)': ['current_timestamp(?)'],
8
+ '0': ['0', 'false'],
9
+ };
10
+ getSchemaBeginning(charset, disableForeignKeys) {
11
+ if (disableForeignKeys) {
12
+ return `set names ${charset};\n${this.disableForeignKeysSQL()}\n\n`;
13
+ }
14
+ return `set names ${charset};\n\n`;
15
+ }
16
+ disableForeignKeysSQL() {
17
+ return 'set foreign_key_checks = 0;';
18
+ }
19
+ enableForeignKeysSQL() {
20
+ return 'set foreign_key_checks = 1;';
21
+ }
22
+ finalizeTable(table, charset, collate) {
23
+ let sql = ` default character set ${charset}`;
24
+ if (collate) {
25
+ sql += ` collate ${collate}`;
26
+ }
27
+ sql += ' engine = InnoDB';
28
+ if (table.comment) {
29
+ sql += ` comment = ${this.platform.quoteValue(table.comment)}`;
30
+ }
31
+ return sql;
32
+ }
33
+ getListTablesSQL() {
34
+ return `select table_name as table_name, nullif(table_schema, schema()) as schema_name, table_comment as table_comment from information_schema.tables where table_type = 'BASE TABLE' and table_schema = schema()`;
35
+ }
36
+ async loadInformationSchema(schema, connection, tables) {
37
+ if (tables.length === 0) {
38
+ return;
39
+ }
40
+ const columns = await this.getAllColumns(connection, tables);
41
+ const indexes = await this.getAllIndexes(connection, tables);
42
+ const checks = await this.getAllChecks(connection, tables);
43
+ const fks = await this.getAllForeignKeys(connection, tables);
44
+ const enums = await this.getAllEnumDefinitions(connection, tables);
45
+ for (const t of tables) {
46
+ const key = this.getTableKey(t);
47
+ const table = schema.addTable(t.table_name, t.schema_name, t.table_comment);
48
+ const pks = await this.getPrimaryKeys(connection, indexes[key], table.name, table.schema);
49
+ table.init(columns[key], indexes[key], checks[key], pks, fks[key], enums[key]);
50
+ }
51
+ }
52
+ async getAllIndexes(connection, tables) {
53
+ const sql = `select table_name as table_name, nullif(table_schema, schema()) as schema_name, index_name as index_name, non_unique as non_unique, column_name as column_name /*!80013 , expression as expression */
54
+ from information_schema.statistics where table_schema = database()
55
+ and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
56
+ order by schema_name, table_name, index_name, seq_in_index`;
57
+ const allIndexes = await connection.execute(sql);
58
+ const ret = {};
59
+ for (const index of allIndexes) {
60
+ const key = this.getTableKey(index);
61
+ const indexDef = {
62
+ columnNames: [index.column_name],
63
+ keyName: index.index_name,
64
+ unique: !index.non_unique,
65
+ primary: index.index_name === 'PRIMARY',
66
+ constraint: !index.non_unique,
67
+ };
68
+ if (!index.column_name || index.expression?.match(/ where /i)) {
69
+ indexDef.expression = index.expression; // required for the `getCreateIndexSQL()` call
70
+ indexDef.expression = this.getCreateIndexSQL(index.table_name, indexDef, !!index.expression);
71
+ }
72
+ ret[key] ??= [];
73
+ ret[key].push(indexDef);
74
+ }
75
+ for (const key of Object.keys(ret)) {
76
+ ret[key] = await this.mapIndexes(ret[key]);
77
+ }
78
+ return ret;
79
+ }
80
+ getCreateIndexSQL(tableName, index, partialExpression = false) {
81
+ /* v8 ignore next */
82
+ if (index.expression && !partialExpression) {
83
+ return index.expression;
84
+ }
85
+ tableName = this.quote(tableName);
86
+ const keyName = this.quote(index.keyName);
87
+ const sql = `alter table ${tableName} add ${index.unique ? 'unique' : 'index'} ${keyName} `;
88
+ if (index.expression && partialExpression) {
89
+ return `${sql}(${index.expression})`;
90
+ }
91
+ // JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
92
+ if (index.columnNames.some(column => column.includes('.'))) {
93
+ const columns = this.platform.getJsonIndexDefinition(index);
94
+ const sql = `alter table ${tableName} add ${index.unique ? 'unique ' : ''}index ${keyName} `;
95
+ return `${sql}(${columns.join(', ')})`;
96
+ }
97
+ return `${sql}(${index.columnNames.map(c => this.quote(c)).join(', ')})`;
98
+ }
99
+ async getAllColumns(connection, tables) {
100
+ const sql = `select table_name as table_name,
101
+ nullif(table_schema, schema()) as schema_name,
102
+ column_name as column_name,
103
+ column_default as column_default,
104
+ nullif(column_comment, '') as column_comment,
105
+ is_nullable as is_nullable,
106
+ data_type as data_type,
107
+ column_type as column_type,
108
+ column_key as column_key,
109
+ extra as extra,
110
+ generation_expression as generation_expression,
111
+ numeric_precision as numeric_precision,
112
+ numeric_scale as numeric_scale,
113
+ ifnull(datetime_precision, character_maximum_length) length
114
+ from information_schema.columns where table_schema = database() and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name))})
115
+ order by ordinal_position`;
116
+ const allColumns = await connection.execute(sql);
117
+ const str = (val) => val != null ? '' + val : val;
118
+ const extra = (val) => val.replace(/auto_increment|default_generated|(stored|virtual) generated/i, '').trim() || undefined;
119
+ const ret = {};
120
+ for (const col of allColumns) {
121
+ const mappedType = this.platform.getMappedType(col.column_type);
122
+ const defaultValue = str(this.normalizeDefaultValue((mappedType.compareAsType() === 'boolean' && ['0', '1'].includes(col.column_default))
123
+ ? ['false', 'true'][+col.column_default]
124
+ : col.column_default, col.length));
125
+ const key = this.getTableKey(col);
126
+ const generated = col.generation_expression ? `(${col.generation_expression.replaceAll(`\\'`, `'`)}) ${col.extra.match(/stored generated/i) ? 'stored' : 'virtual'}` : undefined;
127
+ ret[key] ??= [];
128
+ ret[key].push({
129
+ name: col.column_name,
130
+ type: this.platform.isNumericColumn(mappedType) ? col.column_type.replace(/ unsigned$/, '').replace(/\(\d+\)$/, '') : col.column_type,
131
+ mappedType,
132
+ unsigned: col.column_type.endsWith(' unsigned'),
133
+ length: col.length,
134
+ default: this.wrap(defaultValue, mappedType),
135
+ nullable: col.is_nullable === 'YES',
136
+ primary: col.column_key === 'PRI',
137
+ unique: col.column_key === 'UNI',
138
+ autoincrement: col.extra === 'auto_increment',
139
+ precision: col.numeric_precision,
140
+ scale: col.numeric_scale,
141
+ comment: col.column_comment,
142
+ extra: extra(col.extra),
143
+ generated,
144
+ });
145
+ }
146
+ return ret;
147
+ }
148
+ async getAllChecks(connection, tables) {
149
+ /* v8 ignore next */
150
+ if (!(await this.supportsCheckConstraints(connection))) {
151
+ return {};
152
+ }
153
+ const sql = this.getChecksSQL(tables);
154
+ const allChecks = await connection.execute(sql);
155
+ const ret = {};
156
+ for (const check of allChecks) {
157
+ const key = this.getTableKey(check);
158
+ ret[key] ??= [];
159
+ ret[key].push({
160
+ name: check.name,
161
+ columnName: check.column_name,
162
+ definition: `check ${check.expression}`,
163
+ expression: check.expression.replace(/^\((.*)\)$/, '$1'),
164
+ });
165
+ }
166
+ return ret;
167
+ }
168
+ async getAllForeignKeys(connection, tables) {
169
+ const sql = `select k.constraint_name as constraint_name, nullif(k.table_schema, schema()) as schema_name, k.table_name as table_name, k.column_name as column_name, k.referenced_table_name as referenced_table_name, k.referenced_column_name as referenced_column_name, c.update_rule as update_rule, c.delete_rule as delete_rule
170
+ from information_schema.key_column_usage k
171
+ inner join information_schema.referential_constraints c on c.constraint_name = k.constraint_name and c.table_name = k.table_name
172
+ where k.table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
173
+ and k.table_schema = database() and c.constraint_schema = database() and k.referenced_column_name is not null
174
+ order by constraint_name, k.ordinal_position`;
175
+ const allFks = await connection.execute(sql);
176
+ const ret = {};
177
+ for (const fk of allFks) {
178
+ const key = this.getTableKey(fk);
179
+ ret[key] ??= [];
180
+ ret[key].push(fk);
181
+ }
182
+ Object.keys(ret).forEach(key => {
183
+ const parts = key.split('.');
184
+ /* v8 ignore next */
185
+ const schemaName = parts.length > 1 ? parts[0] : undefined;
186
+ ret[key] = this.mapForeignKeys(ret[key], key, schemaName);
187
+ });
188
+ return ret;
189
+ }
190
+ getPreAlterTable(tableDiff, safe) {
191
+ // Dropping primary keys requires to unset autoincrement attribute on the particular column first.
192
+ const pk = Object.values(tableDiff.removedIndexes).find(idx => idx.primary);
193
+ if (!pk || safe) {
194
+ return [];
195
+ }
196
+ return pk.columnNames
197
+ .filter(col => tableDiff.fromTable.hasColumn(col))
198
+ .map(col => tableDiff.fromTable.getColumn(col))
199
+ .filter(col => col.autoincrement)
200
+ .map(col => `alter table \`${tableDiff.name}\` modify \`${col.name}\` ${this.getColumnDeclarationSQL({ ...col, autoincrement: false })}`);
201
+ }
202
+ getRenameColumnSQL(tableName, oldColumnName, to) {
203
+ tableName = this.quote(tableName);
204
+ oldColumnName = this.quote(oldColumnName);
205
+ const columnName = this.quote(to.name);
206
+ return `alter table ${tableName} change ${oldColumnName} ${columnName} ${this.getColumnDeclarationSQL(to)}`;
207
+ }
208
+ getRenameIndexSQL(tableName, index, oldIndexName) {
209
+ tableName = this.quote(tableName);
210
+ oldIndexName = this.quote(oldIndexName);
211
+ const keyName = this.quote(index.keyName);
212
+ return [`alter table ${tableName} rename index ${oldIndexName} to ${keyName}`];
213
+ }
214
+ getChangeColumnCommentSQL(tableName, to, schemaName) {
215
+ tableName = this.quote(tableName);
216
+ const columnName = this.quote(to.name);
217
+ return `alter table ${tableName} modify ${columnName} ${this.getColumnDeclarationSQL(to)}`;
218
+ }
219
+ alterTableColumn(column, table, changedProperties) {
220
+ const col = this.createTableColumn(column, table, changedProperties);
221
+ return [`alter table ${table.getQuotedName()} modify ${col}`];
222
+ }
223
+ getColumnDeclarationSQL(col) {
224
+ let ret = col.type;
225
+ ret += col.unsigned ? ' unsigned' : '';
226
+ ret += col.autoincrement ? ' auto_increment' : '';
227
+ ret += ' ';
228
+ ret += col.nullable ? 'null' : 'not null';
229
+ ret += col.default ? ' default ' + col.default : '';
230
+ ret += col.comment ? ` comment ${this.platform.quoteValue(col.comment)}` : '';
231
+ return ret;
232
+ }
233
+ async getAllEnumDefinitions(connection, tables) {
234
+ const sql = `select column_name as column_name, column_type as column_type, table_name as table_name
235
+ from information_schema.columns
236
+ where data_type = 'enum' and table_name in (${tables.map(t => `'${t.table_name}'`).join(', ')}) and table_schema = database()`;
237
+ const enums = await connection.execute(sql);
238
+ return enums.reduce((o, item) => {
239
+ o[item.table_name] ??= {};
240
+ o[item.table_name][item.column_name] = item.column_type.match(/enum\((.*)\)/)[1].split(',').map((item) => item.match(/'(.*)'/)[1]);
241
+ return o;
242
+ }, {});
243
+ }
244
+ async supportsCheckConstraints(connection) {
245
+ if (this._cache.supportsCheckConstraints != null) {
246
+ return this._cache.supportsCheckConstraints;
247
+ }
248
+ const sql = `select 1 from information_schema.tables where table_name = 'CHECK_CONSTRAINTS' and table_schema = 'information_schema'`;
249
+ const res = await connection.execute(sql);
250
+ return this._cache.supportsCheckConstraints = res.length > 0;
251
+ }
252
+ getChecksSQL(tables) {
253
+ return `select cc.constraint_schema as table_schema, tc.table_name as table_name, cc.constraint_name as name, cc.check_clause as expression
254
+ from information_schema.check_constraints cc
255
+ join information_schema.table_constraints tc
256
+ on tc.constraint_schema = cc.constraint_schema
257
+ and tc.constraint_name = cc.constraint_name
258
+ and constraint_type = 'CHECK'
259
+ where tc.table_name in (${tables.map(t => this.platform.quoteValue(t.table_name))}) and tc.constraint_schema = database()
260
+ order by tc.constraint_name`;
261
+ }
262
+ normalizeDefaultValue(defaultValue, length) {
263
+ return super.normalizeDefaultValue(defaultValue, length, MySqlSchemaHelper.DEFAULT_VALUES);
264
+ }
265
+ wrap(val, type) {
266
+ const stringType = type instanceof StringType || type instanceof TextType || type instanceof EnumType;
267
+ return typeof val === 'string' && val.length > 0 && stringType ? this.platform.quoteValue(val) : val;
268
+ }
269
+ }
@@ -0,0 +1,4 @@
1
+ export * from './MySqlExceptionConverter.js';
2
+ export * from './MySqlSchemaHelper.js';
3
+ export * from './MySqlPlatform.js';
4
+ export * from './MySqlNativeQueryBuilder.js';
@@ -0,0 +1,4 @@
1
+ export * from './MySqlExceptionConverter.js';
2
+ export * from './MySqlSchemaHelper.js';
3
+ export * from './MySqlPlatform.js';
4
+ export * from './MySqlNativeQueryBuilder.js';
@@ -0,0 +1,5 @@
1
+ import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
2
+ /** @internal */
3
+ export declare class PostgreSqlNativeQueryBuilder extends NativeQueryBuilder {
4
+ protected compileTruncate(): void;
5
+ }
@@ -0,0 +1,8 @@
1
+ import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
2
+ /** @internal */
3
+ export class PostgreSqlNativeQueryBuilder extends NativeQueryBuilder {
4
+ compileTruncate() {
5
+ super.compileTruncate();
6
+ this.parts.push('restart identity cascade');
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from './PostgreSqlNativeQueryBuilder.js';
@@ -0,0 +1 @@
1
+ export * from './PostgreSqlNativeQueryBuilder.js';
@@ -0,0 +1,6 @@
1
+ import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
2
+ export declare abstract class BaseSqliteConnection extends AbstractSqlConnection {
3
+ connect(options?: {
4
+ skipOnConnect?: boolean;
5
+ }): Promise<void>;
6
+ }
@@ -0,0 +1,8 @@
1
+ import { CompiledQuery } from 'kysely';
2
+ import { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
3
+ export class BaseSqliteConnection extends AbstractSqlConnection {
4
+ async connect(options) {
5
+ await super.connect(options);
6
+ await this.getClient().executeQuery(CompiledQuery.raw('pragma foreign_keys = on'));
7
+ }
8
+ }
@@ -0,0 +1,70 @@
1
+ import { type EntityProperty, type IsolationLevel } from '@mikro-orm/core';
2
+ import { AbstractSqlPlatform } from '../../AbstractSqlPlatform.js';
3
+ import { SqliteNativeQueryBuilder } from './SqliteNativeQueryBuilder.js';
4
+ import { SqliteSchemaHelper } from './SqliteSchemaHelper.js';
5
+ import { SqliteExceptionConverter } from './SqliteExceptionConverter.js';
6
+ export declare abstract class BaseSqlitePlatform extends AbstractSqlPlatform {
7
+ protected readonly schemaHelper: SqliteSchemaHelper;
8
+ protected readonly exceptionConverter: SqliteExceptionConverter;
9
+ /** @internal */
10
+ createNativeQueryBuilder(): SqliteNativeQueryBuilder;
11
+ usesDefaultKeyword(): boolean;
12
+ usesReturningStatement(): boolean;
13
+ usesEnumCheckConstraints(): boolean;
14
+ getCurrentTimestampSQL(length: number): string;
15
+ getDateTimeTypeDeclarationSQL(column: {
16
+ length: number;
17
+ }): string;
18
+ getBeginTransactionSQL(options?: {
19
+ isolationLevel?: IsolationLevel;
20
+ readOnly?: boolean;
21
+ }): string[];
22
+ getEnumTypeDeclarationSQL(column: {
23
+ items?: unknown[];
24
+ fieldNames: string[];
25
+ length?: number;
26
+ unsigned?: boolean;
27
+ autoincrement?: boolean;
28
+ }): string;
29
+ getTinyIntTypeDeclarationSQL(column: {
30
+ length?: number;
31
+ unsigned?: boolean;
32
+ autoincrement?: boolean;
33
+ }): string;
34
+ getSmallIntTypeDeclarationSQL(column: {
35
+ length?: number;
36
+ unsigned?: boolean;
37
+ autoincrement?: boolean;
38
+ }): string;
39
+ getIntegerTypeDeclarationSQL(column: {
40
+ length?: number;
41
+ unsigned?: boolean;
42
+ autoincrement?: boolean;
43
+ }): string;
44
+ getFloatDeclarationSQL(): string;
45
+ getBooleanTypeDeclarationSQL(): string;
46
+ getCharTypeDeclarationSQL(column: {
47
+ length?: number;
48
+ }): string;
49
+ getVarcharTypeDeclarationSQL(column: {
50
+ length?: number;
51
+ }): string;
52
+ normalizeColumnType(type: string, options: {
53
+ length?: number;
54
+ precision?: number;
55
+ scale?: number;
56
+ }): string;
57
+ convertsJsonAutomatically(): boolean;
58
+ /**
59
+ * This is used to narrow the value of Date properties as they will be stored as timestamps in sqlite.
60
+ * We use this method to convert Dates to timestamps when computing the changeset, so we have the right
61
+ * data type in the payload as well as in original entity data. Without that, we would end up with diffs
62
+ * including all Date properties, as we would be comparing Date object with timestamp.
63
+ */
64
+ processDateProperty(value: unknown): string | number | Date;
65
+ getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence'): string;
66
+ supportsDeferredUniqueConstraints(): boolean;
67
+ getFullTextWhereClause(): string;
68
+ quoteVersionValue(value: Date | number, prop: EntityProperty): Date | string | number;
69
+ quoteValue(value: any): string;
70
+ }
@@ -0,0 +1,104 @@
1
+ import { AbstractSqlPlatform } from '../../AbstractSqlPlatform.js';
2
+ import { SqliteNativeQueryBuilder } from './SqliteNativeQueryBuilder.js';
3
+ import { SqliteSchemaHelper } from './SqliteSchemaHelper.js';
4
+ import { SqliteExceptionConverter } from './SqliteExceptionConverter.js';
5
+ export class BaseSqlitePlatform extends AbstractSqlPlatform {
6
+ schemaHelper = new SqliteSchemaHelper(this);
7
+ exceptionConverter = new SqliteExceptionConverter();
8
+ /** @internal */
9
+ createNativeQueryBuilder() {
10
+ return new SqliteNativeQueryBuilder(this);
11
+ }
12
+ usesDefaultKeyword() {
13
+ return false;
14
+ }
15
+ usesReturningStatement() {
16
+ return true;
17
+ }
18
+ usesEnumCheckConstraints() {
19
+ return true;
20
+ }
21
+ getCurrentTimestampSQL(length) {
22
+ return super.getCurrentTimestampSQL(0);
23
+ }
24
+ getDateTimeTypeDeclarationSQL(column) {
25
+ return 'datetime';
26
+ }
27
+ getBeginTransactionSQL(options) {
28
+ return ['begin'];
29
+ }
30
+ getEnumTypeDeclarationSQL(column) {
31
+ if (column.items?.every(item => typeof item === 'string')) {
32
+ return 'text';
33
+ }
34
+ /* v8 ignore next */
35
+ return this.getTinyIntTypeDeclarationSQL(column);
36
+ }
37
+ getTinyIntTypeDeclarationSQL(column) {
38
+ return this.getIntegerTypeDeclarationSQL(column);
39
+ }
40
+ getSmallIntTypeDeclarationSQL(column) {
41
+ return this.getIntegerTypeDeclarationSQL(column);
42
+ }
43
+ getIntegerTypeDeclarationSQL(column) {
44
+ return 'integer';
45
+ }
46
+ getFloatDeclarationSQL() {
47
+ return 'real';
48
+ }
49
+ getBooleanTypeDeclarationSQL() {
50
+ return 'integer';
51
+ }
52
+ getCharTypeDeclarationSQL(column) {
53
+ return 'text';
54
+ }
55
+ getVarcharTypeDeclarationSQL(column) {
56
+ return 'text';
57
+ }
58
+ normalizeColumnType(type, options) {
59
+ const simpleType = this.extractSimpleType(type);
60
+ if (['varchar', 'text'].includes(simpleType)) {
61
+ return this.getVarcharTypeDeclarationSQL(options);
62
+ }
63
+ return simpleType;
64
+ }
65
+ convertsJsonAutomatically() {
66
+ return false;
67
+ }
68
+ /**
69
+ * This is used to narrow the value of Date properties as they will be stored as timestamps in sqlite.
70
+ * We use this method to convert Dates to timestamps when computing the changeset, so we have the right
71
+ * data type in the payload as well as in original entity data. Without that, we would end up with diffs
72
+ * including all Date properties, as we would be comparing Date object with timestamp.
73
+ */
74
+ processDateProperty(value) {
75
+ if (value instanceof Date) {
76
+ return +value;
77
+ }
78
+ return value;
79
+ }
80
+ getIndexName(tableName, columns, type) {
81
+ if (type === 'primary') {
82
+ return this.getDefaultPrimaryName(tableName, columns);
83
+ }
84
+ return super.getIndexName(tableName, columns, type);
85
+ }
86
+ supportsDeferredUniqueConstraints() {
87
+ return false;
88
+ }
89
+ getFullTextWhereClause() {
90
+ return `:column: match :query`;
91
+ }
92
+ quoteVersionValue(value, prop) {
93
+ if (prop.runtimeType === 'Date') {
94
+ return this.escape(value).replace(/^'|\.\d{3}'$/g, '');
95
+ }
96
+ return value;
97
+ }
98
+ quoteValue(value) {
99
+ if (value instanceof Date) {
100
+ return '' + +value;
101
+ }
102
+ return super.quoteValue(value);
103
+ }
104
+ }
@@ -0,0 +1,9 @@
1
+ import { ExceptionConverter, type Dictionary, type DriverException } from '@mikro-orm/core';
2
+ export declare class SqliteExceptionConverter extends ExceptionConverter {
3
+ /**
4
+ * @inheritDoc
5
+ * @see http://www.sqlite.org/c3ref/c_abort.html
6
+ * @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractSQLiteDriver.php
7
+ */
8
+ convertException(exception: Error & Dictionary): DriverException;
9
+ }
@@ -0,0 +1,54 @@
1
+ import { ConnectionException, ExceptionConverter, InvalidFieldNameException, LockWaitTimeoutException, NonUniqueFieldNameException, CheckConstraintViolationException, NotNullConstraintViolationException, ReadOnlyException, SyntaxErrorException, TableExistsException, TableNotFoundException, UniqueConstraintViolationException, ForeignKeyConstraintViolationException, } from '@mikro-orm/core';
2
+ export class SqliteExceptionConverter extends ExceptionConverter {
3
+ /**
4
+ * @inheritDoc
5
+ * @see http://www.sqlite.org/c3ref/c_abort.html
6
+ * @see https://github.com/doctrine/dbal/blob/master/src/Driver/AbstractSQLiteDriver.php
7
+ */
8
+ convertException(exception) {
9
+ /* v8 ignore next */
10
+ if (exception.message.includes('database is locked')) {
11
+ return new LockWaitTimeoutException(exception);
12
+ }
13
+ if (exception.message.includes('must be unique') ||
14
+ exception.message.includes('is not unique') ||
15
+ exception.message.includes('are not unique') ||
16
+ exception.message.includes('UNIQUE constraint failed')) {
17
+ return new UniqueConstraintViolationException(exception);
18
+ }
19
+ if (exception.message.includes('may not be NULL') || exception.message.includes('NOT NULL constraint failed')) {
20
+ return new NotNullConstraintViolationException(exception);
21
+ }
22
+ /* v8 ignore next */
23
+ if (exception.message.includes('CHECK constraint failed')) {
24
+ return new CheckConstraintViolationException(exception);
25
+ }
26
+ if (exception.message.includes('no such table:')) {
27
+ return new TableNotFoundException(exception);
28
+ }
29
+ if (exception.message.includes('already exists')) {
30
+ return new TableExistsException(exception);
31
+ }
32
+ if (exception.message.includes('no such column:')) {
33
+ return new InvalidFieldNameException(exception);
34
+ }
35
+ if (exception.message.includes('ambiguous column name')) {
36
+ return new NonUniqueFieldNameException(exception);
37
+ }
38
+ if (exception.message.includes('syntax error')) {
39
+ return new SyntaxErrorException(exception);
40
+ }
41
+ /* v8 ignore next */
42
+ if (exception.message.includes('attempt to write a readonly database')) {
43
+ return new ReadOnlyException(exception);
44
+ }
45
+ /* v8 ignore next */
46
+ if (exception.message.includes('unable to open database file')) {
47
+ return new ConnectionException(exception);
48
+ }
49
+ if (exception.message.includes('FOREIGN KEY constraint failed')) {
50
+ return new ForeignKeyConstraintViolationException(exception);
51
+ }
52
+ return super.convertException(exception);
53
+ }
54
+ }
@@ -0,0 +1,6 @@
1
+ import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
2
+ /** @internal */
3
+ export declare class SqliteNativeQueryBuilder extends NativeQueryBuilder {
4
+ protected compileTruncate(): void;
5
+ protected addLockClause(): void;
6
+ }
@@ -0,0 +1,11 @@
1
+ import { NativeQueryBuilder } from '../../query/NativeQueryBuilder.js';
2
+ /** @internal */
3
+ export class SqliteNativeQueryBuilder extends NativeQueryBuilder {
4
+ compileTruncate() {
5
+ const sql = `delete from ${this.getTableName()}`;
6
+ this.parts.push(sql);
7
+ }
8
+ addLockClause() {
9
+ return; // not supported
10
+ }
11
+ }
@@ -0,0 +1,38 @@
1
+ import { type Connection } from '@mikro-orm/core';
2
+ import type { AbstractSqlConnection } from '../../AbstractSqlConnection.js';
3
+ import { SchemaHelper } from '../../schema/SchemaHelper.js';
4
+ import type { Column, IndexDef, Table, TableDifference } from '../../typings.js';
5
+ import type { DatabaseTable } from '../../schema/DatabaseTable.js';
6
+ import type { DatabaseSchema } from '../../schema/DatabaseSchema.js';
7
+ export declare class SqliteSchemaHelper extends SchemaHelper {
8
+ disableForeignKeysSQL(): string;
9
+ enableForeignKeysSQL(): string;
10
+ supportsSchemaConstraints(): boolean;
11
+ getListTablesSQL(): string;
12
+ getDropDatabaseSQL(name: string): string;
13
+ loadInformationSchema(schema: DatabaseSchema, connection: AbstractSqlConnection, tables: Table[], schemas?: string[]): Promise<void>;
14
+ createTable(table: DatabaseTable, alter?: boolean): string[];
15
+ createTableColumn(column: Column, table: DatabaseTable, _changedProperties?: Set<string>): string | undefined;
16
+ getAddColumnsSQL(table: DatabaseTable, columns: Column[], diff?: TableDifference): string[];
17
+ dropForeignKey(tableName: string, constraintName: string): string;
18
+ getDropColumnsSQL(tableName: string, columns: Column[], schemaName?: string): string;
19
+ getCreateIndexSQL(tableName: string, index: IndexDef): string;
20
+ private parseTableDefinition;
21
+ private getColumns;
22
+ private getEnumDefinitions;
23
+ getPrimaryKeys(connection: AbstractSqlConnection, indexes: IndexDef[], tableName: string, schemaName?: string): Promise<string[]>;
24
+ private getIndexes;
25
+ private getChecks;
26
+ private getColumnDefinitions;
27
+ private getForeignKeys;
28
+ getManagementDbName(): string;
29
+ getCreateDatabaseSQL(name: string): string;
30
+ databaseExists(connection: Connection, name: string): Promise<boolean>;
31
+ /**
32
+ * Implicit indexes will be ignored when diffing
33
+ */
34
+ isImplicitIndex(name: string): boolean;
35
+ dropIndex(table: string, index: IndexDef, oldIndexName?: string): string;
36
+ alterTable(diff: TableDifference, safe?: boolean): string[];
37
+ private getAlterTempTableSQL;
38
+ }