@nsshunt/stsappframework 3.1.144 → 3.1.146

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 (49) hide show
  1. package/dist/fhir/STSFhirTypes.js +1 -0
  2. package/dist/fhir/STSFhirTypes.js.map +1 -1
  3. package/dist/fhir/dalFhirManager.js +4 -0
  4. package/dist/fhir/dalFhirManager.js.map +1 -1
  5. package/dist/fhir/dalFhirManagerIORedisJson.js +201 -0
  6. package/dist/fhir/dalFhirManagerIORedisJson.js.map +1 -0
  7. package/dist/fhir/dalFhirManagerIORedisJson.test.js +47 -0
  8. package/dist/fhir/dalFhirManagerIORedisJson.test.js.map +1 -0
  9. package/dist/fhir/dalFhirManagerPGRes.js +31 -5
  10. package/dist/fhir/dalFhirManagerPGRes.js.map +1 -1
  11. package/dist/fhir/dalFhirManagerPGRes.test.js +12 -0
  12. package/dist/fhir/dalFhirManagerPGRes.test.js.map +1 -1
  13. package/dist/fhir/dalFhirManagerPGResEntity.js +32 -5
  14. package/dist/fhir/dalFhirManagerPGResEntity.js.map +1 -1
  15. package/dist/fhir/dalFhirManagerPGResEntity.test.js +12 -0
  16. package/dist/fhir/dalFhirManagerPGResEntity.test.js.map +1 -1
  17. package/dist/fhir/dalFhirManagerRedisJson.js +124 -28
  18. package/dist/fhir/dalFhirManagerRedisJson.js.map +1 -1
  19. package/dist/fhir/dalFhirManagerRedisJson.test.js +14 -2
  20. package/dist/fhir/dalFhirManagerRedisJson.test.js.map +1 -1
  21. package/dist/fhir/dalFhirTestHelpers.js +23 -1
  22. package/dist/fhir/dalFhirTestHelpers.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/fhir/STSFhirTypes.ts +5 -4
  25. package/src/fhir/dalFhirManager.ts +6 -1
  26. package/src/fhir/dalFhirManagerIORedisJson.test.ts +58 -0
  27. package/src/fhir/dalFhirManagerIORedisJson.ts +218 -0
  28. package/src/fhir/dalFhirManagerPGRes.test.ts +12 -0
  29. package/src/fhir/dalFhirManagerPGRes.ts +37 -6
  30. package/src/fhir/dalFhirManagerPGResEntity.test.ts +12 -0
  31. package/src/fhir/dalFhirManagerPGResEntity.ts +55 -5
  32. package/src/fhir/dalFhirManagerRedisJson.test.ts +14 -2
  33. package/src/fhir/dalFhirManagerRedisJson.ts +131 -28
  34. package/src/fhir/dalFhirTestHelpers.ts +26 -1
  35. package/types/fhir/STSFhirTypes.d.ts +5 -4
  36. package/types/fhir/STSFhirTypes.d.ts.map +1 -1
  37. package/types/fhir/dalFhirManager.d.ts.map +1 -1
  38. package/types/fhir/dalFhirManagerIORedisJson.d.ts +19 -0
  39. package/types/fhir/dalFhirManagerIORedisJson.d.ts.map +1 -0
  40. package/types/fhir/dalFhirManagerIORedisJson.test.d.ts +2 -0
  41. package/types/fhir/dalFhirManagerIORedisJson.test.d.ts.map +1 -0
  42. package/types/fhir/dalFhirManagerPGRes.d.ts +3 -3
  43. package/types/fhir/dalFhirManagerPGRes.d.ts.map +1 -1
  44. package/types/fhir/dalFhirManagerPGResEntity.d.ts +3 -3
  45. package/types/fhir/dalFhirManagerPGResEntity.d.ts.map +1 -1
  46. package/types/fhir/dalFhirManagerRedisJson.d.ts +3 -3
  47. package/types/fhir/dalFhirManagerRedisJson.d.ts.map +1 -1
  48. package/types/fhir/dalFhirTestHelpers.d.ts +1 -0
  49. package/types/fhir/dalFhirTestHelpers.d.ts.map +1 -1
