diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index 62bee8c85..c5914a1a7 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 @@ -120,13 +135,24 @@ class ConnectionParameters { getLibpqConnectionString(cb) { var params = [] + var pgOptions = [] + add(params, this, 'user') add(params, this, 'password') add(params, this, 'port') add(params, this, 'application_name') add(params, this, 'fallback_application_name') 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') diff --git a/packages/pg/test/unit/connection-parameters/creation-tests.js b/packages/pg/test/unit/connection-parameters/creation-tests.js index e4dd1af72..e30194e8b 100644 --- a/packages/pg/test/unit/connection-parameters/creation-tests.js +++ b/packages/pg/test/unit/connection-parameters/creation-tests.js @@ -172,6 +172,49 @@ test('libpq connection string building', function () { ) }) + test('builds conn string with options and statement_timeout', function () { + var config = { + user: 'brian', + password: 'xyz', + port: 888, + host: 'localhost', + database: 'bam', + statement_timeout: 5000, + idle_in_transaction_session_timeout: 5000, + options: '-c geqo=off -c foobar=off', + } + 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 -c geqo=off -c foobar=off'" + ) + }) + ) + }) + + test('builds conn string with options and without statement_timeout', function () { + var config = { + user: 'brian', + password: 'xyz', + port: 888, + host: 'localhost', + database: 'bam', + options: '-c geqo=off -c foobar=off', + } + var subject = new ConnectionParameters(config) + subject.getLibpqConnectionString( + assert.calls(function (err, constring) { + assert(!err) + var parts = constring.split(/ (?=([^\']*\'[^\']*\')*[^\']*$)/) + checkForPart(parts, "options='-c geqo=off -c foobar=off'") + }) + ) + }) + test('builds dns string', function () { var config = { user: 'brian',