@@ -4,6 +4,7 @@ const PostgresRelationDoesNotExistError = '42P01';
4
4
const PostgresDuplicateRelationError = '42P07' ;
5
5
const PostgresDuplicateColumnError = '42701' ;
6
6
const PostgresUniqueIndexViolationError = '23505' ;
7
+ const PostgresTransactionAbortedError = '25P02' ;
7
8
const logger = require ( '../../../logger' ) ;
8
9
9
10
const debug = function ( ) {
@@ -385,8 +386,9 @@ export class PostgresStorageAdapter {
385
386
this . _client = createClient ( uri , databaseOptions ) ;
386
387
}
387
388
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") )' )
390
392
. catch ( error => {
391
393
if ( error . code === PostgresDuplicateRelationError || error . code === PostgresUniqueIndexViolationError ) {
392
394
// Table already exists, must have been created by a different request. Ignore error.
@@ -410,13 +412,20 @@ export class PostgresStorageAdapter {
410
412
}
411
413
412
414
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 ] ) ;
415
420
} )
416
421
. then ( ( ) => {
417
422
return toParseSchema ( schema )
418
423
} )
419
424
. 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
+
420
429
if ( err . code === PostgresUniqueIndexViolationError && err . detail . includes ( className ) ) {
421
430
throw new Parse . Error ( Parse . Error . DUPLICATE_VALUE , `Class ${ className } already exists.` )
422
431
}
@@ -425,7 +434,8 @@ export class PostgresStorageAdapter {
425
434
}
426
435
427
436
// Just create a table, do not insert in schema
428
- createTable ( className , schema ) {
437
+ createTable ( className , schema , conn ) {
438
+ conn = conn || this . _client ;
429
439
debug ( 'createTable' , className , schema ) ;
430
440
let valuesArray = [ ] ;
431
441
let patternsArray = [ ] ;
@@ -458,10 +468,10 @@ export class PostgresStorageAdapter {
458
468
}
459
469
index = index + 2 ;
460
470
} ) ;
461
- const qs = `CREATE TABLE $1:name (${ patternsArray . join ( ',' ) } )` ;
471
+ const qs = `CREATE TABLE IF NOT EXISTS $1:name (${ patternsArray . join ( ',' ) } )` ;
462
472
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 ) )
465
475
. catch ( error => {
466
476
if ( error . code === PostgresDuplicateRelationError ) {
467
477
// Table already exists, must have been created by a different request. Ignore error.
@@ -471,7 +481,7 @@ export class PostgresStorageAdapter {
471
481
} ) . then ( ( ) => {
472
482
// Create the relation tables
473
483
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 } ` } ) ;
475
485
} ) ) ;
476
486
} ) ;
477
487
}
0 commit comments