@@ -0,0 +1,218 @@
1
+ /* eslint @typescript-eslint/no-unused-vars: 0 */ // --> OFF
2
+ /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
3
+ import { IDomainResource, IDALFhirDataAccessManager, IFhirManagerRedisJsonOptions } from './STSFhirTypes'
4
+
5
+ import { Redis, RedisOptions } from "ioredis";
6
+
7
+ import chalk from 'chalk'
8
+ import { JSONObject } from '@nsshunt/stsutils';
9
+
10
+ export class DALFhirManagerIORedisJson<T> implements IDALFhirDataAccessManager<T> {
11
+ #options: IFhirManagerRedisJsonOptions;
12
+ #redis: Redis | null = null;
13
+ #indexName: string = 'idx:stsfhirresindex';
14
+
15
+ constructor(options: IFhirManagerRedisJsonOptions) {
16
+ this.#options = options;
17
+ }
18
+
19
+ get options() {
20
+ return this.#options;
21
+ }
22
+
23
+ set options(options: IFhirManagerRedisJsonOptions) {
24
+ this.#options = options;
25
+ }
26
+
27
+ async Start() {
28
+ const redisOptions: RedisOptions = {
29
+ showFriendlyErrorStack: true,
30
+ maxRetriesPerRequest: 20
31
+ }
32
+
33
+ this.#redis = new Redis(this.#options.redisUrl, redisOptions);
34
+ await this.#CreateIndex();
35
+ }
36
+
37
+ async Stop() {
38
+ if (this.#redis) {
39
+ this.#redis.quit();
40
+ this.#redis.disconnect();
41
+ }
42
+ }
43
+
44
+ #CreateIndex = async () => {
45
+ if (!this.#redis) {
46
+ return;
47
+ }
48
+
49
+ try {
50
+ //const retVal = await this.#redis.ft.dropIndex(this.#indexName);
51
+ const retVal = await this.#redis.call('FT.DROPINDEX', this.#indexName);
52
+
53
+ console.log(retVal);
54
+ } catch (error) {
55
+ console.log(chalk.red(error))
56
+ }
57
+
58
+ try {
59
+ const retVal = await this.#redis.call('FT.CREATE', this.#indexName, 'ON', 'HASH', 'PREFIX', '1', `${this.#options.resourceName}_`,
60
+ 'SCHEMA', 'id', 'TEXT', 'SORTABLE');
61
+ console.log(retVal);
62
+ } catch (error) {
63
+ console.log(chalk.red(error))
64
+ }
65
+ }
66
+
67
+ #SearchBy = async (id: string): Promise<any> => {
68
+ if (!this.#redis) {
69
+ return null;
70
+ }
71
+
72
+ const query = `@id:${this.#options.resourceName}_${id}*`;
73
+
74
+ const retVal: any = await this.#redis.call('FT.SEARCH', this.#indexName, query,
75
+ 'RETURN', '2', 'id', 'data', 'SORTBY', 'id', 'DESC', 'LIMIT', '0', '100');
76
+
77
+ return retVal;
78
+ }
79
+
80
+ GetResourceType(fhir: Partial<T>): string {
81
+ return `${this.#options.resourceName}_${(fhir as Partial<IDomainResource>).id}`;
82
+ }
83
+
84
+ async GetFhirResource(fhir: Partial<T>, ecb?: (error: Error) => void): Promise<T | null> {
85
+ if (this.#redis) {
86
+ const retValRaw = await this.#redis.hgetall(this.GetResourceType(fhir))
87
+ if (retValRaw) {
88
+ try {
89
+ const { id, data } = retValRaw;
90
+ return JSON.parse(data) as T;
91
+ } catch (error: unknown) {
92
+ if (ecb) {
93
+ ecb(error as Error);
94
+ }
95
+ return null;
96
+ }
97
+ } else {
98
+ return null;
99
+ }
100
+ } else {
101
+ return null;
102
+ }
103
+ }
104
+
105
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
106
+ async CreateFhirResource(fhir: T, ecb?: (error: Error) => void): Promise<T | null> {
107
+ if (this.#redis) {
108
+ const record = {
109
+ id: this.GetResourceType(fhir),
110
+ data: JSON.stringify(fhir)
111
+ } as any;
112
+
113
+ const retVal = await this.#redis.hmset(this.GetResourceType(fhir), record);
114
+
115
+ if (retVal) {
116
+ return fhir;
117
+ } else {
118
+ return null;
119
+ }
120
+ } else {
121
+ return null;
122
+ }
123
+ }
124
+
125
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
126
+ async UpdateFhirResource(fhir: T, ecb?: (error: Error) => void): Promise<T | null> {
127
+ if (this.#redis) {
128
+ const record = {
129
+ id: this.GetResourceType(fhir),
130
+ data: JSON.stringify(fhir)
131
+ } as any;
132
+
133
+ const retVal = await this.#redis.hmset(this.GetResourceType(fhir), record);
134
+
135
+ if (retVal) {
136
+ return fhir;
137
+ } else {
138
+ return null;
139
+ }
140
+ } else {
141
+ return null;
142
+ }
143
+ }
144
+
145
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
146
+ async DeleteFhirResource(fhir: Partial<T>, ecb?: (error: Error) => void): Promise<T | null> {
147
+ if (this.#redis) {
148
+ const deleteResource = await this.GetFhirResource(fhir);
149
+ if (deleteResource) {
150
+ const retVal = await this.#redis.del(this.GetResourceType(fhir));
151
+ if (retVal) {
152
+ return deleteResource;
153
+ } else {
154
+ return null;
155
+ }
156
+ } else {
157
+ return null;
158
+ }
159
+ } else {
160
+ return null;
161
+ }
162
+ }
163
+
164
+ async GetFhirResources(filters: string[], ecb?: (error: Error) => void): Promise<T[] | null> {
165
+ const promArray: Promise<T[]>[] = [ ];
166
+ filters.forEach(filter => {
167
+ const prom = async (): Promise<T[]> => {
168
+ const retValArray: T[] = [ ];
169
+ const retVal = await this.#SearchBy(filter);
170
+ // First index is the total number of records in the search (does not consider limit)
171
+ //const listLength = retVal[0];
172
+
173
+ let index = 1;
174
+ const obj: JSONObject = { };
175
+ for (;;) {
176
+ if (index >= retVal.length) {
177
+ break;
178
+ }
179
+ const id = retVal[index++];
180
+ obj[id] = { }
181
+ const values = retVal[index++];
182
+ let dataIndex = 0;
183
+ for (let j=0; j < values.length / 2; j++) {
184
+ const field = values[dataIndex++];
185
+ if ((field as string).localeCompare('data') === 0) {
186
+ const value = JSON.parse(values[dataIndex++]);
187
+ obj[id] = value;
188
+ } else {
189
+ dataIndex++;
190
+ }
191
+ }
192
+ retValArray.push(obj[id]);
193
+ }
194
+ return retValArray;
195
+ }
196
+ promArray.push(prom());
197
+ });
198
+
199
+ const promRetVal = await Promise.all(promArray);
200
+ let retVal: T[] = [ ];
201
+ promRetVal.forEach(prv => {
202
+ retVal = retVal.concat(prv);
203
+ });
204
+ return retVal;
205
+ }
206
+
207
+ async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
208
+ return null;
209
+ }
210
+
211
+ async UpdateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
212
+ return null
213
+ }
214
+
215
+ async DeleteFhirResources(fhir: Partial<T>[], ecb?: (error: Error) => void): Promise<T[] | null> {
216
+ return null;
217
+ }
218
+ }
@@ -9,6 +9,7 @@ import { JestSleep } from '@nsshunt/stsutils'
9
9
  import { TestHelpers } from './dalFhirTestHelpers'
