API Data Fercher First Debugging Completed
This commit is contained in:
1 parent
9d2c818372
commit
7ff18ccdda
2 files changed
+127
-82
No files matched your search
@@ -1 +1 @@
|
||||
{"type":"Data Mine","name":"Masters","config":"{\n\"codeName\": \"Masters\"\n}","project":"Superalgos","sensorBots":[{"type":"Sensor Bot","name":"Exchange Raw Data","config":"{\n \"codeName\": \"Exchange-Raw-Data\"\n}","project":"Superalgos","processes":[{"type":"Process Definition","name":"Historic-OHLCVs","config":"{\n \"codeName\": \"Historic-OHLCVs\",\n \"description\": \"Retrieves and saves historical maket data\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000,\n \"botModule\": \"Exchange Raw Data Historic OHLCVs\"\n}","project":"Superalgos","processOutput":{"type":"Process Output","name":"New Process Output","project":"Superalgos","outputDatasets":[],"outputDatasetFolders":[],"id":"dfe2556e-a765-4e38-9d30-7f91090c0069","savedPayload":{"position":{"x":19705.67390477555,"y":18305.314530096774},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Superalgos","statusDependencies":[{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Superalgos","id":"ea39c98b-18e2-44ce-9f7f-86a8a76a688a","savedPayload":{"position":{"x":20031.77290451477,"y":18126.735984334173},"targetPosition":{"x":19849.144475812154,"y":18364.741986421544},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}}],"dataDependencies":[],"dataMineDataDependencies":[],"id":"5c7fae5a-6da6-4864-a167-f2f21d578c72","savedPayload":{"position":{"x":19849.144475812154,"y":18364.741986421544},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Superalgos","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e","savedPayload":{"position":{"x":19943.679906862923,"y":18487.94295879939},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"","project":"Superalgos","id":"957e7e3a-b167-40be-93b5-9ba4ceff56e5","savedPayload":{"position":{"x":19963.94950552168,"y":18641.90584617493},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Superalgos","id":"fe40a546-43ee-49df-908a-7e72f598f0cd","savedPayload":{"position":{"x":19904.52204919691,"y":18785.376417211533},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"5eb11d6a-022e-4f60-97c4-d6cf90b249dc","savedPayload":{"position":{"x":19666.516047109537,"y":18602.747988508916},"targetPosition":{"x":19389.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":3,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"Candles","config":"{\n\"codeName\": \"Candles\"\n}","project":"Superalgos","datasets":[{"type":"Dataset Definition","name":"One-Min","config":"{\n\"codeName\": \"One-Min\"\n}","project":"Superalgos","id":"1c3696e4-c28e-4744-9100-706d6dce0c3c","savedPayload":{"position":{"x":19839.35218735615,"y":18717.55301821844},"targetPosition":{"x":19689.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"id":"2443883b-6959-42a3-ae3b-ef3102ffcdcc","savedPayload":{"position":{"x":19689.35218735615,"y":18717.55301821844},"targetPosition":{"x":19389.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":3,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Product Definition","name":"Volumes","config":"{\n\"codeName\": \"Volumes\"\n}","project":"Superalgos","datasets":[{"type":"Dataset Definition","name":"One-Min","config":"{\n\"codeName\": \"One-MiLine truncated
|
||||
{"type":"Data Mine","name":"Masters","config":"{\n\"codeName\": \"Masters\"\n}","project":"Superalgos","sensorBots":[{"type":"Sensor Bot","name":"Exchange Raw Data","config":"{\n \"codeName\": \"Exchange-Raw-Data\"\n}","project":"Superalgos","processes":[{"type":"Process Definition","name":"Historic-OHLCVs","config":"{\n \"codeName\": \"Historic-OHLCVs\",\n \"description\": \"Retrieves and saves historical maket data\",\n \"deadWaitTime\": 0,\n \"normalWaitTime\": 60000,\n \"retryWaitTime\": 10000,\n \"botModule\": \"Exchange Raw Data Historic OHLCVs\"\n}","project":"Superalgos","processOutput":{"type":"Process Output","name":"New Process Output","project":"Superalgos","outputDatasets":[],"outputDatasetFolders":[],"id":"dfe2556e-a765-4e38-9d30-7f91090c0069","savedPayload":{"position":{"x":19705.67390477555,"y":18305.314530096774},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"processDependencies":{"type":"Process Dependencies","name":"New Process Dependencies","project":"Superalgos","statusDependencies":[{"type":"Status Dependency","name":"Exchange Raw Data Historic-OHLCVs","config":"{\n \"mainUtility\": \"Self Reference\"\n}","project":"Superalgos","id":"ea39c98b-18e2-44ce-9f7f-86a8a76a688a","savedPayload":{"position":{"x":20031.77290451477,"y":18126.735984334173},"targetPosition":{"x":19849.144475812154,"y":18364.741986421544},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{},"referenceParent":{"type":"Status Report","name":"New Status Report","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e"}}}],"dataDependencies":[],"dataMineDataDependencies":[],"id":"5c7fae5a-6da6-4864-a167-f2f21d578c72","savedPayload":{"position":{"x":19849.144475812154,"y":18364.741986421544},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},"statusReport":{"type":"Status Report","name":"New Status Report","project":"Superalgos","id":"181c7c34-7243-497a-9ddb-1b0067c6d66e","savedPayload":{"position":{"x":19943.679906862923,"y":18487.94295879939},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionStartedEvent":{"type":"Execution Started Event","name":"","project":"Superalgos","id":"957e7e3a-b167-40be-93b5-9ba4ceff56e5","savedPayload":{"position":{"x":19963.94950552168,"y":18641.90584617493},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"executionFinishedEvent":{"type":"Execution Finished Event","name":"New Execution Finished Event","project":"Superalgos","id":"fe40a546-43ee-49df-908a-7e72f598f0cd","savedPayload":{"position":{"x":19904.52204919691,"y":18785.376417211533},"targetPosition":{"x":19666.516047109537,"y":18602.747988508916},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":2,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"5eb11d6a-022e-4f60-97c4-d6cf90b249dc","savedPayload":{"position":{"x":19666.516047109537,"y":18602.747988508916},"targetPosition":{"x":19389.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":3,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"products":[{"type":"Product Definition","name":"Candles","config":"{\n\"codeName\": \"Candles\"\n}","project":"Superalgos","datasets":[{"type":"Dataset Definition","name":"One-Min","config":"{\n\"codeName\": \"One-Min\"\n}","project":"Superalgos","id":"1c3696e4-c28e-4744-9100-706d6dce0c3c","savedPayload":{"position":{"x":19839.35218735615,"y":18717.55301821844},"targetPosition":{"x":19689.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":2,"arrangementStyle":0},"uiObject":{}}}],"id":"2443883b-6959-42a3-ae3b-ef3102ffcdcc","savedPayload":{"position":{"x":19689.35218735615,"y":18717.55301821844},"targetPosition":{"x":19389.35218735615,"y":18717.55301821844},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":3,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Product Definition","name":"Volumes","config":"{\n\"codeName\": \"Volumes\"\n}","project":"Superalgos","datasets":[{"type":"Dataset Definition","name":"One-Min","config":"{\n\"codeName\": \"One-MiLine truncated
|
||||
@@ -33,13 +33,15 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
}
|
||||
|
||||
let thisReport // This holds the status report.
|
||||
let processNode // This hold the node Process Definition
|
||||
let lastPage = {} // This holds the last page fetched for each endpoint
|
||||
|
||||
getContextVariables()
|
||||
startProcess()
|
||||
|
||||
function getContextVariables() {
|
||||
try {
|
||||
let processNode = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent
|
||||
processNode = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent
|
||||
let reportKey = processNode.parentNode.parentNode.config.codeName + "-" + processNode.parentNode.config.codeName + "-" + processNode.config.codeName
|
||||
|
||||
TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME,
|
||||
@@ -68,9 +70,9 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
function startProcess() {
|
||||
async function startProcess() {
|
||||
try {
|
||||
let processNode = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent
|
||||
processNode = TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].referenceParent
|
||||
|
||||
if (TS.projects.superalgos.globals.taskConstants.TASK_NODE.bot.processes[processIndex].apiMapReference === undefined) {
|
||||
// TODO Error Handling
|
||||
@@ -136,14 +138,13 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
let dataReceivedArray = [] // This hold the cumulative data received from all calls to the API (multiple pages of data).
|
||||
let pageNumberParameter // This holds the node that represents a Page Number parameter.
|
||||
let pageQueryString // This holds the node part of query sting that deals with page numbers
|
||||
let lastPage = {} // This holds the last page fetched for each endpoint
|
||||
|
||||
getApiEndpoint()
|
||||
getEndpointQueryParameters()
|
||||
fetchAllPages()
|
||||
readDatasetFile()
|
||||
await fetchAllPages()
|
||||
await readDatasetFile()
|
||||
appendToExistingDataset()
|
||||
saveDatasetFile()
|
||||
await saveDatasetFile()
|
||||
|
||||
function getApiEndpoint() {
|
||||
/*
|
||||
@@ -158,7 +159,7 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
if (recordProperty.apiResponseFieldReference !== undefined) {
|
||||
if (recordProperty.apiResponseFieldReference.referenceParent !== undefined) {
|
||||
let apiResponseField = recordProperty.apiResponseFieldReference.referenceParent
|
||||
let endpointNodeFound = TS.projects.superalgos.utilities.nodeFunctions.findNodeInNodeMesh(apiResponseField, 'API endpoint')
|
||||
let endpointNodeFound = TS.projects.superalgos.utilities.nodeFunctions.findNodeInNodeMesh(apiResponseField, 'API Endpoint')
|
||||
|
||||
/*
|
||||
Every Record Property with an apiResponseFieldReference must be on the path
|
||||
@@ -231,23 +232,46 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
that will mean that we have requested already the last page with data.
|
||||
*/
|
||||
let initialPage = 1
|
||||
let finalPage = MAX_SAFE_INTEGER
|
||||
let finalPage = Number.MAX_SAFE_INTEGER
|
||||
if (thisReport.file.lastPage !== undefined) {
|
||||
initialPage = thisReport.file.lastPage[endpointNode.config.codeName]
|
||||
}
|
||||
|
||||
for (let page = initialPage; page < finalPage; page++) {
|
||||
if (queryString === "") {
|
||||
queryString = "?" + pageNumberParameter.config.codeName + "=" + page
|
||||
pageQueryString = "?" + pageNumberParameter.config.codeName + "=" + page
|
||||
} else {
|
||||
queryString = queryString + "&" + pageNumberParameter.config.codeName + "=" + page
|
||||
pageQueryString = "&" + pageNumberParameter.config.codeName + "=" + page
|
||||
}
|
||||
lastPage[endpointNode.config.codeName] = page
|
||||
await fetchAPIData()
|
||||
/*
|
||||
This is how we accumulate the data from multiple pages into a single array.
|
||||
*/
|
||||
let latestDataReceivedArray = JSON.parse(apiDataReceived)
|
||||
dataReceivedArray = dataReceivedArray.concat(latestDataReceivedArray)
|
||||
let fetchResult = await fetchAPIData()
|
||||
|
||||
switch (fetchResult) {
|
||||
case 'UNEXPECTED_API_RESPONSE': {
|
||||
/*
|
||||
Any unexpected response will abort this loop and allow the process to continue,
|
||||
possibly saving accumulated data.
|
||||
*/
|
||||
page = finalPage
|
||||
break
|
||||
}
|
||||
case 'NO_MORE_PAGES': {
|
||||
/*
|
||||
We will just abort this loop and continue.
|
||||
*/
|
||||
page = finalPage
|
||||
break
|
||||
}
|
||||
case 'PAGE_FETCHED': {
|
||||
/*
|
||||
Just stay at the current loop and try to fetch more pages.
|
||||
This is how we accumulate the data from multiple pages into a single array.
|
||||
*/
|
||||
let latestDataReceivedArray = JSON.parse(apiDataReceived)
|
||||
dataReceivedArray = dataReceivedArray.concat(latestDataReceivedArray)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,18 +307,38 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
function onDataArrived(chunk) {
|
||||
chunks.push(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
function onEnd() {
|
||||
apiDataReceived = Buffer.concat(chunks).toString('utf8')
|
||||
resolve()
|
||||
function onEnd() {
|
||||
apiDataReceived = Buffer.concat(chunks).toString('utf8')
|
||||
|
||||
/*
|
||||
If we did not received an array, that probably means something is not
|
||||
good, and we got an HTML with the reason inside.
|
||||
*/
|
||||
if (apiDataReceived.substring(0, 1) !== "[") {
|
||||
TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME,
|
||||
"[WARN] start -> startProcess -> fetchAllPages -> fetchAPIData -> onResponse -> onEnd -> Unexpected Response. Not an Array with Data. -> apiDataReceived = " + apiDataReceived);
|
||||
resolve('UNEXPECTED_API_RESPONSE')
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
The response is an Array, depending if it has data or not we will return
|
||||
NO_MORE_PAGES or PAGE_FETCHED so that pagination procedure knows when to stop.
|
||||
*/
|
||||
if (apiDataReceived === "[]") {
|
||||
resolve('NO_MORE_PAGES')
|
||||
} else {
|
||||
resolve('PAGE_FETCHED')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return promise
|
||||
}
|
||||
|
||||
function readDatasetFile() {
|
||||
async function readDatasetFile() {
|
||||
/*
|
||||
If this process already ran before, then we are going to load the data stored so as to append
|
||||
information to it later.
|
||||
@@ -302,8 +346,8 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
if (thisReport.file.lastRun !== undefined) {
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + productDefinition.config.codeName + "/" + outputDataset.config.codeName
|
||||
let response = fileStorage.asyncGetTextFile(filePath + '/' + fileName)
|
||||
let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + productDefinition.config.codeName + "/" + outputDataset.referenceParent.config.codeName
|
||||
let response = await fileStorage.asyncGetTextFile(filePath + '/' + fileName)
|
||||
let text = response.text
|
||||
|
||||
if (response.err !== undefined && response.err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) {
|
||||
@@ -323,82 +367,83 @@ exports.newSuperalgosBotModulesFetchingProcess = function (processIndex) {
|
||||
}
|
||||
|
||||
function appendToExistingDataset() {
|
||||
if (existingFileContent !== undefined) {
|
||||
// we are going to append the curernt apiDataReceived to the existing file.
|
||||
let existingFileArray = JSON.parse(existingFileContent)
|
||||
|
||||
/*
|
||||
We will create a map with all the existing record primary keys, so as to use it
|
||||
later to avoid appending records that already exists. The first step is to
|
||||
build an array with the primary keys of the file. After that we will populate
|
||||
the existingKeys map.
|
||||
*/
|
||||
let primaryKeys = []
|
||||
let existingKeys = new Map()
|
||||
// we are going to append the curernt apiDataReceived to the existing file.
|
||||
let existingFileArray = JSON.parse(existingFileContent)
|
||||
|
||||
/*
|
||||
Setup the primaryKeys array.
|
||||
*/
|
||||
for (let j = 0; j < productDefinition.record.properties.length; j++) {
|
||||
let recordProperty = productDefinition.record.properties[j]
|
||||
if (recordProperty.config.primaryKey === true) {
|
||||
primaryKeys.push(recordProperty.config.codeName)
|
||||
}
|
||||
/*
|
||||
We will create a map with all the existing record primary keys, so as to use it
|
||||
later to avoid appending records that already exists. The first step is to
|
||||
build an array with the primary keys of the file. After that we will populate
|
||||
the existingKeys map.
|
||||
*/
|
||||
let primaryKeys = []
|
||||
let existingKeys = new Map()
|
||||
|
||||
/*
|
||||
Setup the primaryKeys array.
|
||||
*/
|
||||
for (let j = 0; j < productDefinition.record.properties.length; j++) {
|
||||
let recordProperty = productDefinition.record.properties[j]
|
||||
if (recordProperty.config.primaryKey === true) {
|
||||
primaryKeys.push(recordProperty.config.codeName)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Setup the existingKeys map.
|
||||
*/
|
||||
for (let i = 0; i < existingFileArray.length; i++) {
|
||||
let record = existingFileArray[i]
|
||||
let key = ""
|
||||
for (j = 0; j < primaryKeys.length; j++) {
|
||||
let keyValue = record[primaryKeys[j]]
|
||||
key = key + '->' + keyValue
|
||||
}
|
||||
/*
|
||||
Setup the existingKeys map.
|
||||
*/
|
||||
for (let i = 0; i < existingFileArray.length; i++) {
|
||||
let record = existingFileArray[i]
|
||||
let key = ""
|
||||
for (j = 0; j < primaryKeys.length; j++) {
|
||||
let keyValue = record[primaryKeys[j]]
|
||||
key = key + '->' + keyValue
|
||||
}
|
||||
existingKeys.set(key, record)
|
||||
}
|
||||
|
||||
/*
|
||||
Scan the dataReceivedArray array and insert records into
|
||||
the existingFileArray array only when they are not going to
|
||||
duplicate a primary key.
|
||||
*/
|
||||
for (let i = 0; i < dataReceivedArray.length; i++) {
|
||||
let record = dataReceivedArray[i]
|
||||
|
||||
let key = ""
|
||||
for (j = 0; j < primaryKeys.length; j++) {
|
||||
let keyValue = record[primaryKeys[j]]
|
||||
key = key + '->' + keyValue
|
||||
}
|
||||
if (existingKeys.get(key) === undefined) {
|
||||
existingFileArray.push(record)
|
||||
existingKeys.set(key, record)
|
||||
}
|
||||
|
||||
/*
|
||||
Scan the dataReceivedArray array and insert records into
|
||||
the existingFileArray array only when they are not going to
|
||||
duplicate a primary key.
|
||||
*/
|
||||
for (let i = 0; i < dataReceivedArray.length; i++) {
|
||||
let record = dataReceivedArray[i]
|
||||
|
||||
let key = ""
|
||||
for (j = 0; j < primaryKeys.length; j++) {
|
||||
let keyValue = record[primaryKeys[j]]
|
||||
key = key + '->' + keyValue
|
||||
}
|
||||
if (existingKeys.get(key) === undefined) {
|
||||
existingFileArray.push(record)
|
||||
existingKeys.set(key, record)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
existingFileContent = JSON.stringify(existingFileArray)
|
||||
} else {
|
||||
// we are going to save the current apiDataReceived.
|
||||
existingFileContent = apiDataReceived
|
||||
}
|
||||
|
||||
existingFileContent = JSON.stringify(existingFileArray)
|
||||
}
|
||||
|
||||
function saveDatasetFile() {
|
||||
async function saveDatasetFile() {
|
||||
|
||||
let fileName = 'Data.json'
|
||||
let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + productDefinition.config.codeName + "/" + outputDataset.config.codeName
|
||||
let response = fileStorage.asyncCreateTextFile(filePath + '/' + fileName, existingFileContent + '\n');
|
||||
let filePath = TS.projects.superalgos.globals.processVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).FILE_PATH_ROOT + "/Output/" + productDefinition.config.codeName + "/" + outputDataset.referenceParent.config.codeName
|
||||
let response = await fileStorage.asyncCreateTextFile(filePath + '/' + fileName, existingFileContent + '\n');
|
||||
|
||||
if (response.err !== undefined && err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) {
|
||||
if (response.err !== undefined && response.err.result !== TS.projects.superalgos.globals.standardResponses.DEFAULT_OK_RESPONSE.result) {
|
||||
TS.projects.superalgos.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME,
|
||||
"[ERROR] start -> startProcess -> saveDatasetFile -> Could not save file. -> filePath = " + filePath + "/" + fileName);
|
||||
throw (response.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When all Output Datasets have been succesfully written, we can go and write
|
||||
the Status Report.
|
||||
*/
|
||||
writeStatusReport()
|
||||
|
||||
} catch (err) {
|
||||
|
||||
Reference in new issue
Block a user