Skip to content

Commit

Permalink
[postgres] Improve performance when adding many new fields to the Sch…
Browse files Browse the repository at this point in the history
…ema (#3740)
  • Loading branch information
paulovitin authored and flovilmart committed Apr 23, 2017
1 parent 5e14147 commit 69042fb
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
77 changes: 76 additions & 1 deletion spec/Schema.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('SchemaController', () => {
it('can add classes without needing an object', done => {
config.database.loadSchema()
.then(schema => schema.addClassIfNotExists('NewClass', {
foo: {type: 'String'}
foo: {type: 'String'},
}))
.then(actualSchema => {
const expectedSchema = {
Expand Down Expand Up @@ -210,6 +210,81 @@ describe('SchemaController', () => {
});
});

it('can update classes without needing an object', done => {
const levelPermissions = {
find: { '*': true },
get: { '*': true },
create: { '*': true },
update: { '*': true },
delete: { '*': true },
addField: { '*': true },
};
config.database.loadSchema()
.then(schema => {
schema.validateObject('NewClass', { foo: 2 })
.then(() => schema.reloadData())
.then(() => schema.updateClass('NewClass', {
fooOne: {type: 'Number'},
fooTwo: {type: 'Array'},
fooThree: {type: 'Date'},
fooFour: {type: 'Object'},
fooFive: {type: 'Relation', targetClass: '_User' },
fooSix: {type: 'String'},
fooSeven: {type: 'Object' },
fooEight: {type: 'String'},
fooNine: {type: 'String'},
fooTeen: {type: 'Number' },
fooEleven: {type: 'String'},
fooTwelve: {type: 'String'},
fooThirteen: {type: 'String'},
fooFourteen: {type: 'String'},
fooFifteen: {type: 'String'},
fooSixteen: {type: 'String'},
fooEighteen: {type: 'String'},
fooNineteen: {type: 'String'},
}, levelPermissions, config.database))
.then(actualSchema => {
const expectedSchema = {
className: 'NewClass',
fields: {
objectId: { type: 'String' },
updatedAt: { type: 'Date' },
createdAt: { type: 'Date' },
ACL: { type: 'ACL' },
foo: { type: 'Number' },
fooOne: {type: 'Number'},
fooTwo: {type: 'Array'},
fooThree: {type: 'Date'},
fooFour: {type: 'Object'},
fooFive: {type: 'Relation', targetClass: '_User' },
fooSix: {type: 'String'},
fooSeven: {type: 'Object' },
fooEight: {type: 'String'},
fooNine: {type: 'String'},
fooTeen: {type: 'Number' },
fooEleven: {type: 'String'},
fooTwelve: {type: 'String'},
fooThirteen: {type: 'String'},
fooFourteen: {type: 'String'},
fooFifteen: {type: 'String'},
fooSixteen: {type: 'String'},
fooEighteen: {type: 'String'},
fooNineteen: {type: 'String'},
},
classLevelPermissions: { ...levelPermissions },
};

expect(dd(actualSchema, expectedSchema)).toEqual(undefined);
done();
})
.catch(error => {
console.trace(error);
done();
fail('Error creating class: ' + JSON.stringify(error));
});
});
});

it('will fail to create a class if that class was already created by an object', done => {
config.database.loadSchema()
.then(schema => {
Expand Down
10 changes: 5 additions & 5 deletions src/Adapters/Storage/Postgres/PostgresStorageAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -543,15 +543,15 @@ export class PostgresStorageAdapter {
promise = t.none('CREATE TABLE IF NOT EXISTS $<joinTable:name> ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', {joinTable: `_Join:${fieldName}:${className}`})
}
return promise.then(() => {
return t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $<className>', {className});
return t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $<className> and ("schema"::json->\'fields\'->$<fieldName>) is not null', {className, fieldName});
}).then(result => {
if (fieldName in result[0].schema.fields) {
if (result[0]) {
throw "Attempted to add a field that already exists";
} else {
result[0].schema.fields[fieldName] = type;
const path = `{fields,${fieldName}}`;
return t.none(
'UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>',
{schema: result[0].schema, className}
'UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $<path>, $<type>) WHERE "className"=$<className>',
{ path, type, className }
);
}
});
Expand Down

0 comments on commit 69042fb

Please sign in to comment.