meadow-endpoints 3.0.7 → 4.0.3
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.
- package/Dockerfile_LUXURYCode +1 -1
- package/README.md +48 -14
- package/debug/Animal.json +62 -0
- package/debug/Harness-Configuration.json +31 -0
- package/debug/Harness.js +7 -108
- package/debug/KillHarness.sh +10 -0
- package/dist/meadowendpoints.js +4402 -0
- package/dist/meadowendpoints.min.js +92 -0
- package/dist/meadowendpoints.min.js.map +1 -0
- package/gulpfile.js +83 -0
- package/package.json +27 -15
- package/source/Controller/Meadow-Endpoints-Controller-Base.js +161 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-BehaviorInjection.js +125 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Error-StatusCodes.txt +189 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Error.js +118 -0
- package/source/Controller/components/Meadow-Endpoints-Controller-Log.js +103 -0
- package/source/Controller/utility/Meadow-Endpoints-Filter-Parser.js +225 -0
- package/source/Controller/utility/Meadow-Endpoints-Session-Marshaler.js +48 -0
- package/source/Controller/utility/Meadow-Endpoints-Stream-RecordArray.js +66 -0
- package/source/Meadow-Endpoints-Browser-Shim.js +14 -0
- package/source/Meadow-Endpoints.js +176 -565
- package/source/endpoints/count/Meadow-Endpoint-Count.js +49 -0
- package/source/endpoints/count/Meadow-Endpoint-CountBy.js +40 -0
- package/source/endpoints/create/Meadow-Endpoint-BulkCreate.js +53 -0
- package/source/endpoints/create/Meadow-Endpoint-Create.js +58 -0
- package/source/endpoints/create/Meadow-Operation-Create.js +83 -0
- package/source/endpoints/delete/Meadow-Endpoint-Delete.js +93 -0
- package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +108 -0
- package/source/endpoints/read/Meadow-Endpoint-Read.js +72 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +92 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +85 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadMax.js +55 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +89 -0
- package/source/endpoints/read/Meadow-Endpoint-Reads.js +75 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadsBy.js +100 -0
- package/source/{crud → endpoints/read}/Meadow-Marshal-DistinctList.js +4 -13
- package/source/{crud → endpoints/read}/Meadow-Marshal-LiteList.js +5 -14
- package/source/endpoints/schema/Meadow-Endpoint-New.js +36 -0
- package/source/endpoints/schema/Meadow-Endpoint-Schema.js +36 -0
- package/source/endpoints/schema/Meadow-Endpoint-Validate.js +41 -0
- package/source/endpoints/update/Meadow-Endpoint-BulkUpdate.js +50 -0
- package/source/endpoints/update/Meadow-Endpoint-Update.js +58 -0
- package/source/endpoints/update/Meadow-Operation-Update.js +115 -0
- package/source/endpoints/upsert/Meadow-Endpoint-BulkUpsert.js +53 -0
- package/source/endpoints/upsert/Meadow-Endpoint-Upsert.js +58 -0
- package/source/endpoints/upsert/Meadow-Operation-Upsert.js +132 -0
- package/test/MeadowEndpoints_basic_tests.js +50 -2408
- package/test_support/bookstore-api-endpoint-exercises.paw +0 -0
- package/test_support/bookstore-configuration.json +28 -0
- package/test_support/bookstore-import-books-run.js +1 -0
- package/test_support/bookstore-import-books.js +215 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis-IPC.js +138 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis-run.js +6 -0
- package/test_support/bookstore-serve-meadow-endpoint-apis.js +129 -0
- package/test_support/data/books.csv +10001 -0
- package/test_support/model/ddl/BookStore.ddl +66 -0
- package/test_support/model/generated_diagram/README.md +1 -0
- package/test_support/model/generated_diagram/Stricture_Output.dot +13 -0
- package/test_support/model/generated_diagram/Stricture_Output.png +0 -0
- package/test_support/model/generated_documentation/Dictionary.md +18 -0
- package/test_support/model/generated_documentation/Model-Author.md +20 -0
- package/test_support/model/generated_documentation/Model-Book.md +26 -0
- package/test_support/model/generated_documentation/Model-BookAuthorJoin.md +14 -0
- package/test_support/model/generated_documentation/Model-BookPrice.md +25 -0
- package/test_support/model/generated_documentation/Model-Review.md +22 -0
- package/test_support/model/generated_documentation/ModelChangeTracking.md +17 -0
- package/test_support/model/generated_documentation/README.md +1 -0
- package/test_support/model/manual_scripts/DropTables.sql +5 -0
- package/test_support/model/manual_scripts/README.md +2 -0
- package/test_support/model/sql_create/BookStore-CreateDatabase.mysql.sql +116 -0
- package/test_support/model/sql_create/README.md +1 -0
- package/test_support/test_old/Tests.js +3243 -0
- package/test_support/test_old/untitled.js +88 -0
- package/source/Meadow-Authenticator.js +0 -31
- package/source/Meadow-Authorizers.js +0 -214
- package/source/Meadow-BehaviorModifications.js +0 -170
- package/source/Meadow-CommonServices.js +0 -206
- package/source/Meadow-MarshallSessionData.js +0 -64
- package/source/Restify-RouteParser.js +0 -114
- package/source/authorizers/Meadow-Authorizer-Allow.js +0 -17
- package/source/authorizers/Meadow-Authorizer-Deny.js +0 -17
- package/source/authorizers/Meadow-Authorizer-Mine.js +0 -47
- package/source/authorizers/Meadow-Authorizer-MyCustomer.js +0 -48
- package/source/crud/Meadow-Endpoint-BulkCreate.js +0 -67
- package/source/crud/Meadow-Endpoint-BulkUpdate.js +0 -74
- package/source/crud/Meadow-Endpoint-BulkUpsert.js +0 -76
- package/source/crud/Meadow-Endpoint-Count.js +0 -93
- package/source/crud/Meadow-Endpoint-CountBy.js +0 -101
- package/source/crud/Meadow-Endpoint-Create.js +0 -77
- package/source/crud/Meadow-Endpoint-Delete.js +0 -139
- package/source/crud/Meadow-Endpoint-Read.js +0 -109
- package/source/crud/Meadow-Endpoint-ReadDistinctList.js +0 -146
- package/source/crud/Meadow-Endpoint-ReadLiteList.js +0 -139
- package/source/crud/Meadow-Endpoint-ReadMax.js +0 -86
- package/source/crud/Meadow-Endpoint-ReadSelectList.js +0 -145
- package/source/crud/Meadow-Endpoint-Reads.js +0 -129
- package/source/crud/Meadow-Endpoint-ReadsBy.js +0 -155
- package/source/crud/Meadow-Endpoint-Undelete.js +0 -161
- package/source/crud/Meadow-Endpoint-Update.js +0 -80
- package/source/crud/Meadow-Endpoint-Upsert.js +0 -78
- package/source/crud/Meadow-Operation-Create.js +0 -105
- package/source/crud/Meadow-Operation-Update.js +0 -145
- package/source/crud/Meadow-Operation-Upsert.js +0 -106
- package/source/crud/Meadow-StreamRecordArray.js +0 -45
- package/source/schema/Meadow-Endpoint-New.js +0 -37
- package/source/schema/Meadow-Endpoint-Schema.js +0 -37
- package/source/schema/Meadow-Endpoint-Validate.js +0 -43
- package/test/Animal.json +0 -140
- package/test/MeadowEndpoints_disabledAuth_tests.js +0 -1325
- package/test/MeadowEndpoints_trustedSession_tests.js +0 -1731
- package/test/load/artillery-low.yml +0 -10
- package/test/load/cloud9setup.sh +0 -25
- package/test/load/package.json +0 -19
- package/test/load/test-schema-initializedatabase.sql +0 -29
- package/test/load/test-schema.json +0 -119
- package/test/load/test-server.js +0 -157
- package/test/scripts/InitializeDatabase-C9.sql +0 -7
- /package/{test/schemas → test_support/model}/json_schema/BookStore-Extended.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/BookStore-PICT.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/BookStore.json +0 -0
- /package/{test/schemas → test_support/model}/json_schema/README.md +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Author.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Book.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookAuthorJoin.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-BookPrice.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/BookStore-MeadowSchema-Review.json +0 -0
- /package/{test/schemas → test_support/model}/meadow_schema/README.md +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Update a Record
|
|
3
|
+
*/
|
|
4
|
+
const doUpdate = require('./Meadow-Operation-Update.js');
|
|
5
|
+
|
|
6
|
+
const doAPIEndpointUpdate = function(pRequest, pResponse, fNext)
|
|
7
|
+
{
|
|
8
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'Update');
|
|
9
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
10
|
+
|
|
11
|
+
this.waterfall(
|
|
12
|
+
[
|
|
13
|
+
(fStageComplete) =>
|
|
14
|
+
{
|
|
15
|
+
if (typeof(pRequest.body) !== 'object')
|
|
16
|
+
{
|
|
17
|
+
return fStageComplete(this.ErrorHandler.getError('Record update failure - a valid record is required.', 400));
|
|
18
|
+
}
|
|
19
|
+
if (pRequest.body[this.DAL.defaultIdentifier] < 1)
|
|
20
|
+
{
|
|
21
|
+
return fStageComplete(this.ErrorHandler.getError('Record update failure - a valid record ID is required in the passed-in record.', 400));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
tmpRequestState.Record = pRequest.body;
|
|
25
|
+
return fStageComplete();
|
|
26
|
+
},
|
|
27
|
+
(fStageComplete) =>
|
|
28
|
+
{
|
|
29
|
+
doUpdate.call(this, pRequest.body, pRequest, tmpRequestState, pResponse, fStageComplete);
|
|
30
|
+
},
|
|
31
|
+
(fStageComplete) =>
|
|
32
|
+
{
|
|
33
|
+
if (tmpRequestState.RecordUpdateError)
|
|
34
|
+
{
|
|
35
|
+
return fStageComplete(tmpRequestState.RecordUpdateErrorObject);
|
|
36
|
+
}
|
|
37
|
+
if (tmpRequestState.UpdatedRecords.length < 1)
|
|
38
|
+
{
|
|
39
|
+
return fStageComplete(this.ErrorHandler.getError('Unknown record update failure - no updated records returned.', 500));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
tmpRequestState.Record = tmpRequestState.UpdatedRecords[0];
|
|
43
|
+
|
|
44
|
+
return fStageComplete();
|
|
45
|
+
},
|
|
46
|
+
(fStageComplete) =>
|
|
47
|
+
{
|
|
48
|
+
pResponse.send(tmpRequestState.Record);
|
|
49
|
+
return fStageComplete();
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
(pError) =>
|
|
53
|
+
{
|
|
54
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
module.exports = doAPIEndpointUpdate;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Operation - Update a record
|
|
3
|
+
*/
|
|
4
|
+
const doUpdate = function(pRecordToModify, pRequest, pRequestState, pResponse, fCallback, pOptionalCachedUpdatingRecord)
|
|
5
|
+
{
|
|
6
|
+
// This is a virtual operation
|
|
7
|
+
let tmpRequestState = this.cloneAsyncSafeRequestState(pRequestState, 'doUpdate');
|
|
8
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
9
|
+
|
|
10
|
+
// If there is not a default identifier or cached record, fail
|
|
11
|
+
if ((pRecordToModify[this.DAL.defaultIdentifier] < 1) && (typeof(pOptionalCachedUpdatingRecord) === 'undefined'))
|
|
12
|
+
{
|
|
13
|
+
return fCallback('Record update failure - a valid record ID is required in the passed-in record.');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!Array.isArray(tmpRequestState.ParentRequestState.UpdatedRecords))
|
|
17
|
+
{
|
|
18
|
+
tmpRequestState.ParentRequestState.UpdatedRecords = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.waterfall(
|
|
22
|
+
[
|
|
23
|
+
(fStageComplete) =>
|
|
24
|
+
{
|
|
25
|
+
tmpRequestState.RecordToModify = pRecordToModify;
|
|
26
|
+
|
|
27
|
+
if (typeof(pOptionalCachedUpdatingRecord) !== 'undefined')
|
|
28
|
+
{
|
|
29
|
+
// Use the cached updating record instead of reading a record.
|
|
30
|
+
tmpRequestState.OriginalRecord = pOptionalCachedUpdatingRecord;
|
|
31
|
+
return fStageComplete();
|
|
32
|
+
}
|
|
33
|
+
else
|
|
34
|
+
{
|
|
35
|
+
tmpRequestState.Query = this.DAL.query;
|
|
36
|
+
|
|
37
|
+
tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier, tmpRequestState.RecordToModify[this.DAL.defaultIdentifier]);
|
|
38
|
+
|
|
39
|
+
// Load the record so we can do security checks on it
|
|
40
|
+
this.DAL.doRead(tmpRequestState.Query,
|
|
41
|
+
(pError, pQuery, pRecord) =>
|
|
42
|
+
{
|
|
43
|
+
if (pError)
|
|
44
|
+
{
|
|
45
|
+
return fStageComplete(pError);
|
|
46
|
+
}
|
|
47
|
+
if (!pRecord)
|
|
48
|
+
{
|
|
49
|
+
return fStageComplete(this.ErrorHandler.getError('Record not Found', 404));
|
|
50
|
+
}
|
|
51
|
+
tmpRequestState.Record = pRecord;
|
|
52
|
+
return fStageComplete();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
(fStageComplete) =>
|
|
57
|
+
{
|
|
58
|
+
tmpRequestState.Query = this.DAL.query;
|
|
59
|
+
return fStageComplete();
|
|
60
|
+
},
|
|
61
|
+
(fStageComplete) =>
|
|
62
|
+
{
|
|
63
|
+
tmpRequestState.Query.setIDUser(tmpRequestState.SessionData.UserID);
|
|
64
|
+
tmpRequestState.Query.addRecord(tmpRequestState.RecordToModify);
|
|
65
|
+
|
|
66
|
+
return fStageComplete();
|
|
67
|
+
},
|
|
68
|
+
(fStageComplete) =>
|
|
69
|
+
{
|
|
70
|
+
this.DAL.doUpdate(tmpRequestState.Query,
|
|
71
|
+
(pError, pQuery, pReadQuery, pRecord) =>
|
|
72
|
+
{
|
|
73
|
+
if (pError)
|
|
74
|
+
{
|
|
75
|
+
if (typeof(pError) == 'string')
|
|
76
|
+
{
|
|
77
|
+
return fStageComplete(this.ErrorHandler.getError(pError, 500));
|
|
78
|
+
}
|
|
79
|
+
else
|
|
80
|
+
{
|
|
81
|
+
return fStageComplete(pError);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!pRecord)
|
|
85
|
+
{
|
|
86
|
+
return fStageComplete(this.ErrorHandler.getError(`Error in DAL Update: No record returned from persistence engine.`, 500));
|
|
87
|
+
}
|
|
88
|
+
tmpRequestState.Record = pRecord;
|
|
89
|
+
return fStageComplete();
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
(fStageComplete) => { return this.BehaviorInjection.runBehavior(`Update-PostOperation`, this, pRequest, tmpRequestState, fStageComplete); },
|
|
93
|
+
(fStageComplete) =>
|
|
94
|
+
{
|
|
95
|
+
tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);
|
|
96
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Updated record with ID ${tmpRequestState.Record[this.DAL.defaultIdentifier]}`);
|
|
97
|
+
return fStageComplete();
|
|
98
|
+
}
|
|
99
|
+
], (pError) =>
|
|
100
|
+
{
|
|
101
|
+
if (pError)
|
|
102
|
+
{
|
|
103
|
+
tmpRequestState.Record.Error = pError;
|
|
104
|
+
|
|
105
|
+
tmpRequestState.ParentRequestState.RecordUpdateError = true;
|
|
106
|
+
tmpRequestState.ParentRequestState.RecordUpdateErrorObject = pError;
|
|
107
|
+
|
|
108
|
+
tmpRequestState.ParentRequestState.UpdatedRecords.push(tmpRequestState.Record);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return fCallback();
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
module.exports = doUpdate;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Upsert a set of Records
|
|
3
|
+
*/
|
|
4
|
+
const doUpsert = require('./Meadow-Operation-Upsert.js');
|
|
5
|
+
|
|
6
|
+
const marshalLiteList = require('../read/Meadow-Marshal-LiteList.js');
|
|
7
|
+
|
|
8
|
+
const doAPIEndpointUpserts = function(pRequest, pResponse, fNext)
|
|
9
|
+
{
|
|
10
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'UpsertBulk');
|
|
11
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
12
|
+
|
|
13
|
+
tmpRequestState.CreatedRecords = [];
|
|
14
|
+
tmpRequestState.UpdatedRecords = [];
|
|
15
|
+
tmpRequestState.UpsertedRecords = [];
|
|
16
|
+
tmpRequestState.ErrorRecords = [];
|
|
17
|
+
|
|
18
|
+
this.waterfall(
|
|
19
|
+
[
|
|
20
|
+
(fStageComplete) =>
|
|
21
|
+
{
|
|
22
|
+
if (!Array.isArray(pRequest.body))
|
|
23
|
+
{
|
|
24
|
+
return fStageComplete(this.ErrorHandler.getError(`Record bulk upsert failure - a valid array of records is required.`, 500));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
tmpRequestState.BulkRecords = pRequest.body;
|
|
28
|
+
|
|
29
|
+
return fStageComplete();
|
|
30
|
+
},
|
|
31
|
+
(fStageComplete) =>
|
|
32
|
+
{
|
|
33
|
+
this.eachLimit(tmpRequestState.BulkRecords, 1,
|
|
34
|
+
(pRecord, fCallback) =>
|
|
35
|
+
{
|
|
36
|
+
doUpsert.call(this, pRecord, pRequest, tmpRequestState, pResponse, fCallback);
|
|
37
|
+
}, fStageComplete);
|
|
38
|
+
},
|
|
39
|
+
(fStageComplete) =>
|
|
40
|
+
{
|
|
41
|
+
return this.doStreamRecordArray(pResponse, marshalLiteList.call(this, tmpRequestState.UpsertedRecords, pRequest), fStageComplete);
|
|
42
|
+
},
|
|
43
|
+
(fStageComplete) =>
|
|
44
|
+
{
|
|
45
|
+
this.log.requestCompletedSuccessfully(pRequest, tmpRequestState, `Bulk upsert complete -- ${tmpRequestState.UpsertedRecords} records processed`);
|
|
46
|
+
return fStageComplete();
|
|
47
|
+
}
|
|
48
|
+
], (pError) =>
|
|
49
|
+
{
|
|
50
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
module.exports = doAPIEndpointUpserts;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Endpoint - Upsert (Insert OR Update) a Record
|
|
3
|
+
*/
|
|
4
|
+
var doUpsert = require('./Meadow-Operation-Upsert.js');
|
|
5
|
+
|
|
6
|
+
var doAPIEndpointUpsert = function(pRequest, pResponse, fNext)
|
|
7
|
+
{
|
|
8
|
+
let tmpRequestState = this.initializeRequestState(pRequest, 'Upsert');
|
|
9
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
10
|
+
|
|
11
|
+
// Configure the request for the generic create & update operations
|
|
12
|
+
tmpRequestState.CreatedRecords = [];
|
|
13
|
+
tmpRequestState.UpdatedRecords = [];
|
|
14
|
+
tmpRequestState.UpsertedRecords = [];
|
|
15
|
+
tmpRequestState.ErrorRecords = [];
|
|
16
|
+
|
|
17
|
+
this.waterfall(
|
|
18
|
+
[
|
|
19
|
+
(fStageComplete) =>
|
|
20
|
+
{
|
|
21
|
+
//1. Validate request body to ensure it is a valid record
|
|
22
|
+
if (typeof(pRequest.body) !== 'object')
|
|
23
|
+
{
|
|
24
|
+
return fStageComplete(this.ErrorHandler.getError('Record upsert failure - a valid record is required.', 500));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
tmpRequestState.RecordToUpsert = pRequest.body;
|
|
28
|
+
|
|
29
|
+
return fStageComplete();
|
|
30
|
+
},
|
|
31
|
+
(fStageComplete) =>
|
|
32
|
+
{
|
|
33
|
+
doUpsert.call(this, tmpRequestState.RecordToUpsert, pRequest, tmpRequestState, pResponse, fStageComplete);
|
|
34
|
+
},
|
|
35
|
+
(fStageComplete) =>
|
|
36
|
+
{
|
|
37
|
+
if (tmpRequestState.RecordUpsertError)
|
|
38
|
+
{
|
|
39
|
+
return fStageComplete(tmpRequestState.RecordUpsertErrorMessage);
|
|
40
|
+
}
|
|
41
|
+
if (tmpRequestState.UpsertedRecords.length < 1)
|
|
42
|
+
{
|
|
43
|
+
return fStageComplete(this.ErrorHandler.getError('Record upsert unknown failure - no record back from Upsert operation.', 500));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tmpRequestState.Record = tmpRequestState.UpsertedRecords[0];
|
|
47
|
+
|
|
48
|
+
pResponse.send(tmpRequestState.Record);
|
|
49
|
+
|
|
50
|
+
return fStageComplete();
|
|
51
|
+
}
|
|
52
|
+
], (pError) =>
|
|
53
|
+
{
|
|
54
|
+
return this.ErrorHandler.handleErrorIfSet(pRequest, tmpRequestState, pResponse, pError, fNext);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
module.exports = doAPIEndpointUpsert;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meadow Operation - Upsert a record
|
|
3
|
+
*/
|
|
4
|
+
const doCreate = require('../create/Meadow-Operation-Create.js');
|
|
5
|
+
const doUpdate = require('../update/Meadow-Operation-Update.js');
|
|
6
|
+
|
|
7
|
+
const doUpsert = function(pRecordToUpsert, pRequest, pRequestState, pResponse, fCallback)
|
|
8
|
+
{
|
|
9
|
+
let tmpRequestState = this.cloneAsyncSafeRequestState(pRequestState, 'Upsert');
|
|
10
|
+
let fBehaviorInjector = (pBehaviorHash) => { return (fStageComplete) => { this.BehaviorInjection.runBehavior(pBehaviorHash, this, pRequest, tmpRequestState, fStageComplete); }; };
|
|
11
|
+
|
|
12
|
+
this.waterfall(
|
|
13
|
+
[
|
|
14
|
+
(fStageComplete) =>
|
|
15
|
+
{
|
|
16
|
+
tmpRequestState.Query = this.DAL.query;
|
|
17
|
+
|
|
18
|
+
// Prepare to gather requirements for upserting
|
|
19
|
+
tmpRequestState.Record = pRecordToUpsert;
|
|
20
|
+
|
|
21
|
+
// This operation will be create only if there is no GUID or ID in the record bundle
|
|
22
|
+
tmpRequestState.UpsertCreateOnly = true;
|
|
23
|
+
|
|
24
|
+
// See if there is a default identifier or default GUIdentifier
|
|
25
|
+
if ((typeof(tmpRequestState.Record[this.DAL.defaultGUIdentifier]) !== 'undefined') && tmpRequestState.Record[this.DAL.defaultGUIdentifier].length > 0)
|
|
26
|
+
{
|
|
27
|
+
tmpRequestState.Query.addFilter(this.DAL.defaultGUIdentifier, tmpRequestState.Record[this.DAL.defaultGUIdentifier]);
|
|
28
|
+
tmpRequestState.UpsertCreateOnly = false;
|
|
29
|
+
}
|
|
30
|
+
if ((typeof(tmpRequestState.Record[this.DAL.defaultIdentifier]) !== 'undefined') && (tmpRequestState.Record[this.DAL.defaultIdentifier] > 0))
|
|
31
|
+
{
|
|
32
|
+
tmpRequestState.Query.addFilter(this.DAL.defaultIdentifier, tmpRequestState.Record[this.DAL.defaultIdentifier]);
|
|
33
|
+
tmpRequestState.UpsertCreateOnly = false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return fStageComplete();
|
|
37
|
+
},
|
|
38
|
+
(fStageComplete) =>
|
|
39
|
+
{
|
|
40
|
+
if (tmpRequestState.UpsertCreateOnly)
|
|
41
|
+
{
|
|
42
|
+
tmpRequestState.Operation = 'Create';
|
|
43
|
+
doCreate.call(this, tmpRequestState.Record, pRequest, tmpRequestState, pResponse, fStageComplete);
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
{
|
|
47
|
+
this.DAL.doRead(tmpRequestState.Query,
|
|
48
|
+
(pError, pQuery, pRecord) =>
|
|
49
|
+
{
|
|
50
|
+
if (pError)
|
|
51
|
+
{
|
|
52
|
+
if (typeof(pError) == 'string')
|
|
53
|
+
{
|
|
54
|
+
return fStageComplete(this.ErrorHandler.getError(pError, 500));
|
|
55
|
+
}
|
|
56
|
+
else
|
|
57
|
+
{
|
|
58
|
+
return fStageComplete(pError);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (!pRecord)
|
|
62
|
+
{
|
|
63
|
+
// Record not found -- do a create.
|
|
64
|
+
tmpRequestState.Operation = 'Create';
|
|
65
|
+
doCreate.call(this, tmpRequestState.Record, pRequest, tmpRequestState, pResponse, fStageComplete);
|
|
66
|
+
}
|
|
67
|
+
else
|
|
68
|
+
{
|
|
69
|
+
// Set the default ID in the passed-in record if it doesn't exist..
|
|
70
|
+
if (!tmpRequestState.Record.hasOwnProperty(this.DAL.defaultIdentifier))
|
|
71
|
+
{
|
|
72
|
+
tmpRequestState.Record[this.DAL.defaultIdentifier] = pRecord[this.DAL.defaultIdentifier];
|
|
73
|
+
}
|
|
74
|
+
// If the found record does not match the passed ID --- what the heck?!
|
|
75
|
+
if (tmpRequestState.Record[this.DAL.defaultIdentifier] != pRecord[this.DAL.defaultIdentifier])
|
|
76
|
+
{
|
|
77
|
+
return fStageComplete(this.ErrorHandler.getError('Record IDs do not match', 500));
|
|
78
|
+
}
|
|
79
|
+
// Record found -- do an update. Use the cached record, though.
|
|
80
|
+
tmpRequestState.Operation = 'Update';
|
|
81
|
+
doUpdate.call(this, tmpRequestState.Record, pRequest, tmpRequestState, pResponse, fStageComplete, pRecord);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
(fStageComplete) =>
|
|
87
|
+
{
|
|
88
|
+
// Now stuff the record into the upserted array
|
|
89
|
+
if (tmpRequestState.Operation == 'Update')
|
|
90
|
+
{
|
|
91
|
+
if (tmpRequestState.RecordUpdateError)
|
|
92
|
+
{
|
|
93
|
+
return fStageComplete(tmpRequestState.RecordUpdateErrorObject);
|
|
94
|
+
}
|
|
95
|
+
if (tmpRequestState.UpdatedRecords.length < 1)
|
|
96
|
+
{
|
|
97
|
+
return fStageComplete(this.ErrorHandler.getError('Unknown record update failure - no updated records returned.', 500));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
tmpRequestState.Record = tmpRequestState.UpdatedRecords[0];
|
|
101
|
+
}
|
|
102
|
+
else if (tmpRequestState.Operation == 'Create')
|
|
103
|
+
{
|
|
104
|
+
if (tmpRequestState.RecordCreateError)
|
|
105
|
+
{
|
|
106
|
+
return fStageComplete(tmpRequestState.RecordCreateErrorObject);
|
|
107
|
+
}
|
|
108
|
+
if (tmpRequestState.CreatedRecords.length < 1)
|
|
109
|
+
{
|
|
110
|
+
return fStageComplete(this.ErrorHandler.getError('Unknown record create failure - no created records returned.', 500));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
tmpRequestState.Record = tmpRequestState.CreatedRecords[0];
|
|
114
|
+
}
|
|
115
|
+
else
|
|
116
|
+
{
|
|
117
|
+
return fStageComplete(this.ErrorHandler.getError('Unkknown record upsert failure = no records returned from doUpsert.', 500));
|
|
118
|
+
}
|
|
119
|
+
tmpRequestState.ParentRequestState.UpsertedRecords.push(tmpRequestState.Record);
|
|
120
|
+
return fStageComplete();
|
|
121
|
+
}
|
|
122
|
+
], (pError) =>
|
|
123
|
+
{
|
|
124
|
+
if (pError)
|
|
125
|
+
{
|
|
126
|
+
tmpRequestState.Record.Error = pError;
|
|
127
|
+
}
|
|
128
|
+
return fCallback();
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
module.exports = doUpsert;
|