@twin.org/entity-storage-connector-file 0.0.1-next.8 → 0.0.1-next.9

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.
@@ -114,27 +114,25 @@ class FileEntityStorageConnector {
114
114
  * Get an entity.
115
115
  * @param id The id of the entity to get, or the index value if secondaryIndex is set.
116
116
  * @param secondaryIndex Get the item using a secondary index.
117
+ * @param conditions The optional conditions to match for the entities.
117
118
  * @returns The object if it can be found or undefined.
118
119
  */
119
- async get(id, secondaryIndex) {
120
+ async get(id, secondaryIndex, conditions) {
120
121
  core.Guards.stringValue(this.CLASS_NAME, "id", id);
121
- const lookupKey = secondaryIndex ?? this._primaryKey.property;
122
122
  const store = await this.readStore();
123
- const found = store?.find(entity => entity[lookupKey] === id);
124
- if (found) {
125
- return found;
126
- }
127
- return undefined;
123
+ const foundIndex = this.findItem(store, id, secondaryIndex, conditions);
124
+ return foundIndex === -1 ? undefined : store[foundIndex];
128
125
  }
129
126
  /**
130
127
  * Set an entity.
131
128
  * @param entity The entity to set.
129
+ * @param conditions The optional conditions to match for the entities.
132
130
  * @returns The id of the entity.
133
131
  */
134
- async set(entity) {
132
+ async set(entity, conditions) {
135
133
  core.Guards.object(this.CLASS_NAME, "entity", entity);
136
134
  const store = await this.readStore();
137
- const existingIndex = store.findIndex(e => e[this._primaryKey.property] === entity[this._primaryKey.property]);
135
+ const existingIndex = this.findItem(store, entity[this._primaryKey.property], undefined, conditions);
138
136
  if (existingIndex >= 0) {
139
137
  store[existingIndex] = entity;
140
138
  }
@@ -146,16 +144,17 @@ class FileEntityStorageConnector {
146
144
  /**
147
145
  * Remove the entity.
148
146
  * @param id The id of the entity to remove.
147
+ * @param conditions The optional conditions to match for the entities.
149
148
  * @returns Nothing.
150
149
  */
151
- async remove(id) {
150
+ async remove(id, conditions) {
152
151
  core.Guards.stringValue(this.CLASS_NAME, "id", id);
153
152
  const store = await this.readStore();
154
- const index = store.findIndex(e => e[this._primaryKey.property] === id);
153
+ const index = this.findItem(store, id, undefined, conditions);
155
154
  if (index >= 0) {
156
155
  store.splice(index, 1);
156
+ await this.writeStore(store);
157
157
  }
158
- await this.writeStore(store);
159
158
  }
160
159
  /**
161
160
  * Find all the entities which match the conditions.
@@ -233,6 +232,51 @@ class FileEntityStorageConnector {
233
232
  return false;
234
233
  }
235
234
  }
235
+ /**
236
+ * Find the item in the store.
237
+ * @param store The store to search.
238
+ * @param id The id to search for.
239
+ * @param secondaryIndex The secondary index to search for.
240
+ * @param conditions The optional conditions to match for the entities.
241
+ * @returns The index of the item if found or -1.
242
+ * @internal
243
+ */
244
+ findItem(store, id, secondaryIndex, conditions) {
245
+ const finalConditions = [];
246
+ if (!core.Is.empty(secondaryIndex)) {
247
+ finalConditions.push({
248
+ property: secondaryIndex,
249
+ comparison: entity.ComparisonOperator.Equals,
250
+ value: id
251
+ });
252
+ }
253
+ if (core.Is.arrayValue(conditions)) {
254
+ // If we haven't added a secondary index condition we need to add the primary key condition.
255
+ if (finalConditions.length === 0) {
256
+ finalConditions.push({
257
+ property: this._primaryKey.property,
258
+ comparison: entity.ComparisonOperator.Equals,
259
+ value: id
260
+ });
261
+ }
262
+ finalConditions.push(...conditions.map(c => ({
263
+ property: c.property,
264
+ comparison: entity.ComparisonOperator.Equals,
265
+ value: c.value
266
+ })));
267
+ }
268
+ if (finalConditions.length > 0) {
269
+ for (let i = 0; i < store.length; i++) {
270
+ if (entity.EntityConditions.check(store[i], { conditions: finalConditions })) {
271
+ return i;
272
+ }
273
+ }
274
+ }
275
+ else {
276
+ return store.findIndex(e => e[this._primaryKey.property] === id);
277
+ }
278
+ return -1;
279
+ }
236
280
  }
237
281
 
238
282
  exports.FileEntityStorageConnector = FileEntityStorageConnector;
@@ -1,7 +1,7 @@
1
1
  import { mkdir, readFile, writeFile, access } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { Guards, BaseError, Coerce, ObjectHelper } from '@twin.org/core';
4
- import { EntitySchemaFactory, EntitySchemaHelper, EntitySorter, EntityConditions } from '@twin.org/entity';
3
+ import { Guards, BaseError, Coerce, ObjectHelper, Is } from '@twin.org/core';
4
+ import { EntitySchemaFactory, EntitySchemaHelper, EntitySorter, EntityConditions, ComparisonOperator } from '@twin.org/entity';
5
5
  import { LoggingConnectorFactory } from '@twin.org/logging-models';
6
6
 
7
7
  // Copyright 2024 IOTA Stiftung.
@@ -112,27 +112,25 @@ class FileEntityStorageConnector {
112
112
  * Get an entity.
113
113
  * @param id The id of the entity to get, or the index value if secondaryIndex is set.
114
114
  * @param secondaryIndex Get the item using a secondary index.
115
+ * @param conditions The optional conditions to match for the entities.
115
116
  * @returns The object if it can be found or undefined.
116
117
  */
117
- async get(id, secondaryIndex) {
118
+ async get(id, secondaryIndex, conditions) {
118
119
  Guards.stringValue(this.CLASS_NAME, "id", id);
119
- const lookupKey = secondaryIndex ?? this._primaryKey.property;
120
120
  const store = await this.readStore();
121
- const found = store?.find(entity => entity[lookupKey] === id);
122
- if (found) {
123
- return found;
124
- }
125
- return undefined;
121
+ const foundIndex = this.findItem(store, id, secondaryIndex, conditions);
122
+ return foundIndex === -1 ? undefined : store[foundIndex];
126
123
  }
127
124
  /**
128
125
  * Set an entity.
129
126
  * @param entity The entity to set.
127
+ * @param conditions The optional conditions to match for the entities.
130
128
  * @returns The id of the entity.
131
129
  */
132
- async set(entity) {
130
+ async set(entity, conditions) {
133
131
  Guards.object(this.CLASS_NAME, "entity", entity);
134
132
  const store = await this.readStore();
135
- const existingIndex = store.findIndex(e => e[this._primaryKey.property] === entity[this._primaryKey.property]);
133
+ const existingIndex = this.findItem(store, entity[this._primaryKey.property], undefined, conditions);
136
134
  if (existingIndex >= 0) {
137
135
  store[existingIndex] = entity;
138
136
  }
@@ -144,16 +142,17 @@ class FileEntityStorageConnector {
144
142
  /**
145
143
  * Remove the entity.
146
144
  * @param id The id of the entity to remove.
145
+ * @param conditions The optional conditions to match for the entities.
147
146
  * @returns Nothing.
148
147
  */
149
- async remove(id) {
148
+ async remove(id, conditions) {
150
149
  Guards.stringValue(this.CLASS_NAME, "id", id);
151
150
  const store = await this.readStore();
152
- const index = store.findIndex(e => e[this._primaryKey.property] === id);
151
+ const index = this.findItem(store, id, undefined, conditions);
153
152
  if (index >= 0) {
154
153
  store.splice(index, 1);
154
+ await this.writeStore(store);
155
155
  }
156
- await this.writeStore(store);
157
156
  }
158
157
  /**
159
158
  * Find all the entities which match the conditions.
@@ -231,6 +230,51 @@ class FileEntityStorageConnector {
231
230
  return false;
232
231
  }
233
232
  }
233
+ /**
234
+ * Find the item in the store.
235
+ * @param store The store to search.
236
+ * @param id The id to search for.
237
+ * @param secondaryIndex The secondary index to search for.
238
+ * @param conditions The optional conditions to match for the entities.
239
+ * @returns The index of the item if found or -1.
240
+ * @internal
241
+ */
242
+ findItem(store, id, secondaryIndex, conditions) {
243
+ const finalConditions = [];
244
+ if (!Is.empty(secondaryIndex)) {
245
+ finalConditions.push({
246
+ property: secondaryIndex,
247
+ comparison: ComparisonOperator.Equals,
248
+ value: id
249
+ });
250
+ }
251
+ if (Is.arrayValue(conditions)) {
252
+ // If we haven't added a secondary index condition we need to add the primary key condition.
253
+ if (finalConditions.length === 0) {
254
+ finalConditions.push({
255
+ property: this._primaryKey.property,
256
+ comparison: ComparisonOperator.Equals,
257
+ value: id
258
+ });
259
+ }
260
+ finalConditions.push(...conditions.map(c => ({
261
+ property: c.property,
262
+ comparison: ComparisonOperator.Equals,
263
+ value: c.value
264
+ })));
265
+ }
266
+ if (finalConditions.length > 0) {
267
+ for (let i = 0; i < store.length; i++) {
268
+ if (EntityConditions.check(store[i], { conditions: finalConditions })) {
269
+ return i;
270
+ }
271
+ }
272
+ }
273
+ else {
274
+ return store.findIndex(e => e[this._primaryKey.property] === id);
275
+ }
276
+ return -1;
277
+ }
234
278
  }
235
279
 
236
280
  export { FileEntityStorageConnector };
@@ -34,21 +34,33 @@ export declare class FileEntityStorageConnector<T = unknown> implements IEntityS
34
34
  * Get an entity.
35
35
  * @param id The id of the entity to get, or the index value if secondaryIndex is set.
36
36
  * @param secondaryIndex Get the item using a secondary index.
37
+ * @param conditions The optional conditions to match for the entities.
37
38
  * @returns The object if it can be found or undefined.
38
39
  */
39
- get(id: string, secondaryIndex?: keyof T): Promise<T | undefined>;
40
+ get(id: string, secondaryIndex?: keyof T, conditions?: {
41
+ property: keyof T;
42
+ value: unknown;
43
+ }[]): Promise<T | undefined>;
40
44
  /**
41
45
  * Set an entity.
42
46
  * @param entity The entity to set.
47
+ * @param conditions The optional conditions to match for the entities.
43
48
  * @returns The id of the entity.
44
49
  */
45
- set(entity: T): Promise<void>;
50
+ set(entity: T, conditions?: {
51
+ property: keyof T;
52
+ value: unknown;
53
+ }[]): Promise<void>;
46
54
  /**
47
55
  * Remove the entity.
48
56
  * @param id The id of the entity to remove.
57
+ * @param conditions The optional conditions to match for the entities.
49
58
  * @returns Nothing.
50
59
  */
51
- remove(id: string): Promise<void>;
60
+ remove(id: string, conditions?: {
61
+ property: keyof T;
62
+ value: unknown;
63
+ }[]): Promise<void>;
52
64
  /**
53
65
  * Find all the entities which match the conditions.
54
66
  * @param conditions The conditions to match for the entities.
package/docs/changelog.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # @twin.org/entity-storage-connector-file - Changelog
2
2
 
3
- ## v0.0.1-next.8
3
+ ## v0.0.1-next.9
4
4
 
5
5
  - Initial Release
@@ -94,7 +94,7 @@ The schema for the entities.
94
94
 
95
95
  ### get()
96
96
 
97
- > **get**(`id`, `secondaryIndex`?): `Promise`\<`undefined` \| `T`\>
97
+ > **get**(`id`, `secondaryIndex`?, `conditions`?): `Promise`\<`undefined` \| `T`\>
98
98
 
99
99
  Get an entity.
100
100
 
@@ -108,6 +108,10 @@ The id of the entity to get, or the index value if secondaryIndex is set.
108
108
 
109
109
  Get the item using a secondary index.
110
110
 
111
+ • **conditions?**: `object`[]
112
+
113
+ The optional conditions to match for the entities.
114
+
111
115
  #### Returns
112
116
 
113
117
  `Promise`\<`undefined` \| `T`\>
@@ -122,7 +126,7 @@ The object if it can be found or undefined.
122
126
 
123
127
  ### set()
124
128
 
125
- > **set**(`entity`): `Promise`\<`void`\>
129
+ > **set**(`entity`, `conditions`?): `Promise`\<`void`\>
126
130
 
127
131
  Set an entity.
128
132
 
@@ -132,6 +136,10 @@ Set an entity.
132
136
 
133
137
  The entity to set.
134
138
 
139
+ • **conditions?**: `object`[]
140
+
141
+ The optional conditions to match for the entities.
142
+
135
143
  #### Returns
136
144
 
137
145
  `Promise`\<`void`\>
@@ -146,7 +154,7 @@ The id of the entity.
146
154
 
147
155
  ### remove()
148
156
 
149
- > **remove**(`id`): `Promise`\<`void`\>
157
+ > **remove**(`id`, `conditions`?): `Promise`\<`void`\>
150
158
 
151
159
  Remove the entity.
152
160
 
@@ -156,6 +164,10 @@ Remove the entity.
156
164
 
157
165
  The id of the entity to remove.
158
166
 
167
+ • **conditions?**: `object`[]
168
+
169
+ The optional conditions to match for the entities.
170
+
159
171
  #### Returns
160
172
 
161
173
  `Promise`\<`void`\>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/entity-storage-connector-file",
3
- "version": "0.0.1-next.8",
3
+ "version": "0.0.1-next.9",
4
4
  "description": "Entity Storage connector implementation using file storage",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "@twin.org/core": "next",
18
18
  "@twin.org/entity": "next",
19
- "@twin.org/entity-storage-models": "0.0.1-next.8",
19
+ "@twin.org/entity-storage-models": "0.0.1-next.9",
20
20
  "@twin.org/logging-models": "next",
21
21
  "@twin.org/nameof": "next"
22
22
  },