UNPKG

vertica-nodejs

Version:

Vertica client - pure javascript & libpq with the same API

180 lines (148 loc) 6.2 kB
// Copyright (c) 2022-2024 Open Text. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. 'use strict' var dns = require('dns') var os = require('os') var defaults = require('./defaults') var parse = require('v-connection-string').parse // parses a connection string var backupServerNodesParser = require('./backup-nodes-parsers').backupServerNodes // parses backup server nodes var val = function (key, config, envVar) { if (envVar === undefined) { envVar = process.env['V_' + key.toUpperCase()] } else if (envVar === false) { // do nothing ... use false } else { envVar = process.env[envVar] } return config[key] || envVar || defaults[key] } // Convert arg to a string, surround in single quotes, and escape single quotes and backslashes var quoteParamValue = function (value) { return "'" + ('' + value).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'" } var add = function (params, config, paramName) { var value = config[paramName] if (value !== undefined && value !== null) { params.push(paramName + '=' + quoteParamValue(value)) } } var parseBackupServerNodes = function (nodes) { // We need to check the type of the input because the ConnectionParameters // constructor will try to assign config = config, which will // cause an error if we try to parse an already parsed value. if (typeof nodes == 'string') { var parsedNodes = backupServerNodesParser(nodes) return parsedNodes.map(pair => pair[1] !== null ? { host: pair[0], port: parseInt(pair[1]) } : { host: pair[0], port: defaults.port }) } else { return nodes } } class ConnectionParameters { constructor(config) { // if a string is passed, it is a raw connection string so we parse it into a config config = typeof config === 'string' ? parse(config) : config || {} // if the config has a connectionString defined, parse IT into the config we use // this will override other default values with what is stored in connectionString if (config.connectionString) { config = Object.assign({}, config, parse(config.connectionString)) } this.database = val('database', config) if (this.database === undefined) { this.database = '' } this.port = parseInt(val('port', config), 10) this.host = val('host', config) // "hiding" the password so it doesn't show up in stack traces // or if the client is console.logged Object.defineProperty(this, 'password', { configurable: true, enumerable: false, writable: true, value: val('password', config), }) Object.defineProperty(this, 'oauth_access_token', { configurable: true, enumerable: false, writable: true, value: val('oauth_access_token', config), }) // user is required for non-OAuth connections this.user = val('user', config) if (!this.user && !this.oauth_access_token) { // TODO: log a notice to the user that the user property was taken from the environment once we fully support logging this.user = process.platform === 'win32' ? process.env.USERNAME : process.env.USER } this.binary = val('binary', config) this.options = val('options', config) this.tls_config = val('tls_config', config) // if the user wants to have more control over the tls socket they can provide their own tls_config object // this is particularly useful for customers migrating over from node-vertica // otherwise we will support standard tls mode support as in other drivers this.tls_mode = val('tls_mode', config) //this.tls_client_key = val('tls_client_key', config) //this.tls_client_cert = val('tls_client_cert', config) this.tls_trusted_certs = val('tls_trusted_certs', config) this.client_encoding = val('client_encoding', config) this.replication = val('replication', config) // a domain socket begins with '/' this.isDomainSocket = !(this.host || '').indexOf('/') this.statement_timeout = val('statement_timeout', config, false) this.idle_in_transaction_session_timeout = val('idle_in_transaction_session_timeout', config, false) this.query_timeout = val('query_timeout', config, false) this.backup_server_node = parseBackupServerNodes(val('backup_server_node', config)) this.client_label = val('client_label', config, false) this.workload = val('workload', config, false) // client auditing information this.client_type = "Node.js Driver" this.client_version = "1.1.4" try { this.client_os_hostname = os.hostname() } catch (e) { this.client_os_hostname = "" } try { this.client_pid = process.pid.toString() } catch (e) { this.client_pid = "0" } try { this.client_os = os.platform() } catch (e) { this.client_os = "" } try { this.client_os_user_name = os.userInfo().username } catch (e) { this.client_os_user_name = "" } // The frontend sends a requested protocol version to the backend this.protocol_version = (3 << 16 | 16) // 3.16 -> (major << 16 | minor) -> (3 << 16 | 16) -> 196624 if (config.connectionTimeoutMillis === undefined) { this.connect_timeout = process.env.PGCONNECT_TIMEOUT || 0 } else { this.connect_timeout = Math.floor(config.connectionTimeoutMillis / 1000) } if (config.keepAlive === false) { this.keepalives = 0 } else if (config.keepAlive === true) { this.keepalives = 1 } if (typeof config.keepAliveInitialDelayMillis === 'number') { this.keepalives_idle = Math.floor(config.keepAliveInitialDelayMillis / 1000) } } } module.exports = ConnectionParameters