Update PostgresStorageAdapter.js (#2087)

1. Deleting tables in a transaction, as opposed to just a task.
2. Added transaction where it was supposed to be. However, it is not enough, the logic is still broken there...

First, do not use `.catch` before `.then`. It is dangerous without good understanding how it actually works.

Check this out:
```js
        .catch(error => {
          if (error.code === PostgresRelationDoesNotExistError) {
            return this.createClass(className, {fields: {[fieldName]: type}}) // this gets into the following `.then`
          } else if (error.code === PostgresDuplicateColumnError) {
            // Column already exists, created by other request. Carry on to
            // See if it's the right type.
           
// this will get the following `.then` with `undefined` as the value

          } else {
            throw error;
          }
        })
```
This commit is contained in:
Vitaly Tomilov
2016-06-17 08:04:58 +01:00
committed by Drew
parent c37a4ea1a1
commit 7da4debbe0

View File

@@ -136,30 +136,36 @@ export class PostgresStorageAdapter {
} }
addFieldIfNotExists(className, fieldName, type) { addFieldIfNotExists(className, fieldName, type) {
// TODO: Must be re-done into a transaction! // TODO: Must be revised for invalid logic...
return this._client.query('ALTER TABLE $<className:name> ADD COLUMN $<fieldName:name> $<postgresType:raw>', { className, fieldName, postgresType: parseTypeToPostgresType(type) }) return this._client.tx("addFieldIfNotExists", t=> {
.catch(error => { return t.query('ALTER TABLE $<className:name> ADD COLUMN $<fieldName:name> $<postgresType:raw>', {
if (error.code === PostgresRelationDoesNotExistError) { className,
return this.createClass(className, { fields: { [fieldName]: type } }) fieldName,
} else if (error.code === PostgresDuplicateColumnError) { postgresType: parseTypeToPostgresType(type)
// Column already exists, created by other request. Carry on to })
// See if it's the right type. .catch(error => {
} else { if (error.code === PostgresRelationDoesNotExistError) {
throw error; return this.createClass(className, {fields: {[fieldName]: type}})
} } else if (error.code === PostgresDuplicateColumnError) {
}) // Column already exists, created by other request. Carry on to
.then(() => this._client.query('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $<className>', { className })) // See if it's the right type.
.then(result => { } else {
if (fieldName in result[0].schema) { throw error;
throw "Attempted to add a field that already exists"; }
} else { })
result[0].schema.fields[fieldName] = type; .then(() => t.query('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $<className>', {className}))
return this._client.query( .then(result => {
'UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>', if (fieldName in result[0].schema) {
{ schema: result[0].schema, className } throw "Attempted to add a field that already exists";
); } else {
} result[0].schema.fields[fieldName] = type;
}) return t.query(
'UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>',
{schema: result[0].schema, className}
);
}
})
});
} }
// Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.)
@@ -173,7 +179,7 @@ export class PostgresStorageAdapter {
return this._client.query('SELECT "className" FROM "_SCHEMA"') return this._client.query('SELECT "className" FROM "_SCHEMA"')
.then(results => { .then(results => {
const classes = ['_SCHEMA', ...results.map(result => result.className)]; const classes = ['_SCHEMA', ...results.map(result => result.className)];
return this._client.task(t=>t.batch(classes.map(className=>t.none('DROP TABLE $<className:name>', { className })))); return this._client.tx(t=>t.batch(classes.map(className=>t.none('DROP TABLE $<className:name>', { className }))));
}, error => { }, error => {
if (error.code === PostgresRelationDoesNotExistError) { if (error.code === PostgresRelationDoesNotExistError) {
// No _SCHEMA collection. Don't delete anything. // No _SCHEMA collection. Don't delete anything.