Update PostgresStorageAdapter.js (#6275)

* Update PostgresStorageAdapter.js

Improving use of the `await.async` notation in relation to `pg-promise`, and in general.

* Update PostgresStorageAdapter.js

* Update PostgresStorageAdapter.js

Correcting some results.

* Update PostgresStorageAdapter.js
This commit is contained in:
Vitaly Tomilov
2019-12-16 18:50:31 +00:00
committed by Diamond Lewis
parent a72ab50c70
commit 2d665c96a3

View File

@@ -829,9 +829,9 @@ export class PostgresStorageAdapter implements StorageAdapter {
this._client.$pool.end(); this._client.$pool.end();
} }
_ensureSchemaCollectionExists(conn: any) { async _ensureSchemaCollectionExists(conn: any) {
conn = conn || this._client; conn = conn || this._client;
return conn await conn
.none( .none(
'CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )' 'CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )'
) )
@@ -848,7 +848,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
classExists(name: string) { async classExists(name: string) {
return this._client.one( return this._client.one(
'SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)', 'SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)',
[name], [name],
@@ -856,9 +856,9 @@ export class PostgresStorageAdapter implements StorageAdapter {
); );
} }
setClassLevelPermissions(className: string, CLPs: any) { async setClassLevelPermissions(className: string, CLPs: any) {
const self = this; const self = this;
return this._client.task('set-class-level-permissions', async t => { await this._client.task('set-class-level-permissions', async t => {
await self._ensureSchemaCollectionExists(t); await self._ensureSchemaCollectionExists(t);
const values = [ const values = [
className, className,
@@ -867,13 +867,13 @@ export class PostgresStorageAdapter implements StorageAdapter {
JSON.stringify(CLPs), JSON.stringify(CLPs),
]; ];
await t.none( await t.none(
`UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className"=$1`, `UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1`,
values values
); );
}); });
} }
setIndexesWithSchemaFormat( async setIndexesWithSchemaFormat(
className: string, className: string,
submittedIndexes: any, submittedIndexes: any,
existingIndexes: any = {}, existingIndexes: any = {},
@@ -923,7 +923,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
}); });
return conn.tx('set-indexes-with-schema-format', async t => { await conn.tx('set-indexes-with-schema-format', async t => {
if (insertedIndexes.length > 0) { if (insertedIndexes.length > 0) {
await self.createIndexes(className, insertedIndexes, t); await self.createIndexes(className, insertedIndexes, t);
} }
@@ -932,16 +932,16 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
await self._ensureSchemaCollectionExists(t); await self._ensureSchemaCollectionExists(t);
await t.none( await t.none(
'UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className"=$1', 'UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1',
[className, 'schema', 'indexes', JSON.stringify(existingIndexes)] [className, 'schema', 'indexes', JSON.stringify(existingIndexes)]
); );
}); });
} }
createClass(className: string, schema: SchemaType, conn: ?any) { async createClass(className: string, schema: SchemaType, conn: ?any) {
conn = conn || this._client; conn = conn || this._client;
return conn return conn
.tx('create-class', t => { .tx('create-class', async t => {
const q1 = this.createTable(className, schema, t); const q1 = this.createTable(className, schema, t);
const q2 = t.none( const q2 = t.none(
'INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)', 'INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)',
@@ -954,6 +954,8 @@ export class PostgresStorageAdapter implements StorageAdapter {
schema.fields, schema.fields,
t t
); );
// TODO: The test should not verify the returned value, and then
// the method can be simplified, to avoid returning useless stuff.
return t.batch([q1, q2, q3]); return t.batch([q1, q2, q3]);
}) })
.then(() => { .then(() => {
@@ -977,7 +979,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
// Just create a table, do not insert in schema // Just create a table, do not insert in schema
createTable(className: string, schema: SchemaType, conn: any) { async createTable(className: string, schema: SchemaType, conn: any) {
conn = conn || this._client; conn = conn || this._client;
const self = this; const self = this;
debug('createTable', className, schema); debug('createTable', className, schema);
@@ -1042,12 +1044,12 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
schemaUpgrade(className: string, schema: SchemaType, conn: any) { async schemaUpgrade(className: string, schema: SchemaType, conn: any) {
debug('schemaUpgrade', { className, schema }); debug('schemaUpgrade', { className, schema });
conn = conn || this._client; conn = conn || this._client;
const self = this; const self = this;
return conn.tx('schema-upgrade', async t => { await conn.tx('schema-upgrade', async t => {
const columns = await t.map( const columns = await t.map(
'SELECT column_name FROM information_schema.columns WHERE table_name = $<className>', 'SELECT column_name FROM information_schema.columns WHERE table_name = $<className>',
{ className }, { className },
@@ -1068,7 +1070,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
addFieldIfNotExists( async addFieldIfNotExists(
className: string, className: string,
fieldName: string, fieldName: string,
type: any, type: any,
@@ -1078,7 +1080,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
debug('addFieldIfNotExists', { className, fieldName, type }); debug('addFieldIfNotExists', { className, fieldName, type });
conn = conn || this._client; conn = conn || this._client;
const self = this; const self = this;
return conn.tx('add-field-if-not-exists', async t => { await conn.tx('add-field-if-not-exists', async t => {
if (type.type !== 'Relation') { if (type.type !== 'Relation') {
try { try {
await t.none( await t.none(
@@ -1091,7 +1093,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
); );
} catch (error) { } catch (error) {
if (error.code === PostgresRelationDoesNotExistError) { if (error.code === PostgresRelationDoesNotExistError) {
return await self.createClass( return self.createClass(
className, className,
{ fields: { [fieldName]: type } }, { fields: { [fieldName]: type } },
t t
@@ -1128,7 +1130,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
// 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.)
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
deleteClass(className: string) { async deleteClass(className: string) {
const operations = [ const operations = [
{ query: `DROP TABLE IF EXISTS $1:name`, values: [className] }, { query: `DROP TABLE IF EXISTS $1:name`, values: [className] },
{ {
@@ -1142,12 +1144,12 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
// Delete all data known to this adapter. Used for testing. // Delete all data known to this adapter. Used for testing.
deleteAllClasses() { async deleteAllClasses() {
const now = new Date().getTime(); const now = new Date().getTime();
const helpers = this._pgp.helpers; const helpers = this._pgp.helpers;
debug('deleteAllClasses'); debug('deleteAllClasses');
return this._client await this._client
.task('delete-all-classes', async t => { .task('delete-all-classes', async t => {
try { try {
const results = await t.any('SELECT * FROM "_SCHEMA"'); const results = await t.any('SELECT * FROM "_SCHEMA"');
@@ -1196,7 +1198,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
// may do so. // may do so.
// Returns a Promise. // Returns a Promise.
deleteFields( async deleteFields(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
fieldNames: string[] fieldNames: string[]
@@ -1218,9 +1220,9 @@ export class PostgresStorageAdapter implements StorageAdapter {
}) })
.join(', DROP COLUMN'); .join(', DROP COLUMN');
return this._client.tx('delete-fields', async t => { await this._client.tx('delete-fields', async t => {
await t.none( await t.none(
'UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>', 'UPDATE "_SCHEMA" SET "schema" = $<schema> WHERE "className" = $<className>',
{ schema, className } { schema, className }
); );
if (values.length > 1) { if (values.length > 1) {
@@ -1232,7 +1234,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
// Return a promise for all schemas known to this adapter, in Parse format. In case the // Return a promise for all schemas known to this adapter, in Parse format. In case the
// schemas cannot be retrieved, returns a promise that rejects. Requirements for the // schemas cannot be retrieved, returns a promise that rejects. Requirements for the
// rejection reason are TBD. // rejection reason are TBD.
getAllClasses() { async getAllClasses() {
const self = this; const self = this;
return this._client.task('get-all-classes', async t => { return this._client.task('get-all-classes', async t => {
await self._ensureSchemaCollectionExists(t); await self._ensureSchemaCollectionExists(t);
@@ -1245,10 +1247,10 @@ export class PostgresStorageAdapter implements StorageAdapter {
// Return a promise for the schema with the given name, in Parse format. If // Return a promise for the schema with the given name, in Parse format. If
// this adapter doesn't know about the schema, return a promise that rejects with // this adapter doesn't know about the schema, return a promise that rejects with
// undefined as the reason. // undefined as the reason.
getClass(className: string) { async getClass(className: string) {
debug('getClass', className); debug('getClass', className);
return this._client return this._client
.any('SELECT * FROM "_SCHEMA" WHERE "className"=$<className>', { .any('SELECT * FROM "_SCHEMA" WHERE "className" = $<className>', {
className, className,
}) })
.then(result => { .then(result => {
@@ -1261,7 +1263,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
// TODO: remove the mongo format dependency in the return value // TODO: remove the mongo format dependency in the return value
createObject( async createObject(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
object: any, object: any,
@@ -1426,7 +1428,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
// Remove all objects that match the given Parse Query. // Remove all objects that match the given Parse Query.
// If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined.
// If there is some other error, reject with INTERNAL_SERVER_ERROR. // If there is some other error, reject with INTERNAL_SERVER_ERROR.
deleteObjectsByQuery( async deleteObjectsByQuery(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
query: QueryType, query: QueryType,
@@ -1469,7 +1471,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
return promise; return promise;
} }
// Return value not currently well specified. // Return value not currently well specified.
findOneAndUpdate( async findOneAndUpdate(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
query: QueryType, query: QueryType,
@@ -1487,7 +1489,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
// Apply the update to all objects that match the given Parse Query. // Apply the update to all objects that match the given Parse Query.
updateObjectsByQuery( async updateObjectsByQuery(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
query: QueryType, query: QueryType,
@@ -1980,7 +1982,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
// As such, we shouldn't expose this function to users of parse until we have an out-of-band // As such, we shouldn't expose this function to users of parse until we have an out-of-band
// Way of determining if a field is nullable. Undefined doesn't count against uniqueness, // Way of determining if a field is nullable. Undefined doesn't count against uniqueness,
// which is why we use sparse indexes. // which is why we use sparse indexes.
ensureUniqueness( async ensureUniqueness(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
fieldNames: string[] fieldNames: string[]
@@ -2016,7 +2018,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
} }
// Executes a count. // Executes a count.
count( async count(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
query: QueryType, query: QueryType,
@@ -2055,7 +2057,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
distinct( async distinct(
className: string, className: string,
schema: SchemaType, schema: SchemaType,
query: QueryType, query: QueryType,
@@ -2121,7 +2123,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
); );
} }
aggregate(className: string, schema: any, pipeline: any) { async aggregate(className: string, schema: any, pipeline: any) {
debug('aggregate', className, pipeline); debug('aggregate', className, pipeline);
const values = [className]; const values = [className];
let index: number = 2; let index: number = 2;
@@ -2323,7 +2325,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
performInitialization({ VolatileClassesSchemas }: any) { async performInitialization({ VolatileClassesSchemas }: any) {
// TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t) // TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t)
debug('performInitialization'); debug('performInitialization');
const promises = VolatileClassesSchemas.map(schema => { const promises = VolatileClassesSchemas.map(schema => {
@@ -2362,7 +2364,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
}); });
} }
createIndexes(className: string, indexes: any, conn: ?any): Promise<void> { async createIndexes(className: string, indexes: any, conn: ?any): Promise<void> {
return (conn || this._client).tx(t => return (conn || this._client).tx(t =>
t.batch( t.batch(
indexes.map(i => { indexes.map(i => {
@@ -2376,43 +2378,43 @@ export class PostgresStorageAdapter implements StorageAdapter {
); );
} }
createIndexesIfNeeded( async createIndexesIfNeeded(
className: string, className: string,
fieldName: string, fieldName: string,
type: any, type: any,
conn: ?any conn: ?any
): Promise<void> { ): Promise<void> {
return (conn || this._client).none( await (conn || this._client).none(
'CREATE INDEX $1:name ON $2:name ($3:name)', 'CREATE INDEX $1:name ON $2:name ($3:name)',
[fieldName, className, type] [fieldName, className, type]
); );
} }
dropIndexes(className: string, indexes: any, conn: any): Promise<void> { async dropIndexes(className: string, indexes: any, conn: any): Promise<void> {
const queries = indexes.map(i => ({ const queries = indexes.map(i => ({
query: 'DROP INDEX $1:name', query: 'DROP INDEX $1:name',
values: i, values: i,
})); }));
return (conn || this._client).tx(t => await (conn || this._client).tx(t =>
t.none(this._pgp.helpers.concat(queries)) t.none(this._pgp.helpers.concat(queries))
); );
} }
getIndexes(className: string) { async getIndexes(className: string) {
const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}'; const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}';
return this._client.any(qs, { className }); return this._client.any(qs, { className });
} }
updateSchemaWithIndexes(): Promise<void> { async updateSchemaWithIndexes(): Promise<void> {
return Promise.resolve(); return Promise.resolve();
} }
// Used for testing purposes // Used for testing purposes
updateEstimatedCount(className: string) { async updateEstimatedCount(className: string) {
return this._client.none('ANALYZE $1:name', [className]); return this._client.none('ANALYZE $1:name', [className]);
} }
createTransactionalSession(): Promise<any> { async createTransactionalSession(): Promise<any> {
return new Promise(resolve => { return new Promise(resolve => {
const transactionalSession = {}; const transactionalSession = {};
transactionalSession.result = this._client.tx(t => { transactionalSession.result = this._client.tx(t => {