@mikro-orm/mariadb 7.0.2-dev.8 → 7.0.2
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.
- package/MariaDbDriver.d.ts +23 -6
- package/MariaDbDriver.js +20 -19
- package/MariaDbMikroORM.d.ts +52 -12
- package/MariaDbMikroORM.js +15 -14
- package/MariaDbPlatform.d.ts +4 -3
- package/MariaDbPlatform.js +10 -9
- package/MariaDbQueryBuilder.d.ts +7 -2
- package/MariaDbQueryBuilder.js +73 -76
- package/MariaDbSchemaHelper.d.ts +21 -8
- package/MariaDbSchemaHelper.js +143 -139
- package/README.md +128 -294
- package/index.d.ts +5 -1
- package/index.js +1 -1
- package/package.json +5 -5
package/MariaDbSchemaHelper.js
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
import { MySqlSchemaHelper
|
|
1
|
+
import { MySqlSchemaHelper } from '@mikro-orm/mysql';
|
|
2
|
+
/** Schema introspection helper for MariaDB. */
|
|
2
3
|
export class MariaDbSchemaHelper extends MySqlSchemaHelper {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
// MariaDB supports CLUSTERING=YES only with the Aria storage engine.
|
|
9
|
-
// Using this option with InnoDB tables will have no effect (silently ignored).
|
|
10
|
-
// See: https://mariadb.com/kb/en/create-index/#clustering-yes
|
|
11
|
-
if (index.clustered) {
|
|
12
|
-
sql += ' clustering=yes';
|
|
13
|
-
}
|
|
14
|
-
return sql;
|
|
4
|
+
appendMySqlIndexSuffix(sql, index) {
|
|
5
|
+
// MariaDB uses IGNORED instead of MySQL's INVISIBLE keyword
|
|
6
|
+
if (index.invisible) {
|
|
7
|
+
sql += ' ignored';
|
|
15
8
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const table = schema.addTable(t.table_name, t.schema_name, t.table_comment);
|
|
29
|
-
const pks = await this.getPrimaryKeys(connection, indexes[key], table.name, table.schema);
|
|
30
|
-
table.init(columns[key], indexes[key], checks[key], pks, fks[key], enums[key]);
|
|
31
|
-
}
|
|
9
|
+
// MariaDB supports CLUSTERING=YES only with the Aria storage engine.
|
|
10
|
+
// Using this option with InnoDB tables will have no effect (silently ignored).
|
|
11
|
+
// See: https://mariadb.com/kb/en/create-index/#clustering-yes
|
|
12
|
+
if (index.clustered) {
|
|
13
|
+
sql += ' clustering=yes';
|
|
14
|
+
}
|
|
15
|
+
return sql;
|
|
16
|
+
}
|
|
17
|
+
async loadInformationSchema(schema, connection, tables) {
|
|
18
|
+
/* v8 ignore next */
|
|
19
|
+
if (tables.length === 0) {
|
|
20
|
+
return;
|
|
32
21
|
}
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
const columns = await this.getAllColumns(connection, tables);
|
|
23
|
+
const indexes = await this.getAllIndexes(connection, tables);
|
|
24
|
+
const checks = await this.getAllChecks(connection, tables, columns);
|
|
25
|
+
const fks = await this.getAllForeignKeys(connection, tables);
|
|
26
|
+
const enums = await this.getAllEnumDefinitions(connection, tables);
|
|
27
|
+
for (const t of tables) {
|
|
28
|
+
const key = this.getTableKey(t);
|
|
29
|
+
const table = schema.addTable(t.table_name, t.schema_name, t.table_comment);
|
|
30
|
+
const pks = await this.getPrimaryKeys(connection, indexes[key], table.name, table.schema);
|
|
31
|
+
table.init(columns[key], indexes[key], checks[key], pks, fks[key], enums[key]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async getAllIndexes(connection, tables) {
|
|
35
|
+
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, index_type as index_type, sub_part as sub_part, collation as sort_order /*M!100600 , ignored as ignored */
|
|
35
36
|
from information_schema.statistics where table_schema = database()
|
|
36
37
|
and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
|
|
37
38
|
order by schema_name, table_name, index_name, seq_in_index`;
|
|
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
|
-
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;
|
|
39
|
+
const allIndexes = await connection.execute(sql);
|
|
40
|
+
const ret = {};
|
|
41
|
+
for (const index of allIndexes) {
|
|
42
|
+
const key = this.getTableKey(index);
|
|
43
|
+
const indexDef = {
|
|
44
|
+
columnNames: [index.column_name],
|
|
45
|
+
keyName: index.index_name,
|
|
46
|
+
unique: !index.non_unique,
|
|
47
|
+
primary: index.index_name === 'PRIMARY',
|
|
48
|
+
constraint: !index.non_unique,
|
|
49
|
+
};
|
|
50
|
+
// Capture column options (prefix length, sort order)
|
|
51
|
+
if (index.sub_part != null || index.sort_order === 'D') {
|
|
52
|
+
indexDef.columns = [
|
|
53
|
+
{
|
|
54
|
+
name: index.column_name,
|
|
55
|
+
...(index.sub_part != null && { length: index.sub_part }),
|
|
56
|
+
...(index.sort_order === 'D' && { sort: 'DESC' }),
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
// Capture index type for fulltext and spatial indexes
|
|
61
|
+
if (index.index_type === 'FULLTEXT') {
|
|
62
|
+
indexDef.type = 'fulltext';
|
|
63
|
+
} else if (index.index_type === 'SPATIAL') {
|
|
64
|
+
/* v8 ignore next */
|
|
65
|
+
indexDef.type = 'spatial';
|
|
66
|
+
}
|
|
67
|
+
// Capture ignored flag (MariaDB 10.6+, equivalent to MySQL's INVISIBLE)
|
|
68
|
+
/* v8 ignore next */
|
|
69
|
+
if (index.ignored === 'YES') {
|
|
70
|
+
indexDef.invisible = true;
|
|
71
|
+
}
|
|
72
|
+
ret[key] ??= [];
|
|
73
|
+
ret[key].push(indexDef);
|
|
79
74
|
}
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
for (const key of Object.keys(ret)) {
|
|
76
|
+
ret[key] = await this.mapIndexes(ret[key]);
|
|
77
|
+
}
|
|
78
|
+
return ret;
|
|
79
|
+
}
|
|
80
|
+
async getAllColumns(connection, tables) {
|
|
81
|
+
const sql = `select table_name as table_name,
|
|
82
82
|
nullif(table_schema, schema()) as schema_name,
|
|
83
83
|
column_name as column_name,
|
|
84
84
|
column_default as column_default,
|
|
@@ -94,69 +94,73 @@ export class MariaDbSchemaHelper extends MySqlSchemaHelper {
|
|
|
94
94
|
ifnull(datetime_precision, character_maximum_length) length
|
|
95
95
|
from information_schema.columns where table_schema = database() and table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')})
|
|
96
96
|
order by ordinal_position`;
|
|
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
|
-
|
|
132
|
-
|
|
97
|
+
const allColumns = await connection.execute(sql);
|
|
98
|
+
const str = val => (val != null ? '' + val : val);
|
|
99
|
+
const extra = val =>
|
|
100
|
+
val.replace(/auto_increment|default_generated|(stored|virtual) generated/i, '').trim() || undefined;
|
|
101
|
+
const ret = {};
|
|
102
|
+
for (const col of allColumns) {
|
|
103
|
+
const mappedType = this.platform.getMappedType(col.column_type);
|
|
104
|
+
const tmp = this.normalizeDefaultValue(
|
|
105
|
+
mappedType.compareAsType() === 'boolean' && ['0', '1'].includes(col.column_default)
|
|
106
|
+
? ['false', 'true'][+col.column_default]
|
|
107
|
+
: col.column_default,
|
|
108
|
+
col.length,
|
|
109
|
+
);
|
|
110
|
+
const defaultValue = str(tmp === 'NULL' && col.is_nullable === 'YES' ? null : tmp);
|
|
111
|
+
const key = this.getTableKey(col);
|
|
112
|
+
const generated = col.generation_expression
|
|
113
|
+
? `${col.generation_expression.replaceAll(`\\'`, `'`)} ${col.extra.match(/stored generated/i) ? 'stored' : 'virtual'}`
|
|
114
|
+
: undefined;
|
|
115
|
+
ret[key] ??= [];
|
|
116
|
+
ret[key].push({
|
|
117
|
+
name: col.column_name,
|
|
118
|
+
type: this.platform.isNumericColumn(mappedType)
|
|
119
|
+
? col.column_type.replace(/ unsigned$/, '').replace(/\(\d+\)$/, '')
|
|
120
|
+
: col.column_type,
|
|
121
|
+
mappedType,
|
|
122
|
+
unsigned: col.column_type.endsWith(' unsigned'),
|
|
123
|
+
length: col.length,
|
|
124
|
+
default: this.wrap(defaultValue, mappedType),
|
|
125
|
+
nullable: col.is_nullable === 'YES',
|
|
126
|
+
primary: col.column_key === 'PRI',
|
|
127
|
+
unique: col.column_key === 'UNI',
|
|
128
|
+
autoincrement: col.extra === 'auto_increment',
|
|
129
|
+
precision: col.numeric_precision,
|
|
130
|
+
scale: col.numeric_scale,
|
|
131
|
+
comment: col.column_comment,
|
|
132
|
+
extra: extra(col.extra),
|
|
133
|
+
generated,
|
|
134
|
+
});
|
|
133
135
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
136
|
+
return ret;
|
|
137
|
+
}
|
|
138
|
+
async getAllChecks(connection, tables, columns) {
|
|
139
|
+
const sql = this.getChecksSQL(tables);
|
|
140
|
+
const allChecks = await connection.execute(sql);
|
|
141
|
+
const ret = {};
|
|
142
|
+
for (const check of allChecks) {
|
|
143
|
+
const key = this.getTableKey(check);
|
|
144
|
+
const match = /^json_valid\(`(.*)`\)$/i.exec(check.expression);
|
|
145
|
+
const col = columns?.[key]?.find(col => col.name === match?.[1]);
|
|
146
|
+
if (col && match) {
|
|
147
|
+
col.type = 'json';
|
|
148
|
+
col.mappedType = this.platform.getMappedType('json');
|
|
149
|
+
delete col.length;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
ret[key] ??= [];
|
|
153
|
+
ret[key].push({
|
|
154
|
+
name: check.name,
|
|
155
|
+
columnName: check.column_name,
|
|
156
|
+
definition: `check ${check.expression}`,
|
|
157
|
+
expression: check.expression.replace(/^\((.*)\)$/, '$1'),
|
|
158
|
+
});
|
|
157
159
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
return ret;
|
|
161
|
+
}
|
|
162
|
+
getChecksSQL(tables) {
|
|
163
|
+
return `select
|
|
160
164
|
tc.constraint_schema as table_schema,
|
|
161
165
|
tc.table_name as table_name,
|
|
162
166
|
tc.constraint_name as name,
|
|
@@ -165,8 +169,8 @@ export class MariaDbSchemaHelper extends MySqlSchemaHelper {
|
|
|
165
169
|
from information_schema.check_constraints tc
|
|
166
170
|
where tc.table_name in (${tables.map(t => this.platform.quoteValue(t.table_name)).join(', ')}) and tc.constraint_schema = database()
|
|
167
171
|
order by tc.constraint_name`;
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
}
|
|
173
|
+
wrap(val, type) {
|
|
174
|
+
return val;
|
|
175
|
+
}
|
|
172
176
|
}
|