remult 0.22.2 → 0.22.4
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/esm/remult-knex/index.js +2 -2
- package/esm/src/backend-tests/backend-database-test-setup.backend-spec.js +10 -0
- package/esm/src/remult3/RepositoryImplementation.d.ts +1 -1
- package/esm/src/remult3/RepositoryImplementation.js +34 -9
- package/esm/src/shared-tests/db-tests.db-tests.js +92 -0
- package/package.json +1 -1
- package/remult-knex/index.js +2 -2
- package/src/backend-tests/backend-database-test-setup.backend-spec.js +10 -0
- package/src/remult3/RepositoryImplementation.d.ts +1 -1
- package/src/remult3/RepositoryImplementation.js +103 -76
- package/src/shared-tests/db-tests.db-tests.js +161 -0
package/esm/remult-knex/index.js
CHANGED
|
@@ -192,7 +192,7 @@ class KnexEntityDataProvider {
|
|
|
192
192
|
let insert = this.knex(e.$entityName).insert(insertObject);
|
|
193
193
|
if (isAutoIncrement(this.entity.idMetadata.field)) {
|
|
194
194
|
let newId;
|
|
195
|
-
if (this.knex.client.config.client === 'mysql2') {
|
|
195
|
+
if (this.knex.client.config.client === 'mysql2' || this.knex.client.config.client === 'mysql') {
|
|
196
196
|
let result = await insert;
|
|
197
197
|
newId = result[0];
|
|
198
198
|
}
|
|
@@ -380,7 +380,7 @@ export class KnexSchemaBuilder {
|
|
|
380
380
|
KnexSchemaBuilder.logToConsole = true;
|
|
381
381
|
function supportsJson(knex) {
|
|
382
382
|
const client = knex.client.config.client;
|
|
383
|
-
if (client?.includes('sqlite3') || client?.includes('mssql'))
|
|
383
|
+
if (client?.includes('sqlite3') || client?.includes('mssql') || client?.includes('mysql'))
|
|
384
384
|
return false;
|
|
385
385
|
return true;
|
|
386
386
|
}
|
|
@@ -64,6 +64,16 @@ export const mySqlTest = addDatabaseToTest(testKnexSqlImpl(Knex.default({
|
|
|
64
64
|
database: 'test',
|
|
65
65
|
},
|
|
66
66
|
}), 'mysql2'));
|
|
67
|
+
addDatabaseToTest(testKnexSqlImpl(Knex.default({
|
|
68
|
+
client: 'mysql',
|
|
69
|
+
connection: {
|
|
70
|
+
user: 'root',
|
|
71
|
+
password: 'MASTERKEY',
|
|
72
|
+
host: '127.0.0.1',
|
|
73
|
+
database: 'test',
|
|
74
|
+
port: 3307
|
|
75
|
+
},
|
|
76
|
+
}), 'mysql'));
|
|
67
77
|
let pg = createPostgresConnection();
|
|
68
78
|
export function testPostgresImplementation(key, what, focus = false) {
|
|
69
79
|
itWithFocus(key + ' - postgres', async () => {
|
|
@@ -124,7 +124,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
|
|
|
124
124
|
private _columns;
|
|
125
125
|
get fields(): FieldsRef<T>;
|
|
126
126
|
private _saving;
|
|
127
|
-
save(): Promise<T>;
|
|
127
|
+
save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject?: string[]): Promise<T>;
|
|
128
128
|
private getIdFilter;
|
|
129
129
|
delete(): Promise<void>;
|
|
130
130
|
loadDataFrom(data: any, loadItems?: FieldMetadata[]): Promise<void>;
|
|
@@ -190,8 +190,28 @@ export class RepositoryImplementation {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
async update(id, entity) {
|
|
193
|
+
{
|
|
194
|
+
let ref = getEntityRef(entity, false);
|
|
195
|
+
if (ref)
|
|
196
|
+
return (await ref.save());
|
|
197
|
+
}
|
|
193
198
|
let ref = this.getRefForExistingRow(entity, id);
|
|
194
|
-
|
|
199
|
+
if (this.dataProvider.isProxy) {
|
|
200
|
+
return await ref.save(Object.keys(entity));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const r = await this.findId(ref.id, { useCache: false });
|
|
204
|
+
if (!r)
|
|
205
|
+
throw new Error('Not Found');
|
|
206
|
+
for (const key in entity) {
|
|
207
|
+
if (Object.prototype.hasOwnProperty.call(entity, key)) {
|
|
208
|
+
let f = ref.fields[key];
|
|
209
|
+
if (f)
|
|
210
|
+
r[key] = f.value;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return await getEntityRef(r).save();
|
|
214
|
+
}
|
|
195
215
|
}
|
|
196
216
|
getRefForExistingRow(entity, id) {
|
|
197
217
|
let ref = getEntityRef(entity, false);
|
|
@@ -909,7 +929,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
909
929
|
}
|
|
910
930
|
return this._columns;
|
|
911
931
|
}
|
|
912
|
-
async save() {
|
|
932
|
+
async save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
913
933
|
try {
|
|
914
934
|
if (this._saving)
|
|
915
935
|
throw new Error('cannot save while entity is already saving');
|
|
@@ -917,7 +937,8 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
917
937
|
if (this.wasDeleted())
|
|
918
938
|
throw new Error('cannot save a deleted row');
|
|
919
939
|
this.isLoading = true;
|
|
920
|
-
|
|
940
|
+
if (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject === undefined) // no need
|
|
941
|
+
await this.__validateEntity();
|
|
921
942
|
let doNotSave = false;
|
|
922
943
|
for (const col of this.fields) {
|
|
923
944
|
if (col.metadata.options.saving)
|
|
@@ -930,7 +951,9 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
930
951
|
let d = this.copyDataToObject();
|
|
931
952
|
let ignoreKeys = [];
|
|
932
953
|
for (const field of this.metadata.fields) {
|
|
933
|
-
if (field.dbReadOnly
|
|
954
|
+
if (field.dbReadOnly ||
|
|
955
|
+
(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject !== undefined &&
|
|
956
|
+
!onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject.includes(field.key))) {
|
|
934
957
|
d[field.key] = undefined;
|
|
935
958
|
ignoreKeys.push(field.key);
|
|
936
959
|
let f = this.fields.find(field);
|
|
@@ -1834,11 +1857,13 @@ export function decorateColumnSettings(settings, remult) {
|
|
|
1834
1857
|
isIdNumeric =
|
|
1835
1858
|
remult.repo(settings.valueType).metadata.idMetadata.field
|
|
1836
1859
|
.valueType === Number;
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1860
|
+
if (isIdNumeric) {
|
|
1861
|
+
for (const key of [
|
|
1862
|
+
'fieldTypeInDb',
|
|
1863
|
+
]) {
|
|
1864
|
+
//@ts-ignore
|
|
1865
|
+
target[key] = ValueConverters.Integer[key];
|
|
1866
|
+
}
|
|
1842
1867
|
}
|
|
1843
1868
|
}
|
|
1844
1869
|
}
|
|
@@ -1082,3 +1082,95 @@ testAll('test relation to number id', async ({ createEntity }) => {
|
|
|
1082
1082
|
expect(await taskRepo.count({ category: cat[1] })).toBe(1);
|
|
1083
1083
|
expect(await taskRepo.count({ category: { $id: cat[0].id } })).toBe(2);
|
|
1084
1084
|
}, false, { exclude: [TestDbs.mongo, TestDbs.mongoNoTrans] });
|
|
1085
|
+
testAll('test relation to string id', async ({ createEntity }) => {
|
|
1086
|
+
const category = class {
|
|
1087
|
+
constructor() {
|
|
1088
|
+
this.id = '';
|
|
1089
|
+
this.name = '';
|
|
1090
|
+
}
|
|
1091
|
+
};
|
|
1092
|
+
describeClass(category, Entity('rel_ID_string_categories', { allowApiCrud: true }), {
|
|
1093
|
+
id: Fields.cuid(),
|
|
1094
|
+
name: Fields.string(),
|
|
1095
|
+
});
|
|
1096
|
+
const task = class {
|
|
1097
|
+
constructor() {
|
|
1098
|
+
this.id = 0;
|
|
1099
|
+
this.title = '';
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
describeClass(task, Entity('rel_ID_string_task', { allowApiCrud: true }), {
|
|
1103
|
+
id: Fields.autoIncrement(),
|
|
1104
|
+
title: Fields.string(),
|
|
1105
|
+
category: Field(() => category),
|
|
1106
|
+
});
|
|
1107
|
+
const catRepo = await createEntity(category);
|
|
1108
|
+
const taskRepo = await createEntity(task);
|
|
1109
|
+
const cat = await catRepo.insert([{ name: 'cat0' }, { name: 'cat1' }]);
|
|
1110
|
+
await taskRepo.insert([
|
|
1111
|
+
{ title: 't1', category: cat[0] },
|
|
1112
|
+
{ title: 't2', category: cat[0] },
|
|
1113
|
+
{ title: 't3', category: cat[1] },
|
|
1114
|
+
]);
|
|
1115
|
+
expect(taskRepo.fields.category.valueConverter.fieldTypeInDb).toBeUndefined();
|
|
1116
|
+
expect(await taskRepo.count({ category: cat[0] })).toBe(2);
|
|
1117
|
+
expect(await taskRepo.count({ category: cat[1] })).toBe(1);
|
|
1118
|
+
expect(await taskRepo.count({ category: { $id: cat[0].id } })).toBe(2);
|
|
1119
|
+
}, false, { exclude: [TestDbs.mongo, TestDbs.mongoNoTrans] });
|
|
1120
|
+
testAll("test update doesn't override other values", async ({ createEntity, remult }) => {
|
|
1121
|
+
const catRepo = await createEntity(Categories);
|
|
1122
|
+
const cat = await catRepo.insert({ id: 1, categoryName: 'cat' });
|
|
1123
|
+
const task = class {
|
|
1124
|
+
constructor() {
|
|
1125
|
+
this.id = 0;
|
|
1126
|
+
this.title = '';
|
|
1127
|
+
this.completed = false;
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
describeClass(task, Entity('tasks', { allowApiCrud: true }), {
|
|
1131
|
+
id: Fields.integer(),
|
|
1132
|
+
title: Fields.string(),
|
|
1133
|
+
cat: Field(() => Categories),
|
|
1134
|
+
completed: Fields.boolean(),
|
|
1135
|
+
});
|
|
1136
|
+
const taskRepo = await createEntity(task);
|
|
1137
|
+
await taskRepo.insert({ id: 1, cat, title: 'noam' });
|
|
1138
|
+
{
|
|
1139
|
+
const aTask = await taskRepo.findFirst({}, { useCache: false });
|
|
1140
|
+
expect(aTask.title).toBe('noam');
|
|
1141
|
+
expect(aTask.cat.categoryName).toBe('cat');
|
|
1142
|
+
expect(aTask.completed).toBe(false);
|
|
1143
|
+
}
|
|
1144
|
+
await taskRepo.update(1, { completed: true });
|
|
1145
|
+
{
|
|
1146
|
+
const aTask = await taskRepo.findFirst({}, { useCache: false });
|
|
1147
|
+
expect(aTask.id).toBe(1);
|
|
1148
|
+
expect(aTask.title).toBe('noam');
|
|
1149
|
+
expect(aTask.cat.categoryName).toBe('cat');
|
|
1150
|
+
expect(aTask.completed).toBe(true);
|
|
1151
|
+
}
|
|
1152
|
+
}, false);
|
|
1153
|
+
testAll("test update doesn't validate non included fields", async ({ createEntity, remult }) => {
|
|
1154
|
+
const catRepo = await createEntity(Categories);
|
|
1155
|
+
const cat = await catRepo.insert({ id: 1, categoryName: 'cat' });
|
|
1156
|
+
const task = class {
|
|
1157
|
+
constructor() {
|
|
1158
|
+
this.id = 0;
|
|
1159
|
+
this.title = '';
|
|
1160
|
+
this.completed = false;
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
describeClass(task, Entity('tasks', { allowApiCrud: true }), {
|
|
1164
|
+
id: Fields.integer(),
|
|
1165
|
+
title: Fields.string({ validate: Validators.required }),
|
|
1166
|
+
cat: Field(() => Categories),
|
|
1167
|
+
completed: Fields.boolean(),
|
|
1168
|
+
});
|
|
1169
|
+
const taskRepo = await createEntity(task);
|
|
1170
|
+
await taskRepo.insert({ id: 1, cat, title: 'noam' });
|
|
1171
|
+
await taskRepo.update(1, { completed: true });
|
|
1172
|
+
{
|
|
1173
|
+
const aTask = await taskRepo.findId(1, { useCache: false });
|
|
1174
|
+
expect(aTask.completed).toBe(true);
|
|
1175
|
+
}
|
|
1176
|
+
}, false);
|
package/package.json
CHANGED
package/remult-knex/index.js
CHANGED
|
@@ -375,7 +375,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
375
375
|
case 10:
|
|
376
376
|
insert = this.knex(e.$entityName).insert(insertObject);
|
|
377
377
|
if (!remult3_1.isAutoIncrement(this.entity.idMetadata.field)) return [3 /*break*/, 15];
|
|
378
|
-
if (!(this.knex.client.config.client === 'mysql2')) return [3 /*break*/, 12];
|
|
378
|
+
if (!(this.knex.client.config.client === 'mysql2' || this.knex.client.config.client === 'mysql')) return [3 /*break*/, 12];
|
|
379
379
|
return [4 /*yield*/, insert];
|
|
380
380
|
case 11:
|
|
381
381
|
result = _d.sent();
|
|
@@ -825,7 +825,7 @@ var KnexSchemaBuilder = /** @class */ (function () {
|
|
|
825
825
|
exports.KnexSchemaBuilder = KnexSchemaBuilder;
|
|
826
826
|
function supportsJson(knex) {
|
|
827
827
|
var client = knex.client.config.client;
|
|
828
|
-
if ((client === null || client === void 0 ? void 0 : client.includes('sqlite3')) || (client === null || client === void 0 ? void 0 : client.includes('mssql')))
|
|
828
|
+
if ((client === null || client === void 0 ? void 0 : client.includes('sqlite3')) || (client === null || client === void 0 ? void 0 : client.includes('mssql')) || (client === null || client === void 0 ? void 0 : client.includes('mysql')))
|
|
829
829
|
return false;
|
|
830
830
|
return true;
|
|
831
831
|
}
|
|
@@ -92,6 +92,16 @@ exports.mySqlTest = db_tests_setup_1.addDatabaseToTest(testKnexSqlImpl(Knex.defa
|
|
|
92
92
|
database: 'test',
|
|
93
93
|
},
|
|
94
94
|
}), 'mysql2'));
|
|
95
|
+
db_tests_setup_1.addDatabaseToTest(testKnexSqlImpl(Knex.default({
|
|
96
|
+
client: 'mysql',
|
|
97
|
+
connection: {
|
|
98
|
+
user: 'root',
|
|
99
|
+
password: 'MASTERKEY',
|
|
100
|
+
host: '127.0.0.1',
|
|
101
|
+
database: 'test',
|
|
102
|
+
port: 3307
|
|
103
|
+
},
|
|
104
|
+
}), 'mysql'));
|
|
95
105
|
var pg = postgres_1.createPostgresConnection();
|
|
96
106
|
function testPostgresImplementation(key, what, focus) {
|
|
97
107
|
var _this = this;
|
|
@@ -124,7 +124,7 @@ export declare class rowHelperImplementation<T> extends rowHelperBase<T> impleme
|
|
|
124
124
|
private _columns;
|
|
125
125
|
get fields(): FieldsRef<T>;
|
|
126
126
|
private _saving;
|
|
127
|
-
save(): Promise<T>;
|
|
127
|
+
save(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject?: string[]): Promise<T>;
|
|
128
128
|
private getIdFilter;
|
|
129
129
|
delete(): Promise<void>;
|
|
130
130
|
loadDataFrom(data: any, loadItems?: FieldMetadata[]): Promise<void>;
|
|
@@ -324,13 +324,33 @@ var RepositoryImplementation = /** @class */ (function () {
|
|
|
324
324
|
};
|
|
325
325
|
RepositoryImplementation.prototype.update = function (id, entity) {
|
|
326
326
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
327
|
-
var ref;
|
|
327
|
+
var ref_1, ref, r, key, f;
|
|
328
328
|
return tslib_1.__generator(this, function (_a) {
|
|
329
329
|
switch (_a.label) {
|
|
330
330
|
case 0:
|
|
331
|
-
|
|
332
|
-
return [
|
|
331
|
+
ref_1 = getEntityRef(entity, false);
|
|
332
|
+
if (!ref_1) return [3 /*break*/, 2];
|
|
333
|
+
return [4 /*yield*/, ref_1.save()];
|
|
333
334
|
case 1: return [2 /*return*/, (_a.sent())];
|
|
335
|
+
case 2:
|
|
336
|
+
ref = this.getRefForExistingRow(entity, id);
|
|
337
|
+
if (!this.dataProvider.isProxy) return [3 /*break*/, 4];
|
|
338
|
+
return [4 /*yield*/, ref.save(Object.keys(entity))];
|
|
339
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
340
|
+
case 4: return [4 /*yield*/, this.findId(ref.id, { useCache: false })];
|
|
341
|
+
case 5:
|
|
342
|
+
r = _a.sent();
|
|
343
|
+
if (!r)
|
|
344
|
+
throw new Error('Not Found');
|
|
345
|
+
for (key in entity) {
|
|
346
|
+
if (Object.prototype.hasOwnProperty.call(entity, key)) {
|
|
347
|
+
f = ref.fields[key];
|
|
348
|
+
if (f)
|
|
349
|
+
r[key] = f.value;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return [4 /*yield*/, getEntityRef(r).save()];
|
|
353
|
+
case 6: return [2 /*return*/, _a.sent()];
|
|
334
354
|
}
|
|
335
355
|
});
|
|
336
356
|
});
|
|
@@ -1525,7 +1545,7 @@ var rowHelperImplementation = /** @class */ (function (_super) {
|
|
|
1525
1545
|
enumerable: false,
|
|
1526
1546
|
configurable: true
|
|
1527
1547
|
});
|
|
1528
|
-
rowHelperImplementation.prototype.save = function () {
|
|
1548
|
+
rowHelperImplementation.prototype.save = function (onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject) {
|
|
1529
1549
|
var _a;
|
|
1530
1550
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
1531
1551
|
var doNotSave_1, _b, _c, col, e_25_1, d, ignoreKeys, _d, _e, field, f, updatedRow, isNew, changesOnly, wasChanged, key, element, _f, _g, listener, e_26_1, err_1;
|
|
@@ -1533,58 +1553,63 @@ var rowHelperImplementation = /** @class */ (function (_super) {
|
|
|
1533
1553
|
return tslib_1.__generator(this, function (_l) {
|
|
1534
1554
|
switch (_l.label) {
|
|
1535
1555
|
case 0:
|
|
1536
|
-
_l.trys.push([0, ,
|
|
1556
|
+
_l.trys.push([0, , 35, 36]);
|
|
1537
1557
|
if (this._saving)
|
|
1538
1558
|
throw new Error('cannot save while entity is already saving');
|
|
1539
1559
|
this._saving = true;
|
|
1540
1560
|
if (this.wasDeleted())
|
|
1541
1561
|
throw new Error('cannot save a deleted row');
|
|
1542
1562
|
this.isLoading = true;
|
|
1563
|
+
if (!(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject === undefined)) return [3 /*break*/, 2];
|
|
1543
1564
|
return [4 /*yield*/, this.__validateEntity()];
|
|
1544
1565
|
case 1:
|
|
1545
1566
|
_l.sent();
|
|
1546
|
-
doNotSave_1 = false;
|
|
1547
1567
|
_l.label = 2;
|
|
1548
1568
|
case 2:
|
|
1549
|
-
|
|
1550
|
-
_b = tslib_1.__values(this.fields), _c = _b.next();
|
|
1569
|
+
doNotSave_1 = false;
|
|
1551
1570
|
_l.label = 3;
|
|
1552
1571
|
case 3:
|
|
1553
|
-
|
|
1572
|
+
_l.trys.push([3, 8, 9, 10]);
|
|
1573
|
+
_b = tslib_1.__values(this.fields), _c = _b.next();
|
|
1574
|
+
_l.label = 4;
|
|
1575
|
+
case 4:
|
|
1576
|
+
if (!!_c.done) return [3 /*break*/, 7];
|
|
1554
1577
|
col = _c.value;
|
|
1555
|
-
if (!col.metadata.options.saving) return [3 /*break*/,
|
|
1578
|
+
if (!col.metadata.options.saving) return [3 /*break*/, 6];
|
|
1556
1579
|
return [4 /*yield*/, col.metadata.options.saving(this.instance, col)];
|
|
1557
|
-
case 4:
|
|
1558
|
-
_l.sent();
|
|
1559
|
-
_l.label = 5;
|
|
1560
1580
|
case 5:
|
|
1581
|
+
_l.sent();
|
|
1582
|
+
_l.label = 6;
|
|
1583
|
+
case 6:
|
|
1561
1584
|
_c = _b.next();
|
|
1562
|
-
return [3 /*break*/,
|
|
1563
|
-
case
|
|
1564
|
-
case
|
|
1585
|
+
return [3 /*break*/, 4];
|
|
1586
|
+
case 7: return [3 /*break*/, 10];
|
|
1587
|
+
case 8:
|
|
1565
1588
|
e_25_1 = _l.sent();
|
|
1566
1589
|
e_25 = { error: e_25_1 };
|
|
1567
|
-
return [3 /*break*/,
|
|
1568
|
-
case
|
|
1590
|
+
return [3 /*break*/, 10];
|
|
1591
|
+
case 9:
|
|
1569
1592
|
try {
|
|
1570
1593
|
if (_c && !_c.done && (_h = _b.return)) _h.call(_b);
|
|
1571
1594
|
}
|
|
1572
1595
|
finally { if (e_25) throw e_25.error; }
|
|
1573
1596
|
return [7 /*endfinally*/];
|
|
1574
|
-
case 9:
|
|
1575
|
-
if (!this.info.entityInfo.saving) return [3 /*break*/, 11];
|
|
1576
|
-
return [4 /*yield*/, this.info.entityInfo.saving(this.instance, function () { return (doNotSave_1 = true); })];
|
|
1577
1597
|
case 10:
|
|
1578
|
-
|
|
1579
|
-
|
|
1598
|
+
if (!this.info.entityInfo.saving) return [3 /*break*/, 12];
|
|
1599
|
+
return [4 /*yield*/, this.info.entityInfo.saving(this.instance, function () { return (doNotSave_1 = true); })];
|
|
1580
1600
|
case 11:
|
|
1601
|
+
_l.sent();
|
|
1602
|
+
_l.label = 12;
|
|
1603
|
+
case 12:
|
|
1581
1604
|
this.__assertValidity();
|
|
1582
1605
|
d = this.copyDataToObject();
|
|
1583
1606
|
ignoreKeys = [];
|
|
1584
1607
|
try {
|
|
1585
1608
|
for (_d = tslib_1.__values(this.metadata.fields), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
1586
1609
|
field = _e.value;
|
|
1587
|
-
if (field.dbReadOnly
|
|
1610
|
+
if (field.dbReadOnly ||
|
|
1611
|
+
(onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject !== undefined &&
|
|
1612
|
+
!onlyTheseFieldsSentOnlyInTheCaseOfProxySaveWithPartialObject.includes(field.key))) {
|
|
1588
1613
|
d[field.key] = undefined;
|
|
1589
1614
|
ignoreKeys.push(field.key);
|
|
1590
1615
|
f = this.fields.find(field);
|
|
@@ -1603,16 +1628,16 @@ var rowHelperImplementation = /** @class */ (function (_super) {
|
|
|
1603
1628
|
delete d.id;
|
|
1604
1629
|
updatedRow = void 0;
|
|
1605
1630
|
isNew = this.isNew();
|
|
1606
|
-
_l.label =
|
|
1607
|
-
case
|
|
1608
|
-
_l.trys.push([
|
|
1631
|
+
_l.label = 13;
|
|
1632
|
+
case 13:
|
|
1633
|
+
_l.trys.push([13, 32, , 34]);
|
|
1609
1634
|
(_a = this._subscribers) === null || _a === void 0 ? void 0 : _a.reportChanged();
|
|
1610
|
-
if (!this.isNew()) return [3 /*break*/,
|
|
1635
|
+
if (!this.isNew()) return [3 /*break*/, 15];
|
|
1611
1636
|
return [4 /*yield*/, this.edp.insert(d)];
|
|
1612
|
-
case 13:
|
|
1613
|
-
updatedRow = _l.sent();
|
|
1614
|
-
return [3 /*break*/, 18];
|
|
1615
1637
|
case 14:
|
|
1638
|
+
updatedRow = _l.sent();
|
|
1639
|
+
return [3 /*break*/, 19];
|
|
1640
|
+
case 15:
|
|
1616
1641
|
changesOnly = {};
|
|
1617
1642
|
wasChanged = false;
|
|
1618
1643
|
for (key in d) {
|
|
@@ -1627,70 +1652,70 @@ var rowHelperImplementation = /** @class */ (function (_super) {
|
|
|
1627
1652
|
}
|
|
1628
1653
|
if (!wasChanged)
|
|
1629
1654
|
return [2 /*return*/, this.instance];
|
|
1630
|
-
if (!doNotSave_1) return [3 /*break*/,
|
|
1655
|
+
if (!doNotSave_1) return [3 /*break*/, 17];
|
|
1631
1656
|
return [4 /*yield*/, this.edp.find({ where: this.getIdFilter() })];
|
|
1632
|
-
case
|
|
1657
|
+
case 16:
|
|
1633
1658
|
updatedRow = (_l.sent())[0];
|
|
1634
|
-
return [3 /*break*/,
|
|
1635
|
-
case
|
|
1636
|
-
case
|
|
1659
|
+
return [3 /*break*/, 19];
|
|
1660
|
+
case 17: return [4 /*yield*/, this.edp.update(this.id, changesOnly)];
|
|
1661
|
+
case 18:
|
|
1637
1662
|
updatedRow = _l.sent();
|
|
1638
|
-
_l.label =
|
|
1639
|
-
case
|
|
1640
|
-
case 19:
|
|
1641
|
-
_l.sent();
|
|
1642
|
-
if (!this.info.entityInfo.saved) return [3 /*break*/, 21];
|
|
1643
|
-
return [4 /*yield*/, this.info.entityInfo.saved(this.instance)];
|
|
1663
|
+
_l.label = 19;
|
|
1664
|
+
case 19: return [4 /*yield*/, this.loadDataFrom(updatedRow)];
|
|
1644
1665
|
case 20:
|
|
1645
1666
|
_l.sent();
|
|
1646
|
-
|
|
1667
|
+
if (!this.info.entityInfo.saved) return [3 /*break*/, 22];
|
|
1668
|
+
return [4 /*yield*/, this.info.entityInfo.saved(this.instance)];
|
|
1647
1669
|
case 21:
|
|
1648
|
-
|
|
1670
|
+
_l.sent();
|
|
1649
1671
|
_l.label = 22;
|
|
1650
1672
|
case 22:
|
|
1651
|
-
|
|
1652
|
-
_f = tslib_1.__values(this.repository.listeners.filter(function (x) { return x.saved; })), _g = _f.next();
|
|
1673
|
+
if (!this.repository.listeners) return [3 /*break*/, 30];
|
|
1653
1674
|
_l.label = 23;
|
|
1654
1675
|
case 23:
|
|
1655
|
-
|
|
1676
|
+
_l.trys.push([23, 28, 29, 30]);
|
|
1677
|
+
_f = tslib_1.__values(this.repository.listeners.filter(function (x) { return x.saved; })), _g = _f.next();
|
|
1678
|
+
_l.label = 24;
|
|
1679
|
+
case 24:
|
|
1680
|
+
if (!!_g.done) return [3 /*break*/, 27];
|
|
1656
1681
|
listener = _g.value;
|
|
1657
1682
|
return [4 /*yield*/, listener.saved(this.instance, isNew)];
|
|
1658
|
-
case 24:
|
|
1659
|
-
_l.sent();
|
|
1660
|
-
_l.label = 25;
|
|
1661
1683
|
case 25:
|
|
1684
|
+
_l.sent();
|
|
1685
|
+
_l.label = 26;
|
|
1686
|
+
case 26:
|
|
1662
1687
|
_g = _f.next();
|
|
1663
|
-
return [3 /*break*/,
|
|
1664
|
-
case
|
|
1665
|
-
case
|
|
1688
|
+
return [3 /*break*/, 24];
|
|
1689
|
+
case 27: return [3 /*break*/, 30];
|
|
1690
|
+
case 28:
|
|
1666
1691
|
e_26_1 = _l.sent();
|
|
1667
1692
|
e_26 = { error: e_26_1 };
|
|
1668
|
-
return [3 /*break*/,
|
|
1669
|
-
case
|
|
1693
|
+
return [3 /*break*/, 30];
|
|
1694
|
+
case 29:
|
|
1670
1695
|
try {
|
|
1671
1696
|
if (_g && !_g.done && (_k = _f.return)) _k.call(_f);
|
|
1672
1697
|
}
|
|
1673
1698
|
finally { if (e_26) throw e_26.error; }
|
|
1674
1699
|
return [7 /*endfinally*/];
|
|
1675
|
-
case
|
|
1676
|
-
case
|
|
1700
|
+
case 30: return [4 /*yield*/, this.repository.remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }])];
|
|
1701
|
+
case 31:
|
|
1677
1702
|
_l.sent();
|
|
1678
1703
|
this.saveOriginalData();
|
|
1679
1704
|
this._isNew = false;
|
|
1680
1705
|
return [2 /*return*/, this.instance];
|
|
1681
|
-
case
|
|
1706
|
+
case 32:
|
|
1682
1707
|
err_1 = _l.sent();
|
|
1683
1708
|
return [4 /*yield*/, this.catchSaveErrors(err_1)];
|
|
1684
|
-
case
|
|
1709
|
+
case 33:
|
|
1685
1710
|
_l.sent();
|
|
1686
|
-
return [3 /*break*/,
|
|
1687
|
-
case
|
|
1688
|
-
case
|
|
1711
|
+
return [3 /*break*/, 34];
|
|
1712
|
+
case 34: return [3 /*break*/, 36];
|
|
1713
|
+
case 35:
|
|
1689
1714
|
this.isLoading = false;
|
|
1690
1715
|
this._reportChangedToEntityAndFields();
|
|
1691
1716
|
this._saving = false;
|
|
1692
1717
|
return [7 /*endfinally*/];
|
|
1693
|
-
case
|
|
1718
|
+
case 36: return [2 /*return*/];
|
|
1694
1719
|
}
|
|
1695
1720
|
});
|
|
1696
1721
|
});
|
|
@@ -3018,21 +3043,23 @@ function decorateColumnSettings(settings, remult) {
|
|
|
3018
3043
|
isIdNumeric_1 =
|
|
3019
3044
|
remult.repo(settings.valueType).metadata.idMetadata.field
|
|
3020
3045
|
.valueType === Number;
|
|
3021
|
-
|
|
3022
|
-
for (var _b = tslib_1.__values([
|
|
3023
|
-
'fieldTypeInDb',
|
|
3024
|
-
]), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
3025
|
-
var key = _c.value;
|
|
3026
|
-
//@ts-ignore
|
|
3027
|
-
target[key] = valueConverters_1.ValueConverters.Integer[key];
|
|
3028
|
-
}
|
|
3029
|
-
}
|
|
3030
|
-
catch (e_40_1) { e_40 = { error: e_40_1 }; }
|
|
3031
|
-
finally {
|
|
3046
|
+
if (isIdNumeric_1) {
|
|
3032
3047
|
try {
|
|
3033
|
-
|
|
3048
|
+
for (var _b = tslib_1.__values([
|
|
3049
|
+
'fieldTypeInDb',
|
|
3050
|
+
]), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
3051
|
+
var key = _c.value;
|
|
3052
|
+
//@ts-ignore
|
|
3053
|
+
target[key] = valueConverters_1.ValueConverters.Integer[key];
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
catch (e_40_1) { e_40 = { error: e_40_1 }; }
|
|
3057
|
+
finally {
|
|
3058
|
+
try {
|
|
3059
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
3060
|
+
}
|
|
3061
|
+
finally { if (e_40) throw e_40.error; }
|
|
3034
3062
|
}
|
|
3035
|
-
finally { if (e_40) throw e_40.error; }
|
|
3036
3063
|
}
|
|
3037
3064
|
}
|
|
3038
3065
|
}
|
|
@@ -2377,3 +2377,164 @@ db_tests_setup_1.testAll('test relation to number id', function (_a) {
|
|
|
2377
2377
|
});
|
|
2378
2378
|
});
|
|
2379
2379
|
}, false, { exclude: [db_tests_setup_1.TestDbs.mongo, db_tests_setup_1.TestDbs.mongoNoTrans] });
|
|
2380
|
+
db_tests_setup_1.testAll('test relation to string id', function (_a) {
|
|
2381
|
+
var createEntity = _a.createEntity;
|
|
2382
|
+
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
2383
|
+
var category, task, catRepo, taskRepo, cat, _b, _c, _d;
|
|
2384
|
+
return tslib_1.__generator(this, function (_e) {
|
|
2385
|
+
switch (_e.label) {
|
|
2386
|
+
case 0:
|
|
2387
|
+
category = /** @class */ (function () {
|
|
2388
|
+
function class_12() {
|
|
2389
|
+
this.id = '';
|
|
2390
|
+
this.name = '';
|
|
2391
|
+
}
|
|
2392
|
+
return class_12;
|
|
2393
|
+
}());
|
|
2394
|
+
DecoratorReplacer_1.describeClass(category, remult3_1.Entity('rel_ID_string_categories', { allowApiCrud: true }), {
|
|
2395
|
+
id: remult3_1.Fields.cuid(),
|
|
2396
|
+
name: remult3_1.Fields.string(),
|
|
2397
|
+
});
|
|
2398
|
+
task = /** @class */ (function () {
|
|
2399
|
+
function class_13() {
|
|
2400
|
+
this.id = 0;
|
|
2401
|
+
this.title = '';
|
|
2402
|
+
}
|
|
2403
|
+
return class_13;
|
|
2404
|
+
}());
|
|
2405
|
+
DecoratorReplacer_1.describeClass(task, remult3_1.Entity('rel_ID_string_task', { allowApiCrud: true }), {
|
|
2406
|
+
id: remult3_1.Fields.autoIncrement(),
|
|
2407
|
+
title: remult3_1.Fields.string(),
|
|
2408
|
+
category: remult3_1.Field(function () { return category; }),
|
|
2409
|
+
});
|
|
2410
|
+
return [4 /*yield*/, createEntity(category)];
|
|
2411
|
+
case 1:
|
|
2412
|
+
catRepo = _e.sent();
|
|
2413
|
+
return [4 /*yield*/, createEntity(task)];
|
|
2414
|
+
case 2:
|
|
2415
|
+
taskRepo = _e.sent();
|
|
2416
|
+
return [4 /*yield*/, catRepo.insert([{ name: 'cat0' }, { name: 'cat1' }])];
|
|
2417
|
+
case 3:
|
|
2418
|
+
cat = _e.sent();
|
|
2419
|
+
return [4 /*yield*/, taskRepo.insert([
|
|
2420
|
+
{ title: 't1', category: cat[0] },
|
|
2421
|
+
{ title: 't2', category: cat[0] },
|
|
2422
|
+
{ title: 't3', category: cat[1] },
|
|
2423
|
+
])];
|
|
2424
|
+
case 4:
|
|
2425
|
+
_e.sent();
|
|
2426
|
+
expect(taskRepo.fields.category.valueConverter.fieldTypeInDb).toBeUndefined();
|
|
2427
|
+
_b = expect;
|
|
2428
|
+
return [4 /*yield*/, taskRepo.count({ category: cat[0] })];
|
|
2429
|
+
case 5:
|
|
2430
|
+
_b.apply(void 0, [_e.sent()]).toBe(2);
|
|
2431
|
+
_c = expect;
|
|
2432
|
+
return [4 /*yield*/, taskRepo.count({ category: cat[1] })];
|
|
2433
|
+
case 6:
|
|
2434
|
+
_c.apply(void 0, [_e.sent()]).toBe(1);
|
|
2435
|
+
_d = expect;
|
|
2436
|
+
return [4 /*yield*/, taskRepo.count({ category: { $id: cat[0].id } })];
|
|
2437
|
+
case 7:
|
|
2438
|
+
_d.apply(void 0, [_e.sent()]).toBe(2);
|
|
2439
|
+
return [2 /*return*/];
|
|
2440
|
+
}
|
|
2441
|
+
});
|
|
2442
|
+
});
|
|
2443
|
+
}, false, { exclude: [db_tests_setup_1.TestDbs.mongo, db_tests_setup_1.TestDbs.mongoNoTrans] });
|
|
2444
|
+
db_tests_setup_1.testAll("test update doesn't override other values", function (_a) {
|
|
2445
|
+
var createEntity = _a.createEntity, remult = _a.remult;
|
|
2446
|
+
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
2447
|
+
var catRepo, cat, task, taskRepo, aTask, aTask;
|
|
2448
|
+
return tslib_1.__generator(this, function (_b) {
|
|
2449
|
+
switch (_b.label) {
|
|
2450
|
+
case 0: return [4 /*yield*/, createEntity(remult_3_entities_1.Categories)];
|
|
2451
|
+
case 1:
|
|
2452
|
+
catRepo = _b.sent();
|
|
2453
|
+
return [4 /*yield*/, catRepo.insert({ id: 1, categoryName: 'cat' })];
|
|
2454
|
+
case 2:
|
|
2455
|
+
cat = _b.sent();
|
|
2456
|
+
task = /** @class */ (function () {
|
|
2457
|
+
function class_14() {
|
|
2458
|
+
this.id = 0;
|
|
2459
|
+
this.title = '';
|
|
2460
|
+
this.completed = false;
|
|
2461
|
+
}
|
|
2462
|
+
return class_14;
|
|
2463
|
+
}());
|
|
2464
|
+
DecoratorReplacer_1.describeClass(task, remult3_1.Entity('tasks', { allowApiCrud: true }), {
|
|
2465
|
+
id: remult3_1.Fields.integer(),
|
|
2466
|
+
title: remult3_1.Fields.string(),
|
|
2467
|
+
cat: remult3_1.Field(function () { return remult_3_entities_1.Categories; }),
|
|
2468
|
+
completed: remult3_1.Fields.boolean(),
|
|
2469
|
+
});
|
|
2470
|
+
return [4 /*yield*/, createEntity(task)];
|
|
2471
|
+
case 3:
|
|
2472
|
+
taskRepo = _b.sent();
|
|
2473
|
+
return [4 /*yield*/, taskRepo.insert({ id: 1, cat: cat, title: 'noam' })];
|
|
2474
|
+
case 4:
|
|
2475
|
+
_b.sent();
|
|
2476
|
+
return [4 /*yield*/, taskRepo.findFirst({}, { useCache: false })];
|
|
2477
|
+
case 5:
|
|
2478
|
+
aTask = _b.sent();
|
|
2479
|
+
expect(aTask.title).toBe('noam');
|
|
2480
|
+
expect(aTask.cat.categoryName).toBe('cat');
|
|
2481
|
+
expect(aTask.completed).toBe(false);
|
|
2482
|
+
return [4 /*yield*/, taskRepo.update(1, { completed: true })];
|
|
2483
|
+
case 6:
|
|
2484
|
+
_b.sent();
|
|
2485
|
+
return [4 /*yield*/, taskRepo.findFirst({}, { useCache: false })];
|
|
2486
|
+
case 7:
|
|
2487
|
+
aTask = _b.sent();
|
|
2488
|
+
expect(aTask.id).toBe(1);
|
|
2489
|
+
expect(aTask.title).toBe('noam');
|
|
2490
|
+
expect(aTask.cat.categoryName).toBe('cat');
|
|
2491
|
+
expect(aTask.completed).toBe(true);
|
|
2492
|
+
return [2 /*return*/];
|
|
2493
|
+
}
|
|
2494
|
+
});
|
|
2495
|
+
});
|
|
2496
|
+
}, false);
|
|
2497
|
+
db_tests_setup_1.testAll("test update doesn't validate non included fields", function (_a) {
|
|
2498
|
+
var createEntity = _a.createEntity, remult = _a.remult;
|
|
2499
|
+
return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
2500
|
+
var catRepo, cat, task, taskRepo, aTask;
|
|
2501
|
+
return tslib_1.__generator(this, function (_b) {
|
|
2502
|
+
switch (_b.label) {
|
|
2503
|
+
case 0: return [4 /*yield*/, createEntity(remult_3_entities_1.Categories)];
|
|
2504
|
+
case 1:
|
|
2505
|
+
catRepo = _b.sent();
|
|
2506
|
+
return [4 /*yield*/, catRepo.insert({ id: 1, categoryName: 'cat' })];
|
|
2507
|
+
case 2:
|
|
2508
|
+
cat = _b.sent();
|
|
2509
|
+
task = /** @class */ (function () {
|
|
2510
|
+
function class_15() {
|
|
2511
|
+
this.id = 0;
|
|
2512
|
+
this.title = '';
|
|
2513
|
+
this.completed = false;
|
|
2514
|
+
}
|
|
2515
|
+
return class_15;
|
|
2516
|
+
}());
|
|
2517
|
+
DecoratorReplacer_1.describeClass(task, remult3_1.Entity('tasks', { allowApiCrud: true }), {
|
|
2518
|
+
id: remult3_1.Fields.integer(),
|
|
2519
|
+
title: remult3_1.Fields.string({ validate: validators_1.Validators.required }),
|
|
2520
|
+
cat: remult3_1.Field(function () { return remult_3_entities_1.Categories; }),
|
|
2521
|
+
completed: remult3_1.Fields.boolean(),
|
|
2522
|
+
});
|
|
2523
|
+
return [4 /*yield*/, createEntity(task)];
|
|
2524
|
+
case 3:
|
|
2525
|
+
taskRepo = _b.sent();
|
|
2526
|
+
return [4 /*yield*/, taskRepo.insert({ id: 1, cat: cat, title: 'noam' })];
|
|
2527
|
+
case 4:
|
|
2528
|
+
_b.sent();
|
|
2529
|
+
return [4 /*yield*/, taskRepo.update(1, { completed: true })];
|
|
2530
|
+
case 5:
|
|
2531
|
+
_b.sent();
|
|
2532
|
+
return [4 /*yield*/, taskRepo.findId(1, { useCache: false })];
|
|
2533
|
+
case 6:
|
|
2534
|
+
aTask = _b.sent();
|
|
2535
|
+
expect(aTask.completed).toBe(true);
|
|
2536
|
+
return [2 /*return*/];
|
|
2537
|
+
}
|
|
2538
|
+
});
|
|
2539
|
+
});
|
|
2540
|
+
}, false);
|