build: release
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
const url = require('url');
|
||||
const fs = require('fs');
|
||||
function getDatabaseOptionsFromURI(uri) {
|
||||
const databaseOptions = {};
|
||||
|
||||
const parsedURI = url.parse(uri);
|
||||
const queryParams = parseQueryParams(parsedURI.query);
|
||||
const authParts = parsedURI.auth ? parsedURI.auth.split(':') : [];
|
||||
const parsedURI = new URL(uri);
|
||||
const queryParams = parseQueryParams(parsedURI.searchParams.toString());
|
||||
|
||||
databaseOptions.host = parsedURI.hostname || 'localhost';
|
||||
databaseOptions.port = parsedURI.port ? parseInt(parsedURI.port) : 5432;
|
||||
databaseOptions.database = parsedURI.pathname ? parsedURI.pathname.substr(1) : undefined;
|
||||
|
||||
databaseOptions.user = authParts.length > 0 ? authParts[0] : '';
|
||||
databaseOptions.password = authParts.length > 1 ? authParts[1] : '';
|
||||
databaseOptions.user = parsedURI.username;
|
||||
databaseOptions.password = parsedURI.password;
|
||||
|
||||
if (queryParams.ssl && queryParams.ssl.toLowerCase() === 'true') {
|
||||
databaseOptions.ssl = true;
|
||||
|
||||
@@ -7,12 +7,14 @@ import _ from 'lodash';
|
||||
// @flow-disable-next
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import sql from './sql';
|
||||
import { StorageAdapter } from '../StorageAdapter';
|
||||
import type { SchemaType, QueryType, QueryOptions } from '../StorageAdapter';
|
||||
const Utils = require('../../../Utils');
|
||||
|
||||
const PostgresRelationDoesNotExistError = '42P01';
|
||||
const PostgresDuplicateRelationError = '42P07';
|
||||
const PostgresDuplicateColumnError = '42701';
|
||||
const PostgresMissingColumnError = '42703';
|
||||
const PostgresDuplicateObjectError = '42710';
|
||||
const PostgresUniqueIndexViolationError = '23505';
|
||||
const logger = require('../../../logger');
|
||||
|
||||
@@ -22,9 +24,6 @@ const debug = function (...args: any) {
|
||||
log.debug.apply(log, args);
|
||||
};
|
||||
|
||||
import { StorageAdapter } from '../StorageAdapter';
|
||||
import type { SchemaType, QueryType, QueryOptions } from '../StorageAdapter';
|
||||
|
||||
const parseTypeToPostgresType = type => {
|
||||
switch (type.type) {
|
||||
case 'String':
|
||||
@@ -374,6 +373,11 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
|
||||
patterns.push(
|
||||
`(${constraintFieldName} <> $${index} OR ${constraintFieldName} IS NULL)`
|
||||
);
|
||||
} else if (typeof fieldValue.$ne === 'object' && fieldValue.$ne.$relativeTime) {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
'$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'
|
||||
);
|
||||
} else {
|
||||
patterns.push(`($${index}:name <> $${index + 1} OR $${index}:name IS NULL)`);
|
||||
}
|
||||
@@ -399,6 +403,11 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
|
||||
if (fieldName.indexOf('.') >= 0) {
|
||||
values.push(fieldValue.$eq);
|
||||
patterns.push(`${transformDotField(fieldName)} = $${index++}`);
|
||||
} else if (typeof fieldValue.$eq === 'object' && fieldValue.$eq.$relativeTime) {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
'$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'
|
||||
);
|
||||
} else {
|
||||
values.push(fieldName, fieldValue.$eq);
|
||||
patterns.push(`$${index}:name = $${index + 1}`);
|
||||
@@ -513,7 +522,12 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
|
||||
}
|
||||
|
||||
if (typeof fieldValue.$exists !== 'undefined') {
|
||||
if (fieldValue.$exists) {
|
||||
if (typeof fieldValue.$exists === 'object' && fieldValue.$exists.$relativeTime) {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
'$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'
|
||||
);
|
||||
} else if (fieldValue.$exists) {
|
||||
patterns.push(`$${index}:name IS NOT NULL`);
|
||||
} else {
|
||||
patterns.push(`$${index}:name IS NULL`);
|
||||
@@ -757,7 +771,7 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
|
||||
Object.keys(ParseToPosgresComparator).forEach(cmp => {
|
||||
if (fieldValue[cmp] || fieldValue[cmp] === 0) {
|
||||
const pgComparator = ParseToPosgresComparator[cmp];
|
||||
const postgresValue = toPostgresValue(fieldValue[cmp]);
|
||||
let postgresValue = toPostgresValue(fieldValue[cmp]);
|
||||
let constraintFieldName;
|
||||
if (fieldName.indexOf('.') >= 0) {
|
||||
let castType;
|
||||
@@ -775,6 +789,24 @@ const buildWhereClause = ({ schema, query, index, caseInsensitive }): WhereClaus
|
||||
? `CAST ((${transformDotField(fieldName)}) AS ${castType})`
|
||||
: transformDotField(fieldName);
|
||||
} else {
|
||||
if (typeof postgresValue === 'object' && postgresValue.$relativeTime) {
|
||||
if (schema.fields[fieldName].type !== 'Date') {
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
'$relativeTime can only be used with Date field'
|
||||
);
|
||||
}
|
||||
const parserResult = Utils.relativeTimeToDate(postgresValue.$relativeTime);
|
||||
if (parserResult.status === 'success') {
|
||||
postgresValue = toPostgresValue(parserResult.result);
|
||||
} else {
|
||||
console.error('Error while parsing relative date', parserResult);
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_JSON,
|
||||
`bad $relativeTime (${postgresValue.$relativeTime}) value. ${parserResult.info}`
|
||||
);
|
||||
}
|
||||
}
|
||||
constraintFieldName = `$${index++}:name`;
|
||||
values.push(fieldName);
|
||||
}
|
||||
@@ -873,15 +905,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
|
||||
'CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )'
|
||||
)
|
||||
.catch(error => {
|
||||
if (
|
||||
error.code === PostgresDuplicateRelationError ||
|
||||
error.code === PostgresUniqueIndexViolationError ||
|
||||
error.code === PostgresDuplicateObjectError
|
||||
) {
|
||||
// Table already exists, must have been created by a different request. Ignore error.
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2416,6 +2440,11 @@ export class PostgresStorageAdapter implements StorageAdapter {
|
||||
? fieldNames.map((fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`)
|
||||
: fieldNames.map((fieldName, index) => `$${index + 3}:name`);
|
||||
const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`;
|
||||
const setIdempotencyFunction =
|
||||
options.setIdempotencyFunction !== undefined ? options.setIdempotencyFunction : false;
|
||||
if (setIdempotencyFunction) {
|
||||
await this.ensureIdempotencyFunctionExists(options);
|
||||
}
|
||||
await conn.none(qs, [indexNameOptions.name, className, ...fieldNames]).catch(error => {
|
||||
if (
|
||||
error.code === PostgresDuplicateRelationError &&
|
||||
@@ -2436,6 +2465,24 @@ export class PostgresStorageAdapter implements StorageAdapter {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async deleteIdempotencyFunction(options?: Object = {}): Promise<any> {
|
||||
const conn = options.conn !== undefined ? options.conn : this._client;
|
||||
const qs = 'DROP FUNCTION IF EXISTS idempotency_delete_expired_records()';
|
||||
return conn.none(qs).catch(error => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
async ensureIdempotencyFunctionExists(options?: Object = {}): Promise<any> {
|
||||
const conn = options.conn !== undefined ? options.conn : this._client;
|
||||
const ttlOptions = options.ttl !== undefined ? `${options.ttl} seconds` : '60 seconds';
|
||||
const qs =
|
||||
'CREATE OR REPLACE FUNCTION idempotency_delete_expired_records() RETURNS void LANGUAGE plpgsql AS $$ BEGIN DELETE FROM "_Idempotency" WHERE expire < NOW() - INTERVAL $1; END; $$;';
|
||||
return conn.none(qs, [ttlOptions]).catch(error => {
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function convertPolygonToSQL(polygon) {
|
||||
|
||||
Reference in New Issue
Block a user