@memberjunction/external-change-detection 1.7.1 → 1.8.1

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.
@@ -1,4 +1,5 @@
1
- import { BaseEngine, CompositeKey, EntityInfo, UserInfo } from "@memberjunction/core";
1
+ import { BaseEngine, BaseEntity, CompositeKey, EntityField, EntityInfo, Metadata, UserInfo } from "@memberjunction/core";
2
+ import { RecordChangeEntity, RecordChangeReplayRunEntity } from "@memberjunction/core-entities";
2
3
  /**
3
4
  * Represents a change to a single field in a record
4
5
  */
@@ -16,6 +17,12 @@ export declare class ChangeDetectionItem {
16
17
  Type: 'Create' | 'Update' | 'Delete';
17
18
  ChangedAt: Date;
18
19
  Changes: FieldChange[];
20
+ /**
21
+ * Populated for Create and Update types only. This is the latest version of the record from the organic database table
22
+ */
23
+ LatestRecord?: BaseEntity;
24
+ LegacyKey?: boolean;
25
+ LegacyKeyValue?: string;
19
26
  }
20
27
  /**
21
28
  * Result type for a change detection operation
@@ -32,9 +39,27 @@ export declare class ChangeDetectionResult {
32
39
  export declare class ExternalChangeDetectorEngine extends BaseEngine<ExternalChangeDetectorEngine> {
33
40
  Config(forceRefresh?: boolean, contextUser?: UserInfo): Promise<void>;
34
41
  static get Instance(): ExternalChangeDetectorEngine;
42
+ private _IneligibleEntities;
43
+ /**
44
+ * A list of entities that will automatically be excluded from all calls to this class. This array is used as a "safety"
45
+ * mechanism to prevent the system from trying to replay changes to these entities which wouldn't negatively affect system integrity
46
+ * but could cause performance issues. If you want to add/remove entities to this list, you can do so by manipulating this array.
47
+ *
48
+ * If you want to run Change Detection and/or replay changes for entities in this array, you will need to remove them
49
+ * in your code before calling the methods in this class. While executing methods on this class with these default
50
+ * ineligible entities will not cause any issues, they may take a long time to run and utilize a significant amount
51
+ * of resources.
52
+ */
53
+ get IneligibleEntities(): string[];
35
54
  private _EligibleEntities;
36
55
  /**
37
- * A list of the entities that are eligible for external change detection
56
+ * A list of the entities that are eligible for external change detection. This is determined by using the underlying
57
+ * database view vwEntitiesWithExternalChangeTracking which is a view that is maintained by the MJ system and is used to
58
+ * find a list of entities that have the required characteristics that support external change detection. These characteristics
59
+ * include:
60
+ * * The entity has the TrackRecordChanges property set to 1
61
+ * * The entity has the special UpdatedAt/CreatedAt fields (which are called __mj_UpdatedAt and __mj_CreatedAt in the database). These fields are AUTOMATICALLY added to an entity that has TrackRecordChanges set to 1 by the MJ CodeGen tool.
62
+ * * The entity is not in the IneligibleEntities list. See info on the IneligibleEntities property for more information on excluded entities.
38
63
  */
39
64
  get EligibleEntities(): EntityInfo[];
40
65
  /**
@@ -42,6 +67,30 @@ export declare class ExternalChangeDetectorEngine extends BaseEngine<ExternalCha
42
67
  * @param entity
43
68
  */
44
69
  DetectChangesForEntity(entity: EntityInfo): Promise<ChangeDetectionResult>;
70
+ /**
71
+ * This method compares a version of the record in question from the database with the last version we had in RecordChange table
72
+ * @param change
73
+ */
74
+ DetermineRecordChanges(md: Metadata, change: ChangeDetectionItem): Promise<{
75
+ changes: FieldChange[];
76
+ latestRecord: BaseEntity;
77
+ }>;
78
+ protected DoValuesDiffer(field: EntityField, value1: any, value2: any): {
79
+ differ: boolean;
80
+ castValue1: any;
81
+ castValue2: any;
82
+ };
83
+ protected GetLatestRecordChangesDataForEntityRecord(change: ChangeDetectionItem): Promise<any>;
84
+ protected GetLatestDatabaseRecord(md: Metadata, change: ChangeDetectionItem): Promise<BaseEntity>;
85
+ /**
86
+ * Get all of the latest database records together in grouped queries for each entity that has records we need instead
87
+ * of one at a time like GetLatestDatabaseRecord does. This method will return true/false and will place the LatestRecord
88
+ * into each item in the changes array for you.
89
+ * @param md
90
+ * @param changes
91
+ * @returns
92
+ */
93
+ protected GetLatestDatabaseRecords(md: Metadata, changes: ChangeDetectionItem[]): Promise<boolean>;
45
94
  protected getPrimaryKeyString(entity: EntityInfo, tablePrefix: string): string;
46
95
  protected generateDetectUpdatesQuery(entity: EntityInfo): string;
47
96
  protected generateDetectCreationsQuery(entity: EntityInfo): string;
@@ -51,6 +100,37 @@ export declare class ExternalChangeDetectorEngine extends BaseEngine<ExternalCha
51
100
  * @returns
52
101
  */
53
102
  DetectChangesForEntities(entities: EntityInfo[]): Promise<ChangeDetectionResult>;
103
+ /**
104
+ * This method will detect changes for all eligible entities as defined by the EligibleEntities property
105
+ */
54
106
  DetectChangesForAllEligibleEntities(): Promise<ChangeDetectionResult>;