10
10
 
11
11
  import { DALFhirManager } from './dalFhirManager'
12
+ import chalk from 'chalk'
12
13
 
13
14
  describe("Test hl7 fhir resource data access layer - PGRes", () =>
14
15
  {
@@ -37,6 +38,17 @@ describe("Test hl7 fhir resource data access layer - PGRes", () =>
37
38
  await testHelpers.TestFhirPerson(fhirManager.fhirDataAccessManager);
38
39
  }, 30000);
39
40
 
41
+ test('Testing Person', async () => {
42
+ const iterations = 10;
43
+ expect.assertions(iterations + 1);
44
+ await testHelpers.AddFhirPersons(fhirManager.fhirDataAccessManager, iterations);
45
+
46
+ const fhirResources = await fhirManager.fhirDataAccessManager.GetFhirResources(['']);
47
+ expect(fhirResources?.length).toEqual(iterations);
48
+
49
+ console.log(chalk.yellow(JSON.stringify(fhirResources)));
50
+ }, 30000);
51
+
40
52
  afterAll(async () =>
41
53
  {
42
54
  fhirManager.fhirDataAccessManager.Stop();
@@ -1,5 +1,5 @@
1
1
  /* eslint @typescript-eslint/no-unused-vars: 0 */ // --> OFF
2
- import { IDBAccessLayer, IDBResource } from '@nsshunt/stsdatamanagement'
2
+ import { IDBAccessLayer, IDBResource, IDBReturnData } from '@nsshunt/stsdatamanagement'
3
3
 
4
4
  import { IDomainResource, IDALFhirDataAccessManager, IFhirManagerPGResOptions } from './STSFhirTypes'
5
5
 
@@ -20,11 +20,11 @@ export class DALFhirManagerPGRes<T> implements IDALFhirDataAccessManager<T> {
20
20
  this.#options = options;
21
21
  }
22
22
 
23
- Start() {
23
+ async Start() {
24
24
 
25
25
  }
26
26
 
27
- Stop() {
27
+ async Stop() {
28
28
 
29
29
  }
30
30
 
@@ -115,11 +115,42 @@ export class DALFhirManagerPGRes<T> implements IDALFhirDataAccessManager<T> {
115
115
  }
116
116
  }
117
117
 
118
- async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
119
- return null;
118
+ async GetFhirResources(filters: string[], ecb?: (error: Error) => void): Promise<T[] | null> {
119
+ if (!this.#accessLayer) {
120
+ return null;
121
+ }
122
+
123
+ const promArray: Promise<T[]>[] = [ ];
124
+ filters.forEach(filter => {
125
+ const prom = async (): Promise<T[]> => {
126
+ const retVal: T[] = [ ];
127
+
128
+ const resources = await this.#accessLayer.GetResources<T>({
129
+ filters: {
130
+ filter: `${this.#options.resourceName}_${filter}%`,
131
+ limit: '20',
132
+ }
133
+ })
134
+
135
+ const dbResources = (resources.detail as IDBResource<T>[]);
136
+
137
+ dbResources.forEach(dbResource => {
138
+ retVal.push(dbResource.resdesc);
139
+ });
140
+
141
+ return retVal;
142
+ }
143
+ promArray.push(prom());
144
+ })
145
+ const promRetVal = await Promise.all(promArray);
146
+ let retVal: T[] = [ ];
147
+ promRetVal.forEach(prv => {
148
+ retVal = retVal.concat(prv);
149
+ });
150
+ return retVal;
120
151
  }
121
152
 
122
- async GetFhirResources(fhir: Partial<T>[], ecb?: (error: Error) => void): Promise<T[] | null> {
153
+ async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
123
154
  return null;
124
155
  }
125
156
 
@@ -10,6 +10,7 @@ import { TestHelpers } from './dalFhirTestHelpers'
10
10
  import { JestSleep } from '@nsshunt/stsutils'
11
11
 
12
12
  import { DALFhirManager } from './dalFhirManager'
13
+ import chalk from 'chalk'
13
14
 
14
15
  describe("Test hl7 fhir resource data access layer - PGResEntity", () =>
15
16
  {
@@ -39,6 +40,17 @@ describe("Test hl7 fhir resource data access layer - PGResEntity", () =>
39
40
  await testHelpers.TestFhirPerson(fhirManager.fhirDataAccessManager);
40
41
  }, 30000);
41
42
 
43
+ test('Testing Person', async () => {
44
+ const iterations = 10;
45
+ expect.assertions(iterations + 1);
46
+ await testHelpers.AddFhirPersons(fhirManager.fhirDataAccessManager, iterations);
47
+
48
+ const fhirResources = await fhirManager.fhirDataAccessManager.GetFhirResources(['']);
49
+ expect(fhirResources?.length).toEqual(iterations);
50
+
51
+ console.log(chalk.cyan(JSON.stringify(fhirResources)));
52
+ }, 30000);
53
+
42
54
  afterAll(async () =>
43
55
  {
44
56
  fhirManager.fhirDataAccessManager.Stop();
@@ -21,11 +21,11 @@ export class DALFhirManagerPGResEntity<T> implements IDALFhirDataAccessManager<T
21
21
  this.#options = options;
22
22
  }
23
23
 
24
- Start() {
24
+ async Start() {
25
25
 
26
26
  }
27
27
 
28
- Stop() {
28
+ async Stop() {
29
29
 
30
30
  }
31
31
 
@@ -146,11 +146,43 @@ export class DALFhirManagerPGResEntity<T> implements IDALFhirDataAccessManager<T
146
146
  }
147
147
  }
148
148
 
149
- async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
150
- return null;
149
+ async GetFhirResources(filters: string[], ecb?: (error: Error) => void): Promise<T[] | null> {
150
+ if (!this.#accessLayer) {
151
+ return null;
152
+ }
153
+
154
+ const fhirResource = await this.#GetSTSFhirBaseResource();
155
+ const promArray: Promise<T[]>[] = [ ];
156
+ filters.forEach(filter => {
157
+ const prom = async (): Promise<T[]> => {
158
+ const retVal: T[] = [ ];
159
+
160
+ const entities = await this.#accessLayer.GetEntities<T>({
161
+ filters: {
162
+ resname: fhirResource.resname,
163
+ filter: `${filter}%`
164
+ }
165
+ })
166
+
167
+ const dbResources = (entities.detail as IDBEntity<T>[]);
168
+
169
+ dbResources.forEach(dbResource => {
170
+ retVal.push(dbResource.entvalue);
171
+ });
172
+
173
+ return retVal;
174
+ }
175
+ promArray.push(prom());
176
+ })
177
+ const promRetVal = await Promise.all(promArray);
178
+ let retVal: T[] = [ ];
179
+ promRetVal.forEach(prv => {
180
+ retVal = retVal.concat(prv);
181
+ });
182
+ return retVal;
151
183
  }
152
184
 
153
- async GetFhirResources(fhir: Partial<T>[], ecb?: (error: Error) => void): Promise<T[] | null> {
185
+ async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
154
186
  return null;
155
187
  }
156
188
 
@@ -161,4 +193,22 @@ export class DALFhirManagerPGResEntity<T> implements IDALFhirDataAccessManager<T
161
193
  async DeleteFhirResources(fhir: Partial<T>[], ecb?: (error: Error) => void): Promise<T[] | null> {
162
194
  return null;
163
195
  }
196
+
197
+ /*
198
+
199
+ const resources = await accessLayer.GetResources<IUserResourceType>({
200
+ filters: {
201
+ filter: 'RESCP-%',
202
+ limit: '10',
203
+ }
204
+ })
205
+
206
+ const entities = await accessLayer.GetEntities<IUserEntity>({
207
+ filters: {
208
+ resname: 'user-t2',
209
+ filter: '%'
210
+ }
211
+ })
212
+ */
213
+
164
214
  }
@@ -8,6 +8,7 @@ import { TestHelpers } from './dalFhirTestHelpers'
8
8
  import { JestSleep } from '@nsshunt/stsutils'
9
9
 
10
10
  import { DALFhirManager } from './dalFhirManager'
11
+ import chalk from 'chalk'
11
12
 
12
13
  describe.skip("Test hl7 fhir resource data access layer - RedisJson", () =>
13
14
  {
@@ -28,7 +29,7 @@ describe.skip("Test hl7 fhir resource data access layer - RedisJson", () =>
28
29
  }
29
30
  });
30
31
 
31
- fhirManager.fhirDataAccessManager.Start();
32
+ await fhirManager.fhirDataAccessManager.Start();
32
33
  }, 30000);
