diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index 7f39cfaef..b62f0e8a9 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -45,6 +45,21 @@ var add = function (params, config, paramName) { } } +var escapeOptionValue = function (value) { + return ('' + value).replace(/\\/g, '\\\\').replace(/ /g, '\\ ') +} + +var addOption = function (options, config, optionName) { + if (!config[optionName]) { + return + } + + var value = config[optionName] + if (value !== undefined && value !== null) { + options.push('-c ' + optionName + '=' + escapeOptionValue(value)) + } +} + class ConnectionParameters { constructor(config) { // if a string is passed, it is a raw connection string so we parse it into a config @@ -115,6 +130,8 @@ class ConnectionParameters { getLibpqConnectionString(cb) { var params = [] + var pgOptions = [] + add(params, this, 'user') add(params, this, 'password') add(params, this, 'port') @@ -123,6 +140,16 @@ class ConnectionParameters { add(params, this, 'connect_timeout') add(params, this, 'options') + addOption(pgOptions, this, 'statement_timeout') + addOption(pgOptions, this, 'idle_in_transaction_session_timeout') + + if (this.options) { + pgOptions.push(this.options) + } + if (pgOptions.length > 0) { + params.push('options=' + quoteParamValue(pgOptions.join(' '))) + } + var ssl = typeof this.ssl === 'object' ? this.ssl : this.ssl ? { sslmode: this.ssl } : {} add(params, ssl, 'sslmode') add(params, ssl, 'sslca') diff --git a/packages/pg/test/unit/connection-parameters/creation-tests.js b/packages/pg/test/unit/connection-parameters/creation-tests.js index e4dd1af72..ee6b76b41 100644 --- a/packages/pg/test/unit/connection-parameters/creation-tests.js +++ b/packages/pg/test/unit/connection-parameters/creation-tests.js @@ -149,6 +149,9 @@ test('libpq connection string building', function () { var checkForPart = function (array, part) { assert.ok(array.indexOf(part) > -1, array.join(' ') + ' did not contain ' + part) } + var checkForOption = function (array, part) { + assert.ok(array.indexOf(part) > -1, array.join(' ') + ' did not contain ' + part) + } test('builds simple string', function () { var config = { @@ -172,6 +175,26 @@ test('libpq connection string building', function () { ) }) + test('builds conn string with options', function () { + var config = { + user: 'brian', + password: 'xyz', + port: 888, + host: 'localhost', + database: 'bam', + statement_timeout: 5000, + idle_in_transaction_session_timeout: 5000, + } + var subject = new ConnectionParameters(config) + subject.getLibpqConnectionString( + assert.calls(function (err, constring) { + assert(!err) + var parts = constring.split(/ (?=([^\']*\'[^\']*\')*[^\']*$)/) + checkForPart(parts, "options='-c statement_timeout=5000 -c idle_in_transaction_session_timeout=5000'") + }) + ) + }) + test('builds dns string', function () { var config = { user: 'brian',