107
+ /**
108
+ * This method will replay all of the items in the changes array
109
+ * @param changes Array of changes to replay.
110
+ * @param batchSize Optional, defines the # of concurrent changes to replay at once. If you want to replay changes serially, set this to 1
111
+ * @returns {Promise<boolean>} - Returns true if all changes are successfully replayed, otherwise false.
112
+ */
113
+ ReplayChanges(changes: ChangeDetectionItem[], batchSize?: number): Promise<boolean>;
114
+ /**
115
+ * Method creates a new Record Change Replay Run and returns the object for the run
116
+ */
117
+ protected StartRun(): Promise<RecordChangeReplayRunEntity>;
118
+ /**
119
+ * Replays a single change item within a given run. This method will:
120
+ * 1) Create a new Record Change record for the replay item
121
+ * 2) Load a BaseEntity derived class for the entity in question and call either Save() or Delete() and pass in the Replay Only option
122
+ * 3) Record the result in the Record Change record, updating status and if appropriate, the error message
123
+ * @param change
124
+ */
125
+ protected ReplaySingleChange(md: Metadata, run: RecordChangeReplayRunEntity, change: ChangeDetectionItem): Promise<boolean>;
126
+ /**
127
+ * This method will attempt to update the RecordChange record and return true if succesful, false otherwise.
128
+ */
129
+ protected FinishRecordChangeRecord(rc: RecordChangeEntity, code: 'error' | 'success', errorMessage: string): Promise<boolean>;
130
+ /**
131
+ * Creates a new record change record for the start of the replay process.
132
+ * @param change
133
+ */
134
+ protected CreateRecordChangeRecord(md: Metadata, run: RecordChangeReplayRunEntity, change: ChangeDetectionItem): Promise<RecordChangeEntity>;
55
135
  }
56
136
  //# sourceMappingURL=ChangeDetector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChangeDetector.d.ts","sourceRoot":"","sources":["../src/ChangeDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,YAAY,EAAE,UAAU,EAAsB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIpI;;GAEG;AACH,qBAAa,WAAW;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,YAAY,CAAC;IACzB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,qBAAa,qBAAqB;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CACzC;AAED;;;GAGG;AACH,qBAAa,4BAA6B,SAAQ,UAAU,CAAC,4BAA4B,CAAC;IACzE,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ;IAalE,WAAkB,QAAQ,IAAI,4BAA4B,CAEzD;IAED,OAAO,CAAC,iBAAiB,CAAe;IACxC;;OAEG;IACH,IAAW,gBAAgB,IAAI,UAAU,EAAE,CAE1C;IAED;;;OAGG;IACU,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAoFvF,SAAS,CAAC,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAM9E,SAAS,CAAC,0BAA0B,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAuBhE,SAAS,CAAC,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAelE,SAAS,CAAC,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAmBlE;;;OAGG;IACU,wBAAwB,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAwBhF,mCAAmC,IAAI,OAAO,CAAC,qBAAqB,CAAC;CAGrF"}
