@@ -9,7 +9,7 @@ const getColumns = (client, className) => {
9
9
return client . map (
10
10
'SELECT column_name FROM information_schema.columns WHERE table_name = $<className>' ,
11
11
{ className } ,
12
- a => a . column_name
12
+ ( a ) => a . column_name
13
13
) ;
14
14
} ;
15
15
@@ -25,7 +25,7 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
25
25
return adapter . deleteAllClasses ( ) ;
26
26
} ) ;
27
27
28
- it ( 'schemaUpgrade, upgrade the database schema when schema changes' , done => {
28
+ it ( 'schemaUpgrade, upgrade the database schema when schema changes' , ( done ) => {
29
29
const client = adapter . _client ;
30
30
const className = '_PushStatus' ;
31
31
const schema = {
@@ -39,7 +39,7 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
39
39
adapter
40
40
. createTable ( className , schema )
41
41
. then ( ( ) => getColumns ( client , className ) )
42
- . then ( columns => {
42
+ . then ( ( columns ) => {
43
43
expect ( columns ) . toContain ( 'pushTime' ) ;
44
44
expect ( columns ) . toContain ( 'source' ) ;
45
45
expect ( columns ) . toContain ( 'query' ) ;
@@ -49,17 +49,17 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
49
49
return adapter . schemaUpgrade ( className , schema ) ;
50
50
} )
51
51
. then ( ( ) => getColumns ( client , className ) )
52
- . then ( columns => {
52
+ . then ( ( columns ) => {
53
53
expect ( columns ) . toContain ( 'pushTime' ) ;
54
54
expect ( columns ) . toContain ( 'source' ) ;
55
55
expect ( columns ) . toContain ( 'query' ) ;
56
56
expect ( columns ) . toContain ( 'expiration_interval' ) ;
57
57
done ( ) ;
58
58
} )
59
- . catch ( error => done . fail ( error ) ) ;
59
+ . catch ( ( error ) => done . fail ( error ) ) ;
60
60
} ) ;
61
61
62
- it ( 'schemaUpgrade, maintain correct schema' , done => {
62
+ it ( 'schemaUpgrade, maintain correct schema' , ( done ) => {
63
63
const client = adapter . _client ;
64
64
const className = 'Table' ;
65
65
const schema = {
@@ -73,32 +73,32 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
73
73
adapter
74
74
. createTable ( className , schema )
75
75
. then ( ( ) => getColumns ( client , className ) )
76
- . then ( columns => {
76
+ . then ( ( columns ) => {
77
77
expect ( columns ) . toContain ( 'columnA' ) ;
78
78
expect ( columns ) . toContain ( 'columnB' ) ;
79
79
expect ( columns ) . toContain ( 'columnC' ) ;
80
80
81
81
return adapter . schemaUpgrade ( className , schema ) ;
82
82
} )
83
83
. then ( ( ) => getColumns ( client , className ) )
84
- . then ( columns => {
84
+ . then ( ( columns ) => {
85
85
expect ( columns . length ) . toEqual ( 3 ) ;
86
86
expect ( columns ) . toContain ( 'columnA' ) ;
87
87
expect ( columns ) . toContain ( 'columnB' ) ;
88
88
expect ( columns ) . toContain ( 'columnC' ) ;
89
89
90
90
done ( ) ;
91
91
} )
92
- . catch ( error => done . fail ( error ) ) ;
92
+ . catch ( ( error ) => done . fail ( error ) ) ;
93
93
} ) ;
94
94
95
- it ( 'Create a table without columns and upgrade with columns' , done => {
95
+ it ( 'Create a table without columns and upgrade with columns' , ( done ) => {
96
96
const client = adapter . _client ;
97
97
const className = 'EmptyTable' ;
98
98
dropTable ( client , className )
99
99
. then ( ( ) => adapter . createTable ( className , { } ) )
100
100
. then ( ( ) => getColumns ( client , className ) )
101
- . then ( columns => {
101
+ . then ( ( columns ) => {
102
102
expect ( columns . length ) . toBe ( 0 ) ;
103
103
104
104
const newSchema = {
@@ -111,7 +111,7 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
111
111
return adapter . schemaUpgrade ( className , newSchema ) ;
112
112
} )
113
113
. then ( ( ) => getColumns ( client , className ) )
114
- . then ( columns => {
114
+ . then ( ( columns ) => {
115
115
expect ( columns . length ) . toEqual ( 2 ) ;
116
116
expect ( columns ) . toContain ( 'columnA' ) ;
117
117
expect ( columns ) . toContain ( 'columnB' ) ;
@@ -176,10 +176,10 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
176
176
) ;
177
177
await client
178
178
. one ( analyzedExplainQuery , [ tableName , 'objectId' , caseInsensitiveData ] )
179
- . then ( explained => {
179
+ . then ( ( explained ) => {
180
180
const preIndexPlan = explained ;
181
181
182
- preIndexPlan [ 'QUERY PLAN' ] . forEach ( element => {
182
+ preIndexPlan [ 'QUERY PLAN' ] . forEach ( ( element ) => {
183
183
//Make sure search returned with only 1 result
184
184
expect ( element . Plan [ 'Actual Rows' ] ) . toBe ( 1 ) ;
185
185
expect ( element . Plan [ 'Node Type' ] ) . toBe ( 'Seq Scan' ) ;
@@ -195,17 +195,17 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
195
195
'objectId' ,
196
196
caseInsensitiveData ,
197
197
] )
198
- . then ( explained => {
198
+ . then ( ( explained ) => {
199
199
const postIndexPlan = explained ;
200
200
201
- postIndexPlan [ 'QUERY PLAN' ] . forEach ( element => {
201
+ postIndexPlan [ 'QUERY PLAN' ] . forEach ( ( element ) => {
202
202
//Make sure search returned with only 1 result
203
203
expect ( element . Plan [ 'Actual Rows' ] ) . toBe ( 1 ) ;
204
204
//Should not be a sequential scan
205
205
expect ( element . Plan [ 'Node Type' ] ) . not . toContain ( 'Seq Scan' ) ;
206
206
207
207
//Should be using the index created for this
208
- element . Plan . Plans . forEach ( innerElement => {
208
+ element . Plan . Plans . forEach ( ( innerElement ) => {
209
209
expect ( innerElement [ 'Index Name' ] ) . toBe ( indexName ) ;
210
210
} ) ;
211
211
} ) ;
@@ -230,8 +230,8 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
230
230
'objectId' ,
231
231
caseInsensitiveData ,
232
232
] )
233
- . then ( explained => {
234
- explained [ 'QUERY PLAN' ] . forEach ( element => {
233
+ . then ( ( explained ) => {
234
+ explained [ 'QUERY PLAN' ] . forEach ( ( element ) => {
235
235
//Check that basic query plans isn't a sequential scan
236
236
expect ( element . Plan [ 'Node Type' ] ) . not . toContain (
237
237
'Seq Scan'
@@ -244,7 +244,7 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
244
244
} ) ;
245
245
} ) ;
246
246
} )
247
- . catch ( error => {
247
+ . catch ( ( error ) => {
248
248
// Query on non existing table, don't crash
249
249
if ( error . code !== '42P01' ) {
250
250
throw error ;
@@ -276,8 +276,8 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
276
276
{ caseInsensitive : true , explain : true }
277
277
) ;
278
278
279
- preIndexPlan . forEach ( element => {
280
- element [ 'QUERY PLAN' ] . forEach ( innerElement => {
279
+ preIndexPlan . forEach ( ( element ) => {
280
+ element [ 'QUERY PLAN' ] . forEach ( ( innerElement ) => {
281
281
//Check that basic query plans isn't a sequential scan, be careful as find uses "any" to query
282
282
expect ( innerElement . Plan [ 'Node Type' ] ) . toBe ( 'Seq Scan' ) ;
283
283
//Basic query plans shouldn't have an execution time
@@ -302,8 +302,8 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
302
302
{ caseInsensitive : true , explain : true }
303
303
) ;
304
304
305
- postIndexPlan . forEach ( element => {
306
- element [ 'QUERY PLAN' ] . forEach ( innerElement => {
305
+ postIndexPlan . forEach ( ( element ) => {
306
+ element [ 'QUERY PLAN' ] . forEach ( ( innerElement ) => {
307
307
//Check that basic query plans isn't a sequential scan
308
308
expect ( innerElement . Plan [ 'Node Type' ] ) . not . toContain ( 'Seq Scan' ) ;
309
309
@@ -339,13 +339,73 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
339
339
{ username : caseInsensitiveData } ,
340
340
{ caseInsensitive : true , explain : true }
341
341
) ;
342
- indexPlan . forEach ( element => {
343
- element [ 'QUERY PLAN' ] . forEach ( innerElement => {
342
+ indexPlan . forEach ( ( element ) => {
343
+ element [ 'QUERY PLAN' ] . forEach ( ( innerElement ) => {
344
344
expect ( innerElement . Plan [ 'Node Type' ] ) . not . toContain ( 'Seq Scan' ) ;
345
345
expect ( innerElement . Plan [ 'Index Name' ] ) . toContain ( 'parse_default' ) ;
346
346
} ) ;
347
347
} ) ;
348
348
} ) ;
349
+
350
+ it ( 'should allow multiple unique indexes for same field name and different class' , async ( ) => {
351
+ const firstTableName = 'Test1' ;
352
+ const firstTableSchema = new Parse . Schema ( firstTableName ) ;
353
+ const uniqueField = 'uuid' ;
354
+ firstTableSchema . addString ( uniqueField ) ;
355
+ await firstTableSchema . save ( ) ;
356
+ await firstTableSchema . get ( ) ;
357
+
358
+ const secondTableName = 'Test2' ;
359
+ const secondTableSchema = new Parse . Schema ( secondTableName ) ;
360
+ secondTableSchema . addString ( uniqueField ) ;
361
+ await secondTableSchema . save ( ) ;
362
+ await secondTableSchema . get ( ) ;
363
+
364
+ const database = Config . get ( Parse . applicationId ) . database ;
365
+
366
+ //Create index before data is inserted
367
+ await adapter . ensureUniqueness ( firstTableName , firstTableSchema , [
368
+ uniqueField ,
369
+ ] ) ;
370
+ await adapter . ensureUniqueness ( secondTableName , secondTableSchema , [
371
+ uniqueField ,
372
+ ] ) ;
373
+
374
+ //Postgres won't take advantage of the index until it has a lot of records because sequential is faster for small db's
375
+ const client = adapter . _client ;
376
+ await client . none (
377
+ 'INSERT INTO $1:name ($2:name, $3:name) SELECT MD5(random()::text), MD5(random()::text) FROM generate_series(1,5000)' ,
378
+ [ firstTableName , 'objectId' , uniqueField ]
379
+ ) ;
380
+ await client . none (
381
+ 'INSERT INTO $1:name ($2:name, $3:name) SELECT MD5(random()::text), MD5(random()::text) FROM generate_series(1,5000)' ,
382
+ [ secondTableName , 'objectId' , uniqueField ]
383
+ ) ;
384
+
385
+ //Check using find method for Parse
386
+ const indexPlan = await database . find (
387
+ firstTableName ,
388
+ { uuid : '1234' } ,
389
+ { caseInsensitive : false , explain : true }
390
+ ) ;
391
+ indexPlan . forEach ( ( element ) => {
392
+ element [ 'QUERY PLAN' ] . forEach ( ( innerElement ) => {
393
+ expect ( innerElement . Plan [ 'Node Type' ] ) . not . toContain ( 'Seq Scan' ) ;
394
+ expect ( innerElement . Plan [ 'Index Name' ] ) . toContain ( uniqueField ) ;
395
+ } ) ;
396
+ } ) ;
397
+ const indexPlan2 = await database . find (
398
+ secondTableName ,
399
+ { uuid : '1234' } ,
400
+ { caseInsensitive : false , explain : true }
401
+ ) ;
402
+ indexPlan2 . forEach ( ( element ) => {
403
+ element [ 'QUERY PLAN' ] . forEach ( ( innerElement ) => {
404
+ expect ( innerElement . Plan [ 'Node Type' ] ) . not . toContain ( 'Seq Scan' ) ;
405
+ expect ( innerElement . Plan [ 'Index Name' ] ) . toContain ( uniqueField ) ;
406
+ } ) ;
407
+ } ) ;
408
+ } ) ;
349
409
} ) ;
350
410
351
411
describe_only_db ( 'postgres' ) ( 'PostgresStorageAdapter shutdown' , ( ) => {
0 commit comments