@e22m4u/js-repository 0.0.31

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 (183) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.eslintignore +1 -0
  5. package/.eslintrc.cjs +27 -0
  6. package/.husky/commit-msg +4 -0
  7. package/.husky/pre-commit +9 -0
  8. package/.mocharc.cjs +7 -0
  9. package/.prettierrc +7 -0
  10. package/LICENSE +21 -0
  11. package/README.md +523 -0
  12. package/mocha.setup.js +10 -0
  13. package/package.json +57 -0
  14. package/src/adapter/adapter-loader.d.ts +16 -0
  15. package/src/adapter/adapter-loader.js +63 -0
  16. package/src/adapter/adapter-loader.spec.js +31 -0
  17. package/src/adapter/adapter-registry.d.ts +14 -0
  18. package/src/adapter/adapter-registry.js +36 -0
  19. package/src/adapter/adapter-registry.spec.js +36 -0
  20. package/src/adapter/adapter.d.ts +118 -0
  21. package/src/adapter/adapter.js +181 -0
  22. package/src/adapter/adapter.spec.js +144 -0
  23. package/src/adapter/builtin/memory-adapter.d.ts +118 -0
  24. package/src/adapter/builtin/memory-adapter.js +342 -0
  25. package/src/adapter/builtin/memory-adapter.spec.js +2925 -0
  26. package/src/adapter/decorator/data-sanitizing-decorator.d.ts +13 -0
  27. package/src/adapter/decorator/data-sanitizing-decorator.js +44 -0
  28. package/src/adapter/decorator/data-sanitizing-decorator.spec.js +59 -0
  29. package/src/adapter/decorator/data-validation-decorator.d.ts +13 -0
  30. package/src/adapter/decorator/data-validation-decorator.js +41 -0
  31. package/src/adapter/decorator/data-validation-decorator.spec.js +59 -0
  32. package/src/adapter/decorator/default-values-decorator.d.ts +13 -0
  33. package/src/adapter/decorator/default-values-decorator.js +57 -0
  34. package/src/adapter/decorator/default-values-decorator.spec.js +141 -0
  35. package/src/adapter/decorator/fields-filtering-decorator.d.ts +13 -0
  36. package/src/adapter/decorator/fields-filtering-decorator.js +72 -0
  37. package/src/adapter/decorator/fields-filtering-decorator.spec.js +119 -0
  38. package/src/adapter/decorator/inclusion-decorator.d.ts +13 -0
  39. package/src/adapter/decorator/inclusion-decorator.js +78 -0
  40. package/src/adapter/decorator/inclusion-decorator.spec.js +117 -0
  41. package/src/adapter/decorator/index.d.ts +5 -0
  42. package/src/adapter/decorator/index.js +5 -0
  43. package/src/adapter/index.d.ts +3 -0
  44. package/src/adapter/index.js +3 -0
  45. package/src/definition/datasource/datasource-definition-validator.d.ts +14 -0
  46. package/src/definition/datasource/datasource-definition-validator.js +33 -0
  47. package/src/definition/datasource/datasource-definition-validator.spec.js +63 -0
  48. package/src/definition/datasource/datasource-definition.d.ts +7 -0
  49. package/src/definition/datasource/index.d.ts +2 -0
  50. package/src/definition/datasource/index.js +1 -0
  51. package/src/definition/definition-registry.d.ts +50 -0
  52. package/src/definition/definition-registry.js +98 -0
  53. package/src/definition/definition-registry.spec.js +78 -0
  54. package/src/definition/index.d.ts +3 -0
  55. package/src/definition/index.js +3 -0
  56. package/src/definition/model/index.d.ts +7 -0
  57. package/src/definition/model/index.js +6 -0
  58. package/src/definition/model/model-data-sanitizer.d.ts +15 -0
  59. package/src/definition/model/model-data-sanitizer.js +33 -0
  60. package/src/definition/model/model-data-validator.d.ts +32 -0
  61. package/src/definition/model/model-data-validator.js +144 -0
  62. package/src/definition/model/model-data-validator.spec.js +1889 -0
  63. package/src/definition/model/model-definition-utils.d.ts +161 -0
  64. package/src/definition/model/model-definition-utils.js +371 -0
  65. package/src/definition/model/model-definition-utils.spec.js +1474 -0
  66. package/src/definition/model/model-definition-validator.d.ts +14 -0
  67. package/src/definition/model/model-definition-validator.js +83 -0
  68. package/src/definition/model/model-definition-validator.spec.js +143 -0
  69. package/src/definition/model/model-definition.d.ts +28 -0
  70. package/src/definition/model/properties/data-type.d.ts +11 -0
  71. package/src/definition/model/properties/data-type.js +11 -0
  72. package/src/definition/model/properties/default-values-definition-validator.d.ts +15 -0
  73. package/src/definition/model/properties/default-values-definition-validator.js +53 -0
  74. package/src/definition/model/properties/default-values-definition-validator.spec.js +136 -0
  75. package/src/definition/model/properties/index.d.ts +5 -0
  76. package/src/definition/model/properties/index.js +4 -0
  77. package/src/definition/model/properties/primary-keys-definition-validator.d.ts +15 -0
  78. package/src/definition/model/properties/primary-keys-definition-validator.js +55 -0
  79. package/src/definition/model/properties/primary-keys-definition-validator.spec.js +145 -0
  80. package/src/definition/model/properties/properties-definition-validator.d.ts +15 -0
  81. package/src/definition/model/properties/properties-definition-validator.js +194 -0
  82. package/src/definition/model/properties/properties-definition-validator.spec.js +373 -0
  83. package/src/definition/model/properties/property-definition.d.ts +20 -0
  84. package/src/definition/model/relations/index.d.ts +3 -0
  85. package/src/definition/model/relations/index.js +2 -0
  86. package/src/definition/model/relations/relation-definition.d.ts +254 -0
  87. package/src/definition/model/relations/relation-type.d.ts +9 -0
  88. package/src/definition/model/relations/relation-type.js +9 -0
  89. package/src/definition/model/relations/relations-definition-validator.d.ts +15 -0
  90. package/src/definition/model/relations/relations-definition-validator.js +449 -0
  91. package/src/definition/model/relations/relations-definition-validator.spec.js +772 -0
  92. package/src/errors/index.d.ts +3 -0
  93. package/src/errors/index.js +3 -0
  94. package/src/errors/invalid-argument-error.d.ts +6 -0
  95. package/src/errors/invalid-argument-error.js +6 -0
  96. package/src/errors/invalid-argument-error.spec.js +33 -0
  97. package/src/errors/invalid-operator-value-error.d.ts +13 -0
  98. package/src/errors/invalid-operator-value-error.js +24 -0
  99. package/src/errors/invalid-operator-value-error.spec.js +11 -0
  100. package/src/errors/not-implemented-error.d.ts +6 -0
  101. package/src/errors/not-implemented-error.js +6 -0
  102. package/src/errors/not-implemented-error.spec.js +33 -0
  103. package/src/filter/fields-clause-tool.d.ts +38 -0
  104. package/src/filter/fields-clause-tool.js +88 -0
  105. package/src/filter/fields-clause-tool.spec.js +133 -0
  106. package/src/filter/filter.d.ts +335 -0
  107. package/src/filter/include-clause-tool.d.ts +53 -0
  108. package/src/filter/include-clause-tool.js +364 -0
  109. package/src/filter/include-clause-tool.spec.js +653 -0
  110. package/src/filter/index.d.ts +7 -0
  111. package/src/filter/index.js +6 -0
  112. package/src/filter/operator-clause-tool.d.ts +223 -0
  113. package/src/filter/operator-clause-tool.js +515 -0
  114. package/src/filter/operator-clause-tool.spec.js +1064 -0
  115. package/src/filter/order-clause-tool.d.ts +32 -0
  116. package/src/filter/order-clause-tool.js +97 -0
  117. package/src/filter/order-clause-tool.spec.js +438 -0
  118. package/src/filter/slice-clause-tool.d.ts +30 -0
  119. package/src/filter/slice-clause-tool.js +65 -0
  120. package/src/filter/slice-clause-tool.spec.js +117 -0
  121. package/src/filter/where-clause-tool.d.ts +23 -0
  122. package/src/filter/where-clause-tool.js +165 -0
  123. package/src/filter/where-clause-tool.spec.js +280 -0
  124. package/src/index.d.ts +9 -0
  125. package/src/index.js +8 -0
  126. package/src/relations/belongs-to-resolver.d.ts +46 -0
  127. package/src/relations/belongs-to-resolver.js +242 -0
  128. package/src/relations/belongs-to-resolver.spec.js +1047 -0
  129. package/src/relations/has-many-resolver.d.ts +67 -0
  130. package/src/relations/has-many-resolver.js +317 -0
  131. package/src/relations/has-many-resolver.spec.js +2911 -0
  132. package/src/relations/has-one-resolver.d.ts +67 -0
  133. package/src/relations/has-one-resolver.js +311 -0
  134. package/src/relations/has-one-resolver.spec.js +2274 -0
  135. package/src/relations/index.d.ts +4 -0
  136. package/src/relations/index.js +4 -0
  137. package/src/relations/references-many-resolver.d.ts +27 -0
  138. package/src/relations/references-many-resolver.js +113 -0
  139. package/src/relations/references-many-resolver.spec.js +631 -0
  140. package/src/repository/index.d.ts +2 -0
  141. package/src/repository/index.js +2 -0
  142. package/src/repository/repository-registry.d.ts +29 -0
  143. package/src/repository/repository-registry.js +57 -0
  144. package/src/repository/repository-registry.spec.js +38 -0
  145. package/src/repository/repository.d.ts +164 -0
  146. package/src/repository/repository.js +207 -0
  147. package/src/repository/repository.spec.js +202 -0
  148. package/src/schema.d.ts +37 -0
  149. package/src/schema.js +41 -0
  150. package/src/types.d.ts +30 -0
  151. package/src/utils/capitalize.d.ts +6 -0
  152. package/src/utils/capitalize.js +10 -0
  153. package/src/utils/capitalize.spec.js +14 -0
  154. package/src/utils/clone-deep.d.ts +6 -0
  155. package/src/utils/clone-deep.js +61 -0
  156. package/src/utils/clone-deep.spec.js +28 -0
  157. package/src/utils/exclude-object-keys.d.ts +10 -0
  158. package/src/utils/exclude-object-keys.js +20 -0
  159. package/src/utils/exclude-object-keys.spec.js +49 -0
  160. package/src/utils/get-ctor-name.d.ts +6 -0
  161. package/src/utils/get-ctor-name.js +11 -0
  162. package/src/utils/get-ctor-name.spec.js +17 -0
  163. package/src/utils/get-value-by-path.d.ts +12 -0
  164. package/src/utils/get-value-by-path.js +23 -0
  165. package/src/utils/get-value-by-path.spec.js +36 -0
  166. package/src/utils/index.d.ts +10 -0
  167. package/src/utils/index.js +10 -0
  168. package/src/utils/is-ctor.d.ts +7 -0
  169. package/src/utils/is-ctor.js +10 -0
  170. package/src/utils/is-ctor.spec.js +26 -0
  171. package/src/utils/is-pure-object.d.ts +6 -0
  172. package/src/utils/is-pure-object.js +15 -0
  173. package/src/utils/is-pure-object.spec.js +25 -0
  174. package/src/utils/select-object-keys.d.ts +10 -0
  175. package/src/utils/select-object-keys.js +37 -0
  176. package/src/utils/select-object-keys.spec.js +40 -0
  177. package/src/utils/singularize.d.ts +6 -0
  178. package/src/utils/singularize.js +22 -0
  179. package/src/utils/singularize.spec.js +23 -0
  180. package/src/utils/string-to-regexp.d.ts +10 -0
  181. package/src/utils/string-to-regexp.js +22 -0
  182. package/src/utils/string-to-regexp.spec.js +35 -0
  183. package/tsconfig.json +9 -0
