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