/
BetterSqlitePlatform.ts
131 lines (100 loc) · 3.88 KB
/
BetterSqlitePlatform.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// @ts-ignore
import { escape } from 'sqlstring-sqlite';
import type { EntityProperty } from '@mikro-orm/core';
import { expr, JsonProperty, Utils } from '@mikro-orm/core';
import { AbstractSqlPlatform } from '@mikro-orm/knex';
import { BetterSqliteSchemaHelper } from './BetterSqliteSchemaHelper';
import { BetterSqliteExceptionConverter } from './BetterSqliteExceptionConverter';
export class BetterSqlitePlatform extends AbstractSqlPlatform {
protected readonly schemaHelper: BetterSqliteSchemaHelper = new BetterSqliteSchemaHelper(this);
protected readonly exceptionConverter = new BetterSqliteExceptionConverter();
usesDefaultKeyword(): boolean {
return false;
}
getCurrentTimestampSQL(length: number): string {
return super.getCurrentTimestampSQL(0);
}
getDateTimeTypeDeclarationSQL(column: { length: number }): string {
return 'datetime';
}
getEnumTypeDeclarationSQL(column: { items?: unknown[]; fieldNames: string[]; length?: number; unsigned?: boolean; autoincrement?: boolean }): string {
if (column.items?.every(item => Utils.isString(item))) {
return 'text';
}
return this.getTinyIntTypeDeclarationSQL(column);
}
getTinyIntTypeDeclarationSQL(column: { length?: number; unsigned?: boolean; autoincrement?: boolean }): string {
return this.getIntegerTypeDeclarationSQL(column);
}
getSmallIntTypeDeclarationSQL(column: { length?: number; unsigned?: boolean; autoincrement?: boolean }): string {
return this.getIntegerTypeDeclarationSQL(column);
}
getIntegerTypeDeclarationSQL(column: { length?: number; unsigned?: boolean; autoincrement?: boolean }): string {
return 'integer';
}
getFloatDeclarationSQL(): string {
return 'real';
}
getBooleanTypeDeclarationSQL(): string {
return 'integer';
}
getVarcharTypeDeclarationSQL(column: { length?: number }): string {
return 'text';
}
convertsJsonAutomatically(): boolean {
return false;
}
allowsComparingTuples() {
return false;
}
/**
* This is used to narrow the value of Date properties as they will be stored as timestamps in sqlite.
* We use this method to convert Dates to timestamps when computing the changeset, so we have the right
* data type in the payload as well as in original entity data. Without that, we would end up with diffs
* including all Date properties, as we would be comparing Date object with timestamp.
*/
processDateProperty(value: unknown): string | number | Date {
if (value instanceof Date) {
return +value;
}
return value as number;
}
quoteVersionValue(value: Date | number, prop: EntityProperty): Date | string | number {
if (prop.type.toLowerCase() === 'date') {
return escape(value, true, this.timezone).replace(/^'|\.\d{3}'$/g, '');
}
return value;
}
requiresValuesKeyword() {
return true;
}
quoteValue(value: any): string {
/* istanbul ignore if */
if (Utils.isPlainObject(value) || value?.[JsonProperty]) {
return escape(JSON.stringify(value), true, this.timezone);
}
if (value instanceof Date) {
return '' + +value;
}
return escape(value, true, this.timezone);
}
getSearchJsonPropertyKey(path: string[], type: string, aliased: boolean): string {
const [a, ...b] = path;
if (aliased) {
return expr(alias => `json_extract(${this.quoteIdentifier(`${alias}.${a}`)}, '$.${b.join('.')}')`);
}
return `json_extract(${this.quoteIdentifier(a)}, '$.${b.join('.')}')`;
}
getIndexName(tableName: string, columns: string[], type: 'index' | 'unique' | 'foreign' | 'primary' | 'sequence'): string {
if (type === 'primary') {
return this.getDefaultPrimaryName(tableName, columns);
}
return super.getIndexName(tableName, columns, type);
}
getDefaultPrimaryName(tableName: string, columns: string[]): string {
return 'primary';
}
supportsDownMigrations(): boolean {
return false;
}
}