Activation of Avatar draft image fails with postgresql Backend; Potential solution found (see comment)
Description of erroneous behaviour
A CDS Schema looks like this:
entity Person: managed, cuid {
firstname : String(100);
lastname : String(100);
avatar : LargeBinary
@Core.MediaType : avatarType
@Core.ContentDisposition.Filename: avatarFileName
@Core.ContentDisposition.Type : 'inline'
;
avatarFileName : String;
avatarType : String
@Core.IsMediaType;
};
I use following packages
"dependencies": {
"@cap-js/attachments": "^2.1.0",
"@sap/cds": "^8.6.0",
"exceljs": "^4.4.0",
"express": "^4.21.2",
"xlsx": "^0.18.5",
"@cap-js/postgres": "^1"
},
"devDependencies": {
"@cap-js/sqlite": "^1.7.8",
"@sap/eslint-plugin-ui5-jsdocs": "^2.0.8",
"@sap/ux-specification": "^1.124.15",
"@sapui5/ts-types": "^1.131.1",
"eslint": "^9.17.0",
"jest": "^29.7.0"
},
Uploading a image as avatar into draft table works fine. If I try to activat the draft I get following error:
[cds] - ❗️Uncaught TypeError: Client was passed a null or undefined query
at Client.query (internal_node_modules/pg/lib/client.js:529:13)
at internal_node_modules/@cap-js/postgres/lib/PostgresService.js:244:31
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Object.run (internal_node_modules/@cap-js/postgres/lib/PostgresService.js:156:63)
at async PostgresService.onSIMPLE (internal_node_modules/@cap-js/db-service/lib/SQLService.js:234:13)
at async PostgresService.onUPDATE (internal_node_modules/@cap-js/postgres/lib/PostgresService.js:340:14)
at async Promise.all (index 0)
at async PostgresService.onDeep (internal_node_modules/@cap-js/db-service/lib/deep-queries.js:55:3)
at async next (internal_node_modules/@sap/cds/lib/srv/srv-dispatch.js:64:17)
at async next (internal_node_modules/@sap/cds/lib/srv/srv-dispatch.js:64:17) {
query: `UPDATE com_customer_app_EntityName AS "$e" SET ID=$1,avatar=$2,avatarFileName=$3,avatarType=$4,modifiedAt=current_setting('cap.now')::timestamp,modifiedBy=current_setting('cap.applicationuser') WHERE "$e".ID = $5\n` + ' ^'
}
Note: the namespace of the entity was changed in this log!
The data is in the draft table and also show in draft correctly - also after reload. But pressing "SAVE" (meaning activation of draft) fails. I have no code written on my side.
Interstingly I have also a self build attachment navigation where several files can be uploaded there the draft handling seems working.
On UI side I use the avatar annotation which is experimental but I would assume this should not have an effect on draft handling itself?
Anything else I can provide here?
I assume there is an error in PostgresService.js in function ``_prepareStreams(query, values) {```
there is following code
for (const stream of streams) {
proms.push(this.dbc.query(stream))
}
that should be replaced with
for (const stream of streams.filter(s => s && s.constructor.name === 'ParameterStream')) {
proms.push(this.dbc.query(stream))
}
can someone review it?
@sfdfklskldf I had a look at your PR and it seemed to me that the streams array should only contain stream queries. So it seems more fitting to adjust the way that the array is being filled (https://github.com/cap-js/cds-dbs/pull/1179). As the code was using [i] all the non stream query entries should have been undefined. So by using push this should have the same effect as your PR.
Thanks for the review. I created this PR as a quick fix to address the error I encountered. Unfortunately, I don't have the capacity to debug the population of the streams array at the moment. If there's a preferred way to handle this by adjusting how the array is filled, I would appreciate it if someone with more context on that part of the code could take it over. Let me know if the current PR is acceptable as a temporary solution.
Looks like your fix solved this issue.