@@ -0,0 +1,2925 @@
1
+ import {expect} from 'chai';
2
+ import {Schema} from '../../schema.js';
3
+ import {format} from '@e22m4u/js-format';
4
+ import {MemoryAdapter} from './memory-adapter.js';
5
+ import {DataType} from '../../definition/index.js';
6
+ import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '../../definition/index.js';
7
+
8
+ describe('MemoryAdapter', function () {
9
+ describe('_getTableOrCreate', function () {
10
+ it('returns an existing table or creates a new', function () {
11
+ const S = new Schema();
12
+ S.defineModel({name: 'model'});
13
+ const A = S.getService(MemoryAdapter);
14
+ const table = A._getTableOrCreate('model');
15
+ expect(table).to.be.instanceof(Map);
16
+ const sameTable = A._getTableOrCreate('model');
17
+ expect(table).to.be.eq(sameTable);
18
+ });
19
+
20
+ it('uses a model name to find a table, even a table name is specified', function () {
21
+ const S = new Schema();
22
+ S.defineModel({
23
+ name: 'myModel',
24
+ tableName: 'myTable',
25
+ });
26
+ const A = S.getService(MemoryAdapter);
27
+ const table = A._getTableOrCreate('myModel');
28
+ expect(table).to.be.instanceof(Map);
29
+ const sameTable = A._getTableOrCreate('myModel');
30
+ expect(table).to.be.eq(sameTable);
31
+ });
32
+
33
+ it('stores a table by specified table name', function () {
34
+ const S = new Schema();
35
+ S.defineModel({
36
+ name: 'myModel',
37
+ tableName: 'myTable',
38
+ });
39
+ const A = S.getService(MemoryAdapter);
40
+ const table = A._getTableOrCreate('myModel');
41
+ expect(table).to.be.instanceof(Map);
42
+ const sameTable = A._tables.get('myTable');
43
+ expect(table).to.be.eq(sameTable);
44
+ });
45
+ });
46
+
47
+ describe('_genNextIdValue', function () {
48
+ it('returns an unique number identifier', function () {
49
+ const S = new Schema();
50
+ S.defineModel({name: 'model'});
51
+ const A = S.getService(MemoryAdapter);
52
+ const id1 = A._genNextIdValue('model', DEF_PK);
53
+ const id2 = A._genNextIdValue('model', DEF_PK);
54
+ const id3 = A._genNextIdValue('model', DEF_PK);
55
+ expect(id1).to.be.eq(1);
56
+ expect(id2).to.be.eq(2);
57
+ expect(id3).to.be.eq(3);
58
+ });
59
+ });
60
+
61
+ describe('create', function () {
62
+ it('skips existing values when generating a new identifier for a default primary key', async function () {
63
+ const schema = new Schema();
64
+ schema.defineDatasource({
65
+ name: 'memory',
66
+ adapter: 'memory',
67
+ });
68
+ schema.defineModel({
69
+ name: 'model',
70
+ datasource: 'memory',
71
+ });
72
+ const adapter = new MemoryAdapter(schema.container, {});
73
+ const result1 = await adapter.create('model', {});
74
+ const result2 = await adapter.create('model', {});
75
+ const result3 = await adapter.create('model', {[DEF_PK]: 3});
76
+ const result4 = await adapter.create('model', {});
77
+ expect(result1).to.be.eql({[DEF_PK]: 1});
78
+ expect(result2).to.be.eql({[DEF_PK]: 2});
79
+ expect(result3).to.be.eql({[DEF_PK]: 3});
80
+ expect(result4).to.be.eql({[DEF_PK]: 4});
81
+ });
82
+
83
+ it('skips existing values when generating a new identifier for a specified primary key', async function () {
84
+ const schema = new Schema();
85
+ schema.defineDatasource({
86
+ name: 'memory',
87
+ adapter: 'memory',
88
+ });
89
+ schema.defineModel({
90
+ name: 'model',
91
+ datasource: 'memory',
92
+ properties: {
93
+ myId: {
94
+ type: DataType.NUMBER,
95
+ primaryKey: true,
96
+ },
97
+ },
98
+ });
99
+ const adapter = new MemoryAdapter(schema.container, {});
100
+ const result1 = await adapter.create('model', {});
101
+ const result2 = await adapter.create('model', {});
102
+ const result3 = await adapter.create('model', {myId: 3});
103
+ const result4 = await adapter.create('model', {});
104
+ expect(result1).to.be.eql({myId: 1});
105
+ expect(result2).to.be.eql({myId: 2});
106
+ expect(result3).to.be.eql({myId: 3});
107
+ expect(result4).to.be.eql({myId: 4});
108
+ });
109
+
110
+ it('generates a new identifier when a value of a primary key has not provided', async function () {
111
+ const schema = new Schema();
112
+ schema.defineDatasource({
113
+ name: 'memory',
114
+ adapter: 'memory',
115
+ });
116
+ schema.defineModel({
117
+ name: 'model',
118
+ datasource: 'memory',
119
+ properties: {
120
+ foo: DataType.STRING,
121
+ bar: DataType.NUMBER,
122
+ },
123
+ });
124
+ const adapter = new MemoryAdapter(schema.container, {});
125
+ const input = {foo: 'string', bar: 10};
126
+ const created = await adapter.create('model', input);
127
+ const idValue = created[DEF_PK];
128
+ expect(created).to.be.eql({...input, [DEF_PK]: idValue});
129
+ const table = adapter._getTableOrCreate('model');
130
+ const tableData = table.get(idValue);
131
+ expect(tableData).to.be.eql({...input, [DEF_PK]: idValue});
132
+ });
133
+
134
+ it('generates a new identifier when a value of a primary key is undefined', async function () {
135
+ const schema = new Schema();
136
+ schema.defineDatasource({
137
+ name: 'memory',
138
+ adapter: 'memory',
139
+ });
140
+ schema.defineModel({
141
+ name: 'model',
142
+ datasource: 'memory',
143
+ properties: {
144
+ foo: DataType.STRING,
145
+ bar: DataType.NUMBER,
146
+ },
147
+ });
148
+ const adapter = new MemoryAdapter(schema.container, {});
149
+ const input = {
150
+ [DEF_PK]: undefined,
151
+ foo: 'string',
152
+ bar: 10,
153
+ };
154
+ const created = await adapter.create('model', input);
155
+ const idValue = created[DEF_PK];
156
+ expect(created).to.be.eql({...input, [DEF_PK]: idValue});
157
+ const table = adapter._getTableOrCreate('model');
158
+ const tableData = table.get(idValue);
159
+ expect(tableData).to.be.eql({...input, [DEF_PK]: idValue});
160
+ });
161
+
162
+ it('generates a new identifier when a value of a primary key is null', async function () {
163
+ const schema = new Schema();
164
+ schema.defineDatasource({
165
+ name: 'memory',
166
+ adapter: 'memory',
167
+ });
168
+ schema.defineModel({
169
+ name: 'model',
170
+ datasource: 'memory',
171
+ properties: {
172
+ foo: DataType.STRING,
173
+ bar: DataType.NUMBER,
174
+ },
175
+ });
176
+ const adapter = new MemoryAdapter(schema.container, {});
177
+ const input = {
178
+ [DEF_PK]: null,
179
+ foo: 'string',
180
+ bar: 10,
181
+ };
182
+ const created = await adapter.create('model', input);
183
+ const idValue = created[DEF_PK];
184
+ expect(created).to.be.eql({...input, [DEF_PK]: idValue});
185
+ const table = adapter._getTableOrCreate('model');
186
+ const tableData = table.get(idValue);
187
+ expect(tableData).to.be.eql({...input, [DEF_PK]: idValue});
188
+ });
189
+
190
+ it('generates a new identifier for a primary key of a "number" type', async function () {
191
+ const schema = new Schema();
192
+ schema.defineDatasource({
193
+ name: 'memory',
194
+ adapter: 'memory',
195
+ });
196
+ schema.defineModel({
197
+ name: 'model',
198
+ datasource: 'memory',
199
+ properties: {
200
+ myId: {
201
+ type: DataType.NUMBER,
202
+ primaryKey: true,
203
+ },
204
+ },
205
+ });
206
+ const adapter = new MemoryAdapter(schema.container, {});
207
+ const result1 = await adapter.create('model', {});
208
+ const result2 = await adapter.create('model', {});
209
+ const result3 = await adapter.create('model', {});
210
+ expect(result1).to.be.eql({myId: 1});
211
+ expect(result2).to.be.eql({myId: 2});
212
+ expect(result3).to.be.eql({myId: 3});
213
+ });
214
+
215
+ it('generates a new identifier for a primary key of an "any" type', async function () {
216
+ const schema = new Schema();
217
+ schema.defineDatasource({
218
+ name: 'memory',
219
+ adapter: 'memory',
220
+ });
221
+ schema.defineModel({
222
+ name: 'model',
223
+ datasource: 'memory',
224
+ properties: {
225
+ myId: {
226
+ type: DataType.ANY,
227
+ primaryKey: true,
228
+ },
229
+ },
230
+ });
231
+ const adapter = new MemoryAdapter(schema.container, {});
232
+ const result1 = await adapter.create('model', {});
233
+ const result2 = await adapter.create('model', {});
234
+ const result3 = await adapter.create('model', {});
235
+ expect(result1).to.be.eql({myId: 1});
236
+ expect(result2).to.be.eql({myId: 2});
237
+ expect(result3).to.be.eql({myId: 3});
238
+ });
239
+
240
+ it('throws an error when generating a new value for a primary key of a "string" type', async function () {
241
+ const schema = new Schema();
242
+ schema.defineDatasource({
243
+ name: 'memory',
244
+ adapter: 'memory',
245
+ });
246
+ schema.defineModel({
247
+ name: 'model',
248
+ datasource: 'memory',
249
+ properties: {
250
+ myId: {
251
+ type: DataType.STRING,
252
+ primaryKey: true,
253
+ },
254
+ },
255
+ });
256
+ const adapter = new MemoryAdapter(schema.container, {});
257
+ const promise = adapter.create('model', {foo: 'string', bar: 10});
258
+ await expect(promise).to.be.rejectedWith(
259
+ 'The memory adapter able to generate only Number identifiers, ' +
260
+ 'but the primary key "myId" of the model "model" is defined as String. ' +
261
+ 'Do provide your own value for the "myId" property, or change the type ' +
262
+ 'in the primary key definition to a Number that will be ' +
263
+ 'generated automatically.',
264
+ );
265
+ });
266
+
267
+ it('throws an error when generating a new value for a primary key of a "boolean" type', async function () {
268
+ const schema = new Schema();
269
+ schema.defineDatasource({
270
+ name: 'memory',
271
+ adapter: 'memory',
272
+ });
273
+ schema.defineModel({
274
+ name: 'model',
275
+ datasource: 'memory',
276
+ properties: {
277
+ myId: {
278
+ type: DataType.BOOLEAN,
279
+ primaryKey: true,
280
+ },
281
+ },
282
+ });
283
+ const adapter = new MemoryAdapter(schema.container, {});
284
+ const promise = adapter.create('model', {foo: 'string', bar: 10});
285
+ await expect(promise).to.be.rejectedWith(
286
+ 'The memory adapter able to generate only Number identifiers, ' +
287
+ 'but the primary key "myId" of the model "model" is defined as Boolean. ' +
288
+ 'Do provide your own value for the "myId" property, or change the type ' +
289
+ 'in the primary key definition to a Number that will be ' +
290
+ 'generated automatically.',
291
+ );
292
+ });
293
+
294
+ it('throws an error when generating a new value for a primary key of an "array" type', async function () {
295
+ const schema = new Schema();
296
+ schema.defineDatasource({
297
+ name: 'memory',
298
+ adapter: 'memory',
299
+ });
300
+ schema.defineModel({
301
+ name: 'model',
302
+ datasource: 'memory',
303
+ properties: {
304
+ myId: {
305
+ type: DataType.ARRAY,
306
+ itemType: DataType.NUMBER,
307
+ primaryKey: true,
308
+ },
309
+ },
310
+ });
311
+ const adapter = new MemoryAdapter(schema.container, {});
312
+ const promise = adapter.create('model', {});
313
+ await expect(promise).to.be.rejectedWith(
314
+ 'The memory adapter able to generate only Number identifiers, ' +
315
+ 'but the primary key "myId" of the model "model" is defined as Array. ' +
316
+ 'Do provide your own value for the "myId" property, or change the type ' +
317
+ 'in the primary key definition to a Number that will be ' +
318
+ 'generated automatically.',
319
+ );
320
+ });
321
+
322
+ it('throws an error when generating a new value for a primary key of an "object" type', async function () {
323
+ const schema = new Schema();
324
+ schema.defineDatasource({
325
+ name: 'memory',
326
+ adapter: 'memory',
327
+ });
328
+ schema.defineModel({
329
+ name: 'model',
330
+ datasource: 'memory',
331
+ properties: {
332
+ myId: {
333
+ type: DataType.OBJECT,
334
+ primaryKey: true,
335
+ },
336
+ },
337
+ });
338
+ const adapter = new MemoryAdapter(schema.container, {});
339
+ const promise = adapter.create('model', {});
340
+ await expect(promise).to.be.rejectedWith(
341
+ 'The memory adapter able to generate only Number identifiers, ' +
342
+ 'but the primary key "myId" of the model "model" is defined as Object. ' +
343
+ 'Do provide your own value for the "myId" property, or change the type ' +
344
+ 'in the primary key definition to a Number that will be ' +
345
+ 'generated automatically.',
346
+ );
347
+ });
348
+
349
+ it('allows to specify an identifier value for a new item', async function () {
350
+ const schema = new Schema();
351
+ schema.defineDatasource({
352
+ name: 'memory',
353
+ adapter: 'memory',
354
+ });
355
+ schema.defineModel({
356
+ name: 'model',
357
+ datasource: 'memory',
358
+ properties: {
359
+ foo: DataType.STRING,
360
+ bar: DataType.NUMBER,
361
+ },
362
+ });
363
+ const adapter = new MemoryAdapter(schema.container, {});
364
+ const idValue = 5;
365
+ const input = {foo: 'string', bar: 10};
366
+ const created = await adapter.create('model', {
367
+ [DEF_PK]: idValue,
368
+ ...input,
369
+ });
370
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...input});
371
+ const table = adapter._getTableOrCreate('model');
372
+ const tableData = table.get(idValue);
373
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...input});
374
+ });
375
+
376
+ it('throws an error if a given identifier value already exists', async function () {
377
+ const schema = new Schema();
378
+ schema.defineDatasource({
379
+ name: 'memory',
380
+ adapter: 'memory',
381
+ });
382
+ schema.defineModel({
383
+ name: 'model',
384
+ datasource: 'memory',
385
+ properties: {
386
+ foo: DataType.STRING,
387
+ },
388
+ });
389
+ const adapter = new MemoryAdapter(schema.container, {});
390
+ const created = await adapter.create('model', {foo: 'string'});
391
+ const promise = adapter.create('model', created);
392
+ await expect(promise).to.be.rejectedWith(
393
+ format(
394
+ 'The value 1 of the primary key %v already exists in the model "model".',
395
+ DEF_PK,
396
+ ),
397
+ );
398
+ });
399
+
400
+ it('sets default values if they are not provided for a new item', async function () {
401
+ const schema = new Schema();
402
+ schema.defineDatasource({
403
+ name: 'memory',
404
+ adapter: 'memory',
405
+ });
406
+ schema.defineModel({
407
+ name: 'model',
408
+ datasource: 'memory',
409
+ properties: {
410
+ foo: {
411
+ type: DataType.NUMBER,
412
+ default: 10,
413
+ },
414
+ bar: {
415
+ type: DataType.STRING,
416
+ default: 'string',
417
+ },
418
+ },
419
+ });
420
+ const adapter = new MemoryAdapter(schema.container, {});
421
+ const created = await adapter.create('model', {});
422
+ const idValue = created[DEF_PK];
423
+ const defaults = {foo: 10, bar: 'string'};
424
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
425
+ const table = adapter._getTableOrCreate('model');
426
+ const tableData = table.get(idValue);
427
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
428
+ });
429
+
430
+ it('sets default values for properties provided with an undefined value', async function () {
431
+ const schema = new Schema();
432
+ schema.defineDatasource({
433
+ name: 'memory',
434
+ adapter: 'memory',
435
+ });
436
+ schema.defineModel({
437
+ name: 'model',
438
+ datasource: 'memory',
439
+ properties: {
440
+ foo: {
441
+ type: DataType.NUMBER,
442
+ default: 1,
443
+ },
444
+ bar: {
445
+ type: DataType.NUMBER,
446
+ default: 2,
447
+ },
448
+ },
449
+ });
450
+ const adapter = new MemoryAdapter(schema.container, {});
451
+ const created = await adapter.create('model', {foo: undefined});
452
+ const idValue = created[DEF_PK];
453
+ const defaults = {foo: 1, bar: 2};
454
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
455
+ const table = adapter._getTableOrCreate('model');
456
+ const tableData = table.get(idValue);
457
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
458
+ });
459
+
460
+ it('sets default values for properties provided with a null value', async function () {
461
+ const schema = new Schema();
462
+ schema.defineDatasource({
463
+ name: 'memory',
464
+ adapter: 'memory',
465
+ });
466
+ schema.defineModel({
467
+ name: 'model',
468
+ datasource: 'memory',
469
+ properties: {
470
+ foo: {
471
+ type: DataType.NUMBER,
472
+ default: 1,
473
+ },
474
+ bar: {
475
+ type: DataType.NUMBER,
476
+ default: 2,
477
+ },
478
+ },
479
+ });
480
+ const adapter = new MemoryAdapter(schema.container, {});
481
+ const created = await adapter.create('model', {foo: null});
482
+ const idValue = created[DEF_PK];
483
+ const defaults = {foo: 1, bar: 2};
484
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
485
+ const table = adapter._getTableOrCreate('model');
486
+ const tableData = table.get(idValue);
487
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
488
+ });
489
+
490
+ it('uses a specified column name for a primary key', async function () {
491
+ const schema = new Schema();
492
+ schema.defineDatasource({
493
+ name: 'memory',
494
+ adapter: 'memory',
495
+ });
496
+ schema.defineModel({
497
+ name: 'model',
498
+ datasource: 'memory',
499
+ properties: {
500
+ foo: {
501
+ type: DataType.NUMBER,
502
+ primaryKey: true,
503
+ columnName: 'bar',
504
+ },
505
+ },
506
+ });
507
+ const adapter = new MemoryAdapter(schema.container, {});
508
+ const created = await adapter.create('model', {});
509
+ expect(created).to.be.eql({foo: created.foo});
510
+ const table = adapter._getTableOrCreate('model');
511
+ const tableData = table.get(created.foo);
512
+ expect(tableData).to.be.eql({bar: created.foo});
513
+ });
514
+
515
+ it('uses a specified column name for a regular property', async function () {
516
+ const schema = new Schema();
517
+ schema.defineDatasource({
518
+ name: 'memory',
519
+ adapter: 'memory',
520
+ });
521
+ schema.defineModel({
522
+ name: 'model',
523
+ datasource: 'memory',
524
+ properties: {
525
+ foo: {
526
+ type: DataType.NUMBER,
527
+ columnName: 'bar',
528
+ },
529
+ },
530
+ });
531
+ const adapter = new MemoryAdapter(schema.container, {});
532
+ const created = await adapter.create('model', {foo: 10});
533
+ const idValue = created[DEF_PK];
534
+ expect(created).to.be.eql({[DEF_PK]: idValue, foo: 10});
535
+ const table = adapter._getTableOrCreate('model');
536
+ const tableData = table.get(idValue);
537
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, bar: 10});
538
+ });
539
+
540
+ it('uses a specified column name for a regular property with a default value', async function () {
541
+ const schema = new Schema();
542
+ schema.defineDatasource({
543
+ name: 'memory',
544
+ adapter: 'memory',
545
+ });
546
+ schema.defineModel({
547
+ name: 'model',
548
+ datasource: 'memory',
549
+ properties: {
550
+ foo: {
551
+ type: DataType.NUMBER,
552
+ columnName: 'bar',
553
+ default: 10,
554
+ },
555
+ },
556
+ });
557
+ const adapter = new MemoryAdapter(schema.container, {});
558
+ const created = await adapter.create('model', {});
559
+ const idValue = created[DEF_PK];
560
+ expect(created).to.be.eql({[DEF_PK]: idValue, foo: 10});
561
+ const table = adapter._getTableOrCreate('model');
562
+ const tableData = table.get(idValue);
563
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, bar: 10});
564
+ });
565
+
566
+ it('uses a short form of a fields clause to filter a return value', async function () {
567
+ const schema = new Schema();
568
+ schema.defineDatasource({
569
+ name: 'memory',
570
+ adapter: 'memory',
571
+ });
572
+ schema.defineModel({
573
+ name: 'model',
574
+ datasource: 'memory',
575
+ properties: {
576
+ foo: DataType.STRING,
577
+ bar: DataType.NUMBER,
578
+ },
579
+ });
580
+ const adapter = new MemoryAdapter(schema.container, {});
581
+ const input = {foo: 'string', bar: 10};
582
+ const filter = {fields: 'foo'};
583
+ const result = await adapter.create('model', input, filter);
584
+ expect(result).to.be.eql({[DEF_PK]: result[DEF_PK], foo: input.foo});
585
+ });
586
+
587
+ it('uses a full form of a fields clause to filter a return value', async function () {
588
+ const schema = new Schema();
589
+ schema.defineDatasource({
590
+ name: 'memory',
591
+ adapter: 'memory',
592
+ });
593
+ schema.defineModel({
594
+ name: 'model',
595
+ datasource: 'memory',
596
+ properties: {
597
+ foo: DataType.STRING,
598
+ bar: DataType.NUMBER,
599
+ baz: DataType.BOOLEAN,
600
+ },
601
+ });
602
+ const adapter = new MemoryAdapter(schema.container, {});
603
+ const input = {foo: 'string', bar: 10, baz: true};
604
+ const filter = {fields: ['foo', 'bar']};
605
+ const result = await adapter.create('model', input, filter);
606
+ expect(result).to.be.eql({
607
+ [DEF_PK]: result[DEF_PK],
608
+ foo: input.foo,
609
+ bar: input.bar,
610
+ });
611
+ });
612
+
613
+ it('a fields clause uses property names instead of column names', async function () {
614
+ const schema = new Schema();
615
+ schema.defineDatasource({
616
+ name: 'memory',
617
+ adapter: 'memory',
618
+ });
619
+ schema.defineModel({
620
+ name: 'model',
621
+ datasource: 'memory',
622
+ properties: {
623
+ foo: {
624
+ type: DataType.STRING,
625
+ columnName: 'fooCol',
626
+ },
627
+ bar: {
628
+ type: DataType.NUMBER,
629
+ columnName: 'barCol',
630
+ },
631
+ baz: {
632
+ type: DataType.BOOLEAN,
633
+ columnName: 'bazCol',
634
+ },
635
+ },
636
+ });
637
+ const adapter = new MemoryAdapter(schema.container, {});
638
+ const input = {foo: 'string', bar: 10, baz: true};
639
+ const filter = {fields: ['foo', 'bar']};
640
+ const result = await adapter.create('model', input, filter);
641
+ expect(result).to.be.eql({
642
+ [DEF_PK]: result[DEF_PK],
643
+ foo: input.foo,
644
+ bar: input.bar,
645
+ });
646
+ });
647
+ });
648
+
649
+ describe('replaceById', function () {
650
+ it('removes properties when replacing an item by a given identifier', async function () {
651
+ const schema = new Schema();
652
+ schema.defineDatasource({
653
+ name: 'memory',
654
+ adapter: 'memory',
655
+ });
656
+ schema.defineModel({
657
+ name: 'model',
658
+ datasource: 'memory',
659
+ properties: {
660
+ foo: DataType.NUMBER,
661
+ bar: DataType.NUMBER,
662
+ },
663
+ });
664
+ const adapter = new MemoryAdapter(schema.container, {});
665
+ const input = {foo: 1, bar: 2};
666
+ const created = await adapter.create('model', input);
667
+ const idValue = created[DEF_PK];
668
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...input});
669
+ const replaced = await adapter.replaceById('model', idValue, {foo: 2});
670
+ expect(replaced).to.be.eql({[DEF_PK]: idValue, foo: 2});
671
+ const table = adapter._getTableOrCreate('model');
672
+ const tableData = table.get(idValue);
673
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, foo: 2});
674
+ });
675
+
676
+ it('ignores identifier value in a given data in case of a default primary key', async function () {
677
+ const schema = new Schema();
678
+ schema.defineDatasource({
679
+ name: 'memory',
680
+ adapter: 'memory',
681
+ });
682
+ schema.defineModel({
683
+ name: 'model',
684
+ datasource: 'memory',
685
+ });
686
+ const adapter = new MemoryAdapter(schema.container, {});
687
+ const createdModelData = await adapter.create('model', {[DEF_PK]: 10});
688
+ expect(createdModelData).to.be.eql({[DEF_PK]: 10});
689
+ const table = adapter._getTableOrCreate('model');
690
+ const createdTableData = table.get(10);
691
+ expect(createdTableData).to.be.eql({[DEF_PK]: 10});
692
+ const replacedModelData = await adapter.replaceById('model', 10, {
693
+ [DEF_PK]: 20,
694
+ });
695
+ expect(replacedModelData).to.be.eql({[DEF_PK]: 10});
696
+ const replacedTableData = table.get(10);
697
+ expect(replacedTableData).to.be.eql({[DEF_PK]: 10});
698
+ });
699
+
700
+ it('ignores identifier value in a given data in case of a specified primary key', async function () {
701
+ const schema = new Schema();
702
+ schema.defineDatasource({
703
+ name: 'memory',
704
+ adapter: 'memory',
705
+ });
706
+ schema.defineModel({
707
+ name: 'model',
708
+ datasource: 'memory',
709
+ properties: {
710
+ myId: {
711
+ type: DataType.NUMBER,
712
+ primaryKey: true,
713
+ },
714
+ },
715
+ });
716
+ const adapter = new MemoryAdapter(schema.container, {});
717
+ const createdModelData = await adapter.create('model', {myId: 10});
718
+ expect(createdModelData).to.be.eql({myId: 10});
719
+ const table = adapter._getTableOrCreate('model');
720
+ const createdTableData = table.get(10);
721
+ expect(createdTableData).to.be.eql({myId: 10});
722
+ const replacedModelData = await adapter.replaceById('model', 10, {
723
+ myId: 20,
724
+ });
725
+ expect(replacedModelData).to.be.eql({myId: 10});
726
+ const replacedTableData = table.get(10);
727
+ expect(replacedTableData).to.be.eql({myId: 10});
728
+ });
729
+
730
+ it('sets a default values for removed properties when replacing an item', async function () {
731
+ const schema = new Schema();
732
+ schema.defineDatasource({
733
+ name: 'memory',
734
+ adapter: 'memory',
735
+ });
736
+ schema.defineModel({
737
+ name: 'model',
738
+ datasource: 'memory',
739
+ properties: {
740
+ foo: {
741
+ type: DataType.NUMBER,
742
+ default: 1,
743
+ },
744
+ bar: {
745
+ type: DataType.NUMBER,
746
+ default: 2,
747
+ },
748
+ },
749
+ });
750
+ const adapter = new MemoryAdapter(schema.container, {});
751
+ const created = await adapter.create('model', {});
752
+ const idValue = created[DEF_PK];
753
+ const defaults = {foo: 1, bar: 2};
754
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
755
+ const replacing = {foo: 2};
756
+ const replaced = await adapter.replaceById('model', idValue, replacing);
757
+ expect(replaced).to.be.eql({
758
+ [DEF_PK]: idValue,
759
+ ...defaults,
760
+ ...replacing,
761
+ });
762
+ const table = adapter._getTableOrCreate('model');
763
+ const tableData = table.get(idValue);
764
+ expect(tableData).to.be.eql({
765
+ [DEF_PK]: idValue,
766
+ ...defaults,
767
+ ...replacing,
768
+ });
769
+ });
770
+
771
+ it('sets a default values for replaced properties with an undefined value', async function () {
772
+ const schema = new Schema();
773
+ schema.defineDatasource({
774
+ name: 'memory',
775
+ adapter: 'memory',
776
+ });
777
+ schema.defineModel({
778
+ name: 'model',
779
+ datasource: 'memory',
780
+ properties: {
781
+ foo: {
782
+ type: DataType.NUMBER,
783
+ default: 1,
784
+ },
785
+ bar: {
786
+ type: DataType.NUMBER,
787
+ default: 2,
788
+ },
789
+ },
790
+ });
791
+ const adapter = new MemoryAdapter(schema.container, {});
792
+ const created = await adapter.create('model', {});
793
+ const idValue = created[DEF_PK];
794
+ const defaults = {foo: 1, bar: 2};
795
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
796
+ const replaced = await adapter.replaceById('model', idValue, {
797
+ foo: undefined,
798
+ });
799
+ expect(replaced).to.be.eql({[DEF_PK]: idValue, ...defaults});
800
+ const table = adapter._getTableOrCreate('model');
801
+ const tableData = table.get(idValue);
802
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
803
+ });
804
+
805
+ it('sets a default values for replaced properties with a null value', async function () {
806
+ const schema = new Schema();
807
+ schema.defineDatasource({
808
+ name: 'memory',
809
+ adapter: 'memory',
810
+ });
811
+ schema.defineModel({
812
+ name: 'model',
813
+ datasource: 'memory',
814
+ properties: {
815
+ foo: {
816
+ type: DataType.NUMBER,
817
+ default: 1,
818
+ },
819
+ bar: {
820
+ type: DataType.NUMBER,
821
+ default: 2,
822
+ },
823
+ },
824
+ });
825
+ const adapter = new MemoryAdapter(schema.container, {});
826
+ const created = await adapter.create('model', {});
827
+ const idValue = created[DEF_PK];
828
+ const defaults = {foo: 1, bar: 2};
829
+ expect(created).to.be.eql({[DEF_PK]: idValue, ...defaults});
830
+ const replaced = await adapter.replaceById('model', idValue, {
831
+ foo: null,
832
+ });
833
+ expect(replaced).to.be.eql({[DEF_PK]: idValue, ...defaults});
834
+ const table = adapter._getTableOrCreate('model');
835
+ const tableData = table.get(idValue);
836
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
837
+ });
838
+
839
+ it('throws an error if a given identifier does not exist', async function () {
840
+ const schema = new Schema();
841
+ schema.defineDatasource({
842
+ name: 'memory',
843
+ adapter: 'memory',
844
+ });
845
+ schema.defineModel({
846
+ name: 'model',
847
+ datasource: 'memory',
848
+ properties: {
849
+ foo: DataType.NUMBER,
850
+ bar: DataType.NUMBER,
851
+ },
852
+ });
853
+ const adapter = new MemoryAdapter(schema.container, {});
854
+ const promise = adapter.replaceById('model', 1, {foo: 2});
855
+ await expect(promise).to.be.rejectedWith(
856
+ format(
857
+ 'The value 1 of the primary key %v does not exist in the model "model".',
858
+ DEF_PK,
859
+ ),
860
+ );
861
+ });
862
+
863
+ it('uses a specified column name for a primary key', async function () {
864
+ const schema = new Schema();
865
+ schema.defineDatasource({
866
+ name: 'memory',
867
+ adapter: 'memory',
868
+ });
869
+ schema.defineModel({
870
+ name: 'model',
871
+ datasource: 'memory',
872
+ properties: {
873
+ foo: {
874
+ type: DataType.NUMBER,
875
+ primaryKey: true,
876
+ columnName: 'qux',
877
+ },
878
+ bar: DataType.NUMBER,
879
+ baz: DataType.NUMBER,
880
+ },
881
+ });
882
+ const adapter = new MemoryAdapter(schema.container, {});
883
+ const input = {bar: 1, baz: 2};
884
+ const createdModelData = await adapter.create('model', input);
885
+ expect(createdModelData).to.be.eql({
886
+ foo: createdModelData.foo,
887
+ ...input,
888
+ });
889
+ const table = adapter._getTableOrCreate('model');
890
+ const createdTableData = table.get(createdModelData.foo);
891
+ expect(createdTableData).to.be.eql({
892
+ qux: createdModelData.foo,
893
+ ...input,
894
+ });
895
+ const replacing = {bar: 2};
896
+ const replacedModelData = await adapter.replaceById(
897
+ 'model',
898
+ createdModelData.foo,
899
+ replacing,
900
+ );
901
+ expect(replacedModelData).to.be.eql({
902
+ foo: createdModelData.foo,
903
+ ...replacing,
904
+ });
905
+ const replacedTableData = table.get(createdModelData.foo);
906
+ expect(replacedTableData).to.be.eql({
907
+ qux: createdModelData.foo,
908
+ ...replacing,
909
+ });
910
+ });
911
+
912
+ it('uses a specified column name for a regular property', async function () {
913
+ const schema = new Schema();
914
+ schema.defineDatasource({
915
+ name: 'memory',
916
+ adapter: 'memory',
917
+ });
918
+ schema.defineModel({
919
+ name: 'model',
920
+ datasource: 'memory',
921
+ properties: {
922
+ foo: {
923
+ type: DataType.NUMBER,
924
+ columnName: 'baz',
925
+ },
926
+ bar: DataType.NUMBER,
927
+ },
928
+ });
929
+ const adapter = new MemoryAdapter(schema.container, {});
930
+ const input = {foo: 1, bar: 2};
931
+ const createdModelData = await adapter.create('model', input);
932
+ const idValue = createdModelData[DEF_PK];
933
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
934
+ const table = adapter._getTableOrCreate('model');
935
+ const createdTableData = table.get(idValue);
936
+ expect(createdTableData).to.be.eql({
937
+ [DEF_PK]: idValue,
938
+ baz: input.foo,
939
+ bar: input.bar,
940
+ });
941
+ const replacing = {foo: 2};
942
+ const replacedModelData = await adapter.replaceById(
943
+ 'model',
944
+ idValue,
945
+ replacing,
946
+ );
947
+ expect(replacedModelData).to.be.eql({[DEF_PK]: idValue, ...replacing});
948
+ const replacedTableData = table.get(idValue);
949
+ expect(replacedTableData).to.be.eql({
950
+ [DEF_PK]: idValue,
951
+ baz: replacing.foo,
952
+ });
953
+ });
954
+
955
+ it('uses a specified column name for a regular property with a default value', async function () {
956
+ const schema = new Schema();
957
+ schema.defineDatasource({
958
+ name: 'memory',
959
+ adapter: 'memory',
960
+ });
961
+ schema.defineModel({
962
+ name: 'model',
963
+ datasource: 'memory',
964
+ properties: {
965
+ foo: {
966
+ type: DataType.NUMBER,
967
+ columnName: 'baz',
968
+ default: 1,
969
+ },
970
+ bar: {
971
+ type: DataType.NUMBER,
972
+ default: 2,
973
+ },
974
+ },
975
+ });
976
+ const adapter = new MemoryAdapter(schema.container, {});
977
+ const createdModelData = await adapter.create('model', {});
978
+ const idValue = createdModelData[DEF_PK];
979
+ const defaults = {foo: 1, bar: 2};
980
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
981
+ const table = adapter._getTableOrCreate('model');
982
+ const createdTableData = table.get(idValue);
983
+ expect(createdTableData).to.be.eql({
984
+ [DEF_PK]: idValue,
985
+ baz: defaults.foo,
986
+ bar: defaults.bar,
987
+ });
988
+ const replacing = {foo: 2};
989
+ const replacedModelData = await adapter.replaceById(
990
+ 'model',
991
+ idValue,
992
+ replacing,
993
+ );
994
+ expect(replacedModelData).to.be.eql({
995
+ [DEF_PK]: idValue,
996
+ foo: replacing.foo,
997
+ bar: defaults.bar,
998
+ });
999
+ const replacedTableData = table.get(idValue);
1000
+ expect(replacedTableData).to.be.eql({
1001
+ [DEF_PK]: idValue,
1002
+ baz: replacing.foo,
1003
+ bar: defaults.bar,
1004
+ });
1005
+ });
1006
+
1007
+ it('allows to specify a short form of a fields clause to filter a return value', async function () {
1008
+ const schema = new Schema();
1009
+ schema.defineDatasource({
1010
+ name: 'memory',
1011
+ adapter: 'memory',
1012
+ });
1013
+ schema.defineModel({
1014
+ name: 'model',
1015
+ datasource: 'memory',
1016
+ properties: {
1017
+ foo: DataType.STRING,
1018
+ bar: DataType.NUMBER,
1019
+ },
1020
+ });
1021
+ const adapter = new MemoryAdapter(schema.container, {});
1022
+ const input = {foo: 'string', bar: 10};
1023
+ const createdModelData = await adapter.create('model', input);
1024
+ const idValue = createdModelData[DEF_PK];
1025
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1026
+ const table = adapter._getTableOrCreate('model');
1027
+ const createdTableData = table.get(idValue);
1028
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1029
+ const replacedModelData = await adapter.replaceById(
1030
+ 'model',
1031
+ idValue,
1032
+ input,
1033
+ {fields: 'foo'},
1034
+ );
1035
+ expect(replacedModelData).to.be.eql({[DEF_PK]: idValue, foo: input.foo});
1036
+ const replacedTableData = table.get(idValue);
1037
+ expect(replacedTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1038
+ });
1039
+
1040
+ it('allows to specify a full form of a fields clause to filter a return value', async function () {
1041
+ const schema = new Schema();
1042
+ schema.defineDatasource({
1043
+ name: 'memory',
1044
+ adapter: 'memory',
1045
+ });
1046
+ schema.defineModel({
1047
+ name: 'model',
1048
+ datasource: 'memory',
1049
+ properties: {
1050
+ foo: DataType.STRING,
1051
+ bar: DataType.NUMBER,
1052
+ baz: DataType.BOOLEAN,
1053
+ },
1054
+ });
1055
+ const adapter = new MemoryAdapter(schema.container, {});
1056
+ const input = {foo: 'string', bar: 10, baz: true};
1057
+ const createdModelData = await adapter.create('model', input);
1058
+ const idValue = createdModelData[DEF_PK];
1059
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1060
+ const table = adapter._getTableOrCreate('model');
1061
+ const createdTableData = table.get(idValue);
1062
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1063
+ const replacedModelData = await adapter.replaceById(
1064
+ 'model',
1065
+ idValue,
1066
+ input,
1067
+ {fields: ['foo', 'bar']},
1068
+ );
1069
+ expect(replacedModelData).to.be.eql({
1070
+ [DEF_PK]: idValue,
1071
+ foo: input.foo,
1072
+ bar: input.bar,
1073
+ });
1074
+ const replacedTableData = table.get(idValue);
1075
+ expect(replacedTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1076
+ });
1077
+
1078
+ it('a fields clause uses property names instead of column names', async function () {
1079
+ const schema = new Schema();
1080
+ schema.defineDatasource({
1081
+ name: 'memory',
1082
+ adapter: 'memory',
1083
+ });
1084
+ schema.defineModel({
1085
+ name: 'model',
1086
+ datasource: 'memory',
1087
+ properties: {
1088
+ foo: {
1089
+ type: DataType.STRING,
1090
+ columnName: 'fooCol',
1091
+ },
1092
+ bar: {
1093
+ type: DataType.NUMBER,
1094
+ columnName: 'barCol',
1095
+ },
1096
+ baz: {
1097
+ type: DataType.BOOLEAN,
1098
+ columnName: 'bazCol',
1099
+ },
1100
+ },
1101
+ });
1102
+ const adapter = new MemoryAdapter(schema.container, {});
1103
+ const input = {foo: 'string', bar: 10, baz: true};
1104
+ const createdModelData = await adapter.create('model', input);
1105
+ const idValue = createdModelData[DEF_PK];
1106
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1107
+ const table = adapter._getTableOrCreate('model');
1108
+ const createdTableData = table.get(idValue);
1109
+ expect(createdTableData).to.be.eql({
1110
+ [DEF_PK]: idValue,
1111
+ fooCol: input.foo,
1112
+ barCol: input.bar,
1113
+ bazCol: input.baz,
1114
+ });
1115
+ const replacedModelData = await adapter.replaceById(
1116
+ 'model',
1117
+ idValue,
1118
+ input,
1119
+ {fields: ['foo', 'bar']},
1120
+ );
1121
+ expect(replacedModelData).to.be.eql({
1122
+ [DEF_PK]: idValue,
1123
+ foo: input.foo,
1124
+ bar: input.bar,
1125
+ });
1126
+ const replacedTableData = table.get(idValue);
1127
+ expect(replacedTableData).to.be.eql({
1128
+ [DEF_PK]: idValue,
1129
+ fooCol: input.foo,
1130
+ barCol: input.bar,
1131
+ bazCol: input.baz,
1132
+ });
1133
+ });
1134
+ });
1135
+
1136
+ describe('patchById', function () {
1137
+ it('updates only provided properties by a given identifier', async function () {
1138
+ const schema = new Schema();
1139
+ schema.defineDatasource({
1140
+ name: 'memory',
1141
+ adapter: 'memory',
1142
+ });
1143
+ schema.defineModel({
1144
+ name: 'model',
1145
+ datasource: 'memory',
1146
+ properties: {
1147
+ foo: DataType.NUMBER,
1148
+ bar: DataType.NUMBER,
1149
+ },
1150
+ });
1151
+ const adapter = new MemoryAdapter(schema.container, {});
1152
+ const input = {foo: 1, bar: 2};
1153
+ const createdModelData = await adapter.create('model', input);
1154
+ const idValue = createdModelData[DEF_PK];
1155
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1156
+ const table = adapter._getTableOrCreate('model');
1157
+ const createdTableData = table.get(idValue);
1158
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1159
+ const patch = {foo: 20};
1160
+ const patchedModelData = await adapter.patchById('model', idValue, patch);
1161
+ expect(patchedModelData).to.be.eql({
1162
+ [DEF_PK]: idValue,
1163
+ foo: patch.foo,
1164
+ bar: input.bar,
1165
+ });
1166
+ const patchedTableData = table.get(idValue);
1167
+ expect(patchedTableData).to.be.eql({
1168
+ [DEF_PK]: idValue,
1169
+ foo: patch.foo,
1170
+ bar: input.bar,
1171
+ });
1172
+ });
1173
+
1174
+ it('does not throw an error if a partial data does not have required property', async function () {
1175
+ const schema = new Schema();
1176
+ schema.defineDatasource({
1177
+ name: 'memory',
1178
+ adapter: 'memory',
1179
+ });
1180
+ schema.defineModel({
1181
+ name: 'model',
1182
+ datasource: 'memory',
1183
+ properties: {
1184
+ foo: {
1185
+ type: DataType.NUMBER,
1186
+ required: true,
1187
+ },
1188
+ bar: DataType.NUMBER,
1189
+ },
1190
+ });
1191
+ const adapter = new MemoryAdapter(schema.container, {});
1192
+ const input = {foo: 1, bar: 2};
1193
+ const createdModelData = await adapter.create('model', input);
1194
+ const idValue = createdModelData[DEF_PK];
1195
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1196
+ const table = adapter._getTableOrCreate('model');
1197
+ const createdTableData = table.get(idValue);
1198
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1199
+ const patch = {bar: 20};
1200
+ const patchedModelData = await adapter.patchById('model', idValue, patch);
1201
+ expect(patchedModelData).to.be.eql({
1202
+ [DEF_PK]: idValue,
1203
+ foo: input.foo,
1204
+ bar: patch.bar,
1205
+ });
1206
+ const patchedTableData = table.get(idValue);
1207
+ expect(patchedTableData).to.be.eql({
1208
+ [DEF_PK]: idValue,
1209
+ foo: input.foo,
1210
+ bar: patch.bar,
1211
+ });
1212
+ });
1213
+
1214
+ it('ignores identifier value in a given data in case of a default primary key', async function () {
1215
+ const schema = new Schema();
1216
+ schema.defineDatasource({
1217
+ name: 'memory',
1218
+ adapter: 'memory',
1219
+ });
1220
+ schema.defineModel({
1221
+ name: 'model',
1222
+ datasource: 'memory',
1223
+ });
1224
+ const adapter = new MemoryAdapter(schema.container, {});
1225
+ const idValue = 10;
1226
+ const createdModelData = await adapter.create('model', {
1227
+ [DEF_PK]: idValue,
1228
+ });
1229
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue});
1230
+ const table = adapter._getTableOrCreate('model');
1231
+ const createdTableData = table.get(idValue);
1232
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue});
1233
+ const patchedModelData = await adapter.patchById('model', idValue, {
1234
+ [DEF_PK]: 20,
1235
+ });
1236
+ expect(patchedModelData).to.be.eql({[DEF_PK]: idValue});
1237
+ const patchedTableData = table.get(idValue);
1238
+ expect(patchedTableData).to.be.eql({[DEF_PK]: idValue});
1239
+ });
1240
+
1241
+ it('ignores identifier value in a given data in case of a specified primary key', async function () {
1242
+ const schema = new Schema();
1243
+ schema.defineDatasource({
1244
+ name: 'memory',
1245
+ adapter: 'memory',
1246
+ });
1247
+ schema.defineModel({
1248
+ name: 'model',
1249
+ datasource: 'memory',
1250
+ properties: {
1251
+ myId: {
1252
+ type: DataType.NUMBER,
1253
+ primaryKey: true,
1254
+ },
1255
+ },
1256
+ });
1257
+ const adapter = new MemoryAdapter(schema.container, {});
1258
+ const idValue = 10;
1259
+ const createdModelData = await adapter.create('model', {myId: idValue});
1260
+ expect(createdModelData).to.be.eql({myId: idValue});
1261
+ const table = adapter._getTableOrCreate('model');
1262
+ const createdTableData = table.get(idValue);
1263
+ expect(createdTableData).to.be.eql({myId: idValue});
1264
+ const patchedModelData = await adapter.patchById('model', idValue, {
1265
+ myId: 20,
1266
+ });
1267
+ expect(patchedModelData).to.be.eql({myId: idValue});
1268
+ const patchedTableData = table.get(idValue);
1269
+ expect(patchedTableData).to.be.eql({myId: idValue});
1270
+ });
1271
+
1272
+ it('sets a default values for patched properties with an undefined value', async function () {
1273
+ const schema = new Schema();
1274
+ schema.defineDatasource({
1275
+ name: 'memory',
1276
+ adapter: 'memory',
1277
+ });
1278
+ schema.defineModel({
1279
+ name: 'model',
1280
+ datasource: 'memory',
1281
+ properties: {
1282
+ foo: {
1283
+ type: DataType.NUMBER,
1284
+ default: 1,
1285
+ },
1286
+ bar: {
1287
+ type: DataType.NUMBER,
1288
+ default: 2,
1289
+ },
1290
+ },
1291
+ });
1292
+ const adapter = new MemoryAdapter(schema.container, {});
1293
+ const createdModelData = await adapter.create('model', {});
1294
+ const idValue = createdModelData[DEF_PK];
1295
+ const defaults = {foo: 1, bar: 2};
1296
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1297
+ const table = adapter._getTableOrCreate('model');
1298
+ const createdTableData = table.get(idValue);
1299
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1300
+ const patchedModelData = await adapter.patchById('model', idValue, {
1301
+ foo: undefined,
1302
+ });
1303
+ expect(patchedModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1304
+ const patchedTableData = table.get(idValue);
1305
+ expect(patchedTableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1306
+ });
1307
+
1308
+ it('sets a default values for patched properties with a null value', async function () {
1309
+ const schema = new Schema();
1310
+ schema.defineDatasource({
1311
+ name: 'memory',
1312
+ adapter: 'memory',
1313
+ });
1314
+ schema.defineModel({
1315
+ name: 'model',
1316
+ datasource: 'memory',
1317
+ properties: {
1318
+ foo: {
1319
+ type: DataType.NUMBER,
1320
+ default: 1,
1321
+ },
1322
+ bar: {
1323
+ type: DataType.NUMBER,
1324
+ default: 2,
1325
+ },
1326
+ },
1327
+ });
1328
+ const adapter = new MemoryAdapter(schema.container, {});
1329
+ const createdModelData = await adapter.create('model', {});
1330
+ const idValue = createdModelData[DEF_PK];
1331
+ const defaults = {foo: 1, bar: 2};
1332
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1333
+ const table = adapter._getTableOrCreate('model');
1334
+ const createdTableData = table.get(idValue);
1335
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1336
+ const patchedModelData = await adapter.patchById('model', idValue, {
1337
+ foo: null,
1338
+ });
1339
+ expect(patchedModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1340
+ const patchedTableData = table.get(idValue);
1341
+ expect(patchedTableData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1342
+ });
1343
+
1344
+ it('throws an error if a given identifier does not exist', async function () {
1345
+ const schema = new Schema();
1346
+ schema.defineDatasource({
1347
+ name: 'memory',
1348
+ adapter: 'memory',
1349
+ });
1350
+ schema.defineModel({
1351
+ name: 'model',
1352
+ datasource: 'memory',
1353
+ properties: {
1354
+ foo: DataType.NUMBER,
1355
+ bar: DataType.NUMBER,
1356
+ },
1357
+ });
1358
+ const adapter = new MemoryAdapter(schema.container, {});
1359
+ const promise = adapter.patchById('model', 1, {foo: 2});
1360
+ await expect(promise).to.be.rejectedWith(
1361
+ format(
1362
+ 'The value 1 of the primary key %v does not exist in the model "model".',
1363
+ DEF_PK,
1364
+ ),
1365
+ );
1366
+ });
1367
+
1368
+ it('uses a specified column name for a primary key', async function () {
1369
+ const schema = new Schema();
1370
+ schema.defineDatasource({
1371
+ name: 'memory',
1372
+ adapter: 'memory',
1373
+ });
1374
+ schema.defineModel({
1375
+ name: 'model',
1376
+ datasource: 'memory',
1377
+ properties: {
1378
+ foo: {
1379
+ type: DataType.NUMBER,
1380
+ primaryKey: true,
1381
+ columnName: 'qux',
1382
+ },
1383
+ bar: DataType.NUMBER,
1384
+ baz: DataType.NUMBER,
1385
+ },
1386
+ });
1387
+ const adapter = new MemoryAdapter(schema.container, {});
1388
+ const input = {bar: 1, baz: 2};
1389
+ const createdModelData = await adapter.create('model', input);
1390
+ expect(createdModelData).to.be.eql({foo: createdModelData.foo, ...input});
1391
+ const table = adapter._getTableOrCreate('model');
1392
+ const createdTableData = table.get(createdModelData.foo);
1393
+ expect(createdTableData).to.be.eql({qux: createdModelData.foo, ...input});
1394
+ const patching = {bar: 2};
1395
+ const patchedModelData = await adapter.patchById(
1396
+ 'model',
1397
+ createdModelData.foo,
1398
+ patching,
1399
+ );
1400
+ expect(patchedModelData).to.be.eql({
1401
+ foo: createdModelData.foo,
1402
+ bar: patching.bar,
1403
+ baz: input.baz,
1404
+ });
1405
+ const patchedTableData = table.get(createdModelData.foo);
1406
+ expect(patchedTableData).to.be.eql({
1407
+ qux: createdModelData.foo,
1408
+ bar: patching.bar,
1409
+ baz: input.baz,
1410
+ });
1411
+ });
1412
+
1413
+ it('uses a specified column name for a regular property', async function () {
1414
+ const schema = new Schema();
1415
+ schema.defineDatasource({
1416
+ name: 'memory',
1417
+ adapter: 'memory',
1418
+ });
1419
+ schema.defineModel({
1420
+ name: 'model',
1421
+ datasource: 'memory',
1422
+ properties: {
1423
+ foo: {
1424
+ type: DataType.NUMBER,
1425
+ columnName: 'baz',
1426
+ },
1427
+ bar: DataType.NUMBER,
1428
+ },
1429
+ });
1430
+ const adapter = new MemoryAdapter(schema.container, {});
1431
+ const input = {foo: 1, bar: 2};
1432
+ const createdModelData = await adapter.create('model', input);
1433
+ const idValue = createdModelData[DEF_PK];
1434
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1435
+ const table = adapter._getTableOrCreate('model');
1436
+ const createdTableData = table.get(idValue);
1437
+ expect(createdTableData).to.be.eql({
1438
+ [DEF_PK]: idValue,
1439
+ baz: input.foo,
1440
+ bar: input.bar,
1441
+ });
1442
+ const patching = {foo: 2};
1443
+ const patchedModelData = await adapter.patchById(
1444
+ 'model',
1445
+ idValue,
1446
+ patching,
1447
+ );
1448
+ expect(patchedModelData).to.be.eql({
1449
+ [DEF_PK]: idValue,
1450
+ foo: patching.foo,
1451
+ bar: input.bar,
1452
+ });
1453
+ const patchedTableData = table.get(idValue);
1454
+ expect(patchedTableData).to.be.eql({
1455
+ [DEF_PK]: idValue,
1456
+ baz: patching.foo,
1457
+ bar: input.bar,
1458
+ });
1459
+ });
1460
+
1461
+ it('uses a specified column name for a regular property with a default value', async function () {
1462
+ const schema = new Schema();
1463
+ schema.defineDatasource({
1464
+ name: 'memory',
1465
+ adapter: 'memory',
1466
+ });
1467
+ schema.defineModel({
1468
+ name: 'model',
1469
+ datasource: 'memory',
1470
+ properties: {
1471
+ foo: {
1472
+ type: DataType.NUMBER,
1473
+ columnName: 'baz',
1474
+ default: 1,
1475
+ },
1476
+ bar: {
1477
+ type: DataType.NUMBER,
1478
+ default: 2,
1479
+ },
1480
+ },
1481
+ });
1482
+ const adapter = new MemoryAdapter(schema.container, {});
1483
+ const createdModelData = await adapter.create('model', {});
1484
+ const idValue = createdModelData[DEF_PK];
1485
+ const defaults = {foo: 1, bar: 2};
1486
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...defaults});
1487
+ const table = adapter._getTableOrCreate('model');
1488
+ const createdTableData = table.get(idValue);
1489
+ expect(createdTableData).to.be.eql({
1490
+ [DEF_PK]: idValue,
1491
+ baz: defaults.foo,
1492
+ bar: defaults.bar,
1493
+ });
1494
+ const patching = {foo: 2};
1495
+ const patchedModelData = await adapter.patchById(
1496
+ 'model',
1497
+ idValue,
1498
+ patching,
1499
+ );
1500
+ expect(patchedModelData).to.be.eql({
1501
+ [DEF_PK]: idValue,
1502
+ foo: patching.foo,
1503
+ bar: defaults.bar,
1504
+ });
1505
+ const patchedTableData = table.get(idValue);
1506
+ expect(patchedTableData).to.be.eql({
1507
+ [DEF_PK]: idValue,
1508
+ baz: patching.foo,
1509
+ bar: defaults.bar,
1510
+ });
1511
+ });
1512
+
1513
+ it('allows to specify a short form of a fields clause to filter a return value', async function () {
1514
+ const schema = new Schema();
1515
+ schema.defineDatasource({
1516
+ name: 'memory',
1517
+ adapter: 'memory',
1518
+ });
1519
+ schema.defineModel({
1520
+ name: 'model',
1521
+ datasource: 'memory',
1522
+ properties: {
1523
+ foo: DataType.STRING,
1524
+ bar: DataType.NUMBER,
1525
+ },
1526
+ });
1527
+ const adapter = new MemoryAdapter(schema.container, {});
1528
+ const input = {foo: 'string', bar: 10};
1529
+ const createdModelData = await adapter.create('model', input);
1530
+ const idValue = createdModelData[DEF_PK];
1531
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1532
+ const table = adapter._getTableOrCreate('model');
1533
+ const createdTableData = table.get(idValue);
1534
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1535
+ const patchedModelData = await adapter.patchById(
1536
+ 'model',
1537
+ idValue,
1538
+ input,
1539
+ {fields: 'foo'},
1540
+ );
1541
+ expect(patchedModelData).to.be.eql({
1542
+ [DEF_PK]: idValue,
1543
+ foo: input.foo,
1544
+ });
1545
+ const patchedTableData = table.get(idValue);
1546
+ expect(patchedTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1547
+ });
1548
+
1549
+ it('allows to specify a full form of a fields clause to filter a return value', async function () {
1550
+ const schema = new Schema();
1551
+ schema.defineDatasource({
1552
+ name: 'memory',
1553
+ adapter: 'memory',
1554
+ });
1555
+ schema.defineModel({
1556
+ name: 'model',
1557
+ datasource: 'memory',
1558
+ properties: {
1559
+ foo: DataType.STRING,
1560
+ bar: DataType.NUMBER,
1561
+ baz: DataType.BOOLEAN,
1562
+ },
1563
+ });
1564
+ const adapter = new MemoryAdapter(schema.container, {});
1565
+ const input = {foo: 'string', bar: 10, baz: true};
1566
+ const createdModelData = await adapter.create('model', input);
1567
+ const idValue = createdModelData[DEF_PK];
1568
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1569
+ const table = adapter._getTableOrCreate('model');
1570
+ const createdTableData = table.get(idValue);
1571
+ expect(createdTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1572
+ const patchedModelData = await adapter.patchById(
1573
+ 'model',
1574
+ idValue,
1575
+ input,
1576
+ {fields: ['foo', 'bar']},
1577
+ );
1578
+ expect(patchedModelData).to.be.eql({
1579
+ [DEF_PK]: idValue,
1580
+ foo: input.foo,
1581
+ bar: input.bar,
1582
+ });
1583
+ const patchedTableData = table.get(idValue);
1584
+ expect(patchedTableData).to.be.eql({[DEF_PK]: idValue, ...input});
1585
+ });
1586
+
1587
+ it('a fields clause uses property names instead of column names', async function () {
1588
+ const schema = new Schema();
1589
+ schema.defineDatasource({
1590
+ name: 'memory',
1591
+ adapter: 'memory',
1592
+ });
1593
+ schema.defineModel({
1594
+ name: 'model',
1595
+ datasource: 'memory',
1596
+ properties: {
1597
+ foo: {
1598
+ type: DataType.STRING,
1599
+ columnName: 'fooCol',
1600
+ },
1601
+ bar: {
1602
+ type: DataType.NUMBER,
1603
+ columnName: 'barCol',
1604
+ },
1605
+ baz: {
1606
+ type: DataType.BOOLEAN,
1607
+ columnName: 'bazCol',
1608
+ },
1609
+ },
1610
+ });
1611
+ const adapter = new MemoryAdapter(schema.container, {});
1612
+ const input = {foo: 'string', bar: 10, baz: true};
1613
+ const createdModelData = await adapter.create('model', input);
1614
+ const idValue = createdModelData[DEF_PK];
1615
+ expect(createdModelData).to.be.eql({[DEF_PK]: idValue, ...input});
1616
+ const table = adapter._getTableOrCreate('model');
1617
+ const createdTableData = table.get(idValue);
1618
+ expect(createdTableData).to.be.eql({
1619
+ [DEF_PK]: idValue,
1620
+ fooCol: input.foo,
1621
+ barCol: input.bar,
1622
+ bazCol: input.baz,
1623
+ });
1624
+ const patchedModelData = await adapter.patchById(
1625
+ 'model',
1626
+ idValue,
1627
+ input,
1628
+ {fields: ['foo', 'bar']},
1629
+ );
1630
+ expect(patchedModelData).to.be.eql({
1631
+ [DEF_PK]: idValue,
1632
+ foo: input.foo,
1633
+ bar: input.bar,
1634
+ });
1635
+ const patchedTableData = table.get(idValue);
1636
+ expect(patchedTableData).to.be.eql({
1637
+ [DEF_PK]: idValue,
1638
+ fooCol: input.foo,
1639
+ barCol: input.bar,
1640
+ bazCol: input.baz,
1641
+ });
1642
+ });
1643
+ });
1644
+
1645
+ describe('find', function () {
1646
+ it('returns an empty array if a table does not have an items', async function () {
1647
+ const schema = new Schema();
1648
+ schema.defineDatasource({
1649
+ name: 'memory',
1650
+ adapter: 'memory',
1651
+ });
1652
+ schema.defineModel({
1653
+ name: 'model',
1654
+ datasource: 'memory',
1655
+ });
1656
+ const adapter = new MemoryAdapter(schema.container, {});
1657
+ const result = await adapter.find('model');
1658
+ expect(result).to.be.instanceof(Array);
1659
+ expect(result).to.be.empty;
1660
+ });
1661
+
1662
+ it('returns an array of table items', async function () {
1663
+ const schema = new Schema();
1664
+ schema.defineDatasource({
1665
+ name: 'memory',
1666
+ adapter: 'memory',
1667
+ });
1668
+ schema.defineModel({
1669
+ name: 'model',
1670
+ datasource: 'memory',
1671
+ });
1672
+ const adapter = new MemoryAdapter(schema.container, {});
1673
+ await adapter.create('model', {});
1674
+ await adapter.create('model', {});
1675
+ await adapter.create('model', {});
1676
+ const result = await adapter.find('model');
1677
+ expect(result).to.be.instanceof(Array);
1678
+ expect(result).to.have.lengthOf(3);
1679
+ expect(result[0]).to.be.eql({[DEF_PK]: 1});
1680
+ expect(result[1]).to.be.eql({[DEF_PK]: 2});
1681
+ expect(result[2]).to.be.eql({[DEF_PK]: 3});
1682
+ });
1683
+
1684
+ it('uses default values for non-existent properties', async function () {
1685
+ const schema = new Schema();
1686
+ schema.defineDatasource({
1687
+ name: 'memory',
1688
+ adapter: 'memory',
1689
+ });
1690
+ schema.defineModel({
1691
+ name: 'model',
1692
+ datasource: 'memory',
1693
+ properties: {
1694
+ foo: {
1695
+ type: DataType.STRING,
1696
+ default: 'string',
1697
+ },
1698
+ },
1699
+ });
1700
+ const adapter = new MemoryAdapter(schema.container, {});
1701
+ const table = adapter._getTableOrCreate('model');
1702
+ table.set(1, {[DEF_PK]: 1});
1703
+ table.set(2, {[DEF_PK]: 2});
1704
+ table.set(3, {[DEF_PK]: 3});
1705
+ const result = await adapter.find('model');
1706
+ expect(result).to.be.instanceof(Array);
1707
+ expect(result).to.have.lengthOf(3);
1708
+ expect(result[0]).to.be.eql({[DEF_PK]: 1, foo: 'string'});
1709
+ expect(result[1]).to.be.eql({[DEF_PK]: 2, foo: 'string'});
1710
+ expect(result[2]).to.be.eql({[DEF_PK]: 3, foo: 'string'});
1711
+ const tableItems = Array.from(table.values());
1712
+ expect(tableItems).to.have.lengthOf(3);
1713
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1});
1714
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2});
1715
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3});
1716
+ });
1717
+
1718
+ it('uses default values for properties of an undefined', async function () {
1719
+ const schema = new Schema();
1720
+ schema.defineDatasource({
1721
+ name: 'memory',
1722
+ adapter: 'memory',
1723
+ });
1724
+ schema.defineModel({
1725
+ name: 'model',
1726
+ datasource: 'memory',
1727
+ properties: {
1728
+ foo: {
1729
+ type: DataType.STRING,
1730
+ default: 'string',
1731
+ },
1732
+ },
1733
+ });
1734
+ const adapter = new MemoryAdapter(schema.container, {});
1735
+ const table = adapter._getTableOrCreate('model');
1736
+ table.set(1, {[DEF_PK]: 1, foo: undefined});
1737
+ table.set(2, {[DEF_PK]: 2, foo: undefined});
1738
+ table.set(3, {[DEF_PK]: 3, foo: undefined});
1739
+ const result = await adapter.find('model');
1740
+ expect(result).to.be.instanceof(Array);
1741
+ expect(result).to.have.lengthOf(3);
1742
+ expect(result[0]).to.be.eql({[DEF_PK]: 1, foo: 'string'});
1743
+ expect(result[1]).to.be.eql({[DEF_PK]: 2, foo: 'string'});
1744
+ expect(result[2]).to.be.eql({[DEF_PK]: 3, foo: 'string'});
1745
+ const tableItems = Array.from(table.values());
1746
+ expect(tableItems).to.have.lengthOf(3);
1747
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1, foo: undefined});
1748
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2, foo: undefined});
1749
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3, foo: undefined});
1750
+ });
1751
+
1752
+ it('uses default values for properties of a null', async function () {
1753
+ const schema = new Schema();
1754
+ schema.defineDatasource({
1755
+ name: 'memory',
1756
+ adapter: 'memory',
1757
+ });
1758
+ schema.defineModel({
1759
+ name: 'model',
1760
+ datasource: 'memory',
1761
+ properties: {
1762
+ foo: {
1763
+ type: DataType.STRING,
1764
+ default: 'string',
1765
+ },
1766
+ },
1767
+ });
1768
+ const adapter = new MemoryAdapter(schema.container, {});
1769
+ const table = adapter._getTableOrCreate('model');
1770
+ table.set(1, {[DEF_PK]: 1, foo: null});
1771
+ table.set(2, {[DEF_PK]: 2, foo: null});
1772
+ table.set(3, {[DEF_PK]: 3, foo: null});
1773
+ const result = await adapter.find('model');
1774
+ expect(result).to.be.instanceof(Array);
1775
+ expect(result).to.have.lengthOf(3);
1776
+ expect(result[0]).to.be.eql({[DEF_PK]: 1, foo: 'string'});
1777
+ expect(result[1]).to.be.eql({[DEF_PK]: 2, foo: 'string'});
1778
+ expect(result[2]).to.be.eql({[DEF_PK]: 3, foo: 'string'});
1779
+ const tableItems = Array.from(table.values());
1780
+ expect(tableItems).to.have.lengthOf(3);
1781
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1, foo: null});
1782
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2, foo: null});
1783
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3, foo: null});
1784
+ });
1785
+
1786
+ it('allows to specify a short form of a fields clause to filter a return value', async function () {
1787
+ const schema = new Schema();
1788
+ schema.defineDatasource({
1789
+ name: 'memory',
1790
+ adapter: 'memory',
1791
+ });
1792
+ schema.defineModel({
1793
+ name: 'model',
1794
+ datasource: 'memory',
1795
+ properties: {
1796
+ foo: DataType.STRING,
1797
+ bar: DataType.NUMBER,
1798
+ },
1799
+ });
1800
+ const adapter = new MemoryAdapter(schema.container, {});
1801
+ const input = {foo: 'string1', bar: 10};
1802
+ await adapter.create('model', input);
1803
+ await adapter.create('model', input);
1804
+ await adapter.create('model', input);
1805
+ const result = await adapter.find('model', {fields: 'foo'});
1806
+ expect(result).to.be.instanceof(Array);
1807
+ expect(result).to.have.lengthOf(3);
1808
+ expect(result[0]).to.be.eql({[DEF_PK]: 1, foo: input.foo});
1809
+ expect(result[1]).to.be.eql({[DEF_PK]: 2, foo: input.foo});
1810
+ expect(result[2]).to.be.eql({[DEF_PK]: 3, foo: input.foo});
1811
+ const table = adapter._getTableOrCreate('model');
1812
+ const tableItems = Array.from(table.values());
1813
+ expect(tableItems).to.have.lengthOf(3);
1814
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1, ...input});
1815
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2, ...input});
1816
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3, ...input});
1817
+ });
1818
+
1819
+ it('allows to specify a full form of a fields clause to filter a return value', async function () {
1820
+ const schema = new Schema();
1821
+ schema.defineDatasource({
1822
+ name: 'memory',
1823
+ adapter: 'memory',
1824
+ });
1825
+ schema.defineModel({
1826
+ name: 'model',
1827
+ datasource: 'memory',
1828
+ properties: {
1829
+ foo: DataType.STRING,
1830
+ bar: DataType.NUMBER,
1831
+ baz: DataType.BOOLEAN,
1832
+ },
1833
+ });
1834
+ const adapter = new MemoryAdapter(schema.container, {});
1835
+ const input = {foo: 'string1', bar: 10, baz: true};
1836
+ await adapter.create('model', input);
1837
+ await adapter.create('model', input);
1838
+ await adapter.create('model', input);
1839
+ const result = await adapter.find('model', {fields: ['foo', 'bar']});
1840
+ expect(result).to.be.instanceof(Array);
1841
+ expect(result).to.have.lengthOf(3);
1842
+ expect(result[0]).to.be.eql({
1843
+ [DEF_PK]: 1,
1844
+ foo: input.foo,
1845
+ bar: input.bar,
1846
+ });
1847
+ expect(result[1]).to.be.eql({
1848
+ [DEF_PK]: 2,
1849
+ foo: input.foo,
1850
+ bar: input.bar,
1851
+ });
1852
+ expect(result[2]).to.be.eql({
1853
+ [DEF_PK]: 3,
1854
+ foo: input.foo,
1855
+ bar: input.bar,
1856
+ });
1857
+ const table = adapter._getTableOrCreate('model');
1858
+ const tableItems = Array.from(table.values());
1859
+ expect(tableItems).to.have.lengthOf(3);
1860
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1, ...input});
1861
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2, ...input});
1862
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3, ...input});
1863
+ });
1864
+
1865
+ it('a fields clause uses property names instead of column names', async function () {
1866
+ const schema = new Schema();
1867
+ schema.defineDatasource({
1868
+ name: 'memory',
1869
+ adapter: 'memory',
1870
+ });
1871
+ schema.defineModel({
1872
+ name: 'model',
1873
+ datasource: 'memory',
1874
+ properties: {
1875
+ foo: {
1876
+ type: DataType.STRING,
1877
+ columnName: 'fooCol',
1878
+ },
1879
+ bar: {
1880
+ type: DataType.NUMBER,
1881
+ columnName: 'barCol',
1882
+ },
1883
+ baz: {
1884
+ type: DataType.BOOLEAN,
1885
+ columnName: 'bazCol',
1886
+ },
1887
+ },
1888
+ });
1889
+ const adapter = new MemoryAdapter(schema.container, {});
1890
+ const input = {foo: 'string', bar: 10, baz: true};
1891
+ await adapter.create('model', input);
1892
+ await adapter.create('model', input);
1893
+ await adapter.create('model', input);
1894
+ const result = await adapter.find('model', {fields: ['foo', 'bar']});
1895
+ expect(result).to.be.instanceof(Array);
1896
+ expect(result).to.have.lengthOf(3);
1897
+ expect(result[0]).to.be.eql({
1898
+ [DEF_PK]: 1,
1899
+ foo: input.foo,
1900
+ bar: input.bar,
1901
+ });
1902
+ expect(result[1]).to.be.eql({
1903
+ [DEF_PK]: 2,
1904
+ foo: input.foo,
1905
+ bar: input.bar,
1906
+ });
1907
+ expect(result[2]).to.be.eql({
1908
+ [DEF_PK]: 3,
1909
+ foo: input.foo,
1910
+ bar: input.bar,
1911
+ });
1912
+ const table = adapter._getTableOrCreate('model');
1913
+ const tableItems = Array.from(table.values());
1914
+ const tableInput = {fooCol: 'string', barCol: 10, bazCol: true};
1915
+ expect(tableItems).to.have.lengthOf(3);
1916
+ expect(tableItems[0]).to.be.eql({[DEF_PK]: 1, ...tableInput});
1917
+ expect(tableItems[1]).to.be.eql({[DEF_PK]: 2, ...tableInput});
1918
+ expect(tableItems[2]).to.be.eql({[DEF_PK]: 3, ...tableInput});
1919
+ });
1920
+
1921
+ it('allows to specify a short form of an order clause to sort a return value', async function () {
1922
+ const schema = new Schema();
1923
+ schema.defineDatasource({
1924
+ name: 'memory',
1925
+ adapter: 'memory',
1926
+ });
1927
+ schema.defineModel({
1928
+ name: 'model',
1929
+ datasource: 'memory',
1930
+ properties: {
1931
+ foo: DataType.NUMBER,
1932
+ },
1933
+ });
1934
+ const adapter = new MemoryAdapter(schema.container, {});
1935
+ await adapter.create('model', {foo: 20});
1936
+ await adapter.create('model', {foo: 10});
1937
+ await adapter.create('model', {foo: 15});
1938
+ const result1 = await adapter.find('model', {order: 'foo'});
1939
+ const result2 = await adapter.find('model', {order: 'foo ASC'});
1940
+ const result3 = await adapter.find('model', {order: 'foo DESC'});
1941
+ expect(result1).to.have.lengthOf(3);
1942
+ expect(result1[0]).to.be.eql({[DEF_PK]: 2, foo: 10});
1943
+ expect(result1[1]).to.be.eql({[DEF_PK]: 3, foo: 15});
1944
+ expect(result1[2]).to.be.eql({[DEF_PK]: 1, foo: 20});
1945
+ expect(result2).to.have.lengthOf(3);
1946
+ expect(result2[0]).to.be.eql({[DEF_PK]: 2, foo: 10});
1947
+ expect(result2[1]).to.be.eql({[DEF_PK]: 3, foo: 15});
1948
+ expect(result2[2]).to.be.eql({[DEF_PK]: 1, foo: 20});
1949
+ expect(result3).to.have.lengthOf(3);
1950
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1, foo: 20});
1951
+ expect(result3[1]).to.be.eql({[DEF_PK]: 3, foo: 15});
1952
+ expect(result3[2]).to.be.eql({[DEF_PK]: 2, foo: 10});
1953
+ });
1954
+
1955
+ it('allows to specify a full form of an order clause to sort a return value', async function () {
1956
+ const schema = new Schema();
1957
+ schema.defineDatasource({
1958
+ name: 'memory',
1959
+ adapter: 'memory',
1960
+ });
1961
+ schema.defineModel({
1962
+ name: 'model',
1963
+ datasource: 'memory',
1964
+ properties: {
1965
+ foo: DataType.NUMBER,
1966
+ bar: DataType.NUMBER,
1967
+ },
1968
+ });
1969
+ const adapter = new MemoryAdapter(schema.container, {});
1970
+ await adapter.create('model', {foo: 2, bar: 20});
1971
+ await adapter.create('model', {foo: 2, bar: 10});
1972
+ await adapter.create('model', {foo: 1, bar: 15});
1973
+ const filter1 = {order: ['foo', 'bar']};
1974
+ const filter2 = {order: ['foo ASC', 'bar ASC']};
1975
+ const filter3 = {order: ['foo DESC', 'bar DESC']};
1976
+ const filter4 = {order: ['foo', 'bar DESC']};
1977
+ const result1 = await adapter.find('model', filter1);
1978
+ const result2 = await adapter.find('model', filter2);
1979
+ const result3 = await adapter.find('model', filter3);
1980
+ const result4 = await adapter.find('model', filter4);
1981
+ expect(result1).to.have.lengthOf(3);
1982
+ expect(result1[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
1983
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
1984
+ expect(result1[2]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
1985
+ expect(result2).to.have.lengthOf(3);
1986
+ expect(result2[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
1987
+ expect(result2[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
1988
+ expect(result2[2]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
1989
+ expect(result3).to.have.lengthOf(3);
1990
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
1991
+ expect(result3[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
1992
+ expect(result3[2]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
1993
+ expect(result4).to.have.lengthOf(3);
1994
+ expect(result4[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
1995
+ expect(result4[1]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
1996
+ expect(result4[2]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
1997
+ });
1998
+
1999
+ it('an order clause uses property names instead of column names', async function () {
2000
+ const schema = new Schema();
2001
+ schema.defineDatasource({
2002
+ name: 'memory',
2003
+ adapter: 'memory',
2004
+ });
2005
+ schema.defineModel({
2006
+ name: 'model',
2007
+ datasource: 'memory',
2008
+ properties: {
2009
+ foo: {
2010
+ type: DataType.NUMBER,
2011
+ columnName: 'fooCol',
2012
+ },
2013
+ bar: {
2014
+ type: DataType.NUMBER,
2015
+ columnName: 'barCol',
2016
+ },
2017
+ },
2018
+ });
2019
+ const adapter = new MemoryAdapter(schema.container, {});
2020
+ const table = adapter._getTableOrCreate('model');
2021
+ const tableInput1 = {fooCol: 2, barCol: 20};
2022
+ const tableInput2 = {fooCol: 2, barCol: 10};
2023
+ const tableInput3 = {fooCol: 1, barCol: 15};
2024
+ table.set(1, {[DEF_PK]: 1, ...tableInput1});
2025
+ table.set(2, {[DEF_PK]: 2, ...tableInput2});
2026
+ table.set(3, {[DEF_PK]: 3, ...tableInput3});
2027
+ const filter1 = {order: ['foo', 'bar']};
2028
+ const filter2 = {order: ['foo ASC', 'bar ASC']};
2029
+ const filter3 = {order: ['foo DESC', 'bar DESC']};
2030
+ const filter4 = {order: ['foo', 'bar DESC']};
2031
+ const result1 = await adapter.find('model', filter1);
2032
+ const result2 = await adapter.find('model', filter2);
2033
+ const result3 = await adapter.find('model', filter3);
2034
+ const result4 = await adapter.find('model', filter4);
2035
+ expect(result1).to.have.lengthOf(3);
2036
+ expect(result1[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
2037
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
2038
+ expect(result1[2]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
2039
+ expect(result2).to.have.lengthOf(3);
2040
+ expect(result2[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
2041
+ expect(result2[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
2042
+ expect(result2[2]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
2043
+ expect(result3).to.have.lengthOf(3);
2044
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
2045
+ expect(result3[1]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
2046
+ expect(result3[2]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
2047
+ expect(result4).to.have.lengthOf(3);
2048
+ expect(result4[0]).to.be.eql({[DEF_PK]: 3, foo: 1, bar: 15});
2049
+ expect(result4[1]).to.be.eql({[DEF_PK]: 1, foo: 2, bar: 20});
2050
+ expect(result4[2]).to.be.eql({[DEF_PK]: 2, foo: 2, bar: 10});
2051
+ });
2052
+
2053
+ it('allows to specify a where clause to filter a return value', async function () {
2054
+ const schema = new Schema();
2055
+ schema.defineDatasource({
2056
+ name: 'memory',
2057
+ adapter: 'memory',
2058
+ });
2059
+ schema.defineModel({
2060
+ name: 'model',
2061
+ datasource: 'memory',
2062
+ properties: {
2063
+ foo: DataType.NUMBER,
2064
+ bar: DataType.BOOLEAN,
2065
+ baz: DataType.STRING,
2066
+ },
2067
+ });
2068
+ const adapter = new MemoryAdapter(schema.container, {});
2069
+ const input1 = {foo: 20, bar: true, baz: 'abc'};
2070
+ const input2 = {foo: 10, bar: true, baz: 'abc'};
2071
+ const input3 = {foo: 15, bar: false, baz: 'abe'};
2072
+ await adapter.create('model', input1);
2073
+ await adapter.create('model', input2);
2074
+ await adapter.create('model', input3);
2075
+ const filter1 = {where: {foo: 10}};
2076
+ const filter2 = {where: {foo: {gte: 15}, baz: {like: 'bc'}}};
2077
+ const filter3 = {where: {bar: true}};
2078
+ const result1 = await adapter.find('model', filter1);
2079
+ const result2 = await adapter.find('model', filter2);
2080
+ const result3 = await adapter.find('model', filter3);
2081
+ expect(result1).to.have.lengthOf(1);
2082
+ expect(result1[0]).to.be.eql({[DEF_PK]: 2, ...input2});
2083
+ expect(result2).to.have.lengthOf(1);
2084
+ expect(result2[0]).to.be.eql({[DEF_PK]: 1, ...input1});
2085
+ expect(result3).to.have.lengthOf(2);
2086
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1, ...input1});
2087
+ expect(result3[1]).to.be.eql({[DEF_PK]: 2, ...input2});
2088
+ });
2089
+
2090
+ it('a where clause uses property names instead of column names', async function () {
2091
+ const schema = new Schema();
2092
+ schema.defineDatasource({
2093
+ name: 'memory',
2094
+ adapter: 'memory',
2095
+ });
2096
+ schema.defineModel({
2097
+ name: 'model',
2098
+ datasource: 'memory',
2099
+ properties: {
2100
+ foo: {
2101
+ type: DataType.STRING,
2102
+ columnName: 'fooCol',
2103
+ },
2104
+ bar: {
2105
+ type: DataType.NUMBER,
2106
+ columnName: 'barCol',
2107
+ },
2108
+ baz: {
2109
+ type: DataType.BOOLEAN,
2110
+ columnName: 'bazCol',
2111
+ },
2112
+ },
2113
+ });
2114
+ const adapter = new MemoryAdapter(schema.container, {});
2115
+ const table = adapter._getTableOrCreate('model');
2116
+ const tableInput1 = {fooCol: 20, barCol: true, bazCol: 'abc'};
2117
+ const tableInput2 = {fooCol: 10, barCol: true, bazCol: 'abc'};
2118
+ const tableInput3 = {fooCol: 15, barCol: false, bazCol: 'abe'};
2119
+ table.set(1, {[DEF_PK]: 1, ...tableInput1});
2120
+ table.set(2, {[DEF_PK]: 2, ...tableInput2});
2121
+ table.set(3, {[DEF_PK]: 3, ...tableInput3});
2122
+ const input1 = {
2123
+ foo: tableInput1.fooCol,
2124
+ bar: tableInput1.barCol,
2125
+ baz: tableInput1.bazCol,
2126
+ };
2127
+ const input2 = {
2128
+ foo: tableInput2.fooCol,
2129
+ bar: tableInput2.barCol,
2130
+ baz: tableInput2.bazCol,
2131
+ };
2132
+ const filter1 = {where: {foo: 10}};
2133
+ const filter2 = {where: {foo: {gte: 15}, baz: {like: 'bc'}}};
2134
+ const filter3 = {where: {bar: true}};
2135
+ const result1 = await adapter.find('model', filter1);
2136
+ const result2 = await adapter.find('model', filter2);
2137
+ const result3 = await adapter.find('model', filter3);
2138
+ expect(result1).to.have.lengthOf(1);
2139
+ expect(result1[0]).to.be.eql({[DEF_PK]: 2, ...input2});
2140
+ expect(result2).to.have.lengthOf(1);
2141
+ expect(result2[0]).to.be.eql({[DEF_PK]: 1, ...input1});
2142
+ expect(result3).to.have.lengthOf(2);
2143
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1, ...input1});
2144
+ expect(result3[1]).to.be.eql({[DEF_PK]: 2, ...input2});
2145
+ });
2146
+
2147
+ it('a where clause uses a persisted data instead of default values', async function () {
2148
+ const schema = new Schema();
2149
+ schema.defineDatasource({
2150
+ name: 'memory',
2151
+ adapter: 'memory',
2152
+ });
2153
+ schema.defineModel({
2154
+ name: 'model',
2155
+ datasource: 'memory',
2156
+ properties: {
2157
+ foo: {
2158
+ type: DataType.STRING,
2159
+ default: 'hello',
2160
+ },
2161
+ },
2162
+ });
2163
+ const adapter = new MemoryAdapter(schema.container, {});
2164
+ const table = adapter._getTableOrCreate('model');
2165
+ table.set(1, {[DEF_PK]: 1, foo: undefined});
2166
+ table.set(2, {[DEF_PK]: 2, foo: undefined});
2167
+ table.set(3, {[DEF_PK]: 3, foo: 10});
2168
+ const result1 = await adapter.find('model', {where: {foo: undefined}});
2169
+ const result2 = await adapter.find('model', {where: {foo: 10}});
2170
+ const result3 = await adapter.find('model', {where: {foo: 'hello'}});
2171
+ expect(table.size).to.be.eq(3);
2172
+ expect(result1).to.have.lengthOf(2);
2173
+ expect(result1[0]).to.be.eql({[DEF_PK]: 1, foo: 'hello'});
2174
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2, foo: 'hello'});
2175
+ expect(result2).to.have.lengthOf(1);
2176
+ expect(result2[0]).to.be.eql({[DEF_PK]: 3, foo: 10});
2177
+ expect(result3).to.be.empty;
2178
+ });
2179
+
2180
+ it('allows to specify a limit clause to filter a return value', async function () {
2181
+ const schema = new Schema();
2182
+ schema.defineDatasource({
2183
+ name: 'memory',
2184
+ adapter: 'memory',
2185
+ });
2186
+ schema.defineModel({
2187
+ name: 'model',
2188
+ datasource: 'memory',
2189
+ properties: {
2190
+ foo: DataType.NUMBER,
2191
+ },
2192
+ });
2193
+ const adapter = new MemoryAdapter(schema.container, {});
2194
+ await adapter.create('model', {});
2195
+ await adapter.create('model', {});
2196
+ await adapter.create('model', {});
2197
+ const result1 = await adapter.find('model', {limit: 0});
2198
+ const result2 = await adapter.find('model', {limit: 1});
2199
+ const result3 = await adapter.find('model', {limit: 2});
2200
+ expect(result1).to.have.lengthOf(3);
2201
+ expect(result1[0]).to.be.eql({[DEF_PK]: 1});
2202
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2});
2203
+ expect(result1[2]).to.be.eql({[DEF_PK]: 3});
2204
+ expect(result2).to.have.lengthOf(1);
2205
+ expect(result2[0]).to.be.eql({[DEF_PK]: 1});
2206
+ expect(result3).to.have.lengthOf(2);
2207
+ expect(result3[0]).to.be.eql({[DEF_PK]: 1});
2208
+ expect(result3[1]).to.be.eql({[DEF_PK]: 2});
2209
+ });
2210
+
2211
+ it('allows to specify a skip clause to filter a return value', async function () {
2212
+ const schema = new Schema();
2213
+ schema.defineDatasource({
2214
+ name: 'memory',
2215
+ adapter: 'memory',
2216
+ });
2217
+ schema.defineModel({
2218
+ name: 'model',
2219
+ datasource: 'memory',
2220
+ properties: {
2221
+ foo: DataType.NUMBER,
2222
+ },
2223
+ });
2224
+ const adapter = new MemoryAdapter(schema.container, {});
2225
+ await adapter.create('model', {});
2226
+ await adapter.create('model', {});
2227
+ await adapter.create('model', {});
2228
+ const result1 = await adapter.find('model', {skip: 0});
2229
+ const result2 = await adapter.find('model', {skip: 1});
2230
+ const result3 = await adapter.find('model', {skip: 2});
2231
+ expect(result1).to.have.lengthOf(3);
2232
+ expect(result1[0]).to.be.eql({[DEF_PK]: 1});
2233
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2});
2234
+ expect(result1[2]).to.be.eql({[DEF_PK]: 3});
2235
+ expect(result2).to.have.lengthOf(2);
2236
+ expect(result1[1]).to.be.eql({[DEF_PK]: 2});
2237
+ expect(result1[2]).to.be.eql({[DEF_PK]: 3});
2238
+ expect(result3).to.have.lengthOf(1);
2239
+ expect(result1[2]).to.be.eql({[DEF_PK]: 3});
2240
+ });
2241
+ });
2242
+
2243
+ describe('findById', function () {
2244
+ it('throws an error if a given identifier does not exist', async function () {
2245
+ const schema = new Schema();
2246
+ schema.defineDatasource({
2247
+ name: 'memory',
2248
+ adapter: 'memory',
2249
+ });
2250
+ schema.defineModel({
2251
+ name: 'model',
2252
+ datasource: 'memory',
2253
+ });
2254
+ const adapter = new MemoryAdapter(schema.container, {});
2255
+ const promise = adapter.findById('model', 1);
2256
+ await expect(promise).to.be.rejectedWith(
2257
+ format(
2258
+ 'The value 1 of the primary key %v does not exist in the model "model".',
2259
+ DEF_PK,
2260
+ ),
2261
+ );
2262
+ });
2263
+
2264
+ it('uses default values for non-existent properties', async function () {
2265
+ const schema = new Schema();
2266
+ schema.defineDatasource({
2267
+ name: 'memory',
2268
+ adapter: 'memory',
2269
+ });
2270
+ schema.defineModel({
2271
+ name: 'model',
2272
+ datasource: 'memory',
2273
+ properties: {
2274
+ foo: {
2275
+ type: DataType.STRING,
2276
+ default: 'string',
2277
+ },
2278
+ },
2279
+ });
2280
+ const adapter = new MemoryAdapter(schema.container, {});
2281
+ const table = adapter._getTableOrCreate('model');
2282
+ const idValue = 1;
2283
+ table.set(idValue, {[DEF_PK]: idValue});
2284
+ const result = await adapter.findById('model', idValue);
2285
+ expect(result).to.be.eql({[DEF_PK]: idValue, foo: 'string'});
2286
+ const tableData = table.get(idValue);
2287
+ expect(tableData).to.be.eql({[DEF_PK]: idValue});
2288
+ });
2289
+
2290
+ it('uses default values for properties of an undefined', async function () {
2291
+ const schema = new Schema();
2292
+ schema.defineDatasource({
2293
+ name: 'memory',
2294
+ adapter: 'memory',
2295
+ });
2296
+ schema.defineModel({
2297
+ name: 'model',
2298
+ datasource: 'memory',
2299
+ properties: {
2300
+ foo: {
2301
+ type: DataType.STRING,
2302
+ default: 'string',
2303
+ },
2304
+ },
2305
+ });
2306
+ const adapter = new MemoryAdapter(schema.container, {});
2307
+ const table = adapter._getTableOrCreate('model');
2308
+ const idValue = 1;
2309
+ const input = {foo: undefined};
2310
+ table.set(idValue, {[DEF_PK]: idValue, ...input});
2311
+ const result = await adapter.findById('model', idValue);
2312
+ expect(result).to.be.eql({[DEF_PK]: idValue, foo: 'string'});
2313
+ const tableData = table.get(idValue);
2314
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...input});
2315
+ });
2316
+
2317
+ it('uses default values for properties of a null', async function () {
2318
+ const schema = new Schema();
2319
+ schema.defineDatasource({
2320
+ name: 'memory',
2321
+ adapter: 'memory',
2322
+ });
2323
+ schema.defineModel({
2324
+ name: 'model',
2325
+ datasource: 'memory',
2326
+ properties: {
2327
+ foo: {
2328
+ type: DataType.STRING,
2329
+ default: 'string',
2330
+ },
2331
+ },
2332
+ });
2333
+ const adapter = new MemoryAdapter(schema.container, {});
2334
+ const table = adapter._getTableOrCreate('model');
2335
+ const idValue = 1;
2336
+ const input = {foo: null};
2337
+ table.set(idValue, {[DEF_PK]: idValue, ...input});
2338
+ const result = await adapter.findById('model', idValue);
2339
+ expect(result).to.be.eql({[DEF_PK]: idValue, foo: 'string'});
2340
+ const tableData = table.get(idValue);
2341
+ expect(tableData).to.be.eql({[DEF_PK]: idValue, ...input});
2342
+ });
2343
+
2344
+ it('uses a specified column name for a primary key', async function () {
2345
+ const schema = new Schema();
2346
+ schema.defineDatasource({
2347
+ name: 'memory',
2348
+ adapter: 'memory',
2349
+ });
2350
+ schema.defineModel({
2351
+ name: 'model',
2352
+ datasource: 'memory',
2353
+ properties: {
2354
+ foo: {
2355
+ type: DataType.NUMBER,
2356
+ primaryKey: true,
2357
+ columnName: 'qux',
2358
+ },
2359
+ bar: DataType.NUMBER,
2360
+ baz: DataType.NUMBER,
2361
+ },
2362
+ });
2363
+ const adapter = new MemoryAdapter(schema.container, {});
2364
+ const input = {bar: 1, baz: 2};
2365
+ const table = adapter._getTableOrCreate('model');
2366
+ const idValue = 1;
2367
+ table.set(idValue, {qux: idValue, ...input});
2368
+ const result = await adapter.findById('model', idValue);
2369
+ expect(result).to.be.eql({foo: idValue, ...input});
2370
+ });
2371
+
2372
+ it('uses a specified column name for a regular property', async function () {
2373
+ const schema = new Schema();
2374
+ schema.defineDatasource({
2375
+ name: 'memory',
2376
+ adapter: 'memory',
2377
+ });
2378
+ schema.defineModel({
2379
+ name: 'model',
2380
+ datasource: 'memory',
2381
+ properties: {
2382
+ foo: {
2383
+ type: DataType.NUMBER,
2384
+ columnName: 'baz',
2385
+ },
2386
+ bar: DataType.NUMBER,
2387
+ },
2388
+ });
2389
+ const adapter = new MemoryAdapter(schema.container, {});
2390
+ const table = adapter._getTableOrCreate('model');
2391
+ const idValue = 1;
2392
+ const input = {foo: 1, bar: 2};
2393
+ table.set(idValue, {
2394
+ [DEF_PK]: idValue,
2395
+ baz: input.foo,
2396
+ bar: input.bar,
2397
+ });
2398
+ const result = await adapter.findById('model', idValue);
2399
+ expect(result).to.be.eql({[DEF_PK]: idValue, ...input});
2400
+ });
2401
+
2402
+ it('uses a specified column name for a regular property with a default value', async function () {
2403
+ const schema = new Schema();
2404
+ schema.defineDatasource({
2405
+ name: 'memory',
2406
+ adapter: 'memory',
2407
+ });
2408
+ schema.defineModel({
2409
+ name: 'model',
2410
+ datasource: 'memory',
2411
+ properties: {
2412
+ foo: {
2413
+ type: DataType.NUMBER,
2414
+ columnName: 'baz',
2415
+ default: 1,
2416
+ },
2417
+ bar: {
2418
+ type: DataType.NUMBER,
2419
+ default: 2,
2420
+ },
2421
+ },
2422
+ });
2423
+ const adapter = new MemoryAdapter(schema.container, {});
2424
+ const table = adapter._getTableOrCreate('model');
2425
+ const idValue = 1;
2426
+ table.set(idValue, {[DEF_PK]: idValue});
2427
+ const defaults = {foo: 1, bar: 2};
2428
+ const result = await adapter.findById('model', idValue);
2429
+ expect(result).to.be.eql({[DEF_PK]: idValue, ...defaults});
2430
+ });
2431
+
2432
+ it('allows to specify a short form of a fields clause to filter a return value', async function () {
2433
+ const schema = new Schema();
2434
+ schema.defineDatasource({
2435
+ name: 'memory',
2436
+ adapter: 'memory',
2437
+ });
2438
+ schema.defineModel({
2439
+ name: 'model',
2440
+ datasource: 'memory',
2441
+ properties: {
2442
+ foo: DataType.STRING,
2443
+ bar: DataType.NUMBER,
2444
+ },
2445
+ });
2446
+ const adapter = new MemoryAdapter(schema.container, {});
2447
+ const table = adapter._getTableOrCreate('model');
2448
+ const input = {foo: 'string', bar: 10};
2449
+ const idValue = 1;
2450
+ table.set(idValue, {[DEF_PK]: idValue, ...input});
2451
+ const result = await adapter.findById('model', idValue, {fields: 'foo'});
2452
+ expect(result).to.be.eql({[DEF_PK]: idValue, foo: input.foo});
2453
+ });
2454
+
2455
+ it('allows to specify a full form of a fields clause to filter a return value', async function () {
2456
+ const schema = new Schema();
2457
+ schema.defineDatasource({
2458
+ name: 'memory',
2459
+ adapter: 'memory',
2460
+ });
2461
+ schema.defineModel({
2462
+ name: 'model',
2463
+ datasource: 'memory',
2464
+ properties: {
2465
+ foo: DataType.STRING,
2466
+ bar: DataType.NUMBER,
2467
+ baz: DataType.BOOLEAN,
2468
+ },
2469
+ });
2470
+ const adapter = new MemoryAdapter(schema.container, {});
2471
+ const table = adapter._getTableOrCreate('model');
2472
+ const input = {foo: 'string', bar: 10, baz: true};
2473
+ const idValue = 1;
2474
+ table.set(idValue, {[DEF_PK]: idValue, ...input});
2475
+ const filter = {fields: ['foo', 'bar']};
2476
+ const result = await adapter.findById('model', idValue, filter);
2477
+ expect(result).to.be.eql({
2478
+ [DEF_PK]: idValue,
2479
+ foo: input.foo,
2480
+ bar: input.bar,
2481
+ });
2482
+ });
2483
+
2484
+ it('a fields clause uses property names instead of column names', async function () {
2485
+ const schema = new Schema();
2486
+ schema.defineDatasource({
2487
+ name: 'memory',
2488
+ adapter: 'memory',
2489
+ });
2490
+ schema.defineModel({
2491
+ name: 'model',
2492
+ datasource: 'memory',
2493
+ properties: {
2494
+ foo: {
2495
+ type: DataType.STRING,
2496
+ columnName: 'fooCol',
2497
+ },
2498
+ bar: {
2499
+ type: DataType.NUMBER,
2500
+ columnName: 'barCol',
2501
+ },
2502
+ baz: {
2503
+ type: DataType.BOOLEAN,
2504
+ columnName: 'bazCol',
2505
+ },
2506
+ },
2507
+ });
2508
+ const adapter = new MemoryAdapter(schema.container, {});
2509
+ const table = adapter._getTableOrCreate('model');
2510
+ const tableInput = {fooCol: 'string', barCol: 10, bazCol: true};
2511
+ const idValue = 1;
2512
+ table.set(idValue, {
2513
+ [DEF_PK]: idValue,
2514
+ ...tableInput,
2515
+ });
2516
+ const filter = {fields: ['foo', 'bar']};
2517
+ const result = await adapter.findById('model', idValue, filter);
2518
+ expect(result).to.be.eql({
2519
+ [DEF_PK]: idValue,
2520
+ foo: tableInput.fooCol,
2521
+ bar: tableInput.barCol,
2522
+ });
2523
+ });
2524
+ });
2525
+
2526
+ describe('delete', function () {
2527
+ it('removes all table items and returns their number', async function () {
2528
+ const schema = new Schema();
2529
+ schema.defineDatasource({
2530
+ name: 'memory',
2531
+ adapter: 'memory',
2532
+ });
2533
+ schema.defineModel({
2534
+ name: 'model',
2535
+ datasource: 'memory',
2536
+ });
2537
+ const adapter = new MemoryAdapter(schema.container, {});
2538
+ const table = adapter._getTableOrCreate('model');
2539
+ table.set(1, {[DEF_PK]: 1});
2540
+ table.set(2, {[DEF_PK]: 2});
2541
+ table.set(3, {[DEF_PK]: 3});
2542
+ const result = await adapter.delete('model');
2543
+ expect(result).to.be.eq(3);
2544
+ const tableSize = Array.from(table.values()).length;
2545
+ expect(tableSize).to.be.eq(0);
2546
+ });
2547
+
2548
+ it('returns zero if nothing to remove', async function () {
2549
+ const schema = new Schema();
2550
+ schema.defineDatasource({
2551
+ name: 'memory',
2552
+ adapter: 'memory',
2553
+ });
2554
+ schema.defineModel({
2555
+ name: 'model',
2556
+ datasource: 'memory',
2557
+ });
2558
+ const adapter = new MemoryAdapter(schema.container, {});
2559
+ const result = await adapter.delete('model');
2560
+ expect(result).to.be.eq(0);
2561
+ });
2562
+
2563
+ it('uses a given where clause to remove specific items', async function () {
2564
+ const schema = new Schema();
2565
+ schema.defineDatasource({
2566
+ name: 'memory',
2567
+ adapter: 'memory',
2568
+ });
2569
+ schema.defineModel({
2570
+ name: 'model',
2571
+ datasource: 'memory',
2572
+ properties: {
2573
+ foo: DataType.NUMBER,
2574
+ },
2575
+ });
2576
+ const adapter = new MemoryAdapter(schema.container, {});
2577
+ await adapter.create('model', {foo: 20});
2578
+ await adapter.create('model', {foo: 10});
2579
+ await adapter.create('model', {foo: 15});
2580
+ const result = await adapter.delete('model', {foo: {gte: 15}});
2581
+ expect(result).to.be.eq(2);
2582
+ const table = adapter._getTableOrCreate('model');
2583
+ const tableSize = Array.from(table.values()).length;
2584
+ expect(tableSize).to.be.eq(1);
2585
+ expect(table.get(2)).to.be.eql({[DEF_PK]: 2, foo: 10});
2586
+ });
2587
+
2588
+ it('a where clause uses property names instead of column names', async function () {
2589
+ const schema = new Schema();
2590
+ schema.defineDatasource({
2591
+ name: 'memory',
2592
+ adapter: 'memory',
2593
+ });
2594
+ schema.defineModel({
2595
+ name: 'model',
2596
+ datasource: 'memory',
2597
+ properties: {
2598
+ foo: {
2599
+ type: DataType.NUMBER,
2600
+ columnName: 'fooCol',
2601
+ },
2602
+ },
2603
+ });
2604
+ const adapter = new MemoryAdapter(schema.container, {});
2605
+ const table = adapter._getTableOrCreate('model');
2606
+ table.set(1, {[DEF_PK]: 1, fooCol: 20});
2607
+ table.set(2, {[DEF_PK]: 2, fooCol: 10});
2608
+ table.set(3, {[DEF_PK]: 3, fooCol: 15});
2609
+ const result = await adapter.delete('model', {foo: {gte: 15}});
2610
+ expect(result).to.be.eq(2);
2611
+ expect(table.size).to.be.eq(1);
2612
+ expect(table.get(2)).to.be.eql({[DEF_PK]: 2, fooCol: 10});
2613
+ });
2614
+
2615
+ it('a where clause uses a persisted data instead of default values', async function () {
2616
+ const schema = new Schema();
2617
+ schema.defineDatasource({
2618
+ name: 'memory',
2619
+ adapter: 'memory',
2620
+ });
2621
+ schema.defineModel({
2622
+ name: 'model',
2623
+ datasource: 'memory',
2624
+ properties: {
2625
+ foo: {
2626
+ type: DataType.STRING,
2627
+ default: 'hello',
2628
+ },
2629
+ },
2630
+ });
2631
+ const adapter = new MemoryAdapter(schema.container, {});
2632
+ const table = adapter._getTableOrCreate('model');
2633
+ const input1 = {[DEF_PK]: 1, foo: undefined};
2634
+ const input2 = {[DEF_PK]: 2, foo: undefined};
2635
+ const input3 = {[DEF_PK]: 3, foo: 10};
2636
+ const input4 = {[DEF_PK]: 4, foo: true};
2637
+ table.set(1, input1);
2638
+ table.set(2, input2);
2639
+ table.set(3, input3);
2640
+ table.set(4, input4);
2641
+ const result1 = await adapter.delete('model', {foo: undefined});
2642
+ expect(result1).to.be.eq(2);
2643
+ expect(table.size).to.be.eq(2);
2644
+ expect(table.get(3)).to.be.eql(input3);
2645
+ expect(table.get(4)).to.be.eql(input4);
2646
+ const result2 = await adapter.delete('model', {foo: 'hello'});
2647
+ expect(result2).to.be.eq(0);
2648
+ expect(table.size).to.be.eq(2);
2649
+ expect(table.get(3)).to.be.eql(input3);
2650
+ expect(table.get(4)).to.be.eql(input4);
2651
+ const result3 = await adapter.delete('model', {foo: 10});
2652
+ expect(result3).to.be.eq(1);
2653
+ expect(table.size).to.be.eq(1);
2654
+ expect(table.get(4)).to.be.eql(input4);
2655
+ });
2656
+ });
2657
+
2658
+ describe('deleteById', function () {
2659
+ it('returns false if a given identifier is not exist', async function () {
2660
+ const schema = new Schema();
2661
+ schema.defineDatasource({
2662
+ name: 'memory',
2663
+ adapter: 'memory',
2664
+ });
2665
+ schema.defineModel({
2666
+ name: 'model',
2667
+ datasource: 'memory',
2668
+ });
2669
+ const adapter = new MemoryAdapter(schema.container, {});
2670
+ const result = await adapter.deleteById('model', 1);
2671
+ expect(result).to.be.false;
2672
+ });
2673
+
2674
+ it('returns true if an item has removed by a given identifier', async function () {
2675
+ const schema = new Schema();
2676
+ schema.defineDatasource({
2677
+ name: 'memory',
2678
+ adapter: 'memory',
2679
+ });
2680
+ schema.defineModel({
2681
+ name: 'model',
2682
+ datasource: 'memory',
2683
+ });
2684
+ const adapter = new MemoryAdapter(schema.container, {});
2685
+ const created = await adapter.create('model', {});
2686
+ const idValue = created[DEF_PK];
2687
+ const result = await adapter.deleteById('model', idValue);
2688
+ expect(result).to.be.true;
2689
+ });
2690
+
2691
+ it('uses a specified column name for a primary key', async function () {
2692
+ const schema = new Schema();
2693
+ schema.defineDatasource({
2694
+ name: 'memory',
2695
+ adapter: 'memory',
2696
+ });
2697
+ schema.defineModel({
2698
+ name: 'model',
2699
+ datasource: 'memory',
2700
+ properties: {
2701
+ foo: {
2702
+ type: DataType.NUMBER,
2703
+ primaryKey: true,
2704
+ columnName: 'qux',
2705
+ },
2706
+ bar: DataType.NUMBER,
2707
+ },
2708
+ });
2709
+ const adapter = new MemoryAdapter(schema.container, {});
2710
+ const table = adapter._getTableOrCreate('model');
2711
+ const idValue = 1;
2712
+ table.set(idValue, {qux: idValue, bar: 10});
2713
+ const result = await adapter.deleteById('model', idValue);
2714
+ expect(result).to.be.true;
2715
+ const tableSize = Array.from(table.values()).length;
2716
+ expect(tableSize).to.be.eq(0);
2717
+ });
2718
+ });
2719
+
2720
+ describe('exists', function () {
2721
+ it('returns false if a given identifier is not exist', async function () {
2722
+ const schema = new Schema();
2723
+ schema.defineDatasource({
2724
+ name: 'memory',
2725
+ adapter: 'memory',
2726
+ });
2727
+ schema.defineModel({
2728
+ name: 'model',
2729
+ datasource: 'memory',
2730
+ });
2731
+ const adapter = new MemoryAdapter(schema.container, {});
2732
+ const result = await adapter.exists('model', 1);
2733
+ expect(result).to.be.false;
2734
+ });
2735
+
2736
+ it('returns true if a given identifier is exist', async function () {
2737
+ const schema = new Schema();
2738
+ schema.defineDatasource({
2739
+ name: 'memory',
2740
+ adapter: 'memory',
2741
+ });
2742
+ schema.defineModel({
2743
+ name: 'model',
2744
+ datasource: 'memory',
2745
+ });
2746
+ const adapter = new MemoryAdapter(schema.container, {});
2747
+ await adapter.create('model', {});
2748
+ const result = await adapter.exists('model', 1);
2749
+ expect(result).to.be.true;
2750
+ });
2751
+
2752
+ it('uses a specified column name for a primary key', async function () {
2753
+ const schema = new Schema();
2754
+ schema.defineDatasource({
2755
+ name: 'memory',
2756
+ adapter: 'memory',
2757
+ });
2758
+ schema.defineModel({
2759
+ name: 'model',
2760
+ datasource: 'memory',
2761
+ properties: {
2762
+ foo: {
2763
+ type: DataType.NUMBER,
2764
+ primaryKey: true,
2765
+ columnName: 'qux',
2766
+ },
2767
+ },
2768
+ });
2769
+ const adapter = new MemoryAdapter(schema.container, {});
2770
+ const table = adapter._getTableOrCreate('model');
2771
+ const idValue = 1;
2772
+ table.set(idValue, {qux: idValue});
2773
+ const result = await adapter.exists('model', idValue);
2774
+ expect(result).to.be.true;
2775
+ });
2776
+ });
2777
+
2778
+ describe('count', function () {
2779
+ it('returns zero if nothing to count', async function () {
2780
+ const schema = new Schema();
2781
+ schema.defineDatasource({
2782
+ name: 'memory',
2783
+ adapter: 'memory',
2784
+ });
2785
+ schema.defineModel({
2786
+ name: 'model',
2787
+ datasource: 'memory',
2788
+ });
2789
+ const adapter = new MemoryAdapter(schema.container, {});
2790
+ const result = await adapter.count('model');
2791
+ expect(result).to.be.eq(0);
2792
+ });
2793
+
2794
+ it('returns zero if a given where clause does not met', async function () {
2795
+ const schema = new Schema();
2796
+ schema.defineDatasource({
2797
+ name: 'memory',
2798
+ adapter: 'memory',
2799
+ });
2800
+ schema.defineModel({
2801
+ name: 'model',
2802
+ datasource: 'memory',
2803
+ properties: {
2804
+ foo: DataType.NUMBER,
2805
+ },
2806
+ });
2807
+ const adapter = new MemoryAdapter(schema.container, {});
2808
+ await adapter.create('model', {foo: 20});
2809
+ await adapter.create('model', {foo: 10});
2810
+ await adapter.create('model', {foo: 15});
2811
+ const result = await adapter.count('model', {foo: {gte: 150}});
2812
+ expect(result).to.be.eq(0);
2813
+ const table = adapter._getTableOrCreate('model');
2814
+ const tableSize = Array.from(table.values()).length;
2815
+ expect(tableSize).to.be.eq(3);
2816
+ expect(table.get(1)).to.be.eql({[DEF_PK]: 1, foo: 20});
2817
+ expect(table.get(2)).to.be.eql({[DEF_PK]: 2, foo: 10});
2818
+ expect(table.get(3)).to.be.eql({[DEF_PK]: 3, foo: 15});
2819
+ });
2820
+
2821
+ it('returns a number of table items', async function () {
2822
+ const schema = new Schema();
2823
+ schema.defineDatasource({
2824
+ name: 'memory',
2825
+ adapter: 'memory',
2826
+ });
2827
+ schema.defineModel({
2828
+ name: 'model',
2829
+ datasource: 'memory',
2830
+ });
2831
+ const adapter = new MemoryAdapter(schema.container, {});
2832
+ await adapter.create('model', {});
2833
+ await adapter.create('model', {});
2834
+ await adapter.create('model', {});
2835
+ const result = await adapter.count('model');
2836
+ expect(result).to.be.eq(3);
2837
+ });
2838
+
2839
+ it('uses a given where clause to count specific items', async function () {
2840
+ const schema = new Schema();
2841
+ schema.defineDatasource({
2842
+ name: 'memory',
2843
+ adapter: 'memory',
2844
+ });
2845
+ schema.defineModel({
2846
+ name: 'model',
2847
+ datasource: 'memory',
2848
+ properties: {
2849
+ foo: DataType.NUMBER,
2850
+ },
2851
+ });
2852
+ const adapter = new MemoryAdapter(schema.container, {});
2853
+ await adapter.create('model', {foo: 20});
2854
+ await adapter.create('model', {foo: 10});
2855
+ await adapter.create('model', {foo: 15});
2856
+ const result = await adapter.count('model', {foo: {gte: 15}});
2857
+ expect(result).to.be.eq(2);
2858
+ const table = adapter._getTableOrCreate('model');
2859
+ const tableSize = Array.from(table.values()).length;
2860
+ expect(tableSize).to.be.eq(3);
2861
+ expect(table.get(1)).to.be.eql({[DEF_PK]: 1, foo: 20});
2862
+ expect(table.get(2)).to.be.eql({[DEF_PK]: 2, foo: 10});
2863
+ expect(table.get(3)).to.be.eql({[DEF_PK]: 3, foo: 15});
2864
+ });
2865
+
2866
+ it('a where clause uses property names instead of column names', async function () {
2867
+ const schema = new Schema();
2868
+ schema.defineDatasource({
2869
+ name: 'memory',
2870
+ adapter: 'memory',
2871
+ });
2872
+ schema.defineModel({
2873
+ name: 'model',
2874
+ datasource: 'memory',
2875
+ properties: {
2876
+ foo: {
2877
+ type: DataType.NUMBER,
2878
+ columnName: 'fooCol',
2879
+ },
2880
+ },
2881
+ });
2882
+ const adapter = new MemoryAdapter(schema.container, {});
2883
+ const table = adapter._getTableOrCreate('model');
2884
+ table.set(1, {[DEF_PK]: 1, fooCol: 20});
2885
+ table.set(2, {[DEF_PK]: 2, fooCol: 10});
2886
+ table.set(3, {[DEF_PK]: 3, fooCol: 15});
2887
+ const result = await adapter.count('model', {foo: {gte: 15}});
2888
+ expect(result).to.be.eq(2);
2889
+ const tableSize = Array.from(table.values()).length;
2890
+ expect(tableSize).to.be.eq(3);
2891
+ expect(table.get(1)).to.be.eql({[DEF_PK]: 1, fooCol: 20});
2892
+ expect(table.get(2)).to.be.eql({[DEF_PK]: 2, fooCol: 10});
2893
+ expect(table.get(3)).to.be.eql({[DEF_PK]: 3, fooCol: 15});
2894
+ });
2895
+
2896
+ it('a where clause uses a persisted data instead of default values', async function () {
2897
+ const schema = new Schema();
2898
+ schema.defineDatasource({
2899
+ name: 'memory',
2900
+ adapter: 'memory',
2901
+ });
2902
+ schema.defineModel({
2903
+ name: 'model',
2904
+ datasource: 'memory',
2905
+ properties: {
2906
+ foo: {
2907
+ type: DataType.STRING,
2908
+ default: 'hello',
2909
+ },
2910
+ },
2911
+ });
2912
+ const adapter = new MemoryAdapter(schema.container, {});
2913
+ const table = adapter._getTableOrCreate('model');
2914
+ table.set(1, {[DEF_PK]: 1, foo: undefined});
2915
+ table.set(2, {[DEF_PK]: 2, foo: undefined});
2916
+ table.set(3, {[DEF_PK]: 3, foo: 10});
2917
+ const result1 = await adapter.count('model', {foo: undefined});
2918
+ const result2 = await adapter.count('model', {foo: 10});
2919
+ const result3 = await adapter.count('model', {foo: 'hello'});
2920
+ expect(result1).to.be.eq(2);
2921
+ expect(result2).to.be.eq(1);
2922
+ expect(result3).to.be.eq(0);
2923
+ });
2924
+ });
2925
+ });