@strapi/database 4.3.4 → 4.3.5
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/jest.config.js +1 -1
- package/lib/__tests__/lifecycles.test.js +1 -1
- package/lib/connection.js +4 -4
- package/lib/dialects/dialect.js +8 -2
- package/lib/dialects/index.js +2 -2
- package/lib/dialects/mysql/index.js +2 -2
- package/lib/dialects/mysql/schema-inspector.js +12 -16
- package/lib/dialects/postgresql/index.js +2 -2
- package/lib/dialects/postgresql/schema-inspector.js +30 -25
- package/lib/dialects/sqlite/index.js +1 -1
- package/lib/dialects/sqlite/schema-inspector.js +5 -5
- package/lib/entity-manager.js +29 -61
- package/lib/entity-repository.js +1 -1
- package/lib/errors/database.js +12 -0
- package/lib/errors/index.js +15 -0
- package/lib/errors/invalid-date.js +14 -0
- package/lib/errors/invalid-datetime.js +14 -0
- package/lib/errors/invalid-time.js +14 -0
- package/lib/errors/not-null.js +15 -0
- package/lib/fields/biginteger.js +17 -0
- package/lib/fields/boolean.js +39 -0
- package/lib/fields/date.js +16 -0
- package/lib/fields/datetime.js +19 -0
- package/lib/fields/field.js +17 -0
- package/lib/{fields.d.ts → fields/index.d.ts} +0 -0
- package/lib/fields/index.js +49 -0
- package/lib/fields/json.js +16 -0
- package/lib/fields/number.js +23 -0
- package/lib/fields/shared/parsers.js +69 -0
- package/lib/fields/string.js +17 -0
- package/lib/fields/time.js +17 -0
- package/lib/fields/timestamp.js +19 -0
- package/lib/index.js +1 -1
- package/lib/lifecycles/index.js +2 -2
- package/lib/lifecycles/subscribers/models-lifecycles.js +1 -1
- package/lib/lifecycles/subscribers/timestamps.js +2 -2
- package/lib/metadata/index.js +2 -2
- package/lib/metadata/relations.js +12 -15
- package/lib/migrations/index.js +5 -5
- package/lib/migrations/storage.js +4 -11
- package/lib/query/helpers/join.js +5 -5
- package/lib/query/helpers/order-by.js +1 -1
- package/lib/query/helpers/populate.js +43 -51
- package/lib/query/helpers/search.js +5 -5
- package/lib/query/helpers/transform.js +2 -2
- package/lib/query/helpers/where.js +17 -17
- package/lib/query/query-builder.js +11 -14
- package/lib/schema/builder.js +16 -14
- package/lib/schema/diff.js +15 -15
- package/lib/schema/index.js +1 -2
- package/lib/schema/schema.js +4 -4
- package/lib/schema/storage.js +3 -6
- package/lib/types/index.js +6 -6
- package/lib/utils/content-types.js +3 -3
- package/package.json +3 -3
- package/lib/errors.js +0 -56
- package/lib/fields.js +0 -231
package/jest.config.js
CHANGED
|
@@ -6,7 +6,7 @@ describe('LifecycleProvider', () => {
|
|
|
6
6
|
describe('run', () => {
|
|
7
7
|
/** @type {import("../lifecycles").LifecycleProvider} */
|
|
8
8
|
let provider;
|
|
9
|
-
|
|
9
|
+
const dbMetadataGetStub = jest.fn((uid) => ({ uid, name: 'TestModel' }));
|
|
10
10
|
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
const db = {
|
package/lib/connection.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/* eslint-disable
|
|
2
|
-
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
+
|
|
3
3
|
'use strict';
|
|
4
4
|
|
|
5
5
|
const knex = require('knex');
|
|
6
6
|
|
|
7
7
|
const SqliteClient = require('knex/lib/dialects/sqlite3/index');
|
|
8
8
|
|
|
9
|
-
const trySqlitePackage = packageName => {
|
|
9
|
+
const trySqlitePackage = (packageName) => {
|
|
10
10
|
try {
|
|
11
11
|
require.resolve(packageName);
|
|
12
12
|
return packageName;
|
|
@@ -44,7 +44,7 @@ const getSqlitePackageName = () => {
|
|
|
44
44
|
);
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
const createConnection = config => {
|
|
47
|
+
const createConnection = (config) => {
|
|
48
48
|
const knexConfig = { ...config };
|
|
49
49
|
if (knexConfig.client === 'sqlite') {
|
|
50
50
|
const sqlitePackageName = getSqlitePackageName();
|
package/lib/dialects/dialect.js
CHANGED
|
@@ -6,6 +6,7 @@ class Dialect {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
configure() {}
|
|
9
|
+
|
|
9
10
|
initialize() {}
|
|
10
11
|
|
|
11
12
|
getSqlType(type) {
|
|
@@ -28,8 +29,13 @@ class Dialect {
|
|
|
28
29
|
return false;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
async startSchemaUpdate() {
|
|
32
|
-
|
|
32
|
+
async startSchemaUpdate() {
|
|
33
|
+
// noop
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async endSchemaUpdate() {
|
|
37
|
+
// noop
|
|
38
|
+
}
|
|
33
39
|
|
|
34
40
|
transformErrors(error) {
|
|
35
41
|
if (error instanceof Error) {
|
package/lib/dialects/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const getDialectClass = client => {
|
|
3
|
+
const getDialectClass = (client) => {
|
|
4
4
|
switch (client) {
|
|
5
5
|
case 'postgres':
|
|
6
6
|
return require('./postgresql');
|
|
@@ -13,7 +13,7 @@ const getDialectClass = client => {
|
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const getDialect = db => {
|
|
16
|
+
const getDialect = (db) => {
|
|
17
17
|
const { client } = db.config.connection;
|
|
18
18
|
|
|
19
19
|
const constructor = getDialectClass(client);
|
|
@@ -15,12 +15,12 @@ class MysqlDialect extends Dialect {
|
|
|
15
15
|
this.db.config.connection.connection.bigNumberStrings = true;
|
|
16
16
|
this.db.config.connection.connection.typeCast = (field, next) => {
|
|
17
17
|
if (field.type === 'DECIMAL' || field.type === 'NEWDECIMAL') {
|
|
18
|
-
|
|
18
|
+
const value = field.string();
|
|
19
19
|
return value === null ? null : Number(value);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
if (field.type === 'TINY' && field.length === 1) {
|
|
23
|
-
|
|
23
|
+
const value = field.string();
|
|
24
24
|
return value ? value === '1' : null;
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -55,7 +55,7 @@ const SQL_QUERIES = {
|
|
|
55
55
|
`,
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
const toStrapiType = column => {
|
|
58
|
+
const toStrapiType = (column) => {
|
|
59
59
|
const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)[0];
|
|
60
60
|
|
|
61
61
|
switch (rootType) {
|
|
@@ -119,7 +119,7 @@ class MysqlSchemaInspector {
|
|
|
119
119
|
const tables = await this.getTables();
|
|
120
120
|
|
|
121
121
|
schema.tables = await Promise.all(
|
|
122
|
-
tables.map(async tableName => {
|
|
122
|
+
tables.map(async (tableName) => {
|
|
123
123
|
const columns = await this.getColumns(tableName);
|
|
124
124
|
const indexes = await this.getIndexes(tableName);
|
|
125
125
|
const foreignKeys = await this.getForeignKeys(tableName);
|
|
@@ -139,13 +139,13 @@ class MysqlSchemaInspector {
|
|
|
139
139
|
async getTables() {
|
|
140
140
|
const [rows] = await this.db.connection.raw(SQL_QUERIES.TABLE_LIST);
|
|
141
141
|
|
|
142
|
-
return rows.map(row => row.table_name);
|
|
142
|
+
return rows.map((row) => row.table_name);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
async getColumns(tableName) {
|
|
146
146
|
const [rows] = await this.db.connection.raw(SQL_QUERIES.LIST_COLUMNS, [tableName]);
|
|
147
147
|
|
|
148
|
-
return rows.map(row => {
|
|
148
|
+
return rows.map((row) => {
|
|
149
149
|
const { type, args = [], ...rest } = toStrapiType(row);
|
|
150
150
|
|
|
151
151
|
return {
|
|
@@ -214,20 +214,16 @@ class MysqlSchemaInspector {
|
|
|
214
214
|
ret[fkReference.constraint_name].referencedColumns.push(fkReference.referenced_column_name);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
const [
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
tableName,
|
|
222
|
-
]);
|
|
217
|
+
const [fkReferentialConstraints] = await this.db.connection.raw(
|
|
218
|
+
SQL_QUERIES.FOREIGN_KEY_REFERENTIALS_CONSTRAINTS,
|
|
219
|
+
[contraintNames, tableName]
|
|
220
|
+
);
|
|
223
221
|
|
|
224
222
|
for (const fkReferentialConstraint of fkReferentialConstraints) {
|
|
225
|
-
ret[
|
|
226
|
-
fkReferentialConstraint.
|
|
227
|
-
].
|
|
228
|
-
|
|
229
|
-
fkReferentialConstraint.constraint_name
|
|
230
|
-
].onDelete = fkReferentialConstraint.on_delete.toUpperCase();
|
|
223
|
+
ret[fkReferentialConstraint.constraint_name].onUpdate =
|
|
224
|
+
fkReferentialConstraint.on_update.toUpperCase();
|
|
225
|
+
ret[fkReferentialConstraint.constraint_name].onDelete =
|
|
226
|
+
fkReferentialConstraint.on_delete.toUpperCase();
|
|
231
227
|
}
|
|
232
228
|
}
|
|
233
229
|
|
|
@@ -16,7 +16,7 @@ class PostgresDialect extends Dialect {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
initialize() {
|
|
19
|
-
this.db.connection.client.driver.types.setTypeParser(1082, 'text', v => v); // Don't cast DATE string to Date()
|
|
19
|
+
this.db.connection.client.driver.types.setTypeParser(1082, 'text', (v) => v); // Don't cast DATE string to Date()
|
|
20
20
|
this.db.connection.client.driver.types.setTypeParser(1700, 'text', parseFloat);
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -38,7 +38,7 @@ class PostgresDialect extends Dialect {
|
|
|
38
38
|
transformErrors(error) {
|
|
39
39
|
switch (error.code) {
|
|
40
40
|
case '23502': {
|
|
41
|
-
throw new errors.
|
|
41
|
+
throw new errors.NotNullError({ column: error.column });
|
|
42
42
|
}
|
|
43
43
|
default: {
|
|
44
44
|
super.transformErrors(error);
|
|
@@ -51,7 +51,7 @@ const SQL_QUERIES = {
|
|
|
51
51
|
SELECT
|
|
52
52
|
kcu."constraint_name" as constraint_name,
|
|
53
53
|
kcu."column_name" as column_name
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
FROM information_schema.key_column_usage kcu
|
|
56
56
|
WHERE kcu.constraint_name=ANY(?)
|
|
57
57
|
AND kcu.table_schema = ?
|
|
@@ -77,7 +77,7 @@ const SQL_QUERIES = {
|
|
|
77
77
|
`,
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
const toStrapiType = column => {
|
|
80
|
+
const toStrapiType = (column) => {
|
|
81
81
|
const rootType = column.data_type.toLowerCase().match(/[^(), ]+/)[0];
|
|
82
82
|
|
|
83
83
|
switch (rootType) {
|
|
@@ -122,6 +122,18 @@ const toStrapiType = column => {
|
|
|
122
122
|
}
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
+
const getIndexType = (index) => {
|
|
126
|
+
if (index.is_primary) {
|
|
127
|
+
return 'primary';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (index.is_unique) {
|
|
131
|
+
return 'unique';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return null;
|
|
135
|
+
};
|
|
136
|
+
|
|
125
137
|
class PostgresqlSchemaInspector {
|
|
126
138
|
constructor(db) {
|
|
127
139
|
this.db = db;
|
|
@@ -133,7 +145,7 @@ class PostgresqlSchemaInspector {
|
|
|
133
145
|
const tables = await this.getTables();
|
|
134
146
|
|
|
135
147
|
schema.tables = await Promise.all(
|
|
136
|
-
tables.map(async tableName => {
|
|
148
|
+
tables.map(async (tableName) => {
|
|
137
149
|
const columns = await this.getColumns(tableName);
|
|
138
150
|
const indexes = await this.getIndexes(tableName);
|
|
139
151
|
const foreignKeys = await this.getForeignKeys(tableName);
|
|
@@ -159,7 +171,7 @@ class PostgresqlSchemaInspector {
|
|
|
159
171
|
this.getDatabaseSchema(),
|
|
160
172
|
]);
|
|
161
173
|
|
|
162
|
-
return rows.map(row => row.table_name);
|
|
174
|
+
return rows.map((row) => row.table_name);
|
|
163
175
|
}
|
|
164
176
|
|
|
165
177
|
async getColumns(tableName) {
|
|
@@ -168,7 +180,7 @@ class PostgresqlSchemaInspector {
|
|
|
168
180
|
tableName,
|
|
169
181
|
]);
|
|
170
182
|
|
|
171
|
-
return rows.map(row => {
|
|
183
|
+
return rows.map((row) => {
|
|
172
184
|
const { type, args = [], ...rest } = toStrapiType(row);
|
|
173
185
|
|
|
174
186
|
const defaultTo =
|
|
@@ -203,7 +215,7 @@ class PostgresqlSchemaInspector {
|
|
|
203
215
|
ret[index.indexrelid] = {
|
|
204
216
|
columns: [index.column_name],
|
|
205
217
|
name: index.index_name,
|
|
206
|
-
type: index
|
|
218
|
+
type: getIndexType(index),
|
|
207
219
|
};
|
|
208
220
|
} else {
|
|
209
221
|
ret[index.indexrelid].columns.push(index.column_name);
|
|
@@ -234,31 +246,24 @@ class PostgresqlSchemaInspector {
|
|
|
234
246
|
const constraintNames = Object.keys(ret);
|
|
235
247
|
const dbSchema = this.getDatabaseSchema();
|
|
236
248
|
if (constraintNames.length > 0) {
|
|
237
|
-
const {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
dbSchema,
|
|
242
|
-
tableName,
|
|
243
|
-
]);
|
|
249
|
+
const { rows: fkReferences } = await this.db.connection.raw(
|
|
250
|
+
SQL_QUERIES.FOREIGN_KEY_REFERENCES,
|
|
251
|
+
[[constraintNames], dbSchema, tableName]
|
|
252
|
+
);
|
|
244
253
|
|
|
245
254
|
for (const fkReference of fkReferences) {
|
|
246
255
|
ret[fkReference.constraint_name].columns.push(fkReference.column_name);
|
|
247
256
|
|
|
248
|
-
const {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
dbSchema,
|
|
253
|
-
]);
|
|
257
|
+
const { rows: fkReferencesConstraint } = await this.db.connection.raw(
|
|
258
|
+
SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN,
|
|
259
|
+
[[fkReference.constraint_name], dbSchema]
|
|
260
|
+
);
|
|
254
261
|
|
|
255
262
|
for (const fkReferenceC of fkReferencesConstraint) {
|
|
256
|
-
const {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
dbSchema,
|
|
261
|
-
]);
|
|
263
|
+
const { rows: fkReferencesConstraintReferece } = await this.db.connection.raw(
|
|
264
|
+
SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE,
|
|
265
|
+
[fkReferenceC.unique_constraint_name, dbSchema]
|
|
266
|
+
);
|
|
262
267
|
for (const fkReferenceConst of fkReferencesConstraintReferece) {
|
|
263
268
|
ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table;
|
|
264
269
|
ret[fkReference.constraint_name].referencedColumns.push(
|
|
@@ -61,7 +61,7 @@ class SqliteDialect extends Dialect {
|
|
|
61
61
|
transformErrors(error) {
|
|
62
62
|
switch (error.errno) {
|
|
63
63
|
case 19: {
|
|
64
|
-
throw new errors.
|
|
64
|
+
throw new errors.NotNullError(); // TODO: extract column name
|
|
65
65
|
}
|
|
66
66
|
default: {
|
|
67
67
|
super.transformErrors(error);
|
|
@@ -8,7 +8,7 @@ const SQL_QUERIES = {
|
|
|
8
8
|
FOREIGN_KEY_LIST: 'pragma foreign_key_list(??)',
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
const toStrapiType = column => {
|
|
11
|
+
const toStrapiType = (column) => {
|
|
12
12
|
const { type } = column;
|
|
13
13
|
|
|
14
14
|
const rootType = type.toLowerCase().match(/[^(), ]+/)[0];
|
|
@@ -84,13 +84,13 @@ class SqliteSchemaInspector {
|
|
|
84
84
|
async getTables() {
|
|
85
85
|
const rows = await this.db.connection.raw(SQL_QUERIES.TABLE_LIST);
|
|
86
86
|
|
|
87
|
-
return rows.map(row => row.name);
|
|
87
|
+
return rows.map((row) => row.name);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
async getColumns(tableName) {
|
|
91
91
|
const rows = await this.db.connection.raw(SQL_QUERIES.TABLE_INFO, [tableName]);
|
|
92
92
|
|
|
93
|
-
return rows.map(row => {
|
|
93
|
+
return rows.map((row) => {
|
|
94
94
|
const { type, args = [], ...rest } = toStrapiType(row);
|
|
95
95
|
|
|
96
96
|
return {
|
|
@@ -110,11 +110,11 @@ class SqliteSchemaInspector {
|
|
|
110
110
|
|
|
111
111
|
const ret = [];
|
|
112
112
|
|
|
113
|
-
for (const index of indexes.filter(index => !index.name.startsWith('sqlite_'))) {
|
|
113
|
+
for (const index of indexes.filter((index) => !index.name.startsWith('sqlite_'))) {
|
|
114
114
|
const res = await this.db.connection.raw(SQL_QUERIES.INDEX_INFO, [index.name]);
|
|
115
115
|
|
|
116
116
|
ret.push({
|
|
117
|
-
columns: res.map(row => row.name),
|
|
117
|
+
columns: res.map((row) => row.name),
|
|
118
118
|
name: index.name,
|
|
119
119
|
type: index.unique ? 'unique' : null,
|
|
120
120
|
});
|
package/lib/entity-manager.js
CHANGED
|
@@ -7,14 +7,14 @@ const { createQueryBuilder } = require('./query');
|
|
|
7
7
|
const { createRepository } = require('./entity-repository');
|
|
8
8
|
const { isBidirectional, isOneToAny } = require('./metadata/relations');
|
|
9
9
|
|
|
10
|
-
const toId = value => value.id || value;
|
|
11
|
-
const toIds = value => _.castArray(value || []).map(toId);
|
|
10
|
+
const toId = (value) => value.id || value;
|
|
11
|
+
const toIds = (value) => _.castArray(value || []).map(toId);
|
|
12
12
|
|
|
13
|
-
const isValidId = value => _.isString(value) || _.isInteger(value);
|
|
14
|
-
const toAssocs = data => {
|
|
13
|
+
const isValidId = (value) => _.isString(value) || _.isInteger(value);
|
|
14
|
+
const toAssocs = (data) => {
|
|
15
15
|
return _.castArray(data)
|
|
16
|
-
.filter(datum => !_.isNil(datum))
|
|
17
|
-
.map(datum => {
|
|
16
|
+
.filter((datum) => !_.isNil(datum))
|
|
17
|
+
.map((datum) => {
|
|
18
18
|
// if it is a string or an integer return an obj with id = to datum
|
|
19
19
|
if (isValidId(datum)) {
|
|
20
20
|
return { id: datum, __pivot: {} };
|
|
@@ -108,17 +108,14 @@ const processData = (metadata, data = {}, { withDefaults = false } = {}) => {
|
|
|
108
108
|
return obj;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
-
const createEntityManager = db => {
|
|
111
|
+
const createEntityManager = (db) => {
|
|
112
112
|
const repoMap = {};
|
|
113
113
|
|
|
114
114
|
return {
|
|
115
115
|
async findOne(uid, params) {
|
|
116
116
|
const states = await db.lifecycles.run('beforeFindOne', uid, { params });
|
|
117
117
|
|
|
118
|
-
const result = await this.createQueryBuilder(uid)
|
|
119
|
-
.init(params)
|
|
120
|
-
.first()
|
|
121
|
-
.execute();
|
|
118
|
+
const result = await this.createQueryBuilder(uid).init(params).first().execute();
|
|
122
119
|
|
|
123
120
|
await db.lifecycles.run('afterFindOne', uid, { params, result }, states);
|
|
124
121
|
|
|
@@ -129,9 +126,7 @@ const createEntityManager = db => {
|
|
|
129
126
|
async findMany(uid, params) {
|
|
130
127
|
const states = await db.lifecycles.run('beforeFindMany', uid, { params });
|
|
131
128
|
|
|
132
|
-
const result = await this.createQueryBuilder(uid)
|
|
133
|
-
.init(params)
|
|
134
|
-
.execute();
|
|
129
|
+
const result = await this.createQueryBuilder(uid).init(params).execute();
|
|
135
130
|
|
|
136
131
|
await db.lifecycles.run('afterFindMany', uid, { params, result }, states);
|
|
137
132
|
|
|
@@ -166,9 +161,7 @@ const createEntityManager = db => {
|
|
|
166
161
|
|
|
167
162
|
const dataToInsert = processData(metadata, data, { withDefaults: true });
|
|
168
163
|
|
|
169
|
-
const res = await this.createQueryBuilder(uid)
|
|
170
|
-
.insert(dataToInsert)
|
|
171
|
-
.execute();
|
|
164
|
+
const res = await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
|
172
165
|
|
|
173
166
|
const id = res[0].id || res[0];
|
|
174
167
|
|
|
@@ -198,15 +191,15 @@ const createEntityManager = db => {
|
|
|
198
191
|
throw new Error('CreateMany expects data to be an array');
|
|
199
192
|
}
|
|
200
193
|
|
|
201
|
-
const dataToInsert = data.map(datum =>
|
|
194
|
+
const dataToInsert = data.map((datum) =>
|
|
195
|
+
processData(metadata, datum, { withDefaults: true })
|
|
196
|
+
);
|
|
202
197
|
|
|
203
198
|
if (_.isEmpty(dataToInsert)) {
|
|
204
199
|
throw new Error('Nothing to insert');
|
|
205
200
|
}
|
|
206
201
|
|
|
207
|
-
await this.createQueryBuilder(uid)
|
|
208
|
-
.insert(dataToInsert)
|
|
209
|
-
.execute();
|
|
202
|
+
await this.createQueryBuilder(uid).insert(dataToInsert).execute();
|
|
210
203
|
|
|
211
204
|
const result = { count: data.length };
|
|
212
205
|
|
|
@@ -229,11 +222,7 @@ const createEntityManager = db => {
|
|
|
229
222
|
throw new Error('Update requires a where parameter');
|
|
230
223
|
}
|
|
231
224
|
|
|
232
|
-
const entity = await this.createQueryBuilder(uid)
|
|
233
|
-
.select('id')
|
|
234
|
-
.where(where)
|
|
235
|
-
.first()
|
|
236
|
-
.execute();
|
|
225
|
+
const entity = await this.createQueryBuilder(uid).select('id').where(where).first().execute();
|
|
237
226
|
|
|
238
227
|
if (!entity) {
|
|
239
228
|
return null;
|
|
@@ -244,10 +233,7 @@ const createEntityManager = db => {
|
|
|
244
233
|
const dataToUpdate = processData(metadata, data);
|
|
245
234
|
|
|
246
235
|
if (!_.isEmpty(dataToUpdate)) {
|
|
247
|
-
await this.createQueryBuilder(uid)
|
|
248
|
-
.where({ id })
|
|
249
|
-
.update(dataToUpdate)
|
|
250
|
-
.execute();
|
|
236
|
+
await this.createQueryBuilder(uid).where({ id }).update(dataToUpdate).execute();
|
|
251
237
|
}
|
|
252
238
|
|
|
253
239
|
await this.updateRelations(uid, id, data);
|
|
@@ -311,10 +297,7 @@ const createEntityManager = db => {
|
|
|
311
297
|
|
|
312
298
|
const { id } = entity;
|
|
313
299
|
|
|
314
|
-
await this.createQueryBuilder(uid)
|
|
315
|
-
.where({ id })
|
|
316
|
-
.delete()
|
|
317
|
-
.execute();
|
|
300
|
+
await this.createQueryBuilder(uid).where({ id }).delete().execute();
|
|
318
301
|
|
|
319
302
|
await this.deleteRelations(uid, id);
|
|
320
303
|
|
|
@@ -329,10 +312,7 @@ const createEntityManager = db => {
|
|
|
329
312
|
|
|
330
313
|
const { where } = params;
|
|
331
314
|
|
|
332
|
-
const deletedRows = await this.createQueryBuilder(uid)
|
|
333
|
-
.where(where)
|
|
334
|
-
.delete()
|
|
335
|
-
.execute();
|
|
315
|
+
const deletedRows = await this.createQueryBuilder(uid).where(where).delete().execute();
|
|
336
316
|
|
|
337
317
|
const result = { count: deletedRows };
|
|
338
318
|
|
|
@@ -397,9 +377,7 @@ const createEntityManager = db => {
|
|
|
397
377
|
continue;
|
|
398
378
|
}
|
|
399
379
|
|
|
400
|
-
await this.createQueryBuilder(joinTable.name)
|
|
401
|
-
.insert(rows)
|
|
402
|
-
.execute();
|
|
380
|
+
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
|
403
381
|
}
|
|
404
382
|
|
|
405
383
|
continue;
|
|
@@ -412,7 +390,7 @@ const createEntityManager = db => {
|
|
|
412
390
|
|
|
413
391
|
const { idColumn, typeColumn, typeField = '__type' } = morphColumn;
|
|
414
392
|
|
|
415
|
-
const rows = toAssocs(data[attributeName]).map(data => ({
|
|
393
|
+
const rows = toAssocs(data[attributeName]).map((data) => ({
|
|
416
394
|
[joinColumn.name]: id,
|
|
417
395
|
[idColumn.name]: data.id,
|
|
418
396
|
[typeColumn.name]: data[typeField],
|
|
@@ -424,9 +402,7 @@ const createEntityManager = db => {
|
|
|
424
402
|
continue;
|
|
425
403
|
}
|
|
426
404
|
|
|
427
|
-
await this.createQueryBuilder(joinTable.name)
|
|
428
|
-
.insert(rows)
|
|
429
|
-
.execute();
|
|
405
|
+
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
|
430
406
|
|
|
431
407
|
continue;
|
|
432
408
|
}
|
|
@@ -479,7 +455,7 @@ const createEntityManager = db => {
|
|
|
479
455
|
.execute();
|
|
480
456
|
}
|
|
481
457
|
|
|
482
|
-
const insert = toAssocs(data[attributeName]).map(data => {
|
|
458
|
+
const insert = toAssocs(data[attributeName]).map((data) => {
|
|
483
459
|
return {
|
|
484
460
|
[joinColumn.name]: id,
|
|
485
461
|
[inverseJoinColumn.name]: data.id,
|
|
@@ -493,9 +469,7 @@ const createEntityManager = db => {
|
|
|
493
469
|
continue;
|
|
494
470
|
}
|
|
495
471
|
|
|
496
|
-
await this.createQueryBuilder(joinTable.name)
|
|
497
|
-
.insert(insert)
|
|
498
|
-
.execute();
|
|
472
|
+
await this.createQueryBuilder(joinTable.name).insert(insert).execute();
|
|
499
473
|
}
|
|
500
474
|
}
|
|
501
475
|
},
|
|
@@ -570,9 +544,7 @@ const createEntityManager = db => {
|
|
|
570
544
|
continue;
|
|
571
545
|
}
|
|
572
546
|
|
|
573
|
-
await this.createQueryBuilder(joinTable.name)
|
|
574
|
-
.insert(rows)
|
|
575
|
-
.execute();
|
|
547
|
+
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
|
576
548
|
}
|
|
577
549
|
|
|
578
550
|
continue;
|
|
@@ -597,7 +569,7 @@ const createEntityManager = db => {
|
|
|
597
569
|
})
|
|
598
570
|
.execute();
|
|
599
571
|
|
|
600
|
-
const rows = toAssocs(data[attributeName]).map(data => ({
|
|
572
|
+
const rows = toAssocs(data[attributeName]).map((data) => ({
|
|
601
573
|
[joinColumn.name]: id,
|
|
602
574
|
[idColumn.name]: data.id,
|
|
603
575
|
[typeColumn.name]: data[typeField],
|
|
@@ -609,9 +581,7 @@ const createEntityManager = db => {
|
|
|
609
581
|
continue;
|
|
610
582
|
}
|
|
611
583
|
|
|
612
|
-
await this.createQueryBuilder(joinTable.name)
|
|
613
|
-
.insert(rows)
|
|
614
|
-
.execute();
|
|
584
|
+
await this.createQueryBuilder(joinTable.name).insert(rows).execute();
|
|
615
585
|
|
|
616
586
|
continue;
|
|
617
587
|
}
|
|
@@ -664,7 +634,7 @@ const createEntityManager = db => {
|
|
|
664
634
|
}
|
|
665
635
|
|
|
666
636
|
if (!_.isNull(data[attributeName])) {
|
|
667
|
-
const insert = toAssocs(data[attributeName]).map(data => {
|
|
637
|
+
const insert = toAssocs(data[attributeName]).map((data) => {
|
|
668
638
|
return {
|
|
669
639
|
[joinColumn.name]: id,
|
|
670
640
|
[inverseJoinColumn.name]: data.id,
|
|
@@ -678,9 +648,7 @@ const createEntityManager = db => {
|
|
|
678
648
|
continue;
|
|
679
649
|
}
|
|
680
650
|
|
|
681
|
-
await this.createQueryBuilder(joinTable.name)
|
|
682
|
-
.insert(insert)
|
|
683
|
-
.execute();
|
|
651
|
+
await this.createQueryBuilder(joinTable.name).insert(insert).execute();
|
|
684
652
|
}
|
|
685
653
|
}
|
|
686
654
|
}
|
|
@@ -817,7 +785,7 @@ const createEntityManager = db => {
|
|
|
817
785
|
populate,
|
|
818
786
|
});
|
|
819
787
|
|
|
820
|
-
return
|
|
788
|
+
return { ...entity, ...entry };
|
|
821
789
|
},
|
|
822
790
|
|
|
823
791
|
// TODO: support multiple relations at once with the populate syntax
|
package/lib/entity-repository.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
class DatabaseError extends Error {
|
|
4
|
+
constructor(message, details = {}) {
|
|
5
|
+
super();
|
|
6
|
+
this.name = 'DatabaseError';
|
|
7
|
+
this.message = message || 'A database error occured';
|
|
8
|
+
this.details = details;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = DatabaseError;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DatabaseError = require('./database');
|
|
4
|
+
const NotNullError = require('./not-null');
|
|
5
|
+
const InvalidTimeError = require('./invalid-time');
|
|
6
|
+
const InvalidDateError = require('./invalid-date');
|
|
7
|
+
const InvalidDateTimeError = require('./invalid-datetime');
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
DatabaseError,
|
|
11
|
+
NotNullError,
|
|
12
|
+
InvalidTimeError,
|
|
13
|
+
InvalidDateError,
|
|
14
|
+
InvalidDateTimeError,
|
|
15
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DatabaseError = require('./database');
|
|
4
|
+
|
|
5
|
+
class InvalidDateError extends DatabaseError {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super();
|
|
8
|
+
this.name = 'InvalidTimeFormat';
|
|
9
|
+
this.message = message || 'Invalid date format, expected YYYY-MM-DD';
|
|
10
|
+
this.details = {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = InvalidDateError;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DatabaseError = require('./database');
|
|
4
|
+
|
|
5
|
+
class InvalidDateTimeError extends DatabaseError {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super();
|
|
8
|
+
this.name = 'InvalidTimeFormat';
|
|
9
|
+
this.message = message || 'Invalid datetime format, expected a timestamp or an ISO date';
|
|
10
|
+
this.details = {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = InvalidDateTimeError;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const DatabaseError = require('./database');
|
|
4
|
+
|
|
5
|
+
class InvalidTimeError extends DatabaseError {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super();
|
|
8
|
+
this.name = 'InvalidTimeFormat';
|
|
9
|
+
this.message = message || 'Invalid time format, expected HH:mm:ss.SSS';
|
|
10
|
+
this.details = {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = InvalidTimeError;
|