@aws-amplify/datastore-storage-adapter 2.0.49-api-v6-models.b3abc9b.0 → 2.1.0
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/CHANGELOG.md +0 -4
- package/dist/aws-amplify-datastore-sqlite-adapter-expo.js +2087 -1243
- package/dist/aws-amplify-datastore-sqlite-adapter-expo.js.map +1 -1
- package/dist/aws-amplify-datastore-sqlite-adapter-expo.min.js +2 -1
- package/dist/aws-amplify-datastore-sqlite-adapter-expo.min.js.LICENSE.txt +1 -0
- package/dist/aws-amplify-datastore-sqlite-adapter-expo.min.js.map +1 -1
- package/dist/aws-amplify-datastore-storage-adapter.js +2105 -1205
- package/dist/aws-amplify-datastore-storage-adapter.js.map +1 -1
- package/dist/aws-amplify-datastore-storage-adapter.min.js +2 -1
- package/dist/aws-amplify-datastore-storage-adapter.min.js.LICENSE.txt +1 -0
- package/dist/aws-amplify-datastore-storage-adapter.min.js.map +1 -1
- package/jest.setup.js +7 -0
- package/lib/ExpoSQLiteAdapter/ExpoSQLiteAdapter.js +4 -4
- package/lib/ExpoSQLiteAdapter/ExpoSQLiteAdapter.js.map +1 -1
- package/lib/ExpoSQLiteAdapter/ExpoSQLiteDatabase.js +159 -272
- package/lib/ExpoSQLiteAdapter/ExpoSQLiteDatabase.js.map +1 -1
- package/lib/SQLiteAdapter/SQLiteAdapter.js +4 -4
- package/lib/SQLiteAdapter/SQLiteAdapter.js.map +1 -1
- package/lib/SQLiteAdapter/SQLiteDatabase.js +86 -239
- package/lib/SQLiteAdapter/SQLiteDatabase.js.map +1 -1
- package/lib/common/CommonSQLiteAdapter.js +222 -399
- package/lib/common/CommonSQLiteAdapter.js.map +1 -1
- package/lib/common/SQLiteUtils.d.ts +1 -1
- package/lib/common/SQLiteUtils.js +120 -148
- package/lib/common/SQLiteUtils.js.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib-esm/ExpoSQLiteAdapter/ExpoSQLiteAdapter.js +1 -1
- package/lib-esm/ExpoSQLiteAdapter/ExpoSQLiteAdapter.js.map +1 -1
- package/lib-esm/ExpoSQLiteAdapter/ExpoSQLiteDatabase.js +156 -269
- package/lib-esm/ExpoSQLiteAdapter/ExpoSQLiteDatabase.js.map +1 -1
- package/lib-esm/SQLiteAdapter/SQLiteAdapter.js +1 -1
- package/lib-esm/SQLiteAdapter/SQLiteAdapter.js.map +1 -1
- package/lib-esm/SQLiteAdapter/SQLiteDatabase.js +84 -238
- package/lib-esm/SQLiteAdapter/SQLiteDatabase.js.map +1 -1
- package/lib-esm/common/CommonSQLiteAdapter.js +220 -398
- package/lib-esm/common/CommonSQLiteAdapter.js.map +1 -1
- package/lib-esm/common/SQLiteUtils.d.ts +1 -1
- package/lib-esm/common/SQLiteUtils.js +119 -147
- package/lib-esm/common/SQLiteUtils.js.map +1 -1
- package/lib-esm/common/constants.js +1 -1
- package/lib-esm/common/constants.js.map +1 -1
- package/package.json +10 -4
- package/src/ExpoSQLiteAdapter/ExpoSQLiteDatabase.ts +2 -2
- package/src/SQLiteAdapter/SQLiteDatabase.ts +3 -3
- package/src/common/CommonSQLiteAdapter.ts +2 -2
|
@@ -1,415 +1,237 @@
|
|
|
1
|
-
import { __asyncValues, __awaiter, __generator, __read, __values } from "tslib";
|
|
2
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
import { ConsoleLogger
|
|
3
|
+
import { ConsoleLogger } from '@aws-amplify/core';
|
|
5
4
|
import { generateSchemaStatements, queryByIdStatement, modelUpdateStatement, modelInsertStatement, queryAllStatement, queryOneStatement, deleteByIdStatement, deleteByPredicateStatement, } from '../common/SQLiteUtils';
|
|
6
5
|
import { ModelPredicateCreator, ModelSortPredicateCreator, isPredicateObj, OpType, QueryOne, utils, } from '@aws-amplify/datastore';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const { traverseModel, validatePredicate, isModelConstructor } = utils;
|
|
7
|
+
const logger = new ConsoleLogger('DataStore');
|
|
8
|
+
export class CommonSQLiteAdapter {
|
|
9
|
+
constructor(db) {
|
|
11
10
|
this.db = db;
|
|
12
11
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
switch (_a.label) {
|
|
19
|
-
case 0:
|
|
20
|
-
if (!!this.initPromise) return [3 /*break*/, 1];
|
|
21
|
-
this.initPromise = new Promise(function (res, rej) {
|
|
22
|
-
_this.resolve = res;
|
|
23
|
-
_this.reject = rej;
|
|
24
|
-
});
|
|
25
|
-
return [3 /*break*/, 3];
|
|
26
|
-
case 1: return [4 /*yield*/, this.initPromise];
|
|
27
|
-
case 2:
|
|
28
|
-
_a.sent();
|
|
29
|
-
return [2 /*return*/];
|
|
30
|
-
case 3:
|
|
31
|
-
this.schema = theSchema;
|
|
32
|
-
this.namespaceResolver = namespaceResolver;
|
|
33
|
-
this.modelInstanceCreator = modelInstanceCreator;
|
|
34
|
-
this.getModelConstructorByModelName = getModelConstructorByModelName;
|
|
35
|
-
_a.label = 4;
|
|
36
|
-
case 4:
|
|
37
|
-
_a.trys.push([4, 7, , 8]);
|
|
38
|
-
usesCPKCodegen = Object.values(this.schema.namespaces.user.models).some(function (model) {
|
|
39
|
-
return Object.values(model.fields).some(function (field) { var _a; return (_a = field.association) === null || _a === void 0 ? void 0 : _a.hasOwnProperty('targetNames'); });
|
|
40
|
-
});
|
|
41
|
-
if (usesCPKCodegen) {
|
|
42
|
-
logger.error('The SQLite adapter does not support schemas using custom primary key. Set `graphQLTransformer.respectPrimaryKeyAttributesOnConnectionField in `amplify/cli.json` to false to disable custom primary key. To regenerate your API, add or remove an empty newline to your GraphQL schema (to change the computed hash) then run `amplify push`.');
|
|
43
|
-
}
|
|
44
|
-
return [4 /*yield*/, this.db.init()];
|
|
45
|
-
case 5:
|
|
46
|
-
_a.sent();
|
|
47
|
-
statements = generateSchemaStatements(this.schema);
|
|
48
|
-
return [4 /*yield*/, this.db.createSchema(statements)];
|
|
49
|
-
case 6:
|
|
50
|
-
_a.sent();
|
|
51
|
-
this.resolve();
|
|
52
|
-
return [3 /*break*/, 8];
|
|
53
|
-
case 7:
|
|
54
|
-
error_1 = _a.sent();
|
|
55
|
-
this.reject(error_1);
|
|
56
|
-
return [3 /*break*/, 8];
|
|
57
|
-
case 8: return [2 /*return*/];
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
CommonSQLiteAdapter.prototype.clear = function () {
|
|
63
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
64
|
-
return __generator(this, function (_a) {
|
|
65
|
-
switch (_a.label) {
|
|
66
|
-
case 0: return [4 /*yield*/, this.db.clear()];
|
|
67
|
-
case 1:
|
|
68
|
-
_a.sent();
|
|
69
|
-
this.initPromise = undefined;
|
|
70
|
-
return [2 /*return*/];
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
CommonSQLiteAdapter.prototype.save = function (model, condition) {
|
|
76
|
-
var e_1, _a;
|
|
77
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
78
|
-
var modelConstructor, tableName, connectedModels, connectionStoreNames, _b, queryStatement, params, fromDB, predicates, predicateObjs, type, isValid, msg, result, saveStatements, connectionStoreNames_1, connectionStoreNames_1_1, resItem, modelName, item, instance, id, _c, queryStatement_1, params_1, fromDB_1, opType, saveStatement, e_1_1;
|
|
79
|
-
return __generator(this, function (_d) {
|
|
80
|
-
switch (_d.label) {
|
|
81
|
-
case 0:
|
|
82
|
-
modelConstructor = Object.getPrototypeOf(model)
|
|
83
|
-
.constructor;
|
|
84
|
-
tableName = modelConstructor.name;
|
|
85
|
-
connectedModels = traverseModel(modelConstructor.name, model, this.schema.namespaces[this.namespaceResolver(modelConstructor)], this.modelInstanceCreator, this.getModelConstructorByModelName);
|
|
86
|
-
connectionStoreNames = Object.values(connectedModels).map(function (_a) {
|
|
87
|
-
var modelName = _a.modelName, item = _a.item, instance = _a.instance;
|
|
88
|
-
return { modelName: modelName, item: item, instance: instance };
|
|
89
|
-
});
|
|
90
|
-
_b = __read(queryByIdStatement(model.id, tableName), 2), queryStatement = _b[0], params = _b[1];
|
|
91
|
-
return [4 /*yield*/, this.db.get(queryStatement, params)];
|
|
92
|
-
case 1:
|
|
93
|
-
fromDB = _d.sent();
|
|
94
|
-
if (condition && fromDB) {
|
|
95
|
-
predicates = ModelPredicateCreator.getPredicates(condition);
|
|
96
|
-
predicateObjs = predicates.predicates, type = predicates.type;
|
|
97
|
-
isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
98
|
-
if (!isValid) {
|
|
99
|
-
msg = 'Conditional update failed';
|
|
100
|
-
logger.error(msg, { model: fromDB, condition: predicateObjs });
|
|
101
|
-
throw new Error(msg);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
result = [];
|
|
105
|
-
saveStatements = new Set();
|
|
106
|
-
_d.label = 2;
|
|
107
|
-
case 2:
|
|
108
|
-
_d.trys.push([2, 8, 9, 14]);
|
|
109
|
-
connectionStoreNames_1 = __asyncValues(connectionStoreNames);
|
|
110
|
-
_d.label = 3;
|
|
111
|
-
case 3: return [4 /*yield*/, connectionStoreNames_1.next()];
|
|
112
|
-
case 4:
|
|
113
|
-
if (!(connectionStoreNames_1_1 = _d.sent(), !connectionStoreNames_1_1.done)) return [3 /*break*/, 7];
|
|
114
|
-
resItem = connectionStoreNames_1_1.value;
|
|
115
|
-
modelName = resItem.modelName, item = resItem.item, instance = resItem.instance;
|
|
116
|
-
id = item.id;
|
|
117
|
-
_c = __read(queryByIdStatement(id, modelName), 2), queryStatement_1 = _c[0], params_1 = _c[1];
|
|
118
|
-
return [4 /*yield*/, this.db.get(queryStatement_1, params_1)];
|
|
119
|
-
case 5:
|
|
120
|
-
fromDB_1 = _d.sent();
|
|
121
|
-
opType = fromDB_1 === undefined ? OpType.INSERT : OpType.UPDATE;
|
|
122
|
-
saveStatement = fromDB_1
|
|
123
|
-
? modelUpdateStatement(instance, modelName)
|
|
124
|
-
: modelInsertStatement(instance, modelName);
|
|
125
|
-
if (id === model.id || opType === OpType.INSERT) {
|
|
126
|
-
saveStatements.add(saveStatement);
|
|
127
|
-
result.push([instance, opType]);
|
|
128
|
-
}
|
|
129
|
-
_d.label = 6;
|
|
130
|
-
case 6: return [3 /*break*/, 3];
|
|
131
|
-
case 7: return [3 /*break*/, 14];
|
|
132
|
-
case 8:
|
|
133
|
-
e_1_1 = _d.sent();
|
|
134
|
-
e_1 = { error: e_1_1 };
|
|
135
|
-
return [3 /*break*/, 14];
|
|
136
|
-
case 9:
|
|
137
|
-
_d.trys.push([9, , 12, 13]);
|
|
138
|
-
if (!(connectionStoreNames_1_1 && !connectionStoreNames_1_1.done && (_a = connectionStoreNames_1.return))) return [3 /*break*/, 11];
|
|
139
|
-
return [4 /*yield*/, _a.call(connectionStoreNames_1)];
|
|
140
|
-
case 10:
|
|
141
|
-
_d.sent();
|
|
142
|
-
_d.label = 11;
|
|
143
|
-
case 11: return [3 /*break*/, 13];
|
|
144
|
-
case 12:
|
|
145
|
-
if (e_1) throw e_1.error;
|
|
146
|
-
return [7 /*endfinally*/];
|
|
147
|
-
case 13: return [7 /*endfinally*/];
|
|
148
|
-
case 14: return [4 /*yield*/, this.db.batchSave(saveStatements)];
|
|
149
|
-
case 15:
|
|
150
|
-
_d.sent();
|
|
151
|
-
return [2 /*return*/, result];
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
};
|
|
156
|
-
CommonSQLiteAdapter.prototype.load = function (namespaceName, srcModelName, records) {
|
|
157
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
158
|
-
var namespace, relations, connectionTableNames, modelConstructor;
|
|
159
|
-
var _this = this;
|
|
160
|
-
return __generator(this, function (_a) {
|
|
161
|
-
namespace = this.schema.namespaces[namespaceName];
|
|
162
|
-
relations = namespace.relationships[srcModelName].relationTypes;
|
|
163
|
-
connectionTableNames = relations.map(function (_a) {
|
|
164
|
-
var modelName = _a.modelName;
|
|
165
|
-
return modelName;
|
|
166
|
-
});
|
|
167
|
-
modelConstructor = this.getModelConstructorByModelName(namespaceName, srcModelName);
|
|
168
|
-
if (connectionTableNames.length === 0) {
|
|
169
|
-
return [2 /*return*/, records.map(function (record) {
|
|
170
|
-
return _this.modelInstanceCreator(modelConstructor, record);
|
|
171
|
-
})];
|
|
172
|
-
}
|
|
173
|
-
// Remove related-model fields. They're all `null` in the database,
|
|
174
|
-
// and any that happen to be required will result in a false validation
|
|
175
|
-
// error when DataStore attempts to initialize with `null`.
|
|
176
|
-
// These fields aren't actually needed here. DataStore will use the FK's
|
|
177
|
-
// from the schema model.
|
|
178
|
-
return [2 /*return*/, records.map(function (record) {
|
|
179
|
-
var e_2, _a;
|
|
180
|
-
try {
|
|
181
|
-
for (var relations_1 = __values(relations), relations_1_1 = relations_1.next(); !relations_1_1.done; relations_1_1 = relations_1.next()) {
|
|
182
|
-
var r = relations_1_1.value;
|
|
183
|
-
delete record[r.fieldName];
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
187
|
-
finally {
|
|
188
|
-
try {
|
|
189
|
-
if (relations_1_1 && !relations_1_1.done && (_a = relations_1.return)) _a.call(relations_1);
|
|
190
|
-
}
|
|
191
|
-
finally { if (e_2) throw e_2.error; }
|
|
192
|
-
}
|
|
193
|
-
return _this.modelInstanceCreator(modelConstructor, record);
|
|
194
|
-
})];
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
};
|
|
198
|
-
CommonSQLiteAdapter.prototype.query = function (modelConstructor, predicate, pagination) {
|
|
199
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
200
|
-
var tableName, namespaceName, predicates, sortPredicates, limit, page, queryById, records;
|
|
201
|
-
var _this = this;
|
|
202
|
-
return __generator(this, function (_a) {
|
|
203
|
-
switch (_a.label) {
|
|
204
|
-
case 0:
|
|
205
|
-
tableName = modelConstructor.name;
|
|
206
|
-
namespaceName = this.namespaceResolver(modelConstructor);
|
|
207
|
-
predicates = predicate && ModelPredicateCreator.getPredicates(predicate);
|
|
208
|
-
sortPredicates = pagination &&
|
|
209
|
-
pagination.sort &&
|
|
210
|
-
ModelSortPredicateCreator.getPredicates(pagination.sort);
|
|
211
|
-
limit = pagination && pagination.limit;
|
|
212
|
-
page = limit && pagination.page;
|
|
213
|
-
queryById = predicates && this.idFromPredicate(predicates);
|
|
214
|
-
return [4 /*yield*/, (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
215
|
-
var record, _a, queryStatement, params;
|
|
216
|
-
return __generator(this, function (_b) {
|
|
217
|
-
switch (_b.label) {
|
|
218
|
-
case 0:
|
|
219
|
-
if (!queryById) return [3 /*break*/, 2];
|
|
220
|
-
return [4 /*yield*/, this.getById(tableName, queryById)];
|
|
221
|
-
case 1:
|
|
222
|
-
record = _b.sent();
|
|
223
|
-
return [2 /*return*/, record ? [record] : []];
|
|
224
|
-
case 2:
|
|
225
|
-
_a = __read(queryAllStatement(tableName, predicates, sortPredicates, limit, page), 2), queryStatement = _a[0], params = _a[1];
|
|
226
|
-
return [4 /*yield*/, this.db.getAll(queryStatement, params)];
|
|
227
|
-
case 3: return [2 /*return*/, _b.sent()];
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}); })()];
|
|
231
|
-
case 1:
|
|
232
|
-
records = _a.sent();
|
|
233
|
-
return [4 /*yield*/, this.load(namespaceName, modelConstructor.name, records)];
|
|
234
|
-
case 2: return [2 /*return*/, _a.sent()];
|
|
235
|
-
}
|
|
12
|
+
async setUp(theSchema, namespaceResolver, modelInstanceCreator, getModelConstructorByModelName) {
|
|
13
|
+
if (!this.initPromise) {
|
|
14
|
+
this.initPromise = new Promise((res, rej) => {
|
|
15
|
+
this.resolve = res;
|
|
16
|
+
this.reject = rej;
|
|
236
17
|
});
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
await this.initPromise;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.schema = theSchema;
|
|
24
|
+
this.namespaceResolver = namespaceResolver;
|
|
25
|
+
this.modelInstanceCreator = modelInstanceCreator;
|
|
26
|
+
this.getModelConstructorByModelName = getModelConstructorByModelName;
|
|
27
|
+
try {
|
|
28
|
+
const usesCPKCodegen = Object.values(this.schema.namespaces.user.models).some(model => Object.values(model.fields).some(field => field.association?.hasOwnProperty('targetNames')));
|
|
29
|
+
if (usesCPKCodegen) {
|
|
30
|
+
logger.error('The SQLite adapter does not support schemas using custom primary key. Set `graphQLTransformer.respectPrimaryKeyAttributesOnConnectionField in `amplify/cli.json` to false to disable custom primary key. To regenerate your API, add or remove an empty newline to your GraphQL schema (to change the computed hash) then run `amplify push`.');
|
|
31
|
+
}
|
|
32
|
+
await this.db.init();
|
|
33
|
+
const statements = generateSchemaStatements(this.schema);
|
|
34
|
+
await this.db.createSchema(statements);
|
|
35
|
+
this.resolve();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
this.reject(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async clear() {
|
|
42
|
+
await this.db.clear();
|
|
43
|
+
this.initPromise = undefined;
|
|
44
|
+
}
|
|
45
|
+
async save(model, condition) {
|
|
46
|
+
const modelConstructor = Object.getPrototypeOf(model)
|
|
47
|
+
.constructor;
|
|
48
|
+
const { name: tableName } = modelConstructor;
|
|
49
|
+
const connectedModels = traverseModel(modelConstructor.name, model, this.schema.namespaces[this.namespaceResolver(modelConstructor)], this.modelInstanceCreator, this.getModelConstructorByModelName);
|
|
50
|
+
const connectionStoreNames = Object.values(connectedModels).map(({ modelName, item, instance }) => {
|
|
51
|
+
return { modelName, item, instance };
|
|
237
52
|
});
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
53
|
+
const [queryStatement, params] = queryByIdStatement(model.id, tableName);
|
|
54
|
+
const fromDB = await this.db.get(queryStatement, params);
|
|
55
|
+
if (condition && fromDB) {
|
|
56
|
+
const predicates = ModelPredicateCreator.getPredicates(condition);
|
|
57
|
+
const { predicates: predicateObjs, type } = predicates;
|
|
58
|
+
const isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
59
|
+
if (!isValid) {
|
|
60
|
+
const msg = 'Conditional update failed';
|
|
61
|
+
logger.error(msg, { model: fromDB, condition: predicateObjs });
|
|
62
|
+
throw new Error(msg);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const result = [];
|
|
66
|
+
const saveStatements = new Set();
|
|
67
|
+
for await (const resItem of connectionStoreNames) {
|
|
68
|
+
const { modelName, item, instance } = resItem;
|
|
69
|
+
const { id } = item;
|
|
70
|
+
const [queryStatement, params] = queryByIdStatement(id, modelName);
|
|
71
|
+
const fromDB = await this.db.get(queryStatement, params);
|
|
72
|
+
const opType = fromDB === undefined ? OpType.INSERT : OpType.UPDATE;
|
|
73
|
+
const saveStatement = fromDB
|
|
74
|
+
? modelUpdateStatement(instance, modelName)
|
|
75
|
+
: modelInsertStatement(instance, modelName);
|
|
76
|
+
if (id === model.id || opType === OpType.INSERT) {
|
|
77
|
+
saveStatements.add(saveStatement);
|
|
78
|
+
result.push([instance, opType]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
await this.db.batchSave(saveStatements);
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
async load(namespaceName, srcModelName, records) {
|
|
85
|
+
const namespace = this.schema.namespaces[namespaceName];
|
|
86
|
+
const relations = namespace.relationships[srcModelName].relationTypes;
|
|
87
|
+
const connectionTableNames = relations.map(({ modelName }) => modelName);
|
|
88
|
+
const modelConstructor = this.getModelConstructorByModelName(namespaceName, srcModelName);
|
|
89
|
+
if (connectionTableNames.length === 0) {
|
|
90
|
+
return records.map(record => this.modelInstanceCreator(modelConstructor, record));
|
|
91
|
+
}
|
|
92
|
+
// Remove related-model fields. They're all `null` in the database,
|
|
93
|
+
// and any that happen to be required will result in a false validation
|
|
94
|
+
// error when DataStore attempts to initialize with `null`.
|
|
95
|
+
// These fields aren't actually needed here. DataStore will use the FK's
|
|
96
|
+
// from the schema model.
|
|
97
|
+
return records.map(record => {
|
|
98
|
+
for (const r of relations) {
|
|
99
|
+
delete record[r.fieldName];
|
|
100
|
+
}
|
|
101
|
+
return this.modelInstanceCreator(modelConstructor, record);
|
|
252
102
|
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
103
|
+
}
|
|
104
|
+
async query(modelConstructor, predicate, pagination) {
|
|
105
|
+
const { name: tableName } = modelConstructor;
|
|
106
|
+
const namespaceName = this.namespaceResolver(modelConstructor);
|
|
107
|
+
const predicates = predicate && ModelPredicateCreator.getPredicates(predicate);
|
|
108
|
+
const sortPredicates = pagination &&
|
|
109
|
+
pagination.sort &&
|
|
110
|
+
ModelSortPredicateCreator.getPredicates(pagination.sort);
|
|
111
|
+
const limit = pagination && pagination.limit;
|
|
112
|
+
const page = limit && pagination.page;
|
|
113
|
+
const queryById = predicates && this.idFromPredicate(predicates);
|
|
114
|
+
const records = await (async () => {
|
|
115
|
+
if (queryById) {
|
|
116
|
+
const record = await this.getById(tableName, queryById);
|
|
117
|
+
return record ? [record] : [];
|
|
118
|
+
}
|
|
119
|
+
const [queryStatement, params] = queryAllStatement(tableName, predicates, sortPredicates, limit, page);
|
|
120
|
+
return await this.db.getAll(queryStatement, params);
|
|
121
|
+
})();
|
|
122
|
+
return await this.load(namespaceName, modelConstructor.name, records);
|
|
123
|
+
}
|
|
124
|
+
async getById(tableName, id) {
|
|
125
|
+
const [queryStatement, params] = queryByIdStatement(id, tableName);
|
|
126
|
+
const record = await this.db.get(queryStatement, params);
|
|
127
|
+
return record;
|
|
128
|
+
}
|
|
129
|
+
idFromPredicate(predicates) {
|
|
130
|
+
const { predicates: predicateObjs } = predicates;
|
|
131
|
+
const idPredicate = predicateObjs.length === 1 &&
|
|
132
|
+
predicateObjs.find(p => isPredicateObj(p) && p.field === 'id' && p.operator === 'eq');
|
|
258
133
|
return idPredicate && idPredicate.operand;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
tableName = modelConstructor.name;
|
|
268
|
-
_a = __read(queryOneStatement(firstOrLast, tableName), 2), queryStatement = _a[0], params = _a[1];
|
|
269
|
-
return [4 /*yield*/, this.db.get(queryStatement, params)];
|
|
270
|
-
case 1:
|
|
271
|
-
result = _b.sent();
|
|
272
|
-
modelInstance = result && this.modelInstanceCreator(modelConstructor, result);
|
|
273
|
-
return [2 /*return*/, modelInstance];
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
};
|
|
134
|
+
}
|
|
135
|
+
async queryOne(modelConstructor, firstOrLast = QueryOne.FIRST) {
|
|
136
|
+
const { name: tableName } = modelConstructor;
|
|
137
|
+
const [queryStatement, params] = queryOneStatement(firstOrLast, tableName);
|
|
138
|
+
const result = await this.db.get(queryStatement, params);
|
|
139
|
+
const modelInstance = result && this.modelInstanceCreator(modelConstructor, result);
|
|
140
|
+
return modelInstance;
|
|
141
|
+
}
|
|
278
142
|
// Currently does not cascade
|
|
279
143
|
// TODO: use FKs in relations and have `ON DELETE CASCADE` set
|
|
280
144
|
// For Has Many and Has One relations to have SQL handle cascades automatically
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
tableName = modelConstructor.name;
|
|
306
|
-
if (!condition) return [3 /*break*/, 6];
|
|
307
|
-
_a = __read(queryByIdStatement(model.id, tableName), 2), queryStatement = _a[0], params = _a[1];
|
|
308
|
-
return [4 /*yield*/, this.db.get(queryStatement, params)];
|
|
309
|
-
case 4:
|
|
310
|
-
fromDB = _d.sent();
|
|
311
|
-
if (fromDB === undefined) {
|
|
312
|
-
msg = 'Model instance not found in storage';
|
|
313
|
-
logger.warn(msg, { model: model });
|
|
314
|
-
return [2 /*return*/, [[model], []]];
|
|
315
|
-
}
|
|
316
|
-
predicates = ModelPredicateCreator.getPredicates(condition);
|
|
317
|
-
predicateObjs = predicates.predicates, type = predicates.type;
|
|
318
|
-
isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
319
|
-
if (!isValid) {
|
|
320
|
-
msg = 'Conditional update failed';
|
|
321
|
-
logger.error(msg, { model: fromDB, condition: predicateObjs });
|
|
322
|
-
throw new Error(msg);
|
|
323
|
-
}
|
|
324
|
-
_b = __read(deleteByIdStatement(model.id, tableName), 2), deleteStatement = _b[0], deleteParams = _b[1];
|
|
325
|
-
return [4 /*yield*/, this.db.save(deleteStatement, deleteParams)];
|
|
326
|
-
case 5:
|
|
327
|
-
_d.sent();
|
|
328
|
-
return [2 /*return*/, [[model], [model]]];
|
|
329
|
-
case 6:
|
|
330
|
-
_c = __read(deleteByIdStatement(model.id, tableName), 2), deleteStatement = _c[0], params = _c[1];
|
|
331
|
-
return [4 /*yield*/, this.db.save(deleteStatement, params)];
|
|
332
|
-
case 7:
|
|
333
|
-
_d.sent();
|
|
334
|
-
return [2 /*return*/, [[model], [model]]];
|
|
145
|
+
async delete(modelOrModelConstructor, condition) {
|
|
146
|
+
if (isModelConstructor(modelOrModelConstructor)) {
|
|
147
|
+
const modelConstructor = modelOrModelConstructor;
|
|
148
|
+
const namespaceName = this.namespaceResolver(modelConstructor);
|
|
149
|
+
const { name: tableName } = modelConstructor;
|
|
150
|
+
const predicates = condition && ModelPredicateCreator.getPredicates(condition);
|
|
151
|
+
const queryStatement = queryAllStatement(tableName, predicates);
|
|
152
|
+
const deleteStatement = deleteByPredicateStatement(tableName, predicates);
|
|
153
|
+
const models = await this.db.selectAndDelete(queryStatement, deleteStatement);
|
|
154
|
+
const modelInstances = await this.load(namespaceName, modelConstructor.name, models);
|
|
155
|
+
return [modelInstances, modelInstances];
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const model = modelOrModelConstructor;
|
|
159
|
+
const modelConstructor = Object.getPrototypeOf(model)
|
|
160
|
+
.constructor;
|
|
161
|
+
const { name: tableName } = modelConstructor;
|
|
162
|
+
if (condition) {
|
|
163
|
+
const [queryStatement, params] = queryByIdStatement(model.id, tableName);
|
|
164
|
+
const fromDB = await this.db.get(queryStatement, params);
|
|
165
|
+
if (fromDB === undefined) {
|
|
166
|
+
const msg = 'Model instance not found in storage';
|
|
167
|
+
logger.warn(msg, { model });
|
|
168
|
+
return [[model], []];
|
|
335
169
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
return __generator(this, function (_b) {
|
|
344
|
-
switch (_b.label) {
|
|
345
|
-
case 0:
|
|
346
|
-
tableName = modelConstructor.name;
|
|
347
|
-
result = [];
|
|
348
|
-
itemsToSave = [];
|
|
349
|
-
queryStatements = new Set();
|
|
350
|
-
deleteStatements = new Set();
|
|
351
|
-
saveStatements = new Set();
|
|
352
|
-
_loop_1 = function (item) {
|
|
353
|
-
var connectedModels = traverseModel(modelConstructor.name, this_1.modelInstanceCreator(modelConstructor, item), this_1.schema.namespaces[this_1.namespaceResolver(modelConstructor)], this_1.modelInstanceCreator, this_1.getModelConstructorByModelName);
|
|
354
|
-
var id = item.id, _deleted = item._deleted;
|
|
355
|
-
var instance = connectedModels.find(function (_a) {
|
|
356
|
-
var instance = _a.instance;
|
|
357
|
-
return instance.id === id;
|
|
358
|
-
}).instance;
|
|
359
|
-
if (_deleted) {
|
|
360
|
-
// create the delete statements right away
|
|
361
|
-
var deleteStatement = deleteByIdStatement(instance.id, tableName);
|
|
362
|
-
deleteStatements.add(deleteStatement);
|
|
363
|
-
result.push([item, OpType.DELETE]);
|
|
364
|
-
}
|
|
365
|
-
else {
|
|
366
|
-
// query statements for the saves at first
|
|
367
|
-
var queryStatement = queryByIdStatement(id, tableName);
|
|
368
|
-
queryStatements.add(queryStatement);
|
|
369
|
-
// combination of insert and update items
|
|
370
|
-
itemsToSave.push(instance);
|
|
371
|
-
}
|
|
372
|
-
};
|
|
373
|
-
this_1 = this;
|
|
374
|
-
try {
|
|
375
|
-
for (items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
|
|
376
|
-
item = items_1_1.value;
|
|
377
|
-
_loop_1(item);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
381
|
-
finally {
|
|
382
|
-
try {
|
|
383
|
-
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
|
|
384
|
-
}
|
|
385
|
-
finally { if (e_3) throw e_3.error; }
|
|
386
|
-
}
|
|
387
|
-
return [4 /*yield*/, this.db.batchQuery(queryStatements)];
|
|
388
|
-
case 1:
|
|
389
|
-
queryResponses = _b.sent();
|
|
390
|
-
queryResponses.forEach(function (response, idx) {
|
|
391
|
-
if (response === undefined) {
|
|
392
|
-
var insertStatement = modelInsertStatement(itemsToSave[idx], tableName);
|
|
393
|
-
saveStatements.add(insertStatement);
|
|
394
|
-
result.push([itemsToSave[idx], OpType.INSERT]);
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
var updateStatement = modelUpdateStatement(itemsToSave[idx], tableName);
|
|
398
|
-
saveStatements.add(updateStatement);
|
|
399
|
-
result.push([itemsToSave[idx], OpType.UPDATE]);
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
// perform all of the insert/update/delete operations in a single transaction
|
|
403
|
-
return [4 /*yield*/, this.db.batchSave(saveStatements, deleteStatements)];
|
|
404
|
-
case 2:
|
|
405
|
-
// perform all of the insert/update/delete operations in a single transaction
|
|
406
|
-
_b.sent();
|
|
407
|
-
return [2 /*return*/, result];
|
|
170
|
+
const predicates = ModelPredicateCreator.getPredicates(condition);
|
|
171
|
+
const { predicates: predicateObjs, type } = predicates;
|
|
172
|
+
const isValid = validatePredicate(fromDB, type, predicateObjs);
|
|
173
|
+
if (!isValid) {
|
|
174
|
+
const msg = 'Conditional update failed';
|
|
175
|
+
logger.error(msg, { model: fromDB, condition: predicateObjs });
|
|
176
|
+
throw new Error(msg);
|
|
408
177
|
}
|
|
409
|
-
|
|
178
|
+
const [deleteStatement, deleteParams] = deleteByIdStatement(model.id, tableName);
|
|
179
|
+
await this.db.save(deleteStatement, deleteParams);
|
|
180
|
+
return [[model], [model]];
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
const [deleteStatement, params] = deleteByIdStatement(model.id, tableName);
|
|
184
|
+
await this.db.save(deleteStatement, params);
|
|
185
|
+
return [[model], [model]];
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
async batchSave(modelConstructor, items) {
|
|
190
|
+
const { name: tableName } = modelConstructor;
|
|
191
|
+
const result = [];
|
|
192
|
+
const itemsToSave = [];
|
|
193
|
+
// To determine whether an item should result in an insert or update operation
|
|
194
|
+
// We first need to query the local DB on the item id
|
|
195
|
+
const queryStatements = new Set();
|
|
196
|
+
// Deletes don't need to be queried first, because if the item doesn't exist,
|
|
197
|
+
// the delete operation will be a no-op
|
|
198
|
+
const deleteStatements = new Set();
|
|
199
|
+
const saveStatements = new Set();
|
|
200
|
+
for (const item of items) {
|
|
201
|
+
const connectedModels = traverseModel(modelConstructor.name, this.modelInstanceCreator(modelConstructor, item), this.schema.namespaces[this.namespaceResolver(modelConstructor)], this.modelInstanceCreator, this.getModelConstructorByModelName);
|
|
202
|
+
const { id, _deleted } = item;
|
|
203
|
+
const { instance } = connectedModels.find(({ instance }) => instance.id === id);
|
|
204
|
+
if (_deleted) {
|
|
205
|
+
// create the delete statements right away
|
|
206
|
+
const deleteStatement = deleteByIdStatement(instance.id, tableName);
|
|
207
|
+
deleteStatements.add(deleteStatement);
|
|
208
|
+
result.push([item, OpType.DELETE]);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
// query statements for the saves at first
|
|
212
|
+
const queryStatement = queryByIdStatement(id, tableName);
|
|
213
|
+
queryStatements.add(queryStatement);
|
|
214
|
+
// combination of insert and update items
|
|
215
|
+
itemsToSave.push(instance);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// returns the query results for each of the save items
|
|
219
|
+
const queryResponses = await this.db.batchQuery(queryStatements);
|
|
220
|
+
queryResponses.forEach((response, idx) => {
|
|
221
|
+
if (response === undefined) {
|
|
222
|
+
const insertStatement = modelInsertStatement(itemsToSave[idx], tableName);
|
|
223
|
+
saveStatements.add(insertStatement);
|
|
224
|
+
result.push([itemsToSave[idx], OpType.INSERT]);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
const updateStatement = modelUpdateStatement(itemsToSave[idx], tableName);
|
|
228
|
+
saveStatements.add(updateStatement);
|
|
229
|
+
result.push([itemsToSave[idx], OpType.UPDATE]);
|
|
230
|
+
}
|
|
410
231
|
});
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
232
|
+
// perform all of the insert/update/delete operations in a single transaction
|
|
233
|
+
await this.db.batchSave(saveStatements, deleteStatements);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
415
237
|
//# sourceMappingURL=CommonSQLiteAdapter.js.map
|