You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.2 KiB
201 lines
6.2 KiB
var urlParse = require('url').parse; |
|
var ClientConstants = require('./protocol/constants/client'); |
|
var Charsets = require('./protocol/constants/charsets'); |
|
var SSLProfiles = null; |
|
|
|
module.exports = ConnectionConfig; |
|
function ConnectionConfig(options) { |
|
if (typeof options === 'string') { |
|
options = ConnectionConfig.parseUrl(options); |
|
} |
|
|
|
this.host = options.host || 'localhost'; |
|
this.port = options.port || 3306; |
|
this.localAddress = options.localAddress; |
|
this.socketPath = options.socketPath; |
|
this.user = options.user || undefined; |
|
this.password = options.password || undefined; |
|
this.database = options.database; |
|
this.connectTimeout = (options.connectTimeout === undefined) |
|
? (10 * 1000) |
|
: options.connectTimeout; |
|
this.insecureAuth = options.insecureAuth || false; |
|
this.supportBigNumbers = options.supportBigNumbers || false; |
|
this.bigNumberStrings = options.bigNumberStrings || false; |
|
this.dateStrings = options.dateStrings || false; |
|
this.debug = options.debug; |
|
this.trace = options.trace !== false; |
|
this.stringifyObjects = options.stringifyObjects || false; |
|
this.timezone = options.timezone || 'local'; |
|
this.flags = options.flags || ''; |
|
this.queryFormat = options.queryFormat; |
|
this.pool = options.pool || undefined; |
|
this.ssl = (typeof options.ssl === 'string') |
|
? ConnectionConfig.getSSLProfile(options.ssl) |
|
: (options.ssl || false); |
|
this.multipleStatements = options.multipleStatements || false; |
|
this.typeCast = (options.typeCast === undefined) |
|
? true |
|
: options.typeCast; |
|
|
|
if (this.timezone[0] === ' ') { |
|
// "+" is a url encoded char for space so it |
|
// gets translated to space when giving a |
|
// connection string.. |
|
this.timezone = '+' + this.timezone.substr(1); |
|
} |
|
|
|
if (this.ssl) { |
|
// Default rejectUnauthorized to true |
|
this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false; |
|
} |
|
|
|
this.maxPacketSize = 0; |
|
this.charsetNumber = (options.charset) |
|
? ConnectionConfig.getCharsetNumber(options.charset) |
|
: options.charsetNumber || Charsets.UTF8_GENERAL_CI; |
|
|
|
// Set the client flags |
|
var defaultFlags = ConnectionConfig.getDefaultFlags(options); |
|
this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags); |
|
} |
|
|
|
ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) { |
|
var allFlags = ConnectionConfig.parseFlagList(defaultFlags); |
|
var newFlags = ConnectionConfig.parseFlagList(userFlags); |
|
|
|
// Merge the new flags |
|
for (var flag in newFlags) { |
|
if (allFlags[flag] !== false) { |
|
allFlags[flag] = newFlags[flag]; |
|
} |
|
} |
|
|
|
// Build flags |
|
var flags = 0x0; |
|
for (var flag in allFlags) { |
|
if (allFlags[flag]) { |
|
// TODO: Throw here on some future release |
|
flags |= ClientConstants['CLIENT_' + flag] || 0x0; |
|
} |
|
} |
|
|
|
return flags; |
|
}; |
|
|
|
ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) { |
|
var num = Charsets[charset.toUpperCase()]; |
|
|
|
if (num === undefined) { |
|
throw new TypeError('Unknown charset \'' + charset + '\''); |
|
} |
|
|
|
return num; |
|
}; |
|
|
|
ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) { |
|
var defaultFlags = [ |
|
'-COMPRESS', // Compression protocol *NOT* supported |
|
'-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41 |
|
'+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet |
|
'+FOUND_ROWS', // Send found rows instead of affected rows |
|
'+IGNORE_SIGPIPE', // Don't issue SIGPIPE if network failures |
|
'+IGNORE_SPACE', // Let the parser ignore spaces before '(' |
|
'+LOCAL_FILES', // Can use LOAD DATA LOCAL |
|
'+LONG_FLAG', // Longer flags in Protocol::ColumnDefinition320 |
|
'+LONG_PASSWORD', // Use the improved version of Old Password Authentication |
|
'+MULTI_RESULTS', // Can handle multiple resultsets for COM_QUERY |
|
'+ODBC', // Special handling of ODBC behaviour |
|
'-PLUGIN_AUTH', // Does *NOT* support auth plugins |
|
'+PROTOCOL_41', // Uses the 4.1 protocol |
|
'+PS_MULTI_RESULTS', // Can handle multiple resultsets for COM_STMT_EXECUTE |
|
'+RESERVED', // Unused |
|
'+SECURE_CONNECTION', // Supports Authentication::Native41 |
|
'+TRANSACTIONS' // Expects status flags |
|
]; |
|
|
|
if (options && options.multipleStatements) { |
|
// May send multiple statements per COM_QUERY and COM_STMT_PREPARE |
|
defaultFlags.push('+MULTI_STATEMENTS'); |
|
} |
|
|
|
return defaultFlags; |
|
}; |
|
|
|
ConnectionConfig.getSSLProfile = function getSSLProfile(name) { |
|
if (!SSLProfiles) { |
|
SSLProfiles = require('./protocol/constants/ssl_profiles'); |
|
} |
|
|
|
var ssl = SSLProfiles[name]; |
|
|
|
if (ssl === undefined) { |
|
throw new TypeError('Unknown SSL profile \'' + name + '\''); |
|
} |
|
|
|
return ssl; |
|
}; |
|
|
|
ConnectionConfig.parseFlagList = function parseFlagList(flagList) { |
|
var allFlags = Object.create(null); |
|
|
|
if (!flagList) { |
|
return allFlags; |
|
} |
|
|
|
var flags = !Array.isArray(flagList) |
|
? String(flagList || '').toUpperCase().split(/\s*,+\s*/) |
|
: flagList; |
|
|
|
for (var i = 0; i < flags.length; i++) { |
|
var flag = flags[i]; |
|
var offset = 1; |
|
var state = flag[0]; |
|
|
|
if (state === undefined) { |
|
// TODO: throw here on some future release |
|
continue; |
|
} |
|
|
|
if (state !== '-' && state !== '+') { |
|
offset = 0; |
|
state = '+'; |
|
} |
|
|
|
allFlags[flag.substr(offset)] = state === '+'; |
|
} |
|
|
|
return allFlags; |
|
}; |
|
|
|
ConnectionConfig.parseUrl = function(url) { |
|
url = urlParse(url, true); |
|
|
|
var options = { |
|
host : url.hostname, |
|
port : url.port, |
|
database : url.pathname.substr(1) |
|
}; |
|
|
|
if (url.auth) { |
|
var auth = url.auth.split(':'); |
|
options.user = auth.shift(); |
|
options.password = auth.join(':'); |
|
} |
|
|
|
if (url.query) { |
|
for (var key in url.query) { |
|
var value = url.query[key]; |
|
|
|
try { |
|
// Try to parse this as a JSON expression first |
|
options[key] = JSON.parse(value); |
|
} catch (err) { |
|
// Otherwise assume it is a plain string |
|
options[key] = value; |
|
} |
|
} |
|
} |
|
|
|
return options; |
|
};
|
|
|