33
34
 
34
35
  test('Testing Person', async () => {
@@ -36,9 +37,20 @@ describe.skip("Test hl7 fhir resource data access layer - RedisJson", () =>
36
37
  await testHelpers.TestFhirPerson(fhirManager.fhirDataAccessManager);
37
38
  }, 30000);
38
39
 
40
+ test('Testing Person', async () => {
41
+ const iterations = 10;
42
+ expect.assertions(iterations + 1);
43
+ await testHelpers.AddFhirPersons(fhirManager.fhirDataAccessManager, iterations);
44
+
45
+ const fhirResources = await fhirManager.fhirDataAccessManager.GetFhirResources(['']);
46
+ expect(fhirResources?.length).toEqual(iterations);
47
+
48
+ console.log(chalk.green(JSON.stringify(fhirResources)));
49
+ }, 30000);
50
+
39
51
  afterAll(async () =>
40
52
  {
41
- fhirManager.fhirDataAccessManager.Stop();
53
+ await fhirManager.fhirDataAccessManager.Stop();
42
54
  await JestSleep();
43
55
  await testHelpers.StopRedis();
44
56
  }, 5000);
@@ -1,11 +1,15 @@
1
1
  /* eslint @typescript-eslint/no-unused-vars: 0 */ // --> OFF
2
+ /* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
2
3
  import { IDomainResource, IDALFhirDataAccessManager, IFhirManagerRedisJsonOptions } from './STSFhirTypes'
3
4
 
4
- import { Redis, RedisOptions } from "ioredis";
5
+ import { SchemaFieldTypes, createClient, RedisClientType, AggregateSteps, AggregateGroupByReducers } from 'redis';
6
+
7
+ import chalk from 'chalk'
5
8
 
6
9
  export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T> {
7
10
  #options: IFhirManagerRedisJsonOptions;
8
- #redisSubscriber: Redis | null = null;
11
+ #redis: RedisClientType | null = null;
12
+ #indexName: string = 'idx:stsfhirresindex';
9
13
 
10
14
  constructor(options: IFhirManagerRedisJsonOptions) {
11
15
  this.#options = options;
@@ -19,19 +23,71 @@ export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T>
19
23
  this.#options = options;
20
24
  }
21
25
 
22
- Start() {
23
- const redisOptions: RedisOptions = {
24
- showFriendlyErrorStack: true,
25
- maxRetriesPerRequest: 20
26
+ #CreateIndex = async () => {
27
+ if (!this.#redis) {
28
+ return;
29
+ }
30
+
31
+ try {
32
+ const retVal = await this.#redis.ft.dropIndex(this.#indexName);
33
+ console.log(retVal);
34
+ } catch (error) {
35
+ console.log(chalk.red(error))
26
36
  }
37
+
38
+ try {
39
+ const retVal = await this.#redis.ft.create(this.#indexName, { // serviceIndexInstant
40
+ 'id': { type: SchemaFieldTypes.TEXT, SORTABLE: true }
41
+ }, {
42
+ ON: 'HASH',
43
+ PREFIX: `${this.#options.resourceName}_`
44
+ });
45
+ console.log(retVal);
46
+ } catch (error) {
47
+ console.log(chalk.red(error))
48
+ }
49
+ }
50
+
51
+ #SearchBy = async (id: string) => {
52
+ if (!this.#redis) {
53
+ return null;
54
+ }
55
+
56
+ const queryOptions = {
57
+ RETURN: [ 'id', 'data' ],
58
+ LIMIT: {
59
+ from: 0,
60
+ size: 100
61
+ },
62
+ SORTBY: {
63
+ BY: 'id',
64
+ DIRECTION: 'DESC'
65
+ }
66
+ } as any;
67
+
68
+ const query = `@id:${this.#options.resourceName}_${id}*`;
69
+
70
+ const retVal = await this.#redis.ft.search(this.#indexName, query, queryOptions);
27
71
 
28
- this.#redisSubscriber = new Redis(this.#options.redisUrl, redisOptions);
72
+ return retVal;
29
73
  }
30
74
 
31
- Stop() {
32
- if (this.#redisSubscriber) {
33
- this.#redisSubscriber.quit();
34
- this.#redisSubscriber.disconnect();
75
+ async Start() {
76
+ this.#redis = await createClient({url: this.#options.redisUrl})
77
+ .on('error', error => console.error(chalk.red(`Error connecting to redis. Error: [${error}]`)))
78
+ .connect() as any
79
+
80
+ if (this.#redis) {
81
+ await this.#CreateIndex();
82
+ } else {
83
+ console.error(chalk.red(`this.#redis instance not created.`))
84
+ }
85
+ }
86
+
87
+ async Stop() {
88
+ if (this.#redis) {
89
+ //await this.#redis.quit();
90
+ await this.#redis.disconnect();
35
91
  }
36
92
  }
37
93
 
@@ -40,11 +96,12 @@ export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T>
40
96
  }
41
97
 
42
98
  async GetFhirResource(fhir: Partial<T>, ecb?: (error: Error) => void): Promise<T | null> {
43
- if (this.#redisSubscriber) {
44
- const retValRaw = await this.#redisSubscriber?.get(this.GetResourceType(fhir))
99
+ if (this.#redis) {
100
+ const retValRaw = await this.#redis.HGETALL(this.GetResourceType(fhir))
45
101
  if (retValRaw) {
46
102
  try {
47
- return JSON.parse(retValRaw) as T;
103
+ const { id, data } = retValRaw;
104
+ return JSON.parse(data) as T;
48
105
  } catch (error: unknown) {
49
106
  if (ecb) {
50
107
  ecb(error as Error);
@@ -61,19 +118,43 @@ export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T>
61
118
 
62
119
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
63
120
  async CreateFhirResource(fhir: T, ecb?: (error: Error) => void): Promise<T | null> {
64
- const retVal = await this.#redisSubscriber?.set(this.GetResourceType(fhir), JSON.stringify(fhir));
65
- if (retVal) {
66
- return fhir;
121
+ if (this.#redis) {
122
+ const record = {
123
+ id: this.GetResourceType(fhir),
124
+ data: JSON.stringify(fhir)
125
+ } as any;
126
+
127
+ const keyValuePairs: any = Object.entries(record).flat();
128
+
129
+ const retVal = await this.#redis.HSET(this.GetResourceType(fhir), keyValuePairs);
130
+
131
+ if (retVal) {
132
+ return fhir;
133
+ } else {
134
+ return null;
135
+ }
67
136
  } else {
137
+ console.error(chalk.red(`this.#redis not defined.`))
68
138
  return null;
69
139
  }
70
140
  }
71
141
 
72
142
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
73
143
  async UpdateFhirResource(fhir: T, ecb?: (error: Error) => void): Promise<T | null> {
74
- const retVal = await this.#redisSubscriber?.set(this.GetResourceType(fhir), JSON.stringify(fhir));
75
- if (retVal) {
76
- return fhir;
144
+ if (this.#redis) {
145
+ const record = {
146
+ id: this.GetResourceType(fhir),
147
+ data: JSON.stringify(fhir)
148
+ } as any;
149
+
150
+ const keyValuePairs: any = Object.entries(record).flat();
151
+
152
+ const retVal = await this.#redis.HSET(this.GetResourceType(fhir), keyValuePairs);
153
+ if (retVal >= 0) {
154
+ return fhir;
155
+ } else {
156
+ return null;
157
+ }
77
158
  } else {
78
159
  return null;
79
160
  }
@@ -81,11 +162,15 @@ export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T>
81
162
 
82
163
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
83
164
  async DeleteFhirResource(fhir: Partial<T>, ecb?: (error: Error) => void): Promise<T | null> {
84
- const deleteResource = await this.GetFhirResource(fhir);
85
- if (deleteResource) {
86
- const retVal = await this.#redisSubscriber?.del(this.GetResourceType(fhir));
87
- if (retVal) {
88
- return deleteResource;
165
+ if (this.#redis) {
166
+ const deleteResource = await this.GetFhirResource(fhir);
167
+ if (deleteResource) {
168
+ const retVal = await this.#redis.del(this.GetResourceType(fhir));
169
+ if (retVal > 0) {
170
+ return deleteResource;
171
+ } else {
172
+ return null;
173
+ }
89
174
  } else {
90
175
  return null;
91
176
  }
@@ -94,11 +179,29 @@ export class DALFhirManagerRedisJson<T> implements IDALFhirDataAccessManager<T>
94
179
  }
95
180
  }
96
181
 
97
- async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
98
- return null;
182
+ async GetFhirResources(filters: string[], ecb?: (error: Error) => void): Promise<T[] | null> {
183
+ const promArray: Promise<T[]>[] = [ ];
184
+ filters.forEach(filter => {
185
+ const prom = async (): Promise<T[]> => {
186
+ const retValArray: T[] = [ ];
187
+ const retVal = await this.#SearchBy(filter);
188
+ retVal?.documents.forEach(doc => {
189
+ retValArray.push(JSON.parse(doc.value.data as string) as T);
190
+ })
191
+ return retValArray;
192
+ }
193
+ promArray.push(prom());
194
+ });
195
+
196
+ const promRetVal = await Promise.all(promArray);
197
+ let retVal: T[] = [ ];
198
+ promRetVal.forEach(prv => {
199
+ retVal = retVal.concat(prv);
200
+ });
201
+ return retVal;
99
202
  }
100
203
 
101
- async GetFhirResources(fhir: Partial<T>[], ecb?: (error: Error) => void): Promise<T[] | null> {
204
+ async CreateFhirResources(fhir: T[], ecb?: (error: Error) => void): Promise<T[] | null> {
102
205
  return null;
103
206
  }
104
207