@@ -4,6 +4,7 @@ const PostgresRelationDoesNotExistError = '42P01';
44const PostgresDuplicateRelationError = '42P07' ;
55const PostgresDuplicateColumnError = '42701' ;
66const PostgresUniqueIndexViolationError = '23505' ;
7+ const PostgresTransactionAbortedError = '25P02' ;
78const logger = require ( '../../../logger' ) ;
89
910const debug = function ( ) {
@@ -385,8 +386,9 @@ export class PostgresStorageAdapter {
385386 this . _client = createClient ( uri , databaseOptions ) ;
386387 }
387388
388- _ensureSchemaCollectionExists ( ) {
389- return this . _client . none ( 'CREATE TABLE "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )' )
389+ _ensureSchemaCollectionExists ( conn ) {
390+ conn = conn || this . _client ;
391+ return conn . none ( 'CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )' )
390392 . catch ( error => {
391393 if ( error . code === PostgresDuplicateRelationError || error . code === PostgresUniqueIndexViolationError ) {
392394 // Table already exists, must have been created by a different request. Ignore error.
@@ -410,13 +412,20 @@ export class PostgresStorageAdapter {
410412 }
411413
412414 createClass ( className , schema ) {
413- return this . createTable ( className , schema ) . then ( ( ) => {
414- return this . _client . none ( 'INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)' , { className, schema } ) ;
415+ return this . _client . tx ( t => {
416+ const q1 = this . createTable ( className , schema , t ) ;
417+ const q2 = t . none ( 'INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)' , { className, schema } ) ;
418+
419+ return t . batch ( [ q1 , q2 ] ) ;
415420 } )
416421 . then ( ( ) => {
417422 return toParseSchema ( schema )
418423 } )
419424 . catch ( ( err ) => {
425+ if ( Array . isArray ( err . data ) && err . data . length > 1 && err . data [ 0 ] . result . code === PostgresTransactionAbortedError ) {
426+ err = err . data [ 1 ] . result ;
427+ }
428+
420429 if ( err . code === PostgresUniqueIndexViolationError && err . detail . includes ( className ) ) {
421430 throw new Parse . Error ( Parse . Error . DUPLICATE_VALUE , `Class ${ className } already exists.` )
422431 }
@@ -425,7 +434,8 @@ export class PostgresStorageAdapter {
425434 }
426435
427436 // Just create a table, do not insert in schema
428- createTable ( className , schema ) {
437+ createTable ( className , schema , conn ) {
438+ conn = conn || this . _client ;
429439 debug ( 'createTable' , className , schema ) ;
430440 let valuesArray = [ ] ;
431441 let patternsArray = [ ] ;
@@ -458,10 +468,10 @@ export class PostgresStorageAdapter {
458468 }
459469 index = index + 2 ;
460470 } ) ;
461- const qs = `CREATE TABLE $1:name (${ patternsArray . join ( ',' ) } )` ;
471+ const qs = `CREATE TABLE IF NOT EXISTS $1:name (${ patternsArray . join ( ',' ) } )` ;
462472 const values = [ className , ...valuesArray ] ;
463- return this . _ensureSchemaCollectionExists ( )
464- . then ( ( ) => this . _client . none ( qs , values ) )
473+ return this . _ensureSchemaCollectionExists ( conn )
474+ . then ( ( ) => conn . none ( qs , values ) )
465475 . catch ( error => {
466476 if ( error . code === PostgresDuplicateRelationError ) {
467477 // Table already exists, must have been created by a different request. Ignore error.
@@ -471,7 +481,7 @@ export class PostgresStorageAdapter {
471481 } ) . then ( ( ) => {
472482 // Create the relation tables
473483 return Promise . all ( relations . map ( ( fieldName ) => {
474- return this . _client . none ( 'CREATE TABLE IF NOT EXISTS $<joinTable:name> ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )' , { joinTable : `_Join:${ fieldName } :${ className } ` } ) ;
484+ return conn . none ( 'CREATE TABLE IF NOT EXISTS $<joinTable:name> ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )' , { joinTable : `_Join:${ fieldName } :${ className } ` } ) ;
475485 } ) ) ;
476486 } ) ;
477487 }
0 commit comments