Allow configuration options for Postgres (#2873)
* Allow configuration options for Postgres * Fix the use of incorrect options object. * Refactor and test the postgres config parser. * Remove unnecessary try/catch * Remove unnecessary try/catch * Add blank line at the end of the test file * Rename file for consistency purposes
This commit is contained in:
committed by
Florent Vilmart
parent
7af320932a
commit
de36d9640b
65
spec/PostgresConfigParser.spec.js
Normal file
65
spec/PostgresConfigParser.spec.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const parser = require('../src/Adapters/Storage/Postgres/PostgresConfigParser');
|
||||
|
||||
const queryParamTests = {
|
||||
'a=1&b=2': { a: '1', b: '2' },
|
||||
'a=abcd%20efgh&b=abcd%3Defgh': { a: 'abcd efgh', b: 'abcd=efgh' },
|
||||
'a=1&b&c=true': { a: '1', b: '', c: 'true' }
|
||||
}
|
||||
|
||||
describe('PostgresConfigParser.parseQueryParams', () => {
|
||||
it('creates a map from a query string', () => {
|
||||
|
||||
for (const key in queryParamTests) {
|
||||
const result = parser.parseQueryParams(key);
|
||||
|
||||
const testObj = queryParamTests[key];
|
||||
|
||||
expect(Object.keys(result).length)
|
||||
.toEqual(Object.keys(testObj).length);
|
||||
|
||||
for (const k in result) {
|
||||
expect(result[k]).toEqual(testObj[k]);
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
const baseURI = 'postgres://username:password@localhost:5432/db-name'
|
||||
|
||||
const dbOptionsTest = {};
|
||||
dbOptionsTest[`${baseURI}?ssl=true&binary=true&application_name=app_name&fallback_application_name=f_app_name&poolSize=10`] = {
|
||||
ssl: true,
|
||||
binary: true,
|
||||
application_name: 'app_name',
|
||||
fallback_application_name: 'f_app_name',
|
||||
poolSize: 10
|
||||
};
|
||||
dbOptionsTest[`${baseURI}?ssl=&binary=aa`] = {
|
||||
ssl: false,
|
||||
binary: false
|
||||
}
|
||||
|
||||
describe('PostgresConfigParser.getDatabaseOptionsFromURI', () => {
|
||||
it('creates a db options map from a query string', () => {
|
||||
|
||||
for (const key in dbOptionsTest) {
|
||||
const result = parser.getDatabaseOptionsFromURI(key);
|
||||
|
||||
const testObj = dbOptionsTest[key];
|
||||
|
||||
for (const k in testObj) {
|
||||
expect(result[k]).toEqual(testObj[k]);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('sets the poolSize to 10 if the it is not a number', () => {
|
||||
|
||||
const result = parser.getDatabaseOptionsFromURI(`${baseURI}?poolSize=sdf`);
|
||||
|
||||
expect(result.poolSize).toEqual(10);
|
||||
|
||||
});
|
||||
});
|
||||
26
src/Adapters/Storage/Postgres/PostgresClient.js
Normal file
26
src/Adapters/Storage/Postgres/PostgresClient.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const pgp = require('pg-promise')();
|
||||
const parser = require('./PostgresConfigParser');
|
||||
|
||||
export function createClient(uri, databaseOptions) {
|
||||
let client;
|
||||
let dbOptions = {};
|
||||
databaseOptions = databaseOptions || {};
|
||||
|
||||
if (uri) {
|
||||
dbOptions = parser.getDatabaseOptionsFromURI(uri);
|
||||
}
|
||||
|
||||
for (const key in databaseOptions) {
|
||||
dbOptions[key] = databaseOptions[key];
|
||||
}
|
||||
|
||||
client = pgp(dbOptions);
|
||||
|
||||
if (dbOptions.pgOptions) {
|
||||
for (const key in dbOptions.pgOptions) {
|
||||
client.pg.defaults[key] = dbOptions.pgOptions[key];
|
||||
}
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
53
src/Adapters/Storage/Postgres/PostgresConfigParser.js
Normal file
53
src/Adapters/Storage/Postgres/PostgresConfigParser.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const url = require('url');
|
||||
|
||||
function getDatabaseOptionsFromURI(uri) {
|
||||
const databaseOptions = {};
|
||||
|
||||
const parsedURI = url.parse(uri);
|
||||
const queryParams = parseQueryParams(parsedURI.query);
|
||||
const authParts = parsedURI.auth ? parsedURI.auth.split(':') : [];
|
||||
|
||||
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.ssl =
|
||||
queryParams.ssl && queryParams.ssl.toLowerCase() === 'true' ? true : false;
|
||||
databaseOptions.binary =
|
||||
queryParams.binary && queryParams.binary.toLowerCase() === 'true' ? true : false;
|
||||
|
||||
databaseOptions.client_encoding = queryParams.client_encoding;
|
||||
databaseOptions.application_name = queryParams.application_name;
|
||||
databaseOptions.fallback_application_name = queryParams.fallback_application_name;
|
||||
|
||||
if (queryParams.poolSize) {
|
||||
databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10;
|
||||
}
|
||||
|
||||
return databaseOptions;
|
||||
}
|
||||
|
||||
function parseQueryParams(queryString) {
|
||||
queryString = queryString || '';
|
||||
|
||||
return queryString
|
||||
.split('&')
|
||||
.reduce((p, c) => {
|
||||
const parts = c.split('=');
|
||||
p[decodeURIComponent(parts[0])] =
|
||||
parts.length > 1
|
||||
? decodeURIComponent(parts.slice(1).join('='))
|
||||
: '';
|
||||
return p;
|
||||
}, {});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parseQueryParams: parseQueryParams,
|
||||
getDatabaseOptionsFromURI: getDatabaseOptionsFromURI
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
const pgp = require('pg-promise')();
|
||||
import { createClient } from './PostgresClient';
|
||||
|
||||
const PostgresRelationDoesNotExistError = '42P01';
|
||||
const PostgresDuplicateRelationError = '42P07';
|
||||
@@ -379,9 +379,10 @@ export class PostgresStorageAdapter {
|
||||
constructor({
|
||||
uri,
|
||||
collectionPrefix = '',
|
||||
databaseOptions
|
||||
}) {
|
||||
this._collectionPrefix = collectionPrefix;
|
||||
this._client = pgp(uri);
|
||||
this._client = createClient(uri, databaseOptions);
|
||||
}
|
||||
|
||||
_ensureSchemaCollectionExists() {
|
||||
|
||||
@@ -260,7 +260,8 @@ class ParseServer {
|
||||
case 'postgres:':
|
||||
return new PostgresStorageAdapter({
|
||||
uri: databaseURI,
|
||||
collectionPrefix
|
||||
collectionPrefix,
|
||||
databaseOptions
|
||||
});
|
||||
default:
|
||||
return new MongoStorageAdapter({
|
||||
|
||||
Reference in New Issue
Block a user