UNPKG

6.54 kBJavaScriptView Raw
1var urlParse = require('url').parse;
2var ClientConstants = require('./protocol/constants/client');
3var Charsets = require('./protocol/constants/charsets');
4var SSLProfiles = null;
5
6module.exports = ConnectionConfig;
7function ConnectionConfig(options) {
8 if (typeof options === 'string') {
9 options = ConnectionConfig.parseUrl(options);
10 }
11
12 this.host = options.host || 'localhost';
13 this.port = options.port || 8081;
14 this.localAddress = options.localAddress;
15 this.socketPath = options.socketPath;
16 this.user = options.user || undefined;
17 this.password = options.password || undefined;
18 this.database = options.database;
19 this.connectTimeout = (options.connectTimeout === undefined)
20 ? (10 * 1000)
21 : options.connectTimeout;
22 this.insecureAuth = options.insecureAuth || false;
23 this.supportBigNumbers = options.supportBigNumbers || false;
24 this.bigNumberStrings = options.bigNumberStrings || false;
25 this.dateStrings = options.dateStrings || false;
26 this.debug = options.debug;
27 this.trace = options.trace !== false;
28 this.stringifyObjects = options.stringifyObjects || false;
29 this.timezone = options.timezone || 'local';
30 this.flags = options.flags || '';
31 this.queryFormat = options.queryFormat;
32 this.pool = options.pool || undefined;
33 this.ssl = (typeof options.ssl === 'string')
34 ? ConnectionConfig.getSSLProfile(options.ssl)
35 : (options.ssl || false);
36 this.multipleStatements = options.multipleStatements || false;
37 this.typeCast = (options.typeCast === undefined)
38 ? true
39 : options.typeCast;
40
41 if (this.timezone[0] === ' ') {
42 // "+" is a url encoded char for space so it
43 // gets translated to space when giving a
44 // connection string..
45 this.timezone = '+' + this.timezone.substr(1);
46 }
47
48 if (this.ssl) {
49 // Default rejectUnauthorized to true
50 this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
51 }
52
53 this.maxPacketSize = 0;
54 this.charsetNumber = (options.charset)
55 ? ConnectionConfig.getCharsetNumber(options.charset)
56 : options.charsetNumber || Charsets.UTF8_GENERAL_CI;
57
58 // Set the client flags
59 var defaultFlags = ConnectionConfig.getDefaultFlags(options);
60 this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags);
61}
62
63ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) {
64 var allFlags = ConnectionConfig.parseFlagList(defaultFlags);
65 var newFlags = ConnectionConfig.parseFlagList(userFlags);
66
67 // Merge the new flags
68 for (var flag in newFlags) {
69 if (allFlags[flag] !== false) {
70 allFlags[flag] = newFlags[flag];
71 }
72 }
73
74 // Build flags
75 var flags = 0x0;
76 for (var flag in allFlags) {
77 if (allFlags[flag]) {
78 // TODO: Throw here on some future release
79 flags |= ClientConstants['CLIENT_' + flag] || 0x0;
80 }
81 }
82
83 return flags;
84};
85
86ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) {
87 var num = Charsets[charset.toUpperCase()];
88
89 if (num === undefined) {
90 throw new TypeError('Unknown charset \'' + charset + '\'');
91 }
92
93 return num;
94};
95
96ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) {
97 var defaultFlags = [
98 '-COMPRESS', // Compression protocol *NOT* supported
99 '-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41
100 '+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet
101 '+FOUND_ROWS', // Send found rows instead of affected rows
102 '+IGNORE_SIGPIPE', // Don't issue SIGPIPE if network failures
103 '+IGNORE_SPACE', // Let the parser ignore spaces before '('
104 '+LOCAL_FILES', // Can use LOAD DATA LOCAL
105 '+LONG_FLAG', // Longer flags in Protocol::ColumnDefinition320
106 '+LONG_PASSWORD', // Use the improved version of Old Password Authentication
107 '+MULTI_RESULTS', // Can handle multiple resultsets for COM_QUERY
108 '+ODBC', // Special handling of ODBC behaviour
109 '-PLUGIN_AUTH', // Does *NOT* support auth plugins
110 '+PROTOCOL_41', // Uses the 4.1 protocol
111 '+PS_MULTI_RESULTS', // Can handle multiple resultsets for COM_STMT_EXECUTE
112 '+RESERVED', // Unused
113 '+SECURE_CONNECTION', // Supports Authentication::Native41
114 '+TRANSACTIONS' // Expects status flags
115 ];
116
117 if (options && options.multipleStatements) {
118 // May send multiple statements per COM_QUERY and COM_STMT_PREPARE
119 defaultFlags.push('+MULTI_STATEMENTS');
120 }
121
122 return defaultFlags;
123};
124
125ConnectionConfig.getSSLProfile = function getSSLProfile(name) {
126 if (!SSLProfiles) {
127 SSLProfiles = require('./protocol/constants/ssl_profiles');
128 }
129
130 var ssl = SSLProfiles[name];
131
132 if (ssl === undefined) {
133 throw new TypeError('Unknown SSL profile \'' + name + '\'');
134 }
135
136 return ssl;
137};
138
139ConnectionConfig.parseFlagList = function parseFlagList(flagList) {
140 var allFlags = Object.create(null);
141
142 if (!flagList) {
143 return allFlags;
144 }
145
146 var flags = !Array.isArray(flagList)
147 ? String(flagList || '').toUpperCase().split(/\s*,+\s*/)
148 : flagList;
149
150 for (var i = 0; i < flags.length; i++) {
151 var flag = flags[i];
152 var offset = 1;
153 var state = flag[0];
154
155 if (state === undefined) {
156 // TODO: throw here on some future release
157 continue;
158 }
159
160 if (state !== '-' && state !== '+') {
161 offset = 0;
162 state = '+';
163 }
164
165 allFlags[flag.substr(offset)] = state === '+';
166 }
167
168 return allFlags;
169};
170
171ConnectionConfig.parseUrl = function(url) {
172 url = urlParse(url, true);
173
174 var options = {
175 host : url.hostname,
176 port : url.port,
177 database : url.pathname.substr(1)
178 };
179
180 if (url.auth) {
181 var auth = url.auth.split(':');
182 options.user = auth.shift();
183 options.password = auth.join(':');
184 }
185
186 if (url.query) {
187 for (var key in url.query) {
188 var value = url.query[key];
189
190 try {
191 // Try to parse this as a JSON expression first
192 options[key] = JSON.parse(value);
193 } catch (err) {
194 // Otherwise assume it is a plain string
195 options[key] = value;
196 }
197 }
198 }
199
200 return options;
201};