Skip to content

Commit 583887c

Browse files
kulshekharflovilmart
authored andcommitted
Improve update of jsonb fields. Add PG 9.5 to travis. (#2984)
* Improve update of jsonb fields. Add PG 9.5 to travis. * Replace manual escaping with pg-promise's built in
1 parent 8f0ae70 commit 583887c

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
language: node_js
2+
dist: trusty
3+
sudo: required
24
node_js:
35
- '4.5'
46
- '6.1'
57
services:
68
- postgresql
79
- redis-server
810
addons:
9-
postgresql: '9.4'
11+
postgresql: '9.5'
1012
before_script:
1113
- ls -al "$HOME/.mongodb/versions"
1214
- psql -c 'create database parse_server_postgres_adapter_test_database;' -U postgres

spec/RestCreate.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ describe('rest create', () => {
5252
});
5353
});
5454

55-
it_exclude_dbs(['postgres'])('handles object and subdocument', done => {
55+
it('handles object and subdocument', done => {
5656
let obj = { subdoc: {foo: 'bar', wu: 'tan'} };
5757
rest.create(config, auth.nobody(config), 'MyClass', obj)
5858
.then(() => database.adapter.find('MyClass', { fields: {} }, {}, {}))

src/Adapters/Storage/Postgres/PostgresStorageAdapter.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ export class PostgresStorageAdapter {
810810
let index = 2;
811811
schema = toPostgresSchema(schema);
812812

813+
const originalUpdate = {...update};
813814
update = handleDotFields(update);
814815
// Resolve authData first,
815816
// So we don't end up with multiple key updates
@@ -914,9 +915,19 @@ export class PostgresStorageAdapter {
914915
} else if (typeof fieldValue === 'object'
915916
&& schema.fields[fieldName]
916917
&& schema.fields[fieldName].type === 'Object') {
917-
updatePatterns.push(`$${index}:name = $${index + 1}`);
918-
values.push(fieldName, fieldValue);
919-
index += 2;
918+
const keysToDelete = Object.keys(originalUpdate).filter(k => {
919+
// choose top level fields that have a delete operation set
920+
return originalUpdate[k].__op === 'Delete' && k.split('.').length === 2
921+
}).map(k => k.split('.')[1]);
922+
923+
const deletePatterns = keysToDelete.reduce((p, c, i) => {
924+
return p + ` - '$${index + 1 + i}:value'`;
925+
}, '');
926+
927+
updatePatterns.push(`$${index}:name = ( COALESCE($${index}:name, '{}'::jsonb) ${deletePatterns} || $${index + 1 + keysToDelete.length}::jsonb )`);
928+
929+
values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue));
930+
index += 2 + keysToDelete.length;
920931
} else if (Array.isArray(fieldValue)
921932
&& schema.fields[fieldName]
922933
&& schema.fields[fieldName].type === 'Array') {

0 commit comments

Comments
 (0)