1
+ {"version":3,"file":"ChangeDetector.d.ts","sourceRoot":"","sources":["../src/ChangeDetector.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,9 @@ exports.FieldChange = FieldChange;
12
12
  * Represents a change to a single record in an entity
13
13
  */
14
14
  class ChangeDetectionItem {
15
+ constructor() {
16
+ this.LegacyKey = false; // if true, this means that the key was a single value and not a concatenated key
17
+ }
15
18
  }
16
19
  exports.ChangeDetectionItem = ChangeDetectionItem;
17
20
  /**
@@ -25,6 +28,10 @@ exports.ChangeDetectionResult = ChangeDetectionResult;
25
28
  * such as BaseEntity sub-classes as well as any custom logic that are tied to the system via Actions/AI Actions/etc...
26
29
  */
27
30
  class ExternalChangeDetectorEngine extends core_1.BaseEngine {
31
+ constructor() {
32
+ super(...arguments);
33
+ this._IneligibleEntities = []; // ['Entities', 'Entity Fields', 'Entity Field Values', 'Entity Relationships', 'Record Changes']; // default ineligible entities --- turned off for now
34
+ }
28
35
  async Config(forceRefresh, contextUser) {
29
36
  const provider = core_1.Metadata.Provider;
30
37
  const c = [
@@ -40,10 +47,30 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
40
47
  return super.getInstance();
41
48
  }
42
49
  /**
43
- * A list of the entities that are eligible for external change detection
50
+ * A list of entities that will automatically be excluded from all calls to this class. This array is used as a "safety"
51
+ * mechanism to prevent the system from trying to replay changes to these entities which wouldn't negatively affect system integrity
52
+ * but could cause performance issues. If you want to add/remove entities to this list, you can do so by manipulating this array.
53
+ *
54
+ * If you want to run Change Detection and/or replay changes for entities in this array, you will need to remove them
55
+ * in your code before calling the methods in this class. While executing methods on this class with these default
56
+ * ineligible entities will not cause any issues, they may take a long time to run and utilize a significant amount
57
+ * of resources.
58
+ */
59
+ get IneligibleEntities() {
60
+ return this._IneligibleEntities;
61
+ }
62
+ /**
63
+ * A list of the entities that are eligible for external change detection. This is determined by using the underlying
64
+ * database view vwEntitiesWithExternalChangeTracking which is a view that is maintained by the MJ system and is used to
65
+ * find a list of entities that have the required characteristics that support external change detection. These characteristics
66
+ * include:
67
+ * * The entity has the TrackRecordChanges property set to 1
68
+ * * The entity has the special UpdatedAt/CreatedAt fields (which are called __mj_UpdatedAt and __mj_CreatedAt in the database). These fields are AUTOMATICALLY added to an entity that has TrackRecordChanges set to 1 by the MJ CodeGen tool.
69
+ * * The entity is not in the IneligibleEntities list. See info on the IneligibleEntities property for more information on excluded entities.
44
70
  */
45
71
  get EligibleEntities() {
46
- return this._EligibleEntities;
72
+ const netEligible = this._EligibleEntities.filter(e => !this.IneligibleEntities.map(i => i.toLowerCase().trim()).includes(e.Name.toLowerCase().trim()));
73
+ return netEligible;
47
74
  }
48
75
  /**
49
76
  * Detects external changes for a single entity
@@ -51,6 +78,14 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
51
78
  */
52
79
  async DetectChangesForEntity(entity) {
53
80
  try {
81
+ // check to make sure that the entity is in the eligible list
82
+ if (!entity) {
83
+ throw new Error("entity parameter is required");
84
+ }
85
+ else if (!this.EligibleEntities.find(e => e.ID === entity.ID)) {
86
+ throw new Error(`Entity ${entity.Name} is not eligible for external change detection. Refer to the documentation on the EligibleEntities and IneligibleEntities properties for more information.`);
87
+ }
88
+ const md = new core_1.Metadata();
54
89
  const sqlCreates = this.generateDetectCreationsQuery(entity);
55
90
  const sqlUpdates = this.generateDetectUpdatesQuery(entity);
56
91
  const sqlDeletes = this.generateDetectDeletionsQuery(entity);
@@ -61,7 +96,7 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
61
96
  // we have the results for all of the queries, now we need to convert them into ChangeDetectionItems
62
97
  const changes = [];
63
98
  if (createResult && createResult.length > 0) {
64
- createResult.forEach(row => {
99
+ for (const row of createResult) {
65
100
  const item = new ChangeDetectionItem();
66
101
  item.Entity = entity;
67
102
  item.PrimaryKey = new core_1.CompositeKey(entity.PrimaryKeys.map(pk => {
@@ -71,13 +106,13 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
71
106
  };
72
107
  }));
73
108
  item.Type = 'Create';
74
- item.ChangedAt = row.CreatedAt;
75
- item.Changes = [];
109
+ item.ChangedAt = row.CreatedAt >= row.UpdatedAt ? row.CreatedAt : row.UpdatedAt;
110
+ item.Changes = []; // not relevant because the row is new
76
111
  changes.push(item);
77
- });
112
+ }
78
113
  }
79
114
  if (updateResult && updateResult.length > 0) {
80
- updateResult.forEach(row => {
115
+ for (const row of updateResult) {
81
116
  const item = new ChangeDetectionItem();
82
117
  item.Entity = entity;
83
118
  item.PrimaryKey = new core_1.CompositeKey(entity.PrimaryKeys.map(pk => {
@@ -88,30 +123,45 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
88
123
  }));
89
124
  item.Type = 'Update';
90
125
  item.ChangedAt = row.UpdatedAt;
91
- item.Changes = [];
92
126
  // push the item but first make sure it is NOT already in the changes from the
93
127
  // create detection, if it is, we do not push it into changes
94
128
  if (!changes.find(c => c.PrimaryKey.Equals(item.PrimaryKey))) {
95
129
  changes.push(item);
96
130
  }
97
- });
131
+ }
98
132
  }
99
133
  if (deleteResult && deleteResult.length > 0) {
100
134
  deleteResult.forEach(row => {
101
135
  const item = new ChangeDetectionItem();
102
136
  item.Entity = entity;
103
- item.PrimaryKey = new core_1.CompositeKey(entity.PrimaryKeys.map(pk => {
104
- return {
105
- FieldName: pk.Name,
106
- Value: row.RecordID
107
- };
108
- }));
137
+ const ck = new core_1.CompositeKey();
138
+ // row.RecordID should have a format of Field1|Value1||Field2|Value2, however in some cases there is legacy
139
+ // data in the RecordChange table that just has a single value in it and in that case assuming that the entity
140
+ // in question has a single-valued primary key, we can just use that value as the key, so we need to test for that
141
+ // first and if we find that the RecordID is just a single value, we can use that as the key
142
+ if (row.RecordID.indexOf(core_1.CompositeKey.DefaultValueDelimiter) === -1) {
143
+ // there is no field delimiter, so we can assume this is a single value
144
+ ck.LoadFromSingleKeyValuePair(entity.PrimaryKeys[0].Name, row.RecordID); // this is a string like 'Field1Value' (no quotes
145
+ item.LegacyKey = true;
146
+ item.LegacyKeyValue = row.RecordID;
147
+ }
148
+ else
149
+ ck.LoadFromConcatenatedString(row.RecordID); // this is a string like 'Field1Value|Field2Value' (no quotes)
150
+ item.PrimaryKey = ck;
109
151
  item.Type = 'Delete';
110
- item.ChangedAt = row.ChangeDate;
111
- item.Changes = [];
152
+ item.ChangedAt = row.ChangedAt;
153
+ item.Changes = []; // not relevant because the row is now deleted
112
154
  changes.push(item);
113
155
  });
114
156
  }
157
+ await this.GetLatestDatabaseRecords(md, changes); // load everything from the database in one step
158
+ // now we have latest records, go back through and update the Changes field for the UPDATE types
159
+ for (const c of changes) {
160
+ if (c.Type === 'Update') {
161
+ const changesResult = await this.DetermineRecordChanges(md, c);
162
+ c.Changes = changesResult.changes;
163
+ }
164
+ }
115
165
  return {
116
166
  Success: true,
117
167
  Changes: changes
@@ -126,41 +176,207 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
126
176
  };
127
177
  }
128
178
  }
179
+ /**
180
+ * This method compares a version of the record in question from the database with the last version we had in RecordChange table
181
+ * @param change
182
+ */
183
+ async DetermineRecordChanges(md, change) {
184
+ try {
185
+ // Step 1 - load the current record if needed, sometimes already loaded by here
186
+ const record = change.LatestRecord ? change.LatestRecord : await this.GetLatestDatabaseRecord(md, change);
187
+ if (record) {
188
+ // now we have the version from the database that has been updated from an external source
189
+ // then we need to get the latest version from the vwRecordChanges table that matches this entity and RecordID
190
+ const result = await this.GetLatestRecordChangesDataForEntityRecord(change);
191
+ if (result && result.FullRecordJSON && result.FullRecordJSON.length > 0) {
192
+ // we have our row, so get the JSON, parse it and we'll have the differences
193
+ const json = JSON.parse(result.FullRecordJSON);
194
+ // now go through each field in the record object and compare it with the json
195
+ const changes = [];
196
+ for (const field of record.Fields) {
197
+ if (!field.IsPrimaryKey) {
198
+ const differResult = this.DoValuesDiffer(field, field.Value, json[field.Name]);
199
+ if (differResult.differ) {
200
+ changes.push({
201
+ FieldName: field.Name,
202
+ NewValue: differResult.castValue1, // use the typecast values so they're the right types
203
+ OldValue: differResult.castValue2 // use the typecast values so they're the right types
204
+ });
205
+ }
206
+ }
207
+ }
208
+ return { changes, latestRecord: record };
209
+ }
210
+ else {
211
+ (0, core_1.LogStatus)(` WARNING: No record found, or no FullRecordJSON found, in vwRecordChanges for ${change.Entity.Name}: ${change.PrimaryKey.ToConcatenatedString()}`);
212
+ return { changes: [], latestRecord: record };
213
+ }
214
+ }
215
+ else
216
+ throw new Error(`Failed to load record: ${change.Entity.Name}: ${change.PrimaryKey}`);
217
+ }
218
+ catch (e) {
219
+ (0, core_1.LogError)(e);
220
+ return { changes: [], latestRecord: null };
221
+ }
222
+ }
223
+ DoValuesDiffer(field, value1, value2) {
224
+ // type specific comparisons
225
+ // for each scenario, make sure both value1 and value 2 are of the type we care about, if they're not, create new variables
226
+ // of those types and then do type specific comparisons for equality
227
+ switch (field.EntityFieldInfo.TSType) {
228
+ case core_1.EntityFieldTSType.Boolean:
229
+ // check to see if value1 and value2 are both boolean, if not, convert them to boolean
230
+ const v1 = typeof value1 === 'boolean' ? value1 : value1 === 'true' ? true : false;
231
+ const v2 = typeof value2 === 'boolean' ? value2 : value2 === 'true' ? true : false;
232
+ return { differ: v1 !== v2, castValue1: v1, castValue2: v2 };
233
+ case core_1.EntityFieldTSType.Date:
234
+ // check to see if value1 and value2 are both dates, if not, convert them to dates
235
+ const d1 = value1 instanceof Date ? value1 : new Date(value1);
236
+ const d2 = value2 instanceof Date ? value2 : new Date(value2);
237
+ return { differ: d1.getTime() !== d2.getTime(), castValue1: d1, castValue2: d2 };
238
+ case core_1.EntityFieldTSType.Number:
239
+ // check to see if value1 and value2 are both numbers, if not, convert them to numbers
240
+ const n1 = value1 ? typeof value1 === 'number' ? value1 : parseFloat(value1) : value1;
241
+ const n2 = value2 ? typeof value2 === 'number' ? value2 : parseFloat(value2) : value2;
242
+ return { differ: n1 !== n2, castValue1: n1, castValue2: n2 };
243
+ case core_1.EntityFieldTSType.String:
244
+ // check to see if value1 and value2 are both strings, if not, convert them to strings
245
+ const s1 = typeof value1 === 'string' || !value1 ? value1 : value1.toString();
246
+ const s2 = typeof value2 === 'string' || !value2 ? value2 : value2.toString();
247
+ return { differ: s1 !== s2, castValue1: s1, castValue2: s2 };
248
+ default:
249
+ // don't know the type, shouldn't get here, just do a basic TypeScript equality check
250
+ // with a single != instead of !== because we don't want to check type just value
251
+ return { differ: value1 != value2, castValue1: value1, castValue2: value2 };
252
+ }
253
+ }
254
+ async GetLatestRecordChangesDataForEntityRecord(change) {
255
+ const Provider = core_1.Metadata.Provider;
256
+ const sql = `SELECT
257
+ TOP 1 FullRecordJSON
258
+ FROM
259
+ ${Provider.MJCoreSchemaName}.vwRecordChanges
260
+ WHERE
261
+ RecordID = '${change.PrimaryKey.ToConcatenatedString()}'
262
+ AND EntityID = ${change.Entity.ID}
263
+ AND Status <> 'Pending'
264
+ ORDER BY
265
+ ChangedAt DESC`;
266
+ const result = await Provider.ExecuteSQL(sql);
267
+ if (result && result.length > 0)
268
+ return result[0];
269
+ else
270
+ return null;
271
+ }
272
+ async GetLatestDatabaseRecord(md, change) {
273
+ const record = await md.GetEntityObject(change.Entity.Name, this.ContextUser);
274
+ if (await record.InnerLoad(change.PrimaryKey)) {
275
+ return record;
276
+ }
277
+ else
278
+ throw new Error(`Failed to load record: ${change.Entity.Name}: ${change.PrimaryKey}`);
279
+ }
280
+ /**
281
+ * Get all of the latest database records together in grouped queries for each entity that has records we need instead
282
+ * of one at a time like GetLatestDatabaseRecord does. This method will return true/false and will place the LatestRecord
283
+ * into each item in the changes array for you.
284
+ * @param md
285
+ * @param changes
286
+ * @returns
287
+ */
288
+ async GetLatestDatabaseRecords(md, changes) {
289
+ try {
290
+ // Step 1 - group by entity and get a complete list of entities from the changes
291
+ const entities = [];
292
+ const provider = core_1.Metadata.Provider;
293
+ for (const c of changes) {
294
+ let e = entities.find(e => e.entity.ID === c.Entity.ID);
295
+ if (!e) {
296
+ e = {
297
+ entity: c.Entity,
298
+ keys: [c.PrimaryKey]
299
+ };
300
+ entities.push(e);
301
+ }
302
+ else {
303
+ e.keys.push(c.PrimaryKey);
304
+ }
305
+ }
306
+ // now we have a distinct list of entities and all of the pkeys for each one, so we can run a single
307
+ // select statement for each entity
308
+ for (const e of entities) {
309
+ const sql = `SELECT * FROM [${e.entity.SchemaName}].[${e.entity.BaseView}]
310
+ WHERE ${e.keys.map(k => `(${k.KeyValuePairs.map(kvp => {
311
+ const f = e.entity.Fields.find(f => kvp.FieldName.trim().toLowerCase() === f.Name);
312
+ const quotes = f?.NeedsQuotes ? "'" : "";
313
+ return `[${kvp.FieldName}]=${quotes}${kvp.Value}${quotes}`;
314
+ }).join(' AND ')})`).join(' OR ')} `;
315
+ const result = await provider.ExecuteSQL(sql);
316
+ if (result) {
317
+ // we have the rows from the result, now go back through each of the changes we have in the changes array
318
+ // and associate the data with each one
319
+ for (const r of result) {
320
+ const kvp = e.entity.PrimaryKeys.map(pk => {
321
+ return {
322
+ FieldName: pk.Name,
323
+ Value: r[pk.Name]
324
+ };
325
+ });
326
+ const changeItem = changes.find(ci => ci.Entity === e.entity && ci.PrimaryKey.EqualsKey(kvp));
327
+ if (changeItem) {
328
+ // found the match, update latest Record
329
+ const record = await md.GetEntityObject(changeItem.Entity.Name, this.ContextUser);
330
+ record.LoadFromData(r);
331
+ changeItem.LatestRecord = record;
332
+ }
333
+ }
334
+ }
335
+ }
336
+ return true;
337
+ }
338
+ catch (e) {
339
+ (0, core_1.LogError)(e);
340
+ return false;
341
+ }
342
+ }
129
343
  getPrimaryKeyString(entity, tablePrefix) {
130
- return entity.PrimaryKeys.length === 1 ?
131
- `${tablePrefix}.${entity.PrimaryKeys[0].Name}` :
132
- entity.PrimaryKeys.map(pk => `'${pk.Name}|' + CAST(${tablePrefix}.[${pk.Name}] AS NVARCHAR(MAX))`).join(` + '||' + `);
344
+ return entity.PrimaryKeys.map(pk => `'${pk.Name}${core_1.CompositeKey.DefaultValueDelimiter}' + CAST(${tablePrefix}.[${pk.Name}] AS NVARCHAR(MAX))`).join(` + '${core_1.CompositeKey.DefaultFieldDelimiter}' + `);
133
345
  }
134
346
  generateDetectUpdatesQuery(entity) {
135
347
  const primaryKeyString = this.getPrimaryKeyString(entity, 'ot');
136
348
  return `
137
349
  SELECT
138
- ${entity.PrimaryKeys.map(pk => `ot.[${pk.Name}]`).join(', ')}, ot.UpdatedAt
350
+ ${entity.PrimaryKeys.map(pk => `ot.[${pk.Name}]`).join(', ')}, ot.${core_1.EntityInfo.UpdatedAtFieldName} AS UpdatedAt, rc.last_change_time LatestRecordChangeAt
139
351
  FROM
140
352
  [${entity.SchemaName}].[${entity.BaseView}] ot
141
- LEFT JOIN (
353
+ INNER JOIN (
142
354
  SELECT
143
355
  RecordID, MAX(ChangedAt) AS last_change_time
144
356
  FROM
145
357
  __mj.vwRecordChanges
146
358
  WHERE
147
- Type IN ('Update', 'Create')
359
+ Type IN ('Update', 'Create') AND EntityID = ${entity.ID}
148
360
  GROUP BY
149
361
  RecordID
150
362
  ) rc ON ${primaryKeyString} = rc.RecordID
151
363
  WHERE
152
- ot.UpdatedAt > COALESCE(rc.last_change_time, '1900-01-01');
153
- `;
364
+ FORMAT(ot.${core_1.EntityInfo.UpdatedAtFieldName}, 'yyyy-MM-dd HH:mm:ss.fff') > COALESCE(FORMAT(rc.last_change_time, 'yyyy-MM-dd HH:mm:ss.fff'), '1900-01-01 00:00:00.000');`;
365
+ // use up to 3 digits of precision because when we get the values back into JavaScript objects, Date objects only have 3 digits of precision
154
366
  }
155
367
  generateDetectCreationsQuery(entity) {
156
368
  const primaryKeyString = this.getPrimaryKeyString(entity, 'ot');
157
369
  return `
158
370
  SELECT
159
- ${entity.PrimaryKeys.map(pk => `ot.[${pk.Name}]`).join(', ')}, ot.CreatedAt
371
+ ${entity.PrimaryKeys.map(pk => `ot.[${pk.Name}]`).join(', ')}, ot.${core_1.EntityInfo.CreatedAtFieldName} AS CreatedAt, ot.${core_1.EntityInfo.UpdatedAtFieldName} AS UpdatedAt
160
372
  FROM
161
373
  [${entity.SchemaName}].[${entity.BaseView}] ot
162
374
  LEFT JOIN
163
- __mj.vwRecordChanges rc ON ${primaryKeyString} = rc.RecordID AND rc.Type = 'Create'
375
+ __mj.vwRecordChanges rc
376
+ ON
377
+ (${primaryKeyString} = rc.RecordID) AND
378
+ rc.Type = 'Create' AND
379
+ rc.EntityID = ${entity.ID}
164
380
  WHERE
165
381
  rc.RecordID IS NULL;
166
382
  `;
@@ -169,16 +385,26 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
169
385
  const primaryKeyString = this.getPrimaryKeyString(entity, 'ot');
170
386
  return `
171
387
  SELECT
172
- rc.RecordID, rc.ChangedAt
388
+ rc.RecordID, MAX(rc.ChangedAt) ChangedAt
173
389
  FROM
174
390
  __mj.vwRecordChanges rc
175
391
  LEFT JOIN
176
- [${entity.SchemaName}].[${entity.BaseView}] ot ON ${primaryKeyString} = rc.RecordID
392
+ [${entity.SchemaName}].[${entity.BaseView}] ot
393
+ ON
394
+ rc.RecordID = ${primaryKeyString}
177
395
  WHERE
178
396
  ${entity.PrimaryKeys.map(pk => `ot.[${pk.Name}] IS NULL`).join(' AND ')}
179
- AND
180
- rc.Type IN ('Create', 'Update');
181
- `;
397
+ AND
398
+ rc.EntityID = ${entity.ID}
399
+ AND
400
+ NOT EXISTS
401
+ (
402
+ SELECT rc2.ID FROM __mj.vwRecordChanges rc2 WHERE
403
+ rc2.RecordID = rc.RecordID AND rc2.EntityID=rc.EntityID AND rc2.Type='Delete'
404
+ )
405
+ GROUP BY
406
+ rc.RecordID
407
+ `; // last part of above query makes sure we don't include records already deleted in Record Changes
182
408
  }
183
409
  /**
184
410
  * Detects changes across all of the entities specified
@@ -186,14 +412,30 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
186
412
  */
187
413
  async DetectChangesForEntities(entities) {
188
414
  try {
415
+ if (!entities)
416
+ throw new Error("entities parameter is required");
417
+ else if (entities.length === 0)
418
+ throw new Error("entities parameter must have at least one entity in it");
189
419
  const result = new ChangeDetectionResult();
190
420
  result.Success = true;
191
421
  result.Changes = [];
192
- for (const entity of entities) {
193
- const entityResult = await this.DetectChangesForEntity(entity);
194
- result.Changes = result.Changes.concat(entityResult.Changes);
195
- result.Success = result.Success && entityResult.Success;
196
- }
422
+ const promises = [];
423
+ // fire them all off in parallel
424
+ (0, core_1.LogStatus)(`Detecting changes for ${entities.length} entities`);
425
+ let numFinished = 0;
426
+ entities.forEach((e) => {
427
+ (0, core_1.UpdateCurrentConsoleLine)(` Starting change detection changes for ${e.Name}`, core_1.ConsoleColor.gray);
428
+ const p = this.DetectChangesForEntity(e); // no await
429
+ promises.push(p);
430
+ p.then(entityResult => {
431
+ (0, core_1.UpdateCurrentConsoleProgress)(` Finished change detection changes for ${e.Name}`, ++numFinished, entities.length, entityResult.Success ? core_1.ConsoleColor.cyan : core_1.ConsoleColor.crimson);
432
+ result.Changes = result.Changes.concat(entityResult.Changes);
433
+ result.Success = result.Success && entityResult.Success;
434
+ });
435
+ });
436
+ // now wait for all of the promises to finish
437
+ await Promise.all(promises);
438
+ (0, core_1.UpdateCurrentConsoleProgress)(` Finished detecting changes for ${entities.length} entities`, entities.length, entities.length, result.Success ? core_1.ConsoleColor.green : core_1.ConsoleColor.red);
197
439
  return result;
198
440
  }
199
441
  catch (e) {
@@ -205,9 +447,239 @@ class ExternalChangeDetectorEngine extends core_1.BaseEngine {
205
447
  };
206
448
  }
207
449
  }
450
+ /**
451
+ * This method will detect changes for all eligible entities as defined by the EligibleEntities property
452
+ */
208
453
  async DetectChangesForAllEligibleEntities() {
209
454
  return await this.DetectChangesForEntities(this.EligibleEntities);
210
455
  }
456
+ /**
457
+ * This method will replay all of the items in the changes array
458
+ * @param changes Array of changes to replay.
459
+ * @param batchSize Optional, defines the # of concurrent changes to replay at once. If you want to replay changes serially, set this to 1
460
+ * @returns {Promise<boolean>} - Returns true if all changes are successfully replayed, otherwise false.
461
+ */
462
+ async ReplayChanges(changes, batchSize = 20) {
463
+ let run; // delcare outside of try block so we have access to it in the catch block
464
+ try {
465
+ if (changes && changes.length > 0) {
466
+ const md = new core_1.Metadata();
467
+ const results = [];
468
+ run = await this.StartRun();
469
+ (0, core_1.LogStatus)(`Replaying ${changes.length} changes`);
470
+ let numProcessed = 0;
471
+ for (let i = 0; i < changes.length; i += batchSize) {
472
+ const batch = changes.slice(i, i + batchSize);
473
+ // Process the current batch
474
+ const batchPromises = batch.map(async (change) => {
475
+ (0, core_1.UpdateCurrentConsoleProgress)(` Replaying ${change.Entity.Name} ${change.Type} ${change.PrimaryKey.ToConcatenatedString()}`, ++numProcessed, changes.length, core_1.ConsoleColor.gray);
476
+ const result = await this.ReplaySingleChange(md, run, change);
477
+ return { Success: result, change: change };
478
+ });
479
+ // Wait for all promises in the current batch to complete
480
+ const batchResults = await Promise.all(batchPromises);
481
+ results.push(...batchResults);
482
+ }
483
+ // for (const change of changes) {
484
+ // UpdateCurrentConsoleProgress(` Replaying ${change.Entity.Name} ${change.Type} ${change.PrimaryKey.ToConcatenatedString()}`, changes.indexOf(change), changes.length, ConsoleColor.gray);
485
+ // const result = await this.ReplaySingleChange(md, run, change);
486
+ // results.push({Success: result, change: change});
487
+ // }
488
+ run.EndedAt = new Date();
489
+ run.Status = results.every(r => r.Success) ? 'Complete' : 'Error';
490
+ if (await run.Save()) {
491
+ return results.every(r => r.Success);
492
+ }
493
+ else {
494
+ throw new Error("Failed to save run");
495
+ }
496
+ }
497
+ else
498
+ return true; // no changes to process
499
+ }
500
+ catch (e) {
501
+ (0, core_1.LogError)(e);
502
+ if (run) {
503
+ // attempt to mark the run as error
504
+ try {
505
+ run.Status = 'Error';
506
+ run.EndedAt = new Date();
507
+ await run.Save(); // dont' care about return value here, we've already tried to save it and the return value will be false anyway and message is the original root cause of the first exception
508
+ }
509
+ catch (innerError) {
510
+ (0, core_1.LogError)('Attempted to mark run as error failed, make sure you update the database for future runs to be allowed.');
511
+ (0, core_1.LogError)(innerError);
512
+ return false; // couldn't get it done
513
+ }
514
+ }
515
+ return false;
516
+ }
517
+ }
518
+ /**
519
+ * Method creates a new Record Change Replay Run and returns the object for the run
520
+ */
521
+ async StartRun() {
522
+ // first make sure an existing run isn't in progress
523
+ const rv = new core_1.RunView();
524
+ const existingRun = await rv.RunView({
525
+ EntityName: "Record Change Replay Runs",
526
+ ExtraFilter: "Status NOT IN('Complete', 'Error')"
527
+ }, this.ContextUser);
528
+ if (existingRun && existingRun.Success) {
529
+ if (existingRun.Results.length > 0)
530
+ throw new Error(`Existing Record Change Replay Run ${existingRun.Results[0].ID} is not complete or marked as error, cannot start a new run.`);
531
+ else {
532
+ const md = new core_1.Metadata();
533
+ const run = await md.GetEntityObject("Record Change Replay Runs", this.ContextUser);
534
+ run.StartedAt = new Date();
535
+ run.UserID = this.ContextUser.ID;
536
+ run.Status = 'In Progress';
537
+ if (await run.Save()) {
538
+ return run;
539
+ }
540
+ else
541
+ throw new Error("Failed to start run");
542
+ }
543
+ }
544
+ else {
545
+ // failed to run the view
546
+ throw new Error("Failed to check for existing run: " + existingRun.ErrorMessage);
547
+ }
548
+ }
549
+ /**
550
+ * Replays a single change item within a given run. This method will:
551
+ * 1) Create a new Record Change record for the replay item
552
+ * 2) Load a BaseEntity derived class for the entity in question and call either Save() or Delete() and pass in the Replay Only option
553
+ * 3) Record the result in the Record Change record, updating status and if appropriate, the error message
554
+ * @param change
555
+ */
556
+ async ReplaySingleChange(md, run, change) {
557
+ try {
558
+ const rc = await this.CreateRecordChangeRecord(md, run, change);
559
+ if (rc) {
560
+ // step 2 - get the base entity for the change
561
+ let entityObject = change.LatestRecord; // for updates and creates we already have this
562
+ if (!entityObject) {
563
+ // for deletes we don't have this yet - it is not the normal load from DB since it wont be in the database at all
564
+ entityObject = await md.GetEntityObject(change.Entity.Name, this.ContextUser);
565
+ const latestRCData = await this.GetLatestRecordChangesDataForEntityRecord(change);
566
+ if (latestRCData && latestRCData.FullRecordJSON?.length > 0) {
567
+ const obj = JSON.parse(latestRCData.FullRecordJSON);
568
+ entityObject.LoadFromData(obj); // loaded up from the latest data in the Record Change table
569
+ }
570
+ else {
571
+ // we have an issue becuase we don't have data in the RecordChange table so we can't replay the DELETE, so mark that in the error for the RecordChange
572
+ return this.FinishRecordChangeRecord(rc, 'error', 'No prior record data is available in the Record Changes entity, so it is not possible to replay the Delete');
573
+ }
574
+ }
575
+ // if we get here, entityObject is now all set to go for replay!
576
+ if (change.Type === 'Delete') {
577
+ const result = await entityObject.Delete({
578
+ ReplayOnly: true
579
+ });
580
+ return this.FinishRecordChangeRecord(rc, result ? 'success' : 'error', entityObject.LatestResult?.Error);
581
+ }
582
+ else {
583
+ // for updates and creates we just call Save() with the ReplayOnly option
584
+ const result = await entityObject.Save({
585
+ ReplayOnly: true,
586
+ IgnoreDirtyState: false //not relevant for replay
587
+ });
588
+ return this.FinishRecordChangeRecord(rc, result ? 'success' : 'error', entityObject.LatestResult?.Error);
589
+ }
590
+ }
591
+ else {
592
+ throw new Error("Failed to create Record Change record");
593
+ }
594
+ }
595
+ catch (e) {
596
+ (0, core_1.LogError)(e);
597
+ return false;
598
+ }
599
+ }
600
+ /**
601
+ * This method will attempt to update the RecordChange record and return true if succesful, false otherwise.
602
+ */
603
+ async FinishRecordChangeRecord(rc, code, errorMessage) {
604
+ try {
605
+ rc.Status = code === 'error' ? 'Error' : 'Complete';
606
+ rc.ErrorLog = errorMessage;
607
+ if (await rc.Save())
608
+ return true;
609
+ else
610
+ return false;
611
+ }
612
+ catch (e) {
613
+ (0, core_1.LogError)(e);
614
+ return false;
615
+ }
616
+ }
617
+ /**
618
+ * Creates a new record change record for the start of the replay process.
619
+ * @param change
620
+ */
621
+ async CreateRecordChangeRecord(md, run, change) {
622
+ try {
623
+ const rc = await md.GetEntityObject("Record Changes", this.ContextUser);
624
+ rc.EntityID = change.Entity.ID;
625
+ if (change.LegacyKey)
626
+ rc.RecordID = change.LegacyKeyValue; // need to match legacy key otherwise the other RC records will keep coming back up in detect changes runs in the future
627
+ else
628
+ rc.RecordID = change.PrimaryKey.ToConcatenatedString();
629
+ rc.Source = 'External';
630
+ rc.Type = change.Type;
631
+ rc.Status = 'Pending';
632
+ if (change.ChangedAt)
633
+ rc.ChangedAt = change.ChangedAt;
634
+ else {
635
+ // we don't have a ChangedAt from the database, so we need to use the current date
636
+ // however, we want UTC date/time for now as that is what we use in the DB for all of
637
+ // these fields.
638
+ const d = new Date();
639
+ rc.ChangedAt = new Date(d.toISOString());
640
+ }
641
+ const changesObject = {};
642
+ for (const field of change.Changes) {
643
+ changesObject[field.FieldName] = {
644
+ field: field.FieldName,
645
+ oldValue: field.OldValue,
646
+ newValue: field.NewValue
647
+ };
648
+ }
649
+ if (change.Type === 'Update')
650
+ rc.ChangesJSON = JSON.stringify(changesObject);
651
+ else
652
+ rc.ChangesJSON = ''; // not null
653
+ if (change.Type !== 'Delete') {
654
+ const obj = change.LatestRecord?.GetAll();
655
+ if (obj)
656
+ rc.FullRecordJSON = JSON.stringify(obj);
657
+ else
658
+ rc.FullRecordJSON = ''; // null not allowed
659
+ }
660
+ else
661
+ rc.FullRecordJSON = ''; // null not allowed
662
+ const provider = core_1.Metadata.Provider;
663
+ if (change.Type === 'Update')
664
+ rc.ChangesDescription = provider.CreateUserDescriptionOfChanges(changesObject);
665
+ else if (change.Type === 'Create')
666
+ rc.ChangesDescription = 'New Record';
667
+ else
668
+ rc.ChangesDescription = 'Record Deleted';
669
+ rc.ReplayRunID = run.ID;
670
+ rc.UserID = this.ContextUser.ID;
671
+ if (await rc.Save()) {
672
+ return rc;
673
+ }
674
+ else {
675
+ throw new Error("Failed to save Record Change record: " + rc.LatestResult?.Message);
676
+ }
677
+ }
678
+ catch (e) {
679
+ (0, core_1.LogError)(e);
680
+ return null;
681
+ }
682
+ }
211
683
  }
212
684
  exports.ExternalChangeDetectorEngine = ExternalChangeDetectorEngine;
213
685
  //# sourceMappingURL=ChangeDetector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChangeDetector.js","sourceRoot":"","sources":["../src/ChangeDetector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChangeDetector.js","sourceRoot":"","sources":["../src/ChangeDetector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/external-change-detection",
3
- "version": "1.7.1",
3
+ "version": "1.8.1",
4
4
  "description": "Library used by server side applications to determine if changes have been made to entities by external systems/integrations",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,9 +19,9 @@
19
19
  "typescript": "^5.4.5"
20
20
  },
21
21
  "dependencies": {
22
- "@memberjunction/core": "1.7.1",
23
- "@memberjunction/core-entities": "1.7.1",
24
- "@memberjunction/global": "1.7.1",
25
- "@memberjunction/sqlserver-dataprovider": "1.7.1"
22
+ "@memberjunction/core": "1.8.1",
23
+ "@memberjunction/core-entities": "1.8.1",
24
+ "@memberjunction/global": "1.8.1",
25
+ "@memberjunction/sqlserver-dataprovider": "1.8.1"
26
26
  }
27
27
  }