Showing
146 changed files
with
4771 additions
and
0 deletions
1 | +#### 9.0.0 | ||
2 | +* 27/05/2019 | ||
3 | +* For compatibility with legacy browsers, remove `Symbol` references. | ||
4 | + | ||
5 | +#### 8.1.1 | ||
6 | +* 24/02/2019 | ||
7 | +* [BUGFIX] #222 Restore missing `var` to `export BigNumber`. | ||
8 | +* Allow any key in BigNumber.Instance in *bignumber.d.ts*. | ||
9 | + | ||
10 | +#### 8.1.0 | ||
11 | +* 23/02/2019 | ||
12 | +* [NEW FEATURE] #220 Create a BigNumber using `{s, e, c}`. | ||
13 | +* [NEW FEATURE] `isBigNumber`: if `BigNumber.DEBUG` is `true`, also check that the BigNumber instance is well-formed. | ||
14 | +* Remove `instanceof` checks; just use `_isBigNumber` to identify a BigNumber instance. | ||
15 | +* Add `_isBigNumber` to prototype in *bignumber.mjs*. | ||
16 | +* Add tests for BigNumber creation from object. | ||
17 | +* Update *API.html*. | ||
18 | + | ||
19 | +#### 8.0.2 | ||
20 | +* 13/01/2019 | ||
21 | +* #209 `toPrecision` without argument should follow `toString`. | ||
22 | +* Improve *Use* section of *README*. | ||
23 | +* Optimise `toString(10)`. | ||
24 | +* Add verson number to API doc. | ||
25 | + | ||
26 | +#### 8.0.1 | ||
27 | +* 01/11/2018 | ||
28 | +* Rest parameter must be array type in *bignumber.d.ts*. | ||
29 | + | ||
30 | +#### 8.0.0 | ||
31 | +* 01/11/2018 | ||
32 | +* [NEW FEATURE] Add `BigNumber.sum` method. | ||
33 | +* [NEW FEATURE]`toFormat`: add `prefix` and `suffix` options. | ||
34 | +* [NEW FEATURE] #178 Pass custom formatting to `toFormat`. | ||
35 | +* [BREAKING CHANGE] #184 `toFraction`: return array of BigNumbers not strings. | ||
36 | +* [NEW FEATURE] #185 Enable overwrite of `valueOf` to prevent accidental addition to string. | ||
37 | +* #183 Add Node.js `crypto` requirement to documentation. | ||
38 | +* [BREAKING CHANGE] #198 Disallow signs and whitespace in custom alphabet. | ||
39 | +* [NEW FEATURE] #188 Implement `util.inspect.custom` for Node.js REPL. | ||
40 | +* #170 Make `isBigNumber` a type guard in *bignumber.d.ts*. | ||
41 | +* [BREAKING CHANGE] `BigNumber.min` and `BigNumber.max`: don't accept an array. | ||
42 | +* Update *.travis.yml*. | ||
43 | +* Remove *bower.json*. | ||
44 | + | ||
45 | +#### 7.2.1 | ||
46 | +* 24/05/2018 | ||
47 | +* Add `browser` field to *package.json*. | ||
48 | + | ||
49 | +#### 7.2.0 | ||
50 | +* 22/05/2018 | ||
51 | +* #166 Correct *.mjs* file. Remove extension from `main` field in *package.json*. | ||
52 | + | ||
53 | +#### 7.1.0 | ||
54 | +* 18/05/2018 | ||
55 | +* Add `module` field to *package.json* for *bignumber.mjs*. | ||
56 | + | ||
57 | +#### 7.0.2 | ||
58 | +* 17/05/2018 | ||
59 | +* #165 Bugfix: upper-case letters for bases 11-36 in a custom alphabet. | ||
60 | +* Add note to *README* regarding creating BigNumbers from Number values. | ||
61 | + | ||
62 | +#### 7.0.1 | ||
63 | +* 26/04/2018 | ||
64 | +* #158 Fix global object variable name typo. | ||
65 | + | ||
66 | +#### 7.0.0 | ||
67 | +* 26/04/2018 | ||
68 | +* #143 Remove global BigNumber from typings. | ||
69 | +* #144 Enable compatibility with `Object.freeze(Object.prototype)`. | ||
70 | +* #148 #123 #11 Only throw on a number primitive with more than 15 significant digits if `BigNumber.DEBUG` is `true`. | ||
71 | +* Only throw on an invalid BigNumber value if `BigNumber.DEBUG` is `true`. Return BigNumber `NaN` instead. | ||
72 | +* #154 `exponentiatedBy`: allow BigNumber exponent. | ||
73 | +* #156 Prevent Content Security Policy *unsafe-eval* issue. | ||
74 | +* `toFraction`: allow `Infinity` maximum denominator. | ||
75 | +* Comment-out some excess tests to reduce test time. | ||
76 | +* Amend indentation and other spacing. | ||
77 | + | ||
78 | +#### 6.0.0 | ||
79 | +* 26/01/2018 | ||
80 | +* #137 Implement `APLHABET` configuration option. | ||
81 | +* Remove `ERRORS` configuration option. | ||
82 | +* Remove `toDigits` method; extend `precision` method accordingly. | ||
83 | +* Remove s`round` method; extend `decimalPlaces` method accordingly. | ||
84 | +* Remove methods: `ceil`, `floor`, and `truncated`. | ||
85 | +* Remove method aliases: `add`, `cmp`, `isInt`, `isNeg`, `trunc`, `mul`, `neg` and `sub`. | ||
86 | +* Rename methods: `shift` to `shiftedBy`, `another` to `clone`, `toPower` to `exponentiatedBy`, and `equals` to `isEqualTo`. | ||
87 | +* Rename methods: add `is` prefix to `greaterThan`, `greaterThanOrEqualTo`, `lessThan` and `lessThanOrEqualTo`. | ||
88 | +* Add methods: `multipliedBy`, `isBigNumber`, `isPositive`, `integerValue`, `maximum` and `minimum`. | ||
89 | +* Refactor test suite. | ||
90 | +* Add *CHANGELOG.md*. | ||
91 | +* Rewrite *bignumber.d.ts*. | ||
92 | +* Redo API image. | ||
93 | + | ||
94 | +#### 5.0.0 | ||
95 | +* 27/11/2017 | ||
96 | +* #81 Don't throw on constructor call without `new`. | ||
97 | + | ||
98 | +#### 4.1.0 | ||
99 | +* 26/09/2017 | ||
100 | +* Remove node 0.6 from *.travis.yml*. | ||
101 | +* Add *bignumber.mjs*. | ||
102 | + | ||
103 | +#### 4.0.4 | ||
104 | +* 03/09/2017 | ||
105 | +* Add missing aliases to *bignumber.d.ts*. | ||
106 | + | ||
107 | +#### 4.0.3 | ||
108 | +* 30/08/2017 | ||
109 | +* Add types: *bignumber.d.ts*. | ||
110 | + | ||
111 | +#### 4.0.2 | ||
112 | +* 03/05/2017 | ||
113 | +* #120 Workaround Safari/Webkit bug. | ||
114 | + | ||
115 | +#### 4.0.1 | ||
116 | +* 05/04/2017 | ||
117 | +* #121 BigNumber.default to BigNumber['default']. | ||
118 | + | ||
119 | +#### 4.0.0 | ||
120 | +* 09/01/2017 | ||
121 | +* Replace BigNumber.isBigNumber method with isBigNumber prototype property. | ||
122 | + | ||
123 | +#### 3.1.2 | ||
124 | +* 08/01/2017 | ||
125 | +* Minor documentation edit. | ||
126 | + | ||
127 | +#### 3.1.1 | ||
128 | +* 08/01/2017 | ||
129 | +* Uncomment `isBigNumber` tests. | ||
130 | +* Ignore dot files. | ||
131 | + | ||
132 | +#### 3.1.0 | ||
133 | +* 08/01/2017 | ||
134 | +* Add `isBigNumber` method. | ||
135 | + | ||
136 | +#### 3.0.2 | ||
137 | +* 08/01/2017 | ||
138 | +* Bugfix: Possible incorrect value of `ERRORS` after a `BigNumber.another` call (due to `parseNumeric` declaration in outer scope). | ||
139 | + | ||
140 | +#### 3.0.1 | ||
141 | +* 23/11/2016 | ||
142 | +* Apply fix for old ipads with `%` issue, see #57 and #102. | ||
143 | +* Correct error message. | ||
144 | + | ||
145 | +#### 3.0.0 | ||
146 | +* 09/11/2016 | ||
147 | +* Remove `require('crypto')` - leave it to the user. | ||
148 | +* Add `BigNumber.set` as `BigNumber.config` alias. | ||
149 | +* Default `POW_PRECISION` to `0`. | ||
150 | + | ||
151 | +#### 2.4.0 | ||
152 | +* 14/07/2016 | ||
153 | +* #97 Add exports to support ES6 imports. | ||
154 | + | ||
155 | +#### 2.3.0 | ||
156 | +* 07/03/2016 | ||
157 | +* #86 Add modulus parameter to `toPower`. | ||
158 | + | ||
159 | +#### 2.2.0 | ||
160 | +* 03/03/2016 | ||
161 | +* #91 Permit larger JS integers. | ||
162 | + | ||
163 | +#### 2.1.4 | ||
164 | +* 15/12/2015 | ||
165 | +* Correct UMD. | ||
166 | + | ||
167 | +#### 2.1.3 | ||
168 | +* 13/12/2015 | ||
169 | +* Refactor re global object and crypto availability when bundling. | ||
170 | + | ||
171 | +#### 2.1.2 | ||
172 | +* 10/12/2015 | ||
173 | +* Bugfix: `window.crypto` not assigned to `crypto`. | ||
174 | + | ||
175 | +#### 2.1.1 | ||
176 | +* 09/12/2015 | ||
177 | +* Prevent code bundler from adding `crypto` shim. | ||
178 | + | ||
179 | +#### 2.1.0 | ||
180 | +* 26/10/2015 | ||
181 | +* For `valueOf` and `toJSON`, include the minus sign with negative zero. | ||
182 | + | ||
183 | +#### 2.0.8 | ||
184 | +* 2/10/2015 | ||
185 | +* Internal round function bugfix. | ||
186 | + | ||
187 | +#### 2.0.6 | ||
188 | +* 31/03/2015 | ||
189 | +* Add bower.json. Tweak division after in-depth review. | ||
190 | + | ||
191 | +#### 2.0.5 | ||
192 | +* 25/03/2015 | ||
193 | +* Amend README. Remove bitcoin address. | ||
194 | + | ||
195 | +#### 2.0.4 | ||
196 | +* 25/03/2015 | ||
197 | +* Critical bugfix #58: division. | ||
198 | + | ||
199 | +#### 2.0.3 | ||
200 | +* 18/02/2015 | ||
201 | +* Amend README. Add source map. | ||
202 | + | ||
203 | +#### 2.0.2 | ||
204 | +* 18/02/2015 | ||
205 | +* Correct links. | ||
206 | + | ||
207 | +#### 2.0.1 | ||
208 | +* 18/02/2015 | ||
209 | +* Add `max`, `min`, `precision`, `random`, `shiftedBy`, `toDigits` and `truncated` methods. | ||
210 | +* Add the short-forms: `add`, `mul`, `sd`, `sub` and `trunc`. | ||
211 | +* Add an `another` method to enable multiple independent constructors to be created. | ||
212 | +* Add support for the base 2, 8 and 16 prefixes `0b`, `0o` and `0x`. | ||
213 | +* Enable a rounding mode to be specified as a second parameter to `toExponential`, `toFixed`, `toFormat` and `toPrecision`. | ||
214 | +* Add a `CRYPTO` configuration property so cryptographically-secure pseudo-random number generation can be specified. | ||
215 | +* Add a `MODULO_MODE` configuration property to enable the rounding mode used by the `modulo` operation to be specified. | ||
216 | +* Add a `POW_PRECISION` configuration property to enable the number of significant digits calculated by the power operation to be limited. | ||
217 | +* Improve code quality. | ||
218 | +* Improve documentation. | ||
219 | + | ||
220 | +#### 2.0.0 | ||
221 | +* 29/12/2014 | ||
222 | +* Add `dividedToIntegerBy`, `isInteger` and `toFormat` methods. | ||
223 | +* Remove the following short-forms: `isF`, `isZ`, `toE`, `toF`, `toFr`, `toN`, `toP`, `toS`. | ||
224 | +* Store a BigNumber's coefficient in base 1e14, rather than base 10. | ||
225 | +* Add fast path for integers to BigNumber constructor. | ||
226 | +* Incorporate the library into the online documentation. | ||
227 | + | ||
228 | +#### 1.5.0 | ||
229 | +* 13/11/2014 | ||
230 | +* Add `toJSON` and `decimalPlaces` methods. | ||
231 | + | ||
232 | +#### 1.4.1 | ||
233 | +* 08/06/2014 | ||
234 | +* Amend README. | ||
235 | + | ||
236 | +#### 1.4.0 | ||
237 | +* 08/05/2014 | ||
238 | +* Add `toNumber`. | ||
239 | + | ||
240 | +#### 1.3.0 | ||
241 | +* 08/11/2013 | ||
242 | +* Ensure correct rounding of `sqrt` in all, rather than almost all, cases. | ||
243 | +* Maximum radix to 64. | ||
244 | + | ||
245 | +#### 1.2.1 | ||
246 | +* 17/10/2013 | ||
247 | +* Sign of zero when x < 0 and x + (-x) = 0. | ||
248 | + | ||
249 | +#### 1.2.0 | ||
250 | +* 19/9/2013 | ||
251 | +* Throw Error objects for stack. | ||
252 | + | ||
253 | +#### 1.1.1 | ||
254 | +* 22/8/2013 | ||
255 | +* Show original value in constructor error message. | ||
256 | + | ||
257 | +#### 1.1.0 | ||
258 | +* 1/8/2013 | ||
259 | +* Allow numbers with trailing radix point. | ||
260 | + | ||
261 | +#### 1.0.1 | ||
262 | +* Bugfix: error messages with incorrect method name | ||
263 | + | ||
264 | +#### 1.0.0 | ||
265 | +* 8/11/2012 | ||
266 | +* Initial release |
backend/node_modules/bignumber.js/LICENCE
0 → 100644
1 | +The MIT Licence. | ||
2 | + | ||
3 | +Copyright (c) 2019 Michael Mclaughlin | ||
4 | + | ||
5 | +Permission is hereby granted, free of charge, to any person obtaining | ||
6 | +a copy of this software and associated documentation files (the | ||
7 | +'Software'), to deal in the Software without restriction, including | ||
8 | +without limitation the rights to use, copy, modify, merge, publish, | ||
9 | +distribute, sublicense, and/or sell copies of the Software, and to | ||
10 | +permit persons to whom the Software is furnished to do so, subject to | ||
11 | +the following conditions: | ||
12 | + | ||
13 | +The above copyright notice and this permission notice shall be | ||
14 | +included in all copies or substantial portions of the Software. | ||
15 | + | ||
16 | +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
17 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
18 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
19 | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
20 | +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
21 | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
22 | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
23 | + |
backend/node_modules/bignumber.js/README.md
0 → 100644
1 | +![bignumber.js](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/bignumberjs.png) | ||
2 | + | ||
3 | +A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic. | ||
4 | + | ||
5 | +[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.svg)](https://travis-ci.org/MikeMcl/bignumber.js) | ||
6 | + | ||
7 | +<br /> | ||
8 | + | ||
9 | +## Features | ||
10 | + | ||
11 | + - Integers and decimals | ||
12 | + - Simple API but full-featured | ||
13 | + - Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal | ||
14 | + - 8 KB minified and gzipped | ||
15 | + - Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type | ||
16 | + - Includes a `toFraction` and a correctly-rounded `squareRoot` method | ||
17 | + - Supports cryptographically-secure pseudo-random number generation | ||
18 | + - No dependencies | ||
19 | + - Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only | ||
20 | + - Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set | ||
21 | + | ||
22 | +![API](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/API.png) | ||
23 | + | ||
24 | +If a smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/). | ||
25 | +It's less than half the size but only works with decimal numbers and only has half the methods. | ||
26 | +It also does not allow `NaN` or `Infinity`, or have the configuration options of this library. | ||
27 | + | ||
28 | +See also [decimal.js](https://github.com/MikeMcl/decimal.js/), which among other things adds support for non-integer powers, and performs all operations to a specified number of significant digits. | ||
29 | + | ||
30 | +## Load | ||
31 | + | ||
32 | +The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*). | ||
33 | + | ||
34 | +Browser: | ||
35 | + | ||
36 | +```html | ||
37 | +<script src='path/to/bignumber.js'></script> | ||
38 | +``` | ||
39 | + | ||
40 | +[Node.js](http://nodejs.org): | ||
41 | + | ||
42 | +```bash | ||
43 | +$ npm install bignumber.js | ||
44 | +``` | ||
45 | + | ||
46 | +```javascript | ||
47 | +const BigNumber = require('bignumber.js'); | ||
48 | +``` | ||
49 | + | ||
50 | +ES6 module: | ||
51 | + | ||
52 | +```javascript | ||
53 | +import BigNumber from "./bignumber.mjs" | ||
54 | +``` | ||
55 | + | ||
56 | +AMD loader libraries such as [requireJS](http://requirejs.org/): | ||
57 | + | ||
58 | +```javascript | ||
59 | +require(['bignumber'], function(BigNumber) { | ||
60 | + // Use BigNumber here in local scope. No global BigNumber. | ||
61 | +}); | ||
62 | +``` | ||
63 | + | ||
64 | +## Use | ||
65 | + | ||
66 | +The library exports a single constructor function, [`BigNumber`](http://mikemcl.github.io/bignumber.js/#bignumber), which accepts a value of type Number, String or BigNumber, | ||
67 | + | ||
68 | +```javascript | ||
69 | +let x = new BigNumber(123.4567); | ||
70 | +let y = BigNumber('123456.7e-3'); | ||
71 | +let z = new BigNumber(x); | ||
72 | +x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z); // true | ||
73 | +``` | ||
74 | + | ||
75 | +To get the string value of a BigNumber use [`toString()`](http://mikemcl.github.io/bignumber.js/#toS) or [`toFixed()`](http://mikemcl.github.io/bignumber.js/#toFix). Using `toFixed()` prevents exponential notation being returned, no matter how large or small the value. | ||
76 | + | ||
77 | +```javascript | ||
78 | +let x = new BigNumber('1111222233334444555566'); | ||
79 | +x.toString(); // "1.111222233334444555566e+21" | ||
80 | +x.toFixed(); // "1111222233334444555566" | ||
81 | +``` | ||
82 | + | ||
83 | +If the limited precision of Number values is not well understood, it is recommended to create BigNumbers from String values rather than Number values to avoid a potential loss of precision. | ||
84 | + | ||
85 | +*In all further examples below, `let`, semicolons and `toString` calls are not shown. If a commented-out value is in quotes it means `toString` has been called on the preceding expression.* | ||
86 | + | ||
87 | +```javascript | ||
88 | +// Precision loss from using numeric literals with more than 15 significant digits. | ||
89 | +new BigNumber(1.0000000000000001) // '1' | ||
90 | +new BigNumber(88259496234518.57) // '88259496234518.56' | ||
91 | +new BigNumber(99999999999999999999) // '100000000000000000000' | ||
92 | + | ||
93 | +// Precision loss from using numeric literals outside the range of Number values. | ||
94 | +new BigNumber(2e+308) // 'Infinity' | ||
95 | +new BigNumber(1e-324) // '0' | ||
96 | + | ||
97 | +// Precision loss from the unexpected result of arithmetic with Number values. | ||
98 | +new BigNumber(0.7 + 0.1) // '0.7999999999999999' | ||
99 | +``` | ||
100 | + | ||
101 | +When creating a BigNumber from a Number, note that a BigNumber is created from a Number's decimal `toString()` value not from its underlying binary value. If the latter is required, then pass the Number's `toString(2)` value and specify base 2. | ||
102 | + | ||
103 | +```javascript | ||
104 | +new BigNumber(Number.MAX_VALUE.toString(2), 2) | ||
105 | +``` | ||
106 | + | ||
107 | +BigNumbers can be created from values in bases from 2 to 36. See [`ALPHABET`](http://mikemcl.github.io/bignumber.js/#alphabet) to extend this range. | ||
108 | + | ||
109 | +```javascript | ||
110 | +a = new BigNumber(1011, 2) // "11" | ||
111 | +b = new BigNumber('zz.9', 36) // "1295.25" | ||
112 | +c = a.plus(b) // "1306.25" | ||
113 | +``` | ||
114 | + | ||
115 | +Performance is better if base 10 is NOT specified for decimal values. Only specify base 10 when it is desired that the number of decimal places of the input value be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting. | ||
116 | + | ||
117 | +A BigNumber is immutable in the sense that it is not changed by its methods. | ||
118 | + | ||
119 | +```javascript | ||
120 | +0.3 - 0.1 // 0.19999999999999998 | ||
121 | +x = new BigNumber(0.3) | ||
122 | +x.minus(0.1) // "0.2" | ||
123 | +x // "0.3" | ||
124 | +``` | ||
125 | + | ||
126 | +The methods that return a BigNumber can be chained. | ||
127 | + | ||
128 | +```javascript | ||
129 | +x.dividedBy(y).plus(z).times(9) | ||
130 | +x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').integerValue() | ||
131 | +``` | ||
132 | + | ||
133 | +Some of the longer method names have a shorter alias. | ||
134 | + | ||
135 | +```javascript | ||
136 | +x.squareRoot().dividedBy(y).exponentiatedBy(3).isEqualTo(x.sqrt().div(y).pow(3)) // true | ||
137 | +x.modulo(y).multipliedBy(z).eq(x.mod(y).times(z)) // true | ||
138 | +``` | ||
139 | + | ||
140 | +As with JavaScript's Number type, there are [`toExponential`](http://mikemcl.github.io/bignumber.js/#toE), [`toFixed`](http://mikemcl.github.io/bignumber.js/#toFix) and [`toPrecision`](http://mikemcl.github.io/bignumber.js/#toP) methods. | ||
141 | + | ||
142 | +```javascript | ||
143 | +x = new BigNumber(255.5) | ||
144 | +x.toExponential(5) // "2.55500e+2" | ||
145 | +x.toFixed(5) // "255.50000" | ||
146 | +x.toPrecision(5) // "255.50" | ||
147 | +x.toNumber() // 255.5 | ||
148 | +``` | ||
149 | + | ||
150 | + A base can be specified for [`toString`](http://mikemcl.github.io/bignumber.js/#toS). Performance is better if base 10 is NOT specified, i.e. use `toString()` not `toString(10)`. Only specify base 10 when it is desired that the number of decimal places be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting. | ||
151 | + | ||
152 | + ```javascript | ||
153 | + x.toString(16) // "ff.8" | ||
154 | + ``` | ||
155 | + | ||
156 | +There is a [`toFormat`](http://mikemcl.github.io/bignumber.js/#toFor) method which may be useful for internationalisation. | ||
157 | + | ||
158 | +```javascript | ||
159 | +y = new BigNumber('1234567.898765') | ||
160 | +y.toFormat(2) // "1,234,567.90" | ||
161 | +``` | ||
162 | + | ||
163 | +The maximum number of decimal places of the result of an operation involving division (i.e. a division, square root, base conversion or negative power operation) is set using the `set` or `config` method of the `BigNumber` constructor. | ||
164 | + | ||
165 | +The other arithmetic operations always give the exact result. | ||
166 | + | ||
167 | +```javascript | ||
168 | +BigNumber.set({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 }) | ||
169 | + | ||
170 | +x = new BigNumber(2) | ||
171 | +y = new BigNumber(3) | ||
172 | +z = x.dividedBy(y) // "0.6666666667" | ||
173 | +z.squareRoot() // "0.8164965809" | ||
174 | +z.exponentiatedBy(-3) // "3.3749999995" | ||
175 | +z.toString(2) // "0.1010101011" | ||
176 | +z.multipliedBy(z) // "0.44444444448888888889" | ||
177 | +z.multipliedBy(z).decimalPlaces(10) // "0.4444444445" | ||
178 | +``` | ||
179 | + | ||
180 | +There is a [`toFraction`](http://mikemcl.github.io/bignumber.js/#toFr) method with an optional *maximum denominator* argument | ||
181 | + | ||
182 | +```javascript | ||
183 | +y = new BigNumber(355) | ||
184 | +pi = y.dividedBy(113) // "3.1415929204" | ||
185 | +pi.toFraction() // [ "7853982301", "2500000000" ] | ||
186 | +pi.toFraction(1000) // [ "355", "113" ] | ||
187 | +``` | ||
188 | + | ||
189 | +and [`isNaN`](http://mikemcl.github.io/bignumber.js/#isNaN) and [`isFinite`](http://mikemcl.github.io/bignumber.js/#isF) methods, as `NaN` and `Infinity` are valid `BigNumber` values. | ||
190 | + | ||
191 | +```javascript | ||
192 | +x = new BigNumber(NaN) // "NaN" | ||
193 | +y = new BigNumber(Infinity) // "Infinity" | ||
194 | +x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true | ||
195 | +``` | ||
196 | + | ||
197 | +The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign. | ||
198 | + | ||
199 | +```javascript | ||
200 | +x = new BigNumber(-123.456); | ||
201 | +x.c // [ 123, 45600000000000 ] coefficient (i.e. significand) | ||
202 | +x.e // 2 exponent | ||
203 | +x.s // -1 sign | ||
204 | +``` | ||
205 | + | ||
206 | +For advanced usage, multiple BigNumber constructors can be created, each with their own independent configuration. | ||
207 | + | ||
208 | +```javascript | ||
209 | +// Set DECIMAL_PLACES for the original BigNumber constructor | ||
210 | +BigNumber.set({ DECIMAL_PLACES: 10 }) | ||
211 | + | ||
212 | +// Create another BigNumber constructor, optionally passing in a configuration object | ||
213 | +BN = BigNumber.clone({ DECIMAL_PLACES: 5 }) | ||
214 | + | ||
215 | +x = new BigNumber(1) | ||
216 | +y = new BN(1) | ||
217 | + | ||
218 | +x.div(3) // '0.3333333333' | ||
219 | +y.div(3) // '0.33333' | ||
220 | +``` | ||
221 | + | ||
222 | +For further information see the [API](http://mikemcl.github.io/bignumber.js/) reference in the *doc* directory. | ||
223 | + | ||
224 | +## Test | ||
225 | + | ||
226 | +The *test/modules* directory contains the test scripts for each method. | ||
227 | + | ||
228 | +The tests can be run with Node.js or a browser. For Node.js use | ||
229 | + | ||
230 | + $ npm test | ||
231 | + | ||
232 | +or | ||
233 | + | ||
234 | + $ node test/test | ||
235 | + | ||
236 | +To test a single method, use, for example | ||
237 | + | ||
238 | + $ node test/methods/toFraction | ||
239 | + | ||
240 | +For the browser, open *test/test.html*. | ||
241 | + | ||
242 | +## Build | ||
243 | + | ||
244 | +For Node, if [uglify-js](https://github.com/mishoo/UglifyJS2) is installed | ||
245 | + | ||
246 | + npm install uglify-js -g | ||
247 | + | ||
248 | +then | ||
249 | + | ||
250 | + npm run build | ||
251 | + | ||
252 | +will create *bignumber.min.js*. | ||
253 | + | ||
254 | +A source map will also be created in the root directory. | ||
255 | + | ||
256 | +## Feedback | ||
257 | + | ||
258 | +Open an issue, or email | ||
259 | + | ||
260 | +Michael | ||
261 | + | ||
262 | +<a href="mailto:M8ch88l@gmail.com">M8ch88l@gmail.com</a> | ||
263 | + | ||
264 | +## Licence | ||
265 | + | ||
266 | +The MIT Licence. | ||
267 | + | ||
268 | +See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE). |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +{ | ||
2 | + "_from": "bignumber.js@9.0.0", | ||
3 | + "_id": "bignumber.js@9.0.0", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", | ||
6 | + "_location": "/bignumber.js", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "version", | ||
10 | + "registry": true, | ||
11 | + "raw": "bignumber.js@9.0.0", | ||
12 | + "name": "bignumber.js", | ||
13 | + "escapedName": "bignumber.js", | ||
14 | + "rawSpec": "9.0.0", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "9.0.0" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/mysql" | ||
20 | + ], | ||
21 | + "_resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", | ||
22 | + "_shasum": "805880f84a329b5eac6e7cb6f8274b6d82bdf075", | ||
23 | + "_spec": "bignumber.js@9.0.0", | ||
24 | + "_where": "C:\\Users\\worro\\OneDrive\\Desktop\\openSourceSoftware\\backend\\node_modules\\mysql", | ||
25 | + "author": { | ||
26 | + "name": "Michael Mclaughlin", | ||
27 | + "email": "M8ch88l@gmail.com" | ||
28 | + }, | ||
29 | + "browser": "bignumber.js", | ||
30 | + "bugs": { | ||
31 | + "url": "https://github.com/MikeMcl/bignumber.js/issues" | ||
32 | + }, | ||
33 | + "bundleDependencies": false, | ||
34 | + "dependencies": {}, | ||
35 | + "deprecated": false, | ||
36 | + "description": "A library for arbitrary-precision decimal and non-decimal arithmetic", | ||
37 | + "engines": { | ||
38 | + "node": "*" | ||
39 | + }, | ||
40 | + "homepage": "https://github.com/MikeMcl/bignumber.js#readme", | ||
41 | + "keywords": [ | ||
42 | + "arbitrary", | ||
43 | + "precision", | ||
44 | + "arithmetic", | ||
45 | + "big", | ||
46 | + "number", | ||
47 | + "decimal", | ||
48 | + "float", | ||
49 | + "biginteger", | ||
50 | + "bigdecimal", | ||
51 | + "bignumber", | ||
52 | + "bigint", | ||
53 | + "bignum" | ||
54 | + ], | ||
55 | + "license": "MIT", | ||
56 | + "main": "bignumber", | ||
57 | + "module": "bignumber.mjs", | ||
58 | + "name": "bignumber.js", | ||
59 | + "repository": { | ||
60 | + "type": "git", | ||
61 | + "url": "git+https://github.com/MikeMcl/bignumber.js.git" | ||
62 | + }, | ||
63 | + "scripts": { | ||
64 | + "build": "uglifyjs bignumber.js --source-map -c -m -o bignumber.min.js", | ||
65 | + "test": "node test/test" | ||
66 | + }, | ||
67 | + "types": "bignumber.d.ts", | ||
68 | + "version": "9.0.0" | ||
69 | +} |
backend/node_modules/core-util-is/LICENSE
0 → 100644
1 | +Copyright Node.js contributors. All rights reserved. | ||
2 | + | ||
3 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | +of this software and associated documentation files (the "Software"), to | ||
5 | +deal in the Software without restriction, including without limitation the | ||
6 | +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
7 | +sell copies of the Software, and to permit persons to whom the Software is | ||
8 | +furnished to do so, subject to the following conditions: | ||
9 | + | ||
10 | +The above copyright notice and this permission notice shall be included in | ||
11 | +all copies or substantial portions of the Software. | ||
12 | + | ||
13 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
18 | +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
19 | +IN THE SOFTWARE. |
backend/node_modules/core-util-is/README.md
0 → 100644
This diff is collapsed. Click to expand it.
1 | +// Copyright Joyent, Inc. and other Node contributors. | ||
2 | +// | ||
3 | +// Permission is hereby granted, free of charge, to any person obtaining a | ||
4 | +// copy of this software and associated documentation files (the | ||
5 | +// "Software"), to deal in the Software without restriction, including | ||
6 | +// without limitation the rights to use, copy, modify, merge, publish, | ||
7 | +// distribute, sublicense, and/or sell copies of the Software, and to permit | ||
8 | +// persons to whom the Software is furnished to do so, subject to the | ||
9 | +// following conditions: | ||
10 | +// | ||
11 | +// The above copyright notice and this permission notice shall be included | ||
12 | +// in all copies or substantial portions of the Software. | ||
13 | +// | ||
14 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
15 | +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN | ||
17 | +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
18 | +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
19 | +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
20 | +// USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
21 | + | ||
22 | +// NOTE: These type checking functions intentionally don't use `instanceof` | ||
23 | +// because it is fragile and can be easily faked with `Object.create()`. | ||
24 | + | ||
25 | +function isArray(arg) { | ||
26 | + if (Array.isArray) { | ||
27 | + return Array.isArray(arg); | ||
28 | + } | ||
29 | + return objectToString(arg) === '[object Array]'; | ||
30 | +} | ||
31 | +exports.isArray = isArray; | ||
32 | + | ||
33 | +function isBoolean(arg) { | ||
34 | + return typeof arg === 'boolean'; | ||
35 | +} | ||
36 | +exports.isBoolean = isBoolean; | ||
37 | + | ||
38 | +function isNull(arg) { | ||
39 | + return arg === null; | ||
40 | +} | ||
41 | +exports.isNull = isNull; | ||
42 | + | ||
43 | +function isNullOrUndefined(arg) { | ||
44 | + return arg == null; | ||
45 | +} | ||
46 | +exports.isNullOrUndefined = isNullOrUndefined; | ||
47 | + | ||
48 | +function isNumber(arg) { | ||
49 | + return typeof arg === 'number'; | ||
50 | +} | ||
51 | +exports.isNumber = isNumber; | ||
52 | + | ||
53 | +function isString(arg) { | ||
54 | + return typeof arg === 'string'; | ||
55 | +} | ||
56 | +exports.isString = isString; | ||
57 | + | ||
58 | +function isSymbol(arg) { | ||
59 | + return typeof arg === 'symbol'; | ||
60 | +} | ||
61 | +exports.isSymbol = isSymbol; | ||
62 | + | ||
63 | +function isUndefined(arg) { | ||
64 | + return arg === void 0; | ||
65 | +} | ||
66 | +exports.isUndefined = isUndefined; | ||
67 | + | ||
68 | +function isRegExp(re) { | ||
69 | + return objectToString(re) === '[object RegExp]'; | ||
70 | +} | ||
71 | +exports.isRegExp = isRegExp; | ||
72 | + | ||
73 | +function isObject(arg) { | ||
74 | + return typeof arg === 'object' && arg !== null; | ||
75 | +} | ||
76 | +exports.isObject = isObject; | ||
77 | + | ||
78 | +function isDate(d) { | ||
79 | + return objectToString(d) === '[object Date]'; | ||
80 | +} | ||
81 | +exports.isDate = isDate; | ||
82 | + | ||
83 | +function isError(e) { | ||
84 | + return (objectToString(e) === '[object Error]' || e instanceof Error); | ||
85 | +} | ||
86 | +exports.isError = isError; | ||
87 | + | ||
88 | +function isFunction(arg) { | ||
89 | + return typeof arg === 'function'; | ||
90 | +} | ||
91 | +exports.isFunction = isFunction; | ||
92 | + | ||
93 | +function isPrimitive(arg) { | ||
94 | + return arg === null || | ||
95 | + typeof arg === 'boolean' || | ||
96 | + typeof arg === 'number' || | ||
97 | + typeof arg === 'string' || | ||
98 | + typeof arg === 'symbol' || // ES6 symbol | ||
99 | + typeof arg === 'undefined'; | ||
100 | +} | ||
101 | +exports.isPrimitive = isPrimitive; | ||
102 | + | ||
103 | +exports.isBuffer = Buffer.isBuffer; | ||
104 | + | ||
105 | +function objectToString(o) { | ||
106 | + return Object.prototype.toString.call(o); | ||
107 | +} |
1 | +{ | ||
2 | + "_from": "core-util-is@~1.0.0", | ||
3 | + "_id": "core-util-is@1.0.2", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", | ||
6 | + "_location": "/core-util-is", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "range", | ||
10 | + "registry": true, | ||
11 | + "raw": "core-util-is@~1.0.0", | ||
12 | + "name": "core-util-is", | ||
13 | + "escapedName": "core-util-is", | ||
14 | + "rawSpec": "~1.0.0", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "~1.0.0" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/readable-stream" | ||
20 | + ], | ||
21 | + "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", | ||
22 | + "_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", | ||
23 | + "_spec": "core-util-is@~1.0.0", | ||
24 | + "_where": "C:\\Users\\worro\\OneDrive\\Desktop\\openSourceSoftware\\backend\\node_modules\\readable-stream", | ||
25 | + "author": { | ||
26 | + "name": "Isaac Z. Schlueter", | ||
27 | + "email": "i@izs.me", | ||
28 | + "url": "http://blog.izs.me/" | ||
29 | + }, | ||
30 | + "bugs": { | ||
31 | + "url": "https://github.com/isaacs/core-util-is/issues" | ||
32 | + }, | ||
33 | + "bundleDependencies": false, | ||
34 | + "deprecated": false, | ||
35 | + "description": "The `util.is*` functions introduced in Node v0.12.", | ||
36 | + "devDependencies": { | ||
37 | + "tap": "^2.3.0" | ||
38 | + }, | ||
39 | + "homepage": "https://github.com/isaacs/core-util-is#readme", | ||
40 | + "keywords": [ | ||
41 | + "util", | ||
42 | + "isBuffer", | ||
43 | + "isArray", | ||
44 | + "isNumber", | ||
45 | + "isString", | ||
46 | + "isRegExp", | ||
47 | + "isThis", | ||
48 | + "isThat", | ||
49 | + "polyfill" | ||
50 | + ], | ||
51 | + "license": "MIT", | ||
52 | + "main": "lib/util.js", | ||
53 | + "name": "core-util-is", | ||
54 | + "repository": { | ||
55 | + "type": "git", | ||
56 | + "url": "git://github.com/isaacs/core-util-is.git" | ||
57 | + }, | ||
58 | + "scripts": { | ||
59 | + "test": "tap test.js" | ||
60 | + }, | ||
61 | + "version": "1.0.2" | ||
62 | +} |
backend/node_modules/core-util-is/test.js
0 → 100644
1 | +var assert = require('tap'); | ||
2 | + | ||
3 | +var t = require('./lib/util'); | ||
4 | + | ||
5 | +assert.equal(t.isArray([]), true); | ||
6 | +assert.equal(t.isArray({}), false); | ||
7 | + | ||
8 | +assert.equal(t.isBoolean(null), false); | ||
9 | +assert.equal(t.isBoolean(true), true); | ||
10 | +assert.equal(t.isBoolean(false), true); | ||
11 | + | ||
12 | +assert.equal(t.isNull(null), true); | ||
13 | +assert.equal(t.isNull(undefined), false); | ||
14 | +assert.equal(t.isNull(false), false); | ||
15 | +assert.equal(t.isNull(), false); | ||
16 | + | ||
17 | +assert.equal(t.isNullOrUndefined(null), true); | ||
18 | +assert.equal(t.isNullOrUndefined(undefined), true); | ||
19 | +assert.equal(t.isNullOrUndefined(false), false); | ||
20 | +assert.equal(t.isNullOrUndefined(), true); | ||
21 | + | ||
22 | +assert.equal(t.isNumber(null), false); | ||
23 | +assert.equal(t.isNumber('1'), false); | ||
24 | +assert.equal(t.isNumber(1), true); | ||
25 | + | ||
26 | +assert.equal(t.isString(null), false); | ||
27 | +assert.equal(t.isString('1'), true); | ||
28 | +assert.equal(t.isString(1), false); | ||
29 | + | ||
30 | +assert.equal(t.isSymbol(null), false); | ||
31 | +assert.equal(t.isSymbol('1'), false); | ||
32 | +assert.equal(t.isSymbol(1), false); | ||
33 | +assert.equal(t.isSymbol(Symbol()), true); | ||
34 | + | ||
35 | +assert.equal(t.isUndefined(null), false); | ||
36 | +assert.equal(t.isUndefined(undefined), true); | ||
37 | +assert.equal(t.isUndefined(false), false); | ||
38 | +assert.equal(t.isUndefined(), true); | ||
39 | + | ||
40 | +assert.equal(t.isRegExp(null), false); | ||
41 | +assert.equal(t.isRegExp('1'), false); | ||
42 | +assert.equal(t.isRegExp(new RegExp()), true); | ||
43 | + | ||
44 | +assert.equal(t.isObject({}), true); | ||
45 | +assert.equal(t.isObject([]), true); | ||
46 | +assert.equal(t.isObject(new RegExp()), true); | ||
47 | +assert.equal(t.isObject(new Date()), true); | ||
48 | + | ||
49 | +assert.equal(t.isDate(null), false); | ||
50 | +assert.equal(t.isDate('1'), false); | ||
51 | +assert.equal(t.isDate(new Date()), true); | ||
52 | + | ||
53 | +assert.equal(t.isError(null), false); | ||
54 | +assert.equal(t.isError({ err: true }), false); | ||
55 | +assert.equal(t.isError(new Error()), true); | ||
56 | + | ||
57 | +assert.equal(t.isFunction(null), false); | ||
58 | +assert.equal(t.isFunction({ }), false); | ||
59 | +assert.equal(t.isFunction(function() {}), true); | ||
60 | + | ||
61 | +assert.equal(t.isPrimitive(null), true); | ||
62 | +assert.equal(t.isPrimitive(''), true); | ||
63 | +assert.equal(t.isPrimitive(0), true); | ||
64 | +assert.equal(t.isPrimitive(new Date()), false); | ||
65 | + | ||
66 | +assert.equal(t.isBuffer(null), false); | ||
67 | +assert.equal(t.isBuffer({}), false); | ||
68 | +assert.equal(t.isBuffer(new Buffer(0)), true); |
backend/node_modules/isarray/.npmignore
0 → 100644
1 | +node_modules |
backend/node_modules/isarray/.travis.yml
0 → 100644
backend/node_modules/isarray/Makefile
0 → 100644
backend/node_modules/isarray/README.md
0 → 100644
1 | + | ||
2 | +# isarray | ||
3 | + | ||
4 | +`Array#isArray` for older browsers. | ||
5 | + | ||
6 | +[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray) | ||
7 | +[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray) | ||
8 | + | ||
9 | +[![browser support](https://ci.testling.com/juliangruber/isarray.png) | ||
10 | +](https://ci.testling.com/juliangruber/isarray) | ||
11 | + | ||
12 | +## Usage | ||
13 | + | ||
14 | +```js | ||
15 | +var isArray = require('isarray'); | ||
16 | + | ||
17 | +console.log(isArray([])); // => true | ||
18 | +console.log(isArray({})); // => false | ||
19 | +``` | ||
20 | + | ||
21 | +## Installation | ||
22 | + | ||
23 | +With [npm](http://npmjs.org) do | ||
24 | + | ||
25 | +```bash | ||
26 | +$ npm install isarray | ||
27 | +``` | ||
28 | + | ||
29 | +Then bundle for the browser with | ||
30 | +[browserify](https://github.com/substack/browserify). | ||
31 | + | ||
32 | +With [component](http://component.io) do | ||
33 | + | ||
34 | +```bash | ||
35 | +$ component install juliangruber/isarray | ||
36 | +``` | ||
37 | + | ||
38 | +## License | ||
39 | + | ||
40 | +(MIT) | ||
41 | + | ||
42 | +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> | ||
43 | + | ||
44 | +Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
45 | +this software and associated documentation files (the "Software"), to deal in | ||
46 | +the Software without restriction, including without limitation the rights to | ||
47 | +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
48 | +of the Software, and to permit persons to whom the Software is furnished to do | ||
49 | +so, subject to the following conditions: | ||
50 | + | ||
51 | +The above copyright notice and this permission notice shall be included in all | ||
52 | +copies or substantial portions of the Software. | ||
53 | + | ||
54 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
55 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
56 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
57 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
58 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
59 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
60 | +SOFTWARE. |
backend/node_modules/isarray/component.json
0 → 100644
1 | +{ | ||
2 | + "name" : "isarray", | ||
3 | + "description" : "Array#isArray for older browsers", | ||
4 | + "version" : "0.0.1", | ||
5 | + "repository" : "juliangruber/isarray", | ||
6 | + "homepage": "https://github.com/juliangruber/isarray", | ||
7 | + "main" : "index.js", | ||
8 | + "scripts" : [ | ||
9 | + "index.js" | ||
10 | + ], | ||
11 | + "dependencies" : {}, | ||
12 | + "keywords": ["browser","isarray","array"], | ||
13 | + "author": { | ||
14 | + "name": "Julian Gruber", | ||
15 | + "email": "mail@juliangruber.com", | ||
16 | + "url": "http://juliangruber.com" | ||
17 | + }, | ||
18 | + "license": "MIT" | ||
19 | +} |
backend/node_modules/isarray/index.js
0 → 100644
backend/node_modules/isarray/package.json
0 → 100644
1 | +{ | ||
2 | + "_from": "isarray@~1.0.0", | ||
3 | + "_id": "isarray@1.0.0", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", | ||
6 | + "_location": "/isarray", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "range", | ||
10 | + "registry": true, | ||
11 | + "raw": "isarray@~1.0.0", | ||
12 | + "name": "isarray", | ||
13 | + "escapedName": "isarray", | ||
14 | + "rawSpec": "~1.0.0", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "~1.0.0" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/readable-stream" | ||
20 | + ], | ||
21 | + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", | ||
22 | + "_shasum": "bb935d48582cba168c06834957a54a3e07124f11", | ||
23 | + "_spec": "isarray@~1.0.0", | ||
24 | + "_where": "C:\\Users\\worro\\OneDrive\\Desktop\\openSourceSoftware\\backend\\node_modules\\readable-stream", | ||
25 | + "author": { | ||
26 | + "name": "Julian Gruber", | ||
27 | + "email": "mail@juliangruber.com", | ||
28 | + "url": "http://juliangruber.com" | ||
29 | + }, | ||
30 | + "bugs": { | ||
31 | + "url": "https://github.com/juliangruber/isarray/issues" | ||
32 | + }, | ||
33 | + "bundleDependencies": false, | ||
34 | + "dependencies": {}, | ||
35 | + "deprecated": false, | ||
36 | + "description": "Array#isArray for older browsers", | ||
37 | + "devDependencies": { | ||
38 | + "tape": "~2.13.4" | ||
39 | + }, | ||
40 | + "homepage": "https://github.com/juliangruber/isarray", | ||
41 | + "keywords": [ | ||
42 | + "browser", | ||
43 | + "isarray", | ||
44 | + "array" | ||
45 | + ], | ||
46 | + "license": "MIT", | ||
47 | + "main": "index.js", | ||
48 | + "name": "isarray", | ||
49 | + "repository": { | ||
50 | + "type": "git", | ||
51 | + "url": "git://github.com/juliangruber/isarray.git" | ||
52 | + }, | ||
53 | + "scripts": { | ||
54 | + "test": "tape test.js" | ||
55 | + }, | ||
56 | + "testling": { | ||
57 | + "files": "test.js", | ||
58 | + "browsers": [ | ||
59 | + "ie/8..latest", | ||
60 | + "firefox/17..latest", | ||
61 | + "firefox/nightly", | ||
62 | + "chrome/22..latest", | ||
63 | + "chrome/canary", | ||
64 | + "opera/12..latest", | ||
65 | + "opera/next", | ||
66 | + "safari/5.1..latest", | ||
67 | + "ipad/6.0..latest", | ||
68 | + "iphone/6.0..latest", | ||
69 | + "android-browser/4.2..latest" | ||
70 | + ] | ||
71 | + }, | ||
72 | + "version": "1.0.0" | ||
73 | +} |
backend/node_modules/isarray/test.js
0 → 100644
1 | +var isArray = require('./'); | ||
2 | +var test = require('tape'); | ||
3 | + | ||
4 | +test('is array', function(t){ | ||
5 | + t.ok(isArray([])); | ||
6 | + t.notOk(isArray({})); | ||
7 | + t.notOk(isArray(null)); | ||
8 | + t.notOk(isArray(false)); | ||
9 | + | ||
10 | + var obj = {}; | ||
11 | + obj[0] = true; | ||
12 | + t.notOk(isArray(obj)); | ||
13 | + | ||
14 | + var arr = []; | ||
15 | + arr.foo = 'bar'; | ||
16 | + t.ok(isArray(arr)); | ||
17 | + | ||
18 | + t.end(); | ||
19 | +}); | ||
20 | + |
backend/node_modules/mysql/Changes.md
0 → 100644
This diff is collapsed. Click to expand it.
backend/node_modules/mysql/License
0 → 100644
1 | +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors | ||
2 | + | ||
3 | + Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | + of this software and associated documentation files (the "Software"), to deal | ||
5 | + in the Software without restriction, including without limitation the rights | ||
6 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | + copies of the Software, and to permit persons to whom the Software is | ||
8 | + furnished to do so, subject to the following conditions: | ||
9 | + | ||
10 | + The above copyright notice and this permission notice shall be included in | ||
11 | + all copies or substantial portions of the Software. | ||
12 | + | ||
13 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
19 | + THE SOFTWARE. |
backend/node_modules/mysql/Readme.md
0 → 100644
This diff is collapsed. Click to expand it.
backend/node_modules/mysql/index.js
0 → 100644
1 | +var Classes = Object.create(null); | ||
2 | + | ||
3 | +/** | ||
4 | + * Create a new Connection instance. | ||
5 | + * @param {object|string} config Configuration or connection string for new MySQL connection | ||
6 | + * @return {Connection} A new MySQL connection | ||
7 | + * @public | ||
8 | + */ | ||
9 | +exports.createConnection = function createConnection(config) { | ||
10 | + var Connection = loadClass('Connection'); | ||
11 | + var ConnectionConfig = loadClass('ConnectionConfig'); | ||
12 | + | ||
13 | + return new Connection({config: new ConnectionConfig(config)}); | ||
14 | +}; | ||
15 | + | ||
16 | +/** | ||
17 | + * Create a new Pool instance. | ||
18 | + * @param {object|string} config Configuration or connection string for new MySQL connections | ||
19 | + * @return {Pool} A new MySQL pool | ||
20 | + * @public | ||
21 | + */ | ||
22 | +exports.createPool = function createPool(config) { | ||
23 | + var Pool = loadClass('Pool'); | ||
24 | + var PoolConfig = loadClass('PoolConfig'); | ||
25 | + | ||
26 | + return new Pool({config: new PoolConfig(config)}); | ||
27 | +}; | ||
28 | + | ||
29 | +/** | ||
30 | + * Create a new PoolCluster instance. | ||
31 | + * @param {object} [config] Configuration for pool cluster | ||
32 | + * @return {PoolCluster} New MySQL pool cluster | ||
33 | + * @public | ||
34 | + */ | ||
35 | +exports.createPoolCluster = function createPoolCluster(config) { | ||
36 | + var PoolCluster = loadClass('PoolCluster'); | ||
37 | + | ||
38 | + return new PoolCluster(config); | ||
39 | +}; | ||
40 | + | ||
41 | +/** | ||
42 | + * Create a new Query instance. | ||
43 | + * @param {string} sql The SQL for the query | ||
44 | + * @param {array} [values] Any values to insert into placeholders in sql | ||
45 | + * @param {function} [callback] The callback to use when query is complete | ||
46 | + * @return {Query} New query object | ||
47 | + * @public | ||
48 | + */ | ||
49 | +exports.createQuery = function createQuery(sql, values, callback) { | ||
50 | + var Connection = loadClass('Connection'); | ||
51 | + | ||
52 | + return Connection.createQuery(sql, values, callback); | ||
53 | +}; | ||
54 | + | ||
55 | +/** | ||
56 | + * Escape a value for SQL. | ||
57 | + * @param {*} value The value to escape | ||
58 | + * @param {boolean} [stringifyObjects=false] Setting if objects should be stringified | ||
59 | + * @param {string} [timeZone=local] Setting for time zone to use for Date conversion | ||
60 | + * @return {string} Escaped string value | ||
61 | + * @public | ||
62 | + */ | ||
63 | +exports.escape = function escape(value, stringifyObjects, timeZone) { | ||
64 | + var SqlString = loadClass('SqlString'); | ||
65 | + | ||
66 | + return SqlString.escape(value, stringifyObjects, timeZone); | ||
67 | +}; | ||
68 | + | ||
69 | +/** | ||
70 | + * Escape an identifier for SQL. | ||
71 | + * @param {*} value The value to escape | ||
72 | + * @param {boolean} [forbidQualified=false] Setting to treat '.' as part of identifier | ||
73 | + * @return {string} Escaped string value | ||
74 | + * @public | ||
75 | + */ | ||
76 | +exports.escapeId = function escapeId(value, forbidQualified) { | ||
77 | + var SqlString = loadClass('SqlString'); | ||
78 | + | ||
79 | + return SqlString.escapeId(value, forbidQualified); | ||
80 | +}; | ||
81 | + | ||
82 | +/** | ||
83 | + * Format SQL and replacement values into a SQL string. | ||
84 | + * @param {string} sql The SQL for the query | ||
85 | + * @param {array} [values] Any values to insert into placeholders in sql | ||
86 | + * @param {boolean} [stringifyObjects=false] Setting if objects should be stringified | ||
87 | + * @param {string} [timeZone=local] Setting for time zone to use for Date conversion | ||
88 | + * @return {string} Formatted SQL string | ||
89 | + * @public | ||
90 | + */ | ||
91 | +exports.format = function format(sql, values, stringifyObjects, timeZone) { | ||
92 | + var SqlString = loadClass('SqlString'); | ||
93 | + | ||
94 | + return SqlString.format(sql, values, stringifyObjects, timeZone); | ||
95 | +}; | ||
96 | + | ||
97 | +/** | ||
98 | + * Wrap raw SQL strings from escape overriding. | ||
99 | + * @param {string} sql The raw SQL | ||
100 | + * @return {object} Wrapped object | ||
101 | + * @public | ||
102 | + */ | ||
103 | +exports.raw = function raw(sql) { | ||
104 | + var SqlString = loadClass('SqlString'); | ||
105 | + | ||
106 | + return SqlString.raw(sql); | ||
107 | +}; | ||
108 | + | ||
109 | +/** | ||
110 | + * The type constants. | ||
111 | + * @public | ||
112 | + */ | ||
113 | +Object.defineProperty(exports, 'Types', { | ||
114 | + get: loadClass.bind(null, 'Types') | ||
115 | +}); | ||
116 | + | ||
117 | +/** | ||
118 | + * Load the given class. | ||
119 | + * @param {string} className Name of class to default | ||
120 | + * @return {function|object} Class constructor or exports | ||
121 | + * @private | ||
122 | + */ | ||
123 | +function loadClass(className) { | ||
124 | + var Class = Classes[className]; | ||
125 | + | ||
126 | + if (Class !== undefined) { | ||
127 | + return Class; | ||
128 | + } | ||
129 | + | ||
130 | + // This uses a switch for static require analysis | ||
131 | + switch (className) { | ||
132 | + case 'Connection': | ||
133 | + Class = require('./lib/Connection'); | ||
134 | + break; | ||
135 | + case 'ConnectionConfig': | ||
136 | + Class = require('./lib/ConnectionConfig'); | ||
137 | + break; | ||
138 | + case 'Pool': | ||
139 | + Class = require('./lib/Pool'); | ||
140 | + break; | ||
141 | + case 'PoolCluster': | ||
142 | + Class = require('./lib/PoolCluster'); | ||
143 | + break; | ||
144 | + case 'PoolConfig': | ||
145 | + Class = require('./lib/PoolConfig'); | ||
146 | + break; | ||
147 | + case 'SqlString': | ||
148 | + Class = require('./lib/protocol/SqlString'); | ||
149 | + break; | ||
150 | + case 'Types': | ||
151 | + Class = require('./lib/protocol/constants/types'); | ||
152 | + break; | ||
153 | + default: | ||
154 | + throw new Error('Cannot find class \'' + className + '\''); | ||
155 | + } | ||
156 | + | ||
157 | + // Store to prevent invoking require() | ||
158 | + Classes[className] = Class; | ||
159 | + | ||
160 | + return Class; | ||
161 | +} |
backend/node_modules/mysql/lib/Connection.js
0 → 100644
This diff is collapsed. Click to expand it.
1 | +var urlParse = require('url').parse; | ||
2 | +var ClientConstants = require('./protocol/constants/client'); | ||
3 | +var Charsets = require('./protocol/constants/charsets'); | ||
4 | +var SSLProfiles = null; | ||
5 | + | ||
6 | +module.exports = ConnectionConfig; | ||
7 | +function 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 || 3306; | ||
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.localInfile = (options.localInfile === undefined) | ||
37 | + ? true | ||
38 | + : options.localInfile; | ||
39 | + this.multipleStatements = options.multipleStatements || false; | ||
40 | + this.typeCast = (options.typeCast === undefined) | ||
41 | + ? true | ||
42 | + : options.typeCast; | ||
43 | + | ||
44 | + if (this.timezone[0] === ' ') { | ||
45 | + // "+" is a url encoded char for space so it | ||
46 | + // gets translated to space when giving a | ||
47 | + // connection string.. | ||
48 | + this.timezone = '+' + this.timezone.substr(1); | ||
49 | + } | ||
50 | + | ||
51 | + if (this.ssl) { | ||
52 | + // Default rejectUnauthorized to true | ||
53 | + this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false; | ||
54 | + } | ||
55 | + | ||
56 | + this.maxPacketSize = 0; | ||
57 | + this.charsetNumber = (options.charset) | ||
58 | + ? ConnectionConfig.getCharsetNumber(options.charset) | ||
59 | + : options.charsetNumber || Charsets.UTF8_GENERAL_CI; | ||
60 | + | ||
61 | + // Set the client flags | ||
62 | + var defaultFlags = ConnectionConfig.getDefaultFlags(options); | ||
63 | + this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags); | ||
64 | +} | ||
65 | + | ||
66 | +ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) { | ||
67 | + var allFlags = ConnectionConfig.parseFlagList(defaultFlags); | ||
68 | + var newFlags = ConnectionConfig.parseFlagList(userFlags); | ||
69 | + | ||
70 | + // Merge the new flags | ||
71 | + for (var flag in newFlags) { | ||
72 | + if (allFlags[flag] !== false) { | ||
73 | + allFlags[flag] = newFlags[flag]; | ||
74 | + } | ||
75 | + } | ||
76 | + | ||
77 | + // Build flags | ||
78 | + var flags = 0x0; | ||
79 | + for (var flag in allFlags) { | ||
80 | + if (allFlags[flag]) { | ||
81 | + // TODO: Throw here on some future release | ||
82 | + flags |= ClientConstants['CLIENT_' + flag] || 0x0; | ||
83 | + } | ||
84 | + } | ||
85 | + | ||
86 | + return flags; | ||
87 | +}; | ||
88 | + | ||
89 | +ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) { | ||
90 | + var num = Charsets[charset.toUpperCase()]; | ||
91 | + | ||
92 | + if (num === undefined) { | ||
93 | + throw new TypeError('Unknown charset \'' + charset + '\''); | ||
94 | + } | ||
95 | + | ||
96 | + return num; | ||
97 | +}; | ||
98 | + | ||
99 | +ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) { | ||
100 | + var defaultFlags = [ | ||
101 | + '-COMPRESS', // Compression protocol *NOT* supported | ||
102 | + '-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41 | ||
103 | + '+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet | ||
104 | + '+FOUND_ROWS', // Send found rows instead of affected rows | ||
105 | + '+IGNORE_SIGPIPE', // Don't issue SIGPIPE if network failures | ||
106 | + '+IGNORE_SPACE', // Let the parser ignore spaces before '(' | ||
107 | + '+LOCAL_FILES', // Can use LOAD DATA LOCAL | ||
108 | + '+LONG_FLAG', // Longer flags in Protocol::ColumnDefinition320 | ||
109 | + '+LONG_PASSWORD', // Use the improved version of Old Password Authentication | ||
110 | + '+MULTI_RESULTS', // Can handle multiple resultsets for COM_QUERY | ||
111 | + '+ODBC', // Special handling of ODBC behaviour | ||
112 | + '-PLUGIN_AUTH', // Does *NOT* support auth plugins | ||
113 | + '+PROTOCOL_41', // Uses the 4.1 protocol | ||
114 | + '+PS_MULTI_RESULTS', // Can handle multiple resultsets for COM_STMT_EXECUTE | ||
115 | + '+RESERVED', // Unused | ||
116 | + '+SECURE_CONNECTION', // Supports Authentication::Native41 | ||
117 | + '+TRANSACTIONS' // Expects status flags | ||
118 | + ]; | ||
119 | + | ||
120 | + if (options && options.localInfile !== undefined && !options.localInfile) { | ||
121 | + // Disable LOCAL modifier for LOAD DATA INFILE | ||
122 | + defaultFlags.push('-LOCAL_FILES'); | ||
123 | + } | ||
124 | + | ||
125 | + if (options && options.multipleStatements) { | ||
126 | + // May send multiple statements per COM_QUERY and COM_STMT_PREPARE | ||
127 | + defaultFlags.push('+MULTI_STATEMENTS'); | ||
128 | + } | ||
129 | + | ||
130 | + return defaultFlags; | ||
131 | +}; | ||
132 | + | ||
133 | +ConnectionConfig.getSSLProfile = function getSSLProfile(name) { | ||
134 | + if (!SSLProfiles) { | ||
135 | + SSLProfiles = require('./protocol/constants/ssl_profiles'); | ||
136 | + } | ||
137 | + | ||
138 | + var ssl = SSLProfiles[name]; | ||
139 | + | ||
140 | + if (ssl === undefined) { | ||
141 | + throw new TypeError('Unknown SSL profile \'' + name + '\''); | ||
142 | + } | ||
143 | + | ||
144 | + return ssl; | ||
145 | +}; | ||
146 | + | ||
147 | +ConnectionConfig.parseFlagList = function parseFlagList(flagList) { | ||
148 | + var allFlags = Object.create(null); | ||
149 | + | ||
150 | + if (!flagList) { | ||
151 | + return allFlags; | ||
152 | + } | ||
153 | + | ||
154 | + var flags = !Array.isArray(flagList) | ||
155 | + ? String(flagList || '').toUpperCase().split(/\s*,+\s*/) | ||
156 | + : flagList; | ||
157 | + | ||
158 | + for (var i = 0; i < flags.length; i++) { | ||
159 | + var flag = flags[i]; | ||
160 | + var offset = 1; | ||
161 | + var state = flag[0]; | ||
162 | + | ||
163 | + if (state === undefined) { | ||
164 | + // TODO: throw here on some future release | ||
165 | + continue; | ||
166 | + } | ||
167 | + | ||
168 | + if (state !== '-' && state !== '+') { | ||
169 | + offset = 0; | ||
170 | + state = '+'; | ||
171 | + } | ||
172 | + | ||
173 | + allFlags[flag.substr(offset)] = state === '+'; | ||
174 | + } | ||
175 | + | ||
176 | + return allFlags; | ||
177 | +}; | ||
178 | + | ||
179 | +ConnectionConfig.parseUrl = function(url) { | ||
180 | + url = urlParse(url, true); | ||
181 | + | ||
182 | + var options = { | ||
183 | + host : url.hostname, | ||
184 | + port : url.port, | ||
185 | + database : url.pathname.substr(1) | ||
186 | + }; | ||
187 | + | ||
188 | + if (url.auth) { | ||
189 | + var auth = url.auth.split(':'); | ||
190 | + options.user = auth.shift(); | ||
191 | + options.password = auth.join(':'); | ||
192 | + } | ||
193 | + | ||
194 | + if (url.query) { | ||
195 | + for (var key in url.query) { | ||
196 | + var value = url.query[key]; | ||
197 | + | ||
198 | + try { | ||
199 | + // Try to parse this as a JSON expression first | ||
200 | + options[key] = JSON.parse(value); | ||
201 | + } catch (err) { | ||
202 | + // Otherwise assume it is a plain string | ||
203 | + options[key] = value; | ||
204 | + } | ||
205 | + } | ||
206 | + } | ||
207 | + | ||
208 | + return options; | ||
209 | +}; |
backend/node_modules/mysql/lib/Pool.js
0 → 100644
1 | +var mysql = require('../'); | ||
2 | +var Connection = require('./Connection'); | ||
3 | +var EventEmitter = require('events').EventEmitter; | ||
4 | +var Util = require('util'); | ||
5 | +var PoolConnection = require('./PoolConnection'); | ||
6 | + | ||
7 | +module.exports = Pool; | ||
8 | + | ||
9 | +Util.inherits(Pool, EventEmitter); | ||
10 | +function Pool(options) { | ||
11 | + EventEmitter.call(this); | ||
12 | + this.config = options.config; | ||
13 | + this.config.connectionConfig.pool = this; | ||
14 | + | ||
15 | + this._acquiringConnections = []; | ||
16 | + this._allConnections = []; | ||
17 | + this._freeConnections = []; | ||
18 | + this._connectionQueue = []; | ||
19 | + this._closed = false; | ||
20 | +} | ||
21 | + | ||
22 | +Pool.prototype.getConnection = function (cb) { | ||
23 | + | ||
24 | + if (this._closed) { | ||
25 | + var err = new Error('Pool is closed.'); | ||
26 | + err.code = 'POOL_CLOSED'; | ||
27 | + process.nextTick(function () { | ||
28 | + cb(err); | ||
29 | + }); | ||
30 | + return; | ||
31 | + } | ||
32 | + | ||
33 | + var connection; | ||
34 | + var pool = this; | ||
35 | + | ||
36 | + if (this._freeConnections.length > 0) { | ||
37 | + connection = this._freeConnections.shift(); | ||
38 | + this.acquireConnection(connection, cb); | ||
39 | + return; | ||
40 | + } | ||
41 | + | ||
42 | + if (this.config.connectionLimit === 0 || this._allConnections.length < this.config.connectionLimit) { | ||
43 | + connection = new PoolConnection(this, { config: this.config.newConnectionConfig() }); | ||
44 | + | ||
45 | + this._acquiringConnections.push(connection); | ||
46 | + this._allConnections.push(connection); | ||
47 | + | ||
48 | + connection.connect({timeout: this.config.acquireTimeout}, function onConnect(err) { | ||
49 | + spliceConnection(pool._acquiringConnections, connection); | ||
50 | + | ||
51 | + if (pool._closed) { | ||
52 | + err = new Error('Pool is closed.'); | ||
53 | + err.code = 'POOL_CLOSED'; | ||
54 | + } | ||
55 | + | ||
56 | + if (err) { | ||
57 | + pool._purgeConnection(connection); | ||
58 | + cb(err); | ||
59 | + return; | ||
60 | + } | ||
61 | + | ||
62 | + pool.emit('connection', connection); | ||
63 | + pool.emit('acquire', connection); | ||
64 | + cb(null, connection); | ||
65 | + }); | ||
66 | + return; | ||
67 | + } | ||
68 | + | ||
69 | + if (!this.config.waitForConnections) { | ||
70 | + process.nextTick(function(){ | ||
71 | + var err = new Error('No connections available.'); | ||
72 | + err.code = 'POOL_CONNLIMIT'; | ||
73 | + cb(err); | ||
74 | + }); | ||
75 | + return; | ||
76 | + } | ||
77 | + | ||
78 | + this._enqueueCallback(cb); | ||
79 | +}; | ||
80 | + | ||
81 | +Pool.prototype.acquireConnection = function acquireConnection(connection, cb) { | ||
82 | + if (connection._pool !== this) { | ||
83 | + throw new Error('Connection acquired from wrong pool.'); | ||
84 | + } | ||
85 | + | ||
86 | + var changeUser = this._needsChangeUser(connection); | ||
87 | + var pool = this; | ||
88 | + | ||
89 | + this._acquiringConnections.push(connection); | ||
90 | + | ||
91 | + function onOperationComplete(err) { | ||
92 | + spliceConnection(pool._acquiringConnections, connection); | ||
93 | + | ||
94 | + if (pool._closed) { | ||
95 | + err = new Error('Pool is closed.'); | ||
96 | + err.code = 'POOL_CLOSED'; | ||
97 | + } | ||
98 | + | ||
99 | + if (err) { | ||
100 | + pool._connectionQueue.unshift(cb); | ||
101 | + pool._purgeConnection(connection); | ||
102 | + return; | ||
103 | + } | ||
104 | + | ||
105 | + if (changeUser) { | ||
106 | + pool.emit('connection', connection); | ||
107 | + } | ||
108 | + | ||
109 | + pool.emit('acquire', connection); | ||
110 | + cb(null, connection); | ||
111 | + } | ||
112 | + | ||
113 | + if (changeUser) { | ||
114 | + // restore user back to pool configuration | ||
115 | + connection.config = this.config.newConnectionConfig(); | ||
116 | + connection.changeUser({timeout: this.config.acquireTimeout}, onOperationComplete); | ||
117 | + } else { | ||
118 | + // ping connection | ||
119 | + connection.ping({timeout: this.config.acquireTimeout}, onOperationComplete); | ||
120 | + } | ||
121 | +}; | ||
122 | + | ||
123 | +Pool.prototype.releaseConnection = function releaseConnection(connection) { | ||
124 | + | ||
125 | + if (this._acquiringConnections.indexOf(connection) !== -1) { | ||
126 | + // connection is being acquired | ||
127 | + return; | ||
128 | + } | ||
129 | + | ||
130 | + if (connection._pool) { | ||
131 | + if (connection._pool !== this) { | ||
132 | + throw new Error('Connection released to wrong pool'); | ||
133 | + } | ||
134 | + | ||
135 | + if (this._freeConnections.indexOf(connection) !== -1) { | ||
136 | + // connection already in free connection pool | ||
137 | + // this won't catch all double-release cases | ||
138 | + throw new Error('Connection already released'); | ||
139 | + } else { | ||
140 | + // add connection to end of free queue | ||
141 | + this._freeConnections.push(connection); | ||
142 | + this.emit('release', connection); | ||
143 | + } | ||
144 | + } | ||
145 | + | ||
146 | + if (this._closed) { | ||
147 | + // empty the connection queue | ||
148 | + this._connectionQueue.splice(0).forEach(function (cb) { | ||
149 | + var err = new Error('Pool is closed.'); | ||
150 | + err.code = 'POOL_CLOSED'; | ||
151 | + process.nextTick(function () { | ||
152 | + cb(err); | ||
153 | + }); | ||
154 | + }); | ||
155 | + } else if (this._connectionQueue.length) { | ||
156 | + // get connection with next waiting callback | ||
157 | + this.getConnection(this._connectionQueue.shift()); | ||
158 | + } | ||
159 | +}; | ||
160 | + | ||
161 | +Pool.prototype.end = function (cb) { | ||
162 | + this._closed = true; | ||
163 | + | ||
164 | + if (typeof cb !== 'function') { | ||
165 | + cb = function (err) { | ||
166 | + if (err) throw err; | ||
167 | + }; | ||
168 | + } | ||
169 | + | ||
170 | + var calledBack = false; | ||
171 | + var waitingClose = 0; | ||
172 | + | ||
173 | + function onEnd(err) { | ||
174 | + if (!calledBack && (err || --waitingClose <= 0)) { | ||
175 | + calledBack = true; | ||
176 | + cb(err); | ||
177 | + } | ||
178 | + } | ||
179 | + | ||
180 | + while (this._allConnections.length !== 0) { | ||
181 | + waitingClose++; | ||
182 | + this._purgeConnection(this._allConnections[0], onEnd); | ||
183 | + } | ||
184 | + | ||
185 | + if (waitingClose === 0) { | ||
186 | + process.nextTick(onEnd); | ||
187 | + } | ||
188 | +}; | ||
189 | + | ||
190 | +Pool.prototype.query = function (sql, values, cb) { | ||
191 | + var query = Connection.createQuery(sql, values, cb); | ||
192 | + | ||
193 | + if (!(typeof sql === 'object' && 'typeCast' in sql)) { | ||
194 | + query.typeCast = this.config.connectionConfig.typeCast; | ||
195 | + } | ||
196 | + | ||
197 | + if (this.config.connectionConfig.trace) { | ||
198 | + // Long stack trace support | ||
199 | + query._callSite = new Error(); | ||
200 | + } | ||
201 | + | ||
202 | + this.getConnection(function (err, conn) { | ||
203 | + if (err) { | ||
204 | + query.on('error', function () {}); | ||
205 | + query.end(err); | ||
206 | + return; | ||
207 | + } | ||
208 | + | ||
209 | + // Release connection based off event | ||
210 | + query.once('end', function() { | ||
211 | + conn.release(); | ||
212 | + }); | ||
213 | + | ||
214 | + conn.query(query); | ||
215 | + }); | ||
216 | + | ||
217 | + return query; | ||
218 | +}; | ||
219 | + | ||
220 | +Pool.prototype._enqueueCallback = function _enqueueCallback(callback) { | ||
221 | + | ||
222 | + if (this.config.queueLimit && this._connectionQueue.length >= this.config.queueLimit) { | ||
223 | + process.nextTick(function () { | ||
224 | + var err = new Error('Queue limit reached.'); | ||
225 | + err.code = 'POOL_ENQUEUELIMIT'; | ||
226 | + callback(err); | ||
227 | + }); | ||
228 | + return; | ||
229 | + } | ||
230 | + | ||
231 | + // Bind to domain, as dequeue will likely occur in a different domain | ||
232 | + var cb = process.domain | ||
233 | + ? process.domain.bind(callback) | ||
234 | + : callback; | ||
235 | + | ||
236 | + this._connectionQueue.push(cb); | ||
237 | + this.emit('enqueue'); | ||
238 | +}; | ||
239 | + | ||
240 | +Pool.prototype._needsChangeUser = function _needsChangeUser(connection) { | ||
241 | + var connConfig = connection.config; | ||
242 | + var poolConfig = this.config.connectionConfig; | ||
243 | + | ||
244 | + // check if changeUser values are different | ||
245 | + return connConfig.user !== poolConfig.user | ||
246 | + || connConfig.database !== poolConfig.database | ||
247 | + || connConfig.password !== poolConfig.password | ||
248 | + || connConfig.charsetNumber !== poolConfig.charsetNumber; | ||
249 | +}; | ||
250 | + | ||
251 | +Pool.prototype._purgeConnection = function _purgeConnection(connection, callback) { | ||
252 | + var cb = callback || function () {}; | ||
253 | + | ||
254 | + if (connection.state === 'disconnected') { | ||
255 | + connection.destroy(); | ||
256 | + } | ||
257 | + | ||
258 | + this._removeConnection(connection); | ||
259 | + | ||
260 | + if (connection.state !== 'disconnected' && !connection._protocol._quitSequence) { | ||
261 | + connection._realEnd(cb); | ||
262 | + return; | ||
263 | + } | ||
264 | + | ||
265 | + process.nextTick(cb); | ||
266 | +}; | ||
267 | + | ||
268 | +Pool.prototype._removeConnection = function(connection) { | ||
269 | + connection._pool = null; | ||
270 | + | ||
271 | + // Remove connection from all connections | ||
272 | + spliceConnection(this._allConnections, connection); | ||
273 | + | ||
274 | + // Remove connection from free connections | ||
275 | + spliceConnection(this._freeConnections, connection); | ||
276 | + | ||
277 | + this.releaseConnection(connection); | ||
278 | +}; | ||
279 | + | ||
280 | +Pool.prototype.escape = function(value) { | ||
281 | + return mysql.escape(value, this.config.connectionConfig.stringifyObjects, this.config.connectionConfig.timezone); | ||
282 | +}; | ||
283 | + | ||
284 | +Pool.prototype.escapeId = function escapeId(value) { | ||
285 | + return mysql.escapeId(value, false); | ||
286 | +}; | ||
287 | + | ||
288 | +function spliceConnection(array, connection) { | ||
289 | + var index; | ||
290 | + if ((index = array.indexOf(connection)) !== -1) { | ||
291 | + // Remove connection from all connections | ||
292 | + array.splice(index, 1); | ||
293 | + } | ||
294 | +} |
1 | +var Pool = require('./Pool'); | ||
2 | +var PoolConfig = require('./PoolConfig'); | ||
3 | +var PoolNamespace = require('./PoolNamespace'); | ||
4 | +var PoolSelector = require('./PoolSelector'); | ||
5 | +var Util = require('util'); | ||
6 | +var EventEmitter = require('events').EventEmitter; | ||
7 | + | ||
8 | +module.exports = PoolCluster; | ||
9 | + | ||
10 | +/** | ||
11 | + * PoolCluster | ||
12 | + * @constructor | ||
13 | + * @param {object} [config] The pool cluster configuration | ||
14 | + * @public | ||
15 | + */ | ||
16 | +function PoolCluster(config) { | ||
17 | + EventEmitter.call(this); | ||
18 | + | ||
19 | + config = config || {}; | ||
20 | + this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry; | ||
21 | + this._defaultSelector = config.defaultSelector || 'RR'; | ||
22 | + this._removeNodeErrorCount = config.removeNodeErrorCount || 5; | ||
23 | + this._restoreNodeTimeout = config.restoreNodeTimeout || 0; | ||
24 | + | ||
25 | + this._closed = false; | ||
26 | + this._findCaches = Object.create(null); | ||
27 | + this._lastId = 0; | ||
28 | + this._namespaces = Object.create(null); | ||
29 | + this._nodes = Object.create(null); | ||
30 | +} | ||
31 | + | ||
32 | +Util.inherits(PoolCluster, EventEmitter); | ||
33 | + | ||
34 | +PoolCluster.prototype.add = function add(id, config) { | ||
35 | + if (this._closed) { | ||
36 | + throw new Error('PoolCluster is closed.'); | ||
37 | + } | ||
38 | + | ||
39 | + var nodeId = typeof id === 'object' | ||
40 | + ? 'CLUSTER::' + (++this._lastId) | ||
41 | + : String(id); | ||
42 | + | ||
43 | + if (this._nodes[nodeId] !== undefined) { | ||
44 | + throw new Error('Node ID "' + nodeId + '" is already defined in PoolCluster.'); | ||
45 | + } | ||
46 | + | ||
47 | + var poolConfig = typeof id !== 'object' | ||
48 | + ? new PoolConfig(config) | ||
49 | + : new PoolConfig(id); | ||
50 | + | ||
51 | + this._nodes[nodeId] = { | ||
52 | + id : nodeId, | ||
53 | + errorCount : 0, | ||
54 | + pool : new Pool({config: poolConfig}), | ||
55 | + _offlineUntil : 0 | ||
56 | + }; | ||
57 | + | ||
58 | + this._clearFindCaches(); | ||
59 | +}; | ||
60 | + | ||
61 | +PoolCluster.prototype.end = function end(callback) { | ||
62 | + var cb = callback !== undefined | ||
63 | + ? callback | ||
64 | + : _cb; | ||
65 | + | ||
66 | + if (typeof cb !== 'function') { | ||
67 | + throw TypeError('callback argument must be a function'); | ||
68 | + } | ||
69 | + | ||
70 | + if (this._closed) { | ||
71 | + process.nextTick(cb); | ||
72 | + return; | ||
73 | + } | ||
74 | + | ||
75 | + this._closed = true; | ||
76 | + | ||
77 | + var calledBack = false; | ||
78 | + var nodeIds = Object.keys(this._nodes); | ||
79 | + var waitingClose = 0; | ||
80 | + | ||
81 | + function onEnd(err) { | ||
82 | + if (!calledBack && (err || --waitingClose <= 0)) { | ||
83 | + calledBack = true; | ||
84 | + cb(err); | ||
85 | + } | ||
86 | + } | ||
87 | + | ||
88 | + for (var i = 0; i < nodeIds.length; i++) { | ||
89 | + var nodeId = nodeIds[i]; | ||
90 | + var node = this._nodes[nodeId]; | ||
91 | + | ||
92 | + waitingClose++; | ||
93 | + node.pool.end(onEnd); | ||
94 | + } | ||
95 | + | ||
96 | + if (waitingClose === 0) { | ||
97 | + process.nextTick(onEnd); | ||
98 | + } | ||
99 | +}; | ||
100 | + | ||
101 | +PoolCluster.prototype.of = function(pattern, selector) { | ||
102 | + pattern = pattern || '*'; | ||
103 | + | ||
104 | + selector = selector || this._defaultSelector; | ||
105 | + selector = selector.toUpperCase(); | ||
106 | + if (typeof PoolSelector[selector] === 'undefined') { | ||
107 | + selector = this._defaultSelector; | ||
108 | + } | ||
109 | + | ||
110 | + var key = pattern + selector; | ||
111 | + | ||
112 | + if (typeof this._namespaces[key] === 'undefined') { | ||
113 | + this._namespaces[key] = new PoolNamespace(this, pattern, selector); | ||
114 | + } | ||
115 | + | ||
116 | + return this._namespaces[key]; | ||
117 | +}; | ||
118 | + | ||
119 | +PoolCluster.prototype.remove = function remove(pattern) { | ||
120 | + var foundNodeIds = this._findNodeIds(pattern, true); | ||
121 | + | ||
122 | + for (var i = 0; i < foundNodeIds.length; i++) { | ||
123 | + var node = this._getNode(foundNodeIds[i]); | ||
124 | + | ||
125 | + if (node) { | ||
126 | + this._removeNode(node); | ||
127 | + } | ||
128 | + } | ||
129 | +}; | ||
130 | + | ||
131 | +PoolCluster.prototype.getConnection = function(pattern, selector, cb) { | ||
132 | + var namespace; | ||
133 | + if (typeof pattern === 'function') { | ||
134 | + cb = pattern; | ||
135 | + namespace = this.of(); | ||
136 | + } else { | ||
137 | + if (typeof selector === 'function') { | ||
138 | + cb = selector; | ||
139 | + selector = this._defaultSelector; | ||
140 | + } | ||
141 | + | ||
142 | + namespace = this.of(pattern, selector); | ||
143 | + } | ||
144 | + | ||
145 | + namespace.getConnection(cb); | ||
146 | +}; | ||
147 | + | ||
148 | +PoolCluster.prototype._clearFindCaches = function _clearFindCaches() { | ||
149 | + this._findCaches = Object.create(null); | ||
150 | +}; | ||
151 | + | ||
152 | +PoolCluster.prototype._decreaseErrorCount = function _decreaseErrorCount(node) { | ||
153 | + var errorCount = node.errorCount; | ||
154 | + | ||
155 | + if (errorCount > this._removeNodeErrorCount) { | ||
156 | + errorCount = this._removeNodeErrorCount; | ||
157 | + } | ||
158 | + | ||
159 | + if (errorCount < 1) { | ||
160 | + errorCount = 1; | ||
161 | + } | ||
162 | + | ||
163 | + node.errorCount = errorCount - 1; | ||
164 | + | ||
165 | + if (node._offlineUntil) { | ||
166 | + node._offlineUntil = 0; | ||
167 | + this.emit('online', node.id); | ||
168 | + } | ||
169 | +}; | ||
170 | + | ||
171 | +PoolCluster.prototype._findNodeIds = function _findNodeIds(pattern, includeOffline) { | ||
172 | + var currentTime = 0; | ||
173 | + var foundNodeIds = this._findCaches[pattern]; | ||
174 | + | ||
175 | + if (foundNodeIds === undefined) { | ||
176 | + var expression = patternRegExp(pattern); | ||
177 | + var nodeIds = Object.keys(this._nodes); | ||
178 | + | ||
179 | + foundNodeIds = nodeIds.filter(function (id) { | ||
180 | + return id.match(expression); | ||
181 | + }); | ||
182 | + | ||
183 | + this._findCaches[pattern] = foundNodeIds; | ||
184 | + } | ||
185 | + | ||
186 | + if (includeOffline) { | ||
187 | + return foundNodeIds; | ||
188 | + } | ||
189 | + | ||
190 | + return foundNodeIds.filter(function (nodeId) { | ||
191 | + var node = this._getNode(nodeId); | ||
192 | + | ||
193 | + if (!node._offlineUntil) { | ||
194 | + return true; | ||
195 | + } | ||
196 | + | ||
197 | + if (!currentTime) { | ||
198 | + currentTime = getMonotonicMilliseconds(); | ||
199 | + } | ||
200 | + | ||
201 | + return node._offlineUntil <= currentTime; | ||
202 | + }, this); | ||
203 | +}; | ||
204 | + | ||
205 | +PoolCluster.prototype._getNode = function _getNode(id) { | ||
206 | + return this._nodes[id] || null; | ||
207 | +}; | ||
208 | + | ||
209 | +PoolCluster.prototype._increaseErrorCount = function _increaseErrorCount(node) { | ||
210 | + var errorCount = ++node.errorCount; | ||
211 | + | ||
212 | + if (this._removeNodeErrorCount > errorCount) { | ||
213 | + return; | ||
214 | + } | ||
215 | + | ||
216 | + if (this._restoreNodeTimeout > 0) { | ||
217 | + node._offlineUntil = getMonotonicMilliseconds() + this._restoreNodeTimeout; | ||
218 | + this.emit('offline', node.id); | ||
219 | + return; | ||
220 | + } | ||
221 | + | ||
222 | + this._removeNode(node); | ||
223 | + this.emit('remove', node.id); | ||
224 | +}; | ||
225 | + | ||
226 | +PoolCluster.prototype._getConnection = function(node, cb) { | ||
227 | + var self = this; | ||
228 | + | ||
229 | + node.pool.getConnection(function (err, connection) { | ||
230 | + if (err) { | ||
231 | + self._increaseErrorCount(node); | ||
232 | + cb(err); | ||
233 | + return; | ||
234 | + } else { | ||
235 | + self._decreaseErrorCount(node); | ||
236 | + } | ||
237 | + | ||
238 | + connection._clusterId = node.id; | ||
239 | + | ||
240 | + cb(null, connection); | ||
241 | + }); | ||
242 | +}; | ||
243 | + | ||
244 | +PoolCluster.prototype._removeNode = function _removeNode(node) { | ||
245 | + delete this._nodes[node.id]; | ||
246 | + | ||
247 | + this._clearFindCaches(); | ||
248 | + | ||
249 | + node.pool.end(_noop); | ||
250 | +}; | ||
251 | + | ||
252 | +function getMonotonicMilliseconds() { | ||
253 | + var ms; | ||
254 | + | ||
255 | + if (typeof process.hrtime === 'function') { | ||
256 | + ms = process.hrtime(); | ||
257 | + ms = ms[0] * 1e3 + ms[1] * 1e-6; | ||
258 | + } else { | ||
259 | + ms = process.uptime() * 1000; | ||
260 | + } | ||
261 | + | ||
262 | + return Math.floor(ms); | ||
263 | +} | ||
264 | + | ||
265 | +function isRegExp(val) { | ||
266 | + return typeof val === 'object' | ||
267 | + && Object.prototype.toString.call(val) === '[object RegExp]'; | ||
268 | +} | ||
269 | + | ||
270 | +function patternRegExp(pattern) { | ||
271 | + if (isRegExp(pattern)) { | ||
272 | + return pattern; | ||
273 | + } | ||
274 | + | ||
275 | + var source = pattern | ||
276 | + .replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1') | ||
277 | + .replace(/\*/g, '.*'); | ||
278 | + | ||
279 | + return new RegExp('^' + source + '$'); | ||
280 | +} | ||
281 | + | ||
282 | +function _cb(err) { | ||
283 | + if (err) { | ||
284 | + throw err; | ||
285 | + } | ||
286 | +} | ||
287 | + | ||
288 | +function _noop() {} |
backend/node_modules/mysql/lib/PoolConfig.js
0 → 100644
1 | + | ||
2 | +var ConnectionConfig = require('./ConnectionConfig'); | ||
3 | + | ||
4 | +module.exports = PoolConfig; | ||
5 | +function PoolConfig(options) { | ||
6 | + if (typeof options === 'string') { | ||
7 | + options = ConnectionConfig.parseUrl(options); | ||
8 | + } | ||
9 | + | ||
10 | + this.acquireTimeout = (options.acquireTimeout === undefined) | ||
11 | + ? 10 * 1000 | ||
12 | + : Number(options.acquireTimeout); | ||
13 | + this.connectionConfig = new ConnectionConfig(options); | ||
14 | + this.waitForConnections = (options.waitForConnections === undefined) | ||
15 | + ? true | ||
16 | + : Boolean(options.waitForConnections); | ||
17 | + this.connectionLimit = (options.connectionLimit === undefined) | ||
18 | + ? 10 | ||
19 | + : Number(options.connectionLimit); | ||
20 | + this.queueLimit = (options.queueLimit === undefined) | ||
21 | + ? 0 | ||
22 | + : Number(options.queueLimit); | ||
23 | +} | ||
24 | + | ||
25 | +PoolConfig.prototype.newConnectionConfig = function newConnectionConfig() { | ||
26 | + var connectionConfig = new ConnectionConfig(this.connectionConfig); | ||
27 | + | ||
28 | + connectionConfig.clientFlags = this.connectionConfig.clientFlags; | ||
29 | + connectionConfig.maxPacketSize = this.connectionConfig.maxPacketSize; | ||
30 | + | ||
31 | + return connectionConfig; | ||
32 | +}; |
1 | +var inherits = require('util').inherits; | ||
2 | +var Connection = require('./Connection'); | ||
3 | +var Events = require('events'); | ||
4 | + | ||
5 | +module.exports = PoolConnection; | ||
6 | +inherits(PoolConnection, Connection); | ||
7 | + | ||
8 | +function PoolConnection(pool, options) { | ||
9 | + Connection.call(this, options); | ||
10 | + this._pool = pool; | ||
11 | + | ||
12 | + // Bind connection to pool domain | ||
13 | + if (Events.usingDomains) { | ||
14 | + this.domain = pool.domain; | ||
15 | + } | ||
16 | + | ||
17 | + // When a fatal error occurs the connection's protocol ends, which will cause | ||
18 | + // the connection to end as well, thus we only need to watch for the end event | ||
19 | + // and we will be notified of disconnects. | ||
20 | + this.on('end', this._removeFromPool); | ||
21 | + this.on('error', function (err) { | ||
22 | + if (err.fatal) { | ||
23 | + this._removeFromPool(); | ||
24 | + } | ||
25 | + }); | ||
26 | +} | ||
27 | + | ||
28 | +PoolConnection.prototype.release = function release() { | ||
29 | + var pool = this._pool; | ||
30 | + | ||
31 | + if (!pool || pool._closed) { | ||
32 | + return undefined; | ||
33 | + } | ||
34 | + | ||
35 | + return pool.releaseConnection(this); | ||
36 | +}; | ||
37 | + | ||
38 | +// TODO: Remove this when we are removing PoolConnection#end | ||
39 | +PoolConnection.prototype._realEnd = Connection.prototype.end; | ||
40 | + | ||
41 | +PoolConnection.prototype.end = function () { | ||
42 | + console.warn( | ||
43 | + 'Calling conn.end() to release a pooled connection is ' + | ||
44 | + 'deprecated. In next version calling conn.end() will be ' + | ||
45 | + 'restored to default conn.end() behavior. Use ' + | ||
46 | + 'conn.release() instead.' | ||
47 | + ); | ||
48 | + this.release(); | ||
49 | +}; | ||
50 | + | ||
51 | +PoolConnection.prototype.destroy = function () { | ||
52 | + Connection.prototype.destroy.apply(this, arguments); | ||
53 | + this._removeFromPool(this); | ||
54 | +}; | ||
55 | + | ||
56 | +PoolConnection.prototype._removeFromPool = function _removeFromPool() { | ||
57 | + if (!this._pool || this._pool._closed) { | ||
58 | + return; | ||
59 | + } | ||
60 | + | ||
61 | + var pool = this._pool; | ||
62 | + this._pool = null; | ||
63 | + | ||
64 | + pool._purgeConnection(this); | ||
65 | +}; |
1 | +var Connection = require('./Connection'); | ||
2 | +var PoolSelector = require('./PoolSelector'); | ||
3 | + | ||
4 | +module.exports = PoolNamespace; | ||
5 | + | ||
6 | +/** | ||
7 | + * PoolNamespace | ||
8 | + * @constructor | ||
9 | + * @param {PoolCluster} cluster The parent cluster for the namespace | ||
10 | + * @param {string} pattern The selection pattern to use | ||
11 | + * @param {string} selector The selector name to use | ||
12 | + * @public | ||
13 | + */ | ||
14 | +function PoolNamespace(cluster, pattern, selector) { | ||
15 | + this._cluster = cluster; | ||
16 | + this._pattern = pattern; | ||
17 | + this._selector = new PoolSelector[selector](); | ||
18 | +} | ||
19 | + | ||
20 | +PoolNamespace.prototype.getConnection = function(cb) { | ||
21 | + var clusterNode = this._getClusterNode(); | ||
22 | + var cluster = this._cluster; | ||
23 | + var namespace = this; | ||
24 | + | ||
25 | + if (clusterNode === null) { | ||
26 | + var err = null; | ||
27 | + | ||
28 | + if (this._cluster._findNodeIds(this._pattern, true).length !== 0) { | ||
29 | + err = new Error('Pool does not have online node.'); | ||
30 | + err.code = 'POOL_NONEONLINE'; | ||
31 | + } else { | ||
32 | + err = new Error('Pool does not exist.'); | ||
33 | + err.code = 'POOL_NOEXIST'; | ||
34 | + } | ||
35 | + | ||
36 | + cb(err); | ||
37 | + return; | ||
38 | + } | ||
39 | + | ||
40 | + cluster._getConnection(clusterNode, function(err, connection) { | ||
41 | + var retry = err && cluster._canRetry | ||
42 | + && cluster._findNodeIds(namespace._pattern).length !== 0; | ||
43 | + | ||
44 | + if (retry) { | ||
45 | + namespace.getConnection(cb); | ||
46 | + return; | ||
47 | + } | ||
48 | + | ||
49 | + if (err) { | ||
50 | + cb(err); | ||
51 | + return; | ||
52 | + } | ||
53 | + | ||
54 | + cb(null, connection); | ||
55 | + }); | ||
56 | +}; | ||
57 | + | ||
58 | +PoolNamespace.prototype.query = function (sql, values, cb) { | ||
59 | + var cluster = this._cluster; | ||
60 | + var clusterNode = this._getClusterNode(); | ||
61 | + var query = Connection.createQuery(sql, values, cb); | ||
62 | + var namespace = this; | ||
63 | + | ||
64 | + if (clusterNode === null) { | ||
65 | + var err = null; | ||
66 | + | ||
67 | + if (this._cluster._findNodeIds(this._pattern, true).length !== 0) { | ||
68 | + err = new Error('Pool does not have online node.'); | ||
69 | + err.code = 'POOL_NONEONLINE'; | ||
70 | + } else { | ||
71 | + err = new Error('Pool does not exist.'); | ||
72 | + err.code = 'POOL_NOEXIST'; | ||
73 | + } | ||
74 | + | ||
75 | + process.nextTick(function () { | ||
76 | + query.on('error', function () {}); | ||
77 | + query.end(err); | ||
78 | + }); | ||
79 | + return query; | ||
80 | + } | ||
81 | + | ||
82 | + if (!(typeof sql === 'object' && 'typeCast' in sql)) { | ||
83 | + query.typeCast = clusterNode.pool.config.connectionConfig.typeCast; | ||
84 | + } | ||
85 | + | ||
86 | + if (clusterNode.pool.config.connectionConfig.trace) { | ||
87 | + // Long stack trace support | ||
88 | + query._callSite = new Error(); | ||
89 | + } | ||
90 | + | ||
91 | + cluster._getConnection(clusterNode, function (err, conn) { | ||
92 | + var retry = err && cluster._canRetry | ||
93 | + && cluster._findNodeIds(namespace._pattern).length !== 0; | ||
94 | + | ||
95 | + if (retry) { | ||
96 | + namespace.query(query); | ||
97 | + return; | ||
98 | + } | ||
99 | + | ||
100 | + if (err) { | ||
101 | + query.on('error', function () {}); | ||
102 | + query.end(err); | ||
103 | + return; | ||
104 | + } | ||
105 | + | ||
106 | + // Release connection based off event | ||
107 | + query.once('end', function() { | ||
108 | + conn.release(); | ||
109 | + }); | ||
110 | + | ||
111 | + conn.query(query); | ||
112 | + }); | ||
113 | + | ||
114 | + return query; | ||
115 | +}; | ||
116 | + | ||
117 | +PoolNamespace.prototype._getClusterNode = function _getClusterNode() { | ||
118 | + var foundNodeIds = this._cluster._findNodeIds(this._pattern); | ||
119 | + var nodeId; | ||
120 | + | ||
121 | + switch (foundNodeIds.length) { | ||
122 | + case 0: | ||
123 | + nodeId = null; | ||
124 | + break; | ||
125 | + case 1: | ||
126 | + nodeId = foundNodeIds[0]; | ||
127 | + break; | ||
128 | + default: | ||
129 | + nodeId = this._selector(foundNodeIds); | ||
130 | + break; | ||
131 | + } | ||
132 | + | ||
133 | + return nodeId !== null | ||
134 | + ? this._cluster._getNode(nodeId) | ||
135 | + : null; | ||
136 | +}; |
1 | + | ||
2 | +/** | ||
3 | + * PoolSelector | ||
4 | + */ | ||
5 | +var PoolSelector = module.exports = {}; | ||
6 | + | ||
7 | +PoolSelector.RR = function PoolSelectorRoundRobin() { | ||
8 | + var index = 0; | ||
9 | + | ||
10 | + return function(clusterIds) { | ||
11 | + if (index >= clusterIds.length) { | ||
12 | + index = 0; | ||
13 | + } | ||
14 | + | ||
15 | + var clusterId = clusterIds[index++]; | ||
16 | + | ||
17 | + return clusterId; | ||
18 | + }; | ||
19 | +}; | ||
20 | + | ||
21 | +PoolSelector.RANDOM = function PoolSelectorRandom() { | ||
22 | + return function(clusterIds) { | ||
23 | + return clusterIds[Math.floor(Math.random() * clusterIds.length)]; | ||
24 | + }; | ||
25 | +}; | ||
26 | + | ||
27 | +PoolSelector.ORDER = function PoolSelectorOrder() { | ||
28 | + return function(clusterIds) { | ||
29 | + return clusterIds[0]; | ||
30 | + }; | ||
31 | +}; |
1 | +var Buffer = require('safe-buffer').Buffer; | ||
2 | +var Crypto = require('crypto'); | ||
3 | +var Auth = exports; | ||
4 | + | ||
5 | +function auth(name, data, options) { | ||
6 | + options = options || {}; | ||
7 | + | ||
8 | + switch (name) { | ||
9 | + case 'mysql_native_password': | ||
10 | + return Auth.token(options.password, data.slice(0, 20)); | ||
11 | + default: | ||
12 | + return undefined; | ||
13 | + } | ||
14 | +} | ||
15 | +Auth.auth = auth; | ||
16 | + | ||
17 | +function sha1(msg) { | ||
18 | + var hash = Crypto.createHash('sha1'); | ||
19 | + hash.update(msg, 'binary'); | ||
20 | + return hash.digest('binary'); | ||
21 | +} | ||
22 | +Auth.sha1 = sha1; | ||
23 | + | ||
24 | +function xor(a, b) { | ||
25 | + a = Buffer.from(a, 'binary'); | ||
26 | + b = Buffer.from(b, 'binary'); | ||
27 | + var result = Buffer.allocUnsafe(a.length); | ||
28 | + for (var i = 0; i < a.length; i++) { | ||
29 | + result[i] = (a[i] ^ b[i]); | ||
30 | + } | ||
31 | + return result; | ||
32 | +} | ||
33 | +Auth.xor = xor; | ||
34 | + | ||
35 | +Auth.token = function(password, scramble) { | ||
36 | + if (!password) { | ||
37 | + return Buffer.alloc(0); | ||
38 | + } | ||
39 | + | ||
40 | + // password must be in binary format, not utf8 | ||
41 | + var stage1 = sha1((Buffer.from(password, 'utf8')).toString('binary')); | ||
42 | + var stage2 = sha1(stage1); | ||
43 | + var stage3 = sha1(scramble.toString('binary') + stage2); | ||
44 | + return xor(stage3, stage1); | ||
45 | +}; | ||
46 | + | ||
47 | +// This is a port of sql/password.c:hash_password which needs to be used for | ||
48 | +// pre-4.1 passwords. | ||
49 | +Auth.hashPassword = function(password) { | ||
50 | + var nr = [0x5030, 0x5735]; | ||
51 | + var add = 7; | ||
52 | + var nr2 = [0x1234, 0x5671]; | ||
53 | + var result = Buffer.alloc(8); | ||
54 | + | ||
55 | + if (typeof password === 'string'){ | ||
56 | + password = Buffer.from(password); | ||
57 | + } | ||
58 | + | ||
59 | + for (var i = 0; i < password.length; i++) { | ||
60 | + var c = password[i]; | ||
61 | + if (c === 32 || c === 9) { | ||
62 | + // skip space in password | ||
63 | + continue; | ||
64 | + } | ||
65 | + | ||
66 | + // nr^= (((nr & 63)+add)*c)+ (nr << 8); | ||
67 | + // nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8))) | ||
68 | + nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0, 63]), [0, add]), [0, c]), this.shl32(nr, 8))); | ||
69 | + | ||
70 | + // nr2+=(nr2 << 8) ^ nr; | ||
71 | + // nr2 = add(nr2, xor(shl(nr2, 8), nr)) | ||
72 | + nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr)); | ||
73 | + | ||
74 | + // add+=tmp; | ||
75 | + add += c; | ||
76 | + } | ||
77 | + | ||
78 | + this.int31Write(result, nr, 0); | ||
79 | + this.int31Write(result, nr2, 4); | ||
80 | + | ||
81 | + return result; | ||
82 | +}; | ||
83 | + | ||
84 | +Auth.randomInit = function(seed1, seed2) { | ||
85 | + return { | ||
86 | + max_value : 0x3FFFFFFF, | ||
87 | + max_value_dbl : 0x3FFFFFFF, | ||
88 | + seed1 : seed1 % 0x3FFFFFFF, | ||
89 | + seed2 : seed2 % 0x3FFFFFFF | ||
90 | + }; | ||
91 | +}; | ||
92 | + | ||
93 | +Auth.myRnd = function(r){ | ||
94 | + r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value; | ||
95 | + r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value; | ||
96 | + | ||
97 | + return r.seed1 / r.max_value_dbl; | ||
98 | +}; | ||
99 | + | ||
100 | +Auth.scramble323 = function(message, password) { | ||
101 | + if (!password) { | ||
102 | + return Buffer.alloc(0); | ||
103 | + } | ||
104 | + | ||
105 | + var to = Buffer.allocUnsafe(8); | ||
106 | + var hashPass = this.hashPassword(password); | ||
107 | + var hashMessage = this.hashPassword(message.slice(0, 8)); | ||
108 | + var seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0); | ||
109 | + var seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4); | ||
110 | + var r = this.randomInit(seed1, seed2); | ||
111 | + | ||
112 | + for (var i = 0; i < 8; i++){ | ||
113 | + to[i] = Math.floor(this.myRnd(r) * 31) + 64; | ||
114 | + } | ||
115 | + var extra = (Math.floor(this.myRnd(r) * 31)); | ||
116 | + | ||
117 | + for (var i = 0; i < 8; i++){ | ||
118 | + to[i] ^= extra; | ||
119 | + } | ||
120 | + | ||
121 | + return to; | ||
122 | +}; | ||
123 | + | ||
124 | +Auth.xor32 = function(a, b){ | ||
125 | + return [a[0] ^ b[0], a[1] ^ b[1]]; | ||
126 | +}; | ||
127 | + | ||
128 | +Auth.add32 = function(a, b){ | ||
129 | + var w1 = a[1] + b[1]; | ||
130 | + var w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16); | ||
131 | + | ||
132 | + return [w2 & 0xFFFF, w1 & 0xFFFF]; | ||
133 | +}; | ||
134 | + | ||
135 | +Auth.mul32 = function(a, b){ | ||
136 | + // based on this example of multiplying 32b ints using 16b | ||
137 | + // http://www.dsprelated.com/showmessage/89790/1.php | ||
138 | + var w1 = a[1] * b[1]; | ||
139 | + var w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF); | ||
140 | + | ||
141 | + return [w2 & 0xFFFF, w1 & 0xFFFF]; | ||
142 | +}; | ||
143 | + | ||
144 | +Auth.and32 = function(a, b){ | ||
145 | + return [a[0] & b[0], a[1] & b[1]]; | ||
146 | +}; | ||
147 | + | ||
148 | +Auth.shl32 = function(a, b){ | ||
149 | + // assume b is 16 or less | ||
150 | + var w1 = a[1] << b; | ||
151 | + var w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16); | ||
152 | + | ||
153 | + return [w2 & 0xFFFF, w1 & 0xFFFF]; | ||
154 | +}; | ||
155 | + | ||
156 | +Auth.int31Write = function(buffer, number, offset) { | ||
157 | + buffer[offset] = (number[0] >> 8) & 0x7F; | ||
158 | + buffer[offset + 1] = (number[0]) & 0xFF; | ||
159 | + buffer[offset + 2] = (number[1] >> 8) & 0xFF; | ||
160 | + buffer[offset + 3] = (number[1]) & 0xFF; | ||
161 | +}; | ||
162 | + | ||
163 | +Auth.int32Read = function(buffer, offset){ | ||
164 | + return (buffer[offset] << 24) | ||
165 | + + (buffer[offset + 1] << 16) | ||
166 | + + (buffer[offset + 2] << 8) | ||
167 | + + (buffer[offset + 3]); | ||
168 | +}; |
1 | + | ||
2 | +module.exports = BufferList; | ||
3 | +function BufferList() { | ||
4 | + this.bufs = []; | ||
5 | + this.size = 0; | ||
6 | +} | ||
7 | + | ||
8 | +BufferList.prototype.shift = function shift() { | ||
9 | + var buf = this.bufs.shift(); | ||
10 | + | ||
11 | + if (buf) { | ||
12 | + this.size -= buf.length; | ||
13 | + } | ||
14 | + | ||
15 | + return buf; | ||
16 | +}; | ||
17 | + | ||
18 | +BufferList.prototype.push = function push(buf) { | ||
19 | + if (!buf || !buf.length) { | ||
20 | + return; | ||
21 | + } | ||
22 | + | ||
23 | + this.bufs.push(buf); | ||
24 | + this.size += buf.length; | ||
25 | +}; |
1 | +var BIT_16 = Math.pow(2, 16); | ||
2 | +var BIT_24 = Math.pow(2, 24); | ||
3 | +var BUFFER_ALLOC_SIZE = Math.pow(2, 8); | ||
4 | +// The maximum precision JS Numbers can hold precisely | ||
5 | +// Don't panic: Good enough to represent byte values up to 8192 TB | ||
6 | +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53); | ||
7 | +var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; | ||
8 | +var Buffer = require('safe-buffer').Buffer; | ||
9 | + | ||
10 | +module.exports = PacketWriter; | ||
11 | +function PacketWriter() { | ||
12 | + this._buffer = null; | ||
13 | + this._offset = 0; | ||
14 | +} | ||
15 | + | ||
16 | +PacketWriter.prototype.toBuffer = function toBuffer(parser) { | ||
17 | + if (!this._buffer) { | ||
18 | + this._buffer = Buffer.alloc(0); | ||
19 | + this._offset = 0; | ||
20 | + } | ||
21 | + | ||
22 | + var buffer = this._buffer; | ||
23 | + var length = this._offset; | ||
24 | + var packets = Math.floor(length / MAX_PACKET_LENGTH) + 1; | ||
25 | + | ||
26 | + this._buffer = Buffer.allocUnsafe(length + packets * 4); | ||
27 | + this._offset = 0; | ||
28 | + | ||
29 | + for (var packet = 0; packet < packets; packet++) { | ||
30 | + var isLast = (packet + 1 === packets); | ||
31 | + var packetLength = (isLast) | ||
32 | + ? length % MAX_PACKET_LENGTH | ||
33 | + : MAX_PACKET_LENGTH; | ||
34 | + | ||
35 | + var packetNumber = parser.incrementPacketNumber(); | ||
36 | + | ||
37 | + this.writeUnsignedNumber(3, packetLength); | ||
38 | + this.writeUnsignedNumber(1, packetNumber); | ||
39 | + | ||
40 | + var start = packet * MAX_PACKET_LENGTH; | ||
41 | + var end = start + packetLength; | ||
42 | + | ||
43 | + this.writeBuffer(buffer.slice(start, end)); | ||
44 | + } | ||
45 | + | ||
46 | + return this._buffer; | ||
47 | +}; | ||
48 | + | ||
49 | +PacketWriter.prototype.writeUnsignedNumber = function(bytes, value) { | ||
50 | + this._allocate(bytes); | ||
51 | + | ||
52 | + for (var i = 0; i < bytes; i++) { | ||
53 | + this._buffer[this._offset++] = (value >> (i * 8)) & 0xff; | ||
54 | + } | ||
55 | +}; | ||
56 | + | ||
57 | +PacketWriter.prototype.writeFiller = function(bytes) { | ||
58 | + this._allocate(bytes); | ||
59 | + | ||
60 | + for (var i = 0; i < bytes; i++) { | ||
61 | + this._buffer[this._offset++] = 0x00; | ||
62 | + } | ||
63 | +}; | ||
64 | + | ||
65 | +PacketWriter.prototype.writeNullTerminatedString = function(value, encoding) { | ||
66 | + // Typecast undefined into '' and numbers into strings | ||
67 | + value = value || ''; | ||
68 | + value = value + ''; | ||
69 | + | ||
70 | + var bytes = Buffer.byteLength(value, encoding || 'utf-8') + 1; | ||
71 | + this._allocate(bytes); | ||
72 | + | ||
73 | + this._buffer.write(value, this._offset, encoding); | ||
74 | + this._buffer[this._offset + bytes - 1] = 0x00; | ||
75 | + | ||
76 | + this._offset += bytes; | ||
77 | +}; | ||
78 | + | ||
79 | +PacketWriter.prototype.writeString = function(value) { | ||
80 | + // Typecast undefined into '' and numbers into strings | ||
81 | + value = value || ''; | ||
82 | + value = value + ''; | ||
83 | + | ||
84 | + var bytes = Buffer.byteLength(value, 'utf-8'); | ||
85 | + this._allocate(bytes); | ||
86 | + | ||
87 | + this._buffer.write(value, this._offset, 'utf-8'); | ||
88 | + | ||
89 | + this._offset += bytes; | ||
90 | +}; | ||
91 | + | ||
92 | +PacketWriter.prototype.writeBuffer = function(value) { | ||
93 | + var bytes = value.length; | ||
94 | + | ||
95 | + this._allocate(bytes); | ||
96 | + value.copy(this._buffer, this._offset); | ||
97 | + this._offset += bytes; | ||
98 | +}; | ||
99 | + | ||
100 | +PacketWriter.prototype.writeLengthCodedNumber = function(value) { | ||
101 | + if (value === null) { | ||
102 | + this._allocate(1); | ||
103 | + this._buffer[this._offset++] = 251; | ||
104 | + return; | ||
105 | + } | ||
106 | + | ||
107 | + if (value <= 250) { | ||
108 | + this._allocate(1); | ||
109 | + this._buffer[this._offset++] = value; | ||
110 | + return; | ||
111 | + } | ||
112 | + | ||
113 | + if (value > IEEE_754_BINARY_64_PRECISION) { | ||
114 | + throw new Error( | ||
115 | + 'writeLengthCodedNumber: JS precision range exceeded, your ' + | ||
116 | + 'number is > 53 bit: "' + value + '"' | ||
117 | + ); | ||
118 | + } | ||
119 | + | ||
120 | + if (value < BIT_16) { | ||
121 | + this._allocate(3); | ||
122 | + this._buffer[this._offset++] = 252; | ||
123 | + } else if (value < BIT_24) { | ||
124 | + this._allocate(4); | ||
125 | + this._buffer[this._offset++] = 253; | ||
126 | + } else { | ||
127 | + this._allocate(9); | ||
128 | + this._buffer[this._offset++] = 254; | ||
129 | + } | ||
130 | + | ||
131 | + // 16 Bit | ||
132 | + this._buffer[this._offset++] = value & 0xff; | ||
133 | + this._buffer[this._offset++] = (value >> 8) & 0xff; | ||
134 | + | ||
135 | + if (value < BIT_16) { | ||
136 | + return; | ||
137 | + } | ||
138 | + | ||
139 | + // 24 Bit | ||
140 | + this._buffer[this._offset++] = (value >> 16) & 0xff; | ||
141 | + | ||
142 | + if (value < BIT_24) { | ||
143 | + return; | ||
144 | + } | ||
145 | + | ||
146 | + this._buffer[this._offset++] = (value >> 24) & 0xff; | ||
147 | + | ||
148 | + // Hack: Get the most significant 32 bit (JS bitwise operators are 32 bit) | ||
149 | + value = value.toString(2); | ||
150 | + value = value.substr(0, value.length - 32); | ||
151 | + value = parseInt(value, 2); | ||
152 | + | ||
153 | + this._buffer[this._offset++] = value & 0xff; | ||
154 | + this._buffer[this._offset++] = (value >> 8) & 0xff; | ||
155 | + this._buffer[this._offset++] = (value >> 16) & 0xff; | ||
156 | + | ||
157 | + // Set last byte to 0, as we can only support 53 bits in JS (see above) | ||
158 | + this._buffer[this._offset++] = 0; | ||
159 | +}; | ||
160 | + | ||
161 | +PacketWriter.prototype.writeLengthCodedBuffer = function(value) { | ||
162 | + var bytes = value.length; | ||
163 | + this.writeLengthCodedNumber(bytes); | ||
164 | + this.writeBuffer(value); | ||
165 | +}; | ||
166 | + | ||
167 | +PacketWriter.prototype.writeNullTerminatedBuffer = function(value) { | ||
168 | + this.writeBuffer(value); | ||
169 | + this.writeFiller(1); // 0x00 terminator | ||
170 | +}; | ||
171 | + | ||
172 | +PacketWriter.prototype.writeLengthCodedString = function(value) { | ||
173 | + if (value === null) { | ||
174 | + this.writeLengthCodedNumber(null); | ||
175 | + return; | ||
176 | + } | ||
177 | + | ||
178 | + value = (value === undefined) | ||
179 | + ? '' | ||
180 | + : String(value); | ||
181 | + | ||
182 | + var bytes = Buffer.byteLength(value, 'utf-8'); | ||
183 | + this.writeLengthCodedNumber(bytes); | ||
184 | + | ||
185 | + if (!bytes) { | ||
186 | + return; | ||
187 | + } | ||
188 | + | ||
189 | + this._allocate(bytes); | ||
190 | + this._buffer.write(value, this._offset, 'utf-8'); | ||
191 | + this._offset += bytes; | ||
192 | +}; | ||
193 | + | ||
194 | +PacketWriter.prototype._allocate = function _allocate(bytes) { | ||
195 | + if (!this._buffer) { | ||
196 | + this._buffer = Buffer.alloc(Math.max(BUFFER_ALLOC_SIZE, bytes)); | ||
197 | + this._offset = 0; | ||
198 | + return; | ||
199 | + } | ||
200 | + | ||
201 | + var bytesRemaining = this._buffer.length - this._offset; | ||
202 | + if (bytesRemaining >= bytes) { | ||
203 | + return; | ||
204 | + } | ||
205 | + | ||
206 | + var newSize = this._buffer.length + Math.max(BUFFER_ALLOC_SIZE, bytes); | ||
207 | + var oldBuffer = this._buffer; | ||
208 | + | ||
209 | + this._buffer = Buffer.alloc(newSize); | ||
210 | + oldBuffer.copy(this._buffer); | ||
211 | +}; |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 | +module.exports = require('sqlstring'); |
1 | +var Timers = require('timers'); | ||
2 | + | ||
3 | +module.exports = Timer; | ||
4 | +function Timer(object) { | ||
5 | + this._object = object; | ||
6 | + this._timeout = null; | ||
7 | +} | ||
8 | + | ||
9 | +Timer.prototype.active = function active() { | ||
10 | + if (this._timeout) { | ||
11 | + if (this._timeout.refresh) { | ||
12 | + this._timeout.refresh(); | ||
13 | + } else { | ||
14 | + Timers.active(this._timeout); | ||
15 | + } | ||
16 | + } | ||
17 | +}; | ||
18 | + | ||
19 | +Timer.prototype.start = function start(msecs) { | ||
20 | + this.stop(); | ||
21 | + this._timeout = Timers.setTimeout(this._onTimeout.bind(this), msecs); | ||
22 | +}; | ||
23 | + | ||
24 | +Timer.prototype.stop = function stop() { | ||
25 | + if (this._timeout) { | ||
26 | + Timers.clearTimeout(this._timeout); | ||
27 | + this._timeout = null; | ||
28 | + } | ||
29 | +}; | ||
30 | + | ||
31 | +Timer.prototype._onTimeout = function _onTimeout() { | ||
32 | + return this._object._onTimeout(); | ||
33 | +}; |
This diff is collapsed. Click to expand it.
1 | +// Manually extracted from mysql-5.5.23/include/mysql_com.h | ||
2 | +exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */ | ||
3 | +exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */ | ||
4 | +exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */ | ||
5 | +exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */ | ||
6 | +exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */ | ||
7 | +exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */ | ||
8 | +exports.CLIENT_ODBC = 64; /* Odbc client */ | ||
9 | +exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ | ||
10 | +exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */ | ||
11 | +exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */ | ||
12 | +exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */ | ||
13 | +exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */ | ||
14 | +exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */ | ||
15 | +exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */ | ||
16 | +exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */ | ||
17 | +exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */ | ||
18 | + | ||
19 | +exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */ | ||
20 | +exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */ | ||
21 | +exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */ | ||
22 | + | ||
23 | +exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */ | ||
24 | + | ||
25 | +exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824; | ||
26 | +exports.CLIENT_REMEMBER_OPTIONS = 2147483648; |
This diff could not be displayed because it is too large.
1 | +// Manually extracted from mysql-5.5.23/include/mysql_com.h | ||
2 | +exports.NOT_NULL_FLAG = 1; /* Field can't be NULL */ | ||
3 | +exports.PRI_KEY_FLAG = 2; /* Field is part of a primary key */ | ||
4 | +exports.UNIQUE_KEY_FLAG = 4; /* Field is part of a unique key */ | ||
5 | +exports.MULTIPLE_KEY_FLAG = 8; /* Field is part of a key */ | ||
6 | +exports.BLOB_FLAG = 16; /* Field is a blob */ | ||
7 | +exports.UNSIGNED_FLAG = 32; /* Field is unsigned */ | ||
8 | +exports.ZEROFILL_FLAG = 64; /* Field is zerofill */ | ||
9 | +exports.BINARY_FLAG = 128; /* Field is binary */ | ||
10 | + | ||
11 | +/* The following are only sent to new clients */ | ||
12 | +exports.ENUM_FLAG = 256; /* field is an enum */ | ||
13 | +exports.AUTO_INCREMENT_FLAG = 512; /* field is a autoincrement field */ | ||
14 | +exports.TIMESTAMP_FLAG = 1024; /* Field is a timestamp */ | ||
15 | +exports.SET_FLAG = 2048; /* field is a set */ | ||
16 | +exports.NO_DEFAULT_VALUE_FLAG = 4096; /* Field doesn't have default value */ | ||
17 | +exports.ON_UPDATE_NOW_FLAG = 8192; /* Field is set to NOW on UPDATE */ | ||
18 | +exports.NUM_FLAG = 32768; /* Field is num (for clients) */ |
1 | +// Manually extracted from mysql-5.5.23/include/mysql_com.h | ||
2 | + | ||
3 | +/** | ||
4 | + Is raised when a multi-statement transaction | ||
5 | + has been started, either explicitly, by means | ||
6 | + of BEGIN or COMMIT AND CHAIN, or | ||
7 | + implicitly, by the first transactional | ||
8 | + statement, when autocommit=off. | ||
9 | +*/ | ||
10 | +exports.SERVER_STATUS_IN_TRANS = 1; | ||
11 | +exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */ | ||
12 | +exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */ | ||
13 | +exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16; | ||
14 | +exports.SERVER_QUERY_NO_INDEX_USED = 32; | ||
15 | +/** | ||
16 | + The server was able to fulfill the clients request and opened a | ||
17 | + read-only non-scrollable cursor for a query. This flag comes | ||
18 | + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. | ||
19 | +*/ | ||
20 | +exports.SERVER_STATUS_CURSOR_EXISTS = 64; | ||
21 | +/** | ||
22 | + This flag is sent when a read-only cursor is exhausted, in reply to | ||
23 | + COM_STMT_FETCH command. | ||
24 | +*/ | ||
25 | +exports.SERVER_STATUS_LAST_ROW_SENT = 128; | ||
26 | +exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */ | ||
27 | +exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512; | ||
28 | +/** | ||
29 | + Sent to the client if after a prepared statement reprepare | ||
30 | + we discovered that the new statement returns a different | ||
31 | + number of result set columns. | ||
32 | +*/ | ||
33 | +exports.SERVER_STATUS_METADATA_CHANGED = 1024; | ||
34 | +exports.SERVER_QUERY_WAS_SLOW = 2048; | ||
35 | + | ||
36 | +/** | ||
37 | + To mark ResultSet containing output parameter values. | ||
38 | +*/ | ||
39 | +exports.SERVER_PS_OUT_PARAMS = 4096; |
This diff is collapsed. Click to expand it.
1 | +/** | ||
2 | + * MySQL type constants | ||
3 | + * | ||
4 | + * Extracted from version 5.7.29 | ||
5 | + * | ||
6 | + * !! Generated by generate-type-constants.js, do not modify by hand !! | ||
7 | + */ | ||
8 | + | ||
9 | +exports.DECIMAL = 0; | ||
10 | +exports.TINY = 1; | ||
11 | +exports.SHORT = 2; | ||
12 | +exports.LONG = 3; | ||
13 | +exports.FLOAT = 4; | ||
14 | +exports.DOUBLE = 5; | ||
15 | +exports.NULL = 6; | ||
16 | +exports.TIMESTAMP = 7; | ||
17 | +exports.LONGLONG = 8; | ||
18 | +exports.INT24 = 9; | ||
19 | +exports.DATE = 10; | ||
20 | +exports.TIME = 11; | ||
21 | +exports.DATETIME = 12; | ||
22 | +exports.YEAR = 13; | ||
23 | +exports.NEWDATE = 14; | ||
24 | +exports.VARCHAR = 15; | ||
25 | +exports.BIT = 16; | ||
26 | +exports.TIMESTAMP2 = 17; | ||
27 | +exports.DATETIME2 = 18; | ||
28 | +exports.TIME2 = 19; | ||
29 | +exports.JSON = 245; | ||
30 | +exports.NEWDECIMAL = 246; | ||
31 | +exports.ENUM = 247; | ||
32 | +exports.SET = 248; | ||
33 | +exports.TINY_BLOB = 249; | ||
34 | +exports.MEDIUM_BLOB = 250; | ||
35 | +exports.LONG_BLOB = 251; | ||
36 | +exports.BLOB = 252; | ||
37 | +exports.VAR_STRING = 253; | ||
38 | +exports.STRING = 254; | ||
39 | +exports.GEOMETRY = 255; | ||
40 | + | ||
41 | +// Lookup-by-number table | ||
42 | +exports[0] = 'DECIMAL'; | ||
43 | +exports[1] = 'TINY'; | ||
44 | +exports[2] = 'SHORT'; | ||
45 | +exports[3] = 'LONG'; | ||
46 | +exports[4] = 'FLOAT'; | ||
47 | +exports[5] = 'DOUBLE'; | ||
48 | +exports[6] = 'NULL'; | ||
49 | +exports[7] = 'TIMESTAMP'; | ||
50 | +exports[8] = 'LONGLONG'; | ||
51 | +exports[9] = 'INT24'; | ||
52 | +exports[10] = 'DATE'; | ||
53 | +exports[11] = 'TIME'; | ||
54 | +exports[12] = 'DATETIME'; | ||
55 | +exports[13] = 'YEAR'; | ||
56 | +exports[14] = 'NEWDATE'; | ||
57 | +exports[15] = 'VARCHAR'; | ||
58 | +exports[16] = 'BIT'; | ||
59 | +exports[17] = 'TIMESTAMP2'; | ||
60 | +exports[18] = 'DATETIME2'; | ||
61 | +exports[19] = 'TIME2'; | ||
62 | +exports[245] = 'JSON'; | ||
63 | +exports[246] = 'NEWDECIMAL'; | ||
64 | +exports[247] = 'ENUM'; | ||
65 | +exports[248] = 'SET'; | ||
66 | +exports[249] = 'TINY_BLOB'; | ||
67 | +exports[250] = 'MEDIUM_BLOB'; | ||
68 | +exports[251] = 'LONG_BLOB'; | ||
69 | +exports[252] = 'BLOB'; | ||
70 | +exports[253] = 'VAR_STRING'; | ||
71 | +exports[254] = 'STRING'; | ||
72 | +exports[255] = 'GEOMETRY'; |
1 | +module.exports = AuthSwitchRequestPacket; | ||
2 | +function AuthSwitchRequestPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.status = 0xfe; | ||
6 | + this.authMethodName = options.authMethodName; | ||
7 | + this.authMethodData = options.authMethodData; | ||
8 | +} | ||
9 | + | ||
10 | +AuthSwitchRequestPacket.prototype.parse = function parse(parser) { | ||
11 | + this.status = parser.parseUnsignedNumber(1); | ||
12 | + this.authMethodName = parser.parseNullTerminatedString(); | ||
13 | + this.authMethodData = parser.parsePacketTerminatedBuffer(); | ||
14 | +}; | ||
15 | + | ||
16 | +AuthSwitchRequestPacket.prototype.write = function write(writer) { | ||
17 | + writer.writeUnsignedNumber(1, this.status); | ||
18 | + writer.writeNullTerminatedString(this.authMethodName); | ||
19 | + writer.writeBuffer(this.authMethodData); | ||
20 | +}; |
1 | +module.exports = AuthSwitchResponsePacket; | ||
2 | +function AuthSwitchResponsePacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.data = options.data; | ||
6 | +} | ||
7 | + | ||
8 | +AuthSwitchResponsePacket.prototype.parse = function parse(parser) { | ||
9 | + this.data = parser.parsePacketTerminatedBuffer(); | ||
10 | +}; | ||
11 | + | ||
12 | +AuthSwitchResponsePacket.prototype.write = function write(writer) { | ||
13 | + writer.writeBuffer(this.data); | ||
14 | +}; |
1 | +var Buffer = require('safe-buffer').Buffer; | ||
2 | + | ||
3 | +module.exports = ClientAuthenticationPacket; | ||
4 | +function ClientAuthenticationPacket(options) { | ||
5 | + options = options || {}; | ||
6 | + | ||
7 | + this.clientFlags = options.clientFlags; | ||
8 | + this.maxPacketSize = options.maxPacketSize; | ||
9 | + this.charsetNumber = options.charsetNumber; | ||
10 | + this.filler = undefined; | ||
11 | + this.user = options.user; | ||
12 | + this.scrambleBuff = options.scrambleBuff; | ||
13 | + this.database = options.database; | ||
14 | + this.protocol41 = options.protocol41; | ||
15 | +} | ||
16 | + | ||
17 | +ClientAuthenticationPacket.prototype.parse = function(parser) { | ||
18 | + if (this.protocol41) { | ||
19 | + this.clientFlags = parser.parseUnsignedNumber(4); | ||
20 | + this.maxPacketSize = parser.parseUnsignedNumber(4); | ||
21 | + this.charsetNumber = parser.parseUnsignedNumber(1); | ||
22 | + this.filler = parser.parseFiller(23); | ||
23 | + this.user = parser.parseNullTerminatedString(); | ||
24 | + this.scrambleBuff = parser.parseLengthCodedBuffer(); | ||
25 | + this.database = parser.parseNullTerminatedString(); | ||
26 | + } else { | ||
27 | + this.clientFlags = parser.parseUnsignedNumber(2); | ||
28 | + this.maxPacketSize = parser.parseUnsignedNumber(3); | ||
29 | + this.user = parser.parseNullTerminatedString(); | ||
30 | + this.scrambleBuff = parser.parseBuffer(8); | ||
31 | + this.database = parser.parseLengthCodedBuffer(); | ||
32 | + } | ||
33 | +}; | ||
34 | + | ||
35 | +ClientAuthenticationPacket.prototype.write = function(writer) { | ||
36 | + if (this.protocol41) { | ||
37 | + writer.writeUnsignedNumber(4, this.clientFlags); | ||
38 | + writer.writeUnsignedNumber(4, this.maxPacketSize); | ||
39 | + writer.writeUnsignedNumber(1, this.charsetNumber); | ||
40 | + writer.writeFiller(23); | ||
41 | + writer.writeNullTerminatedString(this.user); | ||
42 | + writer.writeLengthCodedBuffer(this.scrambleBuff); | ||
43 | + writer.writeNullTerminatedString(this.database); | ||
44 | + } else { | ||
45 | + writer.writeUnsignedNumber(2, this.clientFlags); | ||
46 | + writer.writeUnsignedNumber(3, this.maxPacketSize); | ||
47 | + writer.writeNullTerminatedString(this.user); | ||
48 | + writer.writeBuffer(this.scrambleBuff); | ||
49 | + if (this.database && this.database.length) { | ||
50 | + writer.writeFiller(1); | ||
51 | + writer.writeBuffer(Buffer.from(this.database)); | ||
52 | + } | ||
53 | + } | ||
54 | +}; |
1 | +module.exports = ComChangeUserPacket; | ||
2 | +function ComChangeUserPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.command = 0x11; | ||
6 | + this.user = options.user; | ||
7 | + this.scrambleBuff = options.scrambleBuff; | ||
8 | + this.database = options.database; | ||
9 | + this.charsetNumber = options.charsetNumber; | ||
10 | +} | ||
11 | + | ||
12 | +ComChangeUserPacket.prototype.parse = function(parser) { | ||
13 | + this.command = parser.parseUnsignedNumber(1); | ||
14 | + this.user = parser.parseNullTerminatedString(); | ||
15 | + this.scrambleBuff = parser.parseLengthCodedBuffer(); | ||
16 | + this.database = parser.parseNullTerminatedString(); | ||
17 | + this.charsetNumber = parser.parseUnsignedNumber(1); | ||
18 | +}; | ||
19 | + | ||
20 | +ComChangeUserPacket.prototype.write = function(writer) { | ||
21 | + writer.writeUnsignedNumber(1, this.command); | ||
22 | + writer.writeNullTerminatedString(this.user); | ||
23 | + writer.writeLengthCodedBuffer(this.scrambleBuff); | ||
24 | + writer.writeNullTerminatedString(this.database); | ||
25 | + writer.writeUnsignedNumber(2, this.charsetNumber); | ||
26 | +}; |
1 | +module.exports = ComPingPacket; | ||
2 | +function ComPingPacket() { | ||
3 | + this.command = 0x0e; | ||
4 | +} | ||
5 | + | ||
6 | +ComPingPacket.prototype.write = function(writer) { | ||
7 | + writer.writeUnsignedNumber(1, this.command); | ||
8 | +}; | ||
9 | + | ||
10 | +ComPingPacket.prototype.parse = function(parser) { | ||
11 | + this.command = parser.parseUnsignedNumber(1); | ||
12 | +}; |
1 | +module.exports = ComQueryPacket; | ||
2 | +function ComQueryPacket(sql) { | ||
3 | + this.command = 0x03; | ||
4 | + this.sql = sql; | ||
5 | +} | ||
6 | + | ||
7 | +ComQueryPacket.prototype.write = function(writer) { | ||
8 | + writer.writeUnsignedNumber(1, this.command); | ||
9 | + writer.writeString(this.sql); | ||
10 | +}; | ||
11 | + | ||
12 | +ComQueryPacket.prototype.parse = function(parser) { | ||
13 | + this.command = parser.parseUnsignedNumber(1); | ||
14 | + this.sql = parser.parsePacketTerminatedString(); | ||
15 | +}; |
1 | +module.exports = ComQuitPacket; | ||
2 | +function ComQuitPacket() { | ||
3 | + this.command = 0x01; | ||
4 | +} | ||
5 | + | ||
6 | +ComQuitPacket.prototype.parse = function parse(parser) { | ||
7 | + this.command = parser.parseUnsignedNumber(1); | ||
8 | +}; | ||
9 | + | ||
10 | +ComQuitPacket.prototype.write = function write(writer) { | ||
11 | + writer.writeUnsignedNumber(1, this.command); | ||
12 | +}; |
1 | +module.exports = ComStatisticsPacket; | ||
2 | +function ComStatisticsPacket() { | ||
3 | + this.command = 0x09; | ||
4 | +} | ||
5 | + | ||
6 | +ComStatisticsPacket.prototype.write = function(writer) { | ||
7 | + writer.writeUnsignedNumber(1, this.command); | ||
8 | +}; | ||
9 | + | ||
10 | +ComStatisticsPacket.prototype.parse = function(parser) { | ||
11 | + this.command = parser.parseUnsignedNumber(1); | ||
12 | +}; |
1 | +module.exports = EofPacket; | ||
2 | +function EofPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.fieldCount = undefined; | ||
6 | + this.warningCount = options.warningCount; | ||
7 | + this.serverStatus = options.serverStatus; | ||
8 | + this.protocol41 = options.protocol41; | ||
9 | +} | ||
10 | + | ||
11 | +EofPacket.prototype.parse = function(parser) { | ||
12 | + this.fieldCount = parser.parseUnsignedNumber(1); | ||
13 | + if (this.protocol41) { | ||
14 | + this.warningCount = parser.parseUnsignedNumber(2); | ||
15 | + this.serverStatus = parser.parseUnsignedNumber(2); | ||
16 | + } | ||
17 | +}; | ||
18 | + | ||
19 | +EofPacket.prototype.write = function(writer) { | ||
20 | + writer.writeUnsignedNumber(1, 0xfe); | ||
21 | + if (this.protocol41) { | ||
22 | + writer.writeUnsignedNumber(2, this.warningCount); | ||
23 | + writer.writeUnsignedNumber(2, this.serverStatus); | ||
24 | + } | ||
25 | +}; |
1 | +module.exports = ErrorPacket; | ||
2 | +function ErrorPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.fieldCount = options.fieldCount; | ||
6 | + this.errno = options.errno; | ||
7 | + this.sqlStateMarker = options.sqlStateMarker; | ||
8 | + this.sqlState = options.sqlState; | ||
9 | + this.message = options.message; | ||
10 | +} | ||
11 | + | ||
12 | +ErrorPacket.prototype.parse = function(parser) { | ||
13 | + this.fieldCount = parser.parseUnsignedNumber(1); | ||
14 | + this.errno = parser.parseUnsignedNumber(2); | ||
15 | + | ||
16 | + // sqlStateMarker ('#' = 0x23) indicates error packet format | ||
17 | + if (parser.peak() === 0x23) { | ||
18 | + this.sqlStateMarker = parser.parseString(1); | ||
19 | + this.sqlState = parser.parseString(5); | ||
20 | + } | ||
21 | + | ||
22 | + this.message = parser.parsePacketTerminatedString(); | ||
23 | +}; | ||
24 | + | ||
25 | +ErrorPacket.prototype.write = function(writer) { | ||
26 | + writer.writeUnsignedNumber(1, 0xff); | ||
27 | + writer.writeUnsignedNumber(2, this.errno); | ||
28 | + | ||
29 | + if (this.sqlStateMarker) { | ||
30 | + writer.writeString(this.sqlStateMarker); | ||
31 | + writer.writeString(this.sqlState); | ||
32 | + } | ||
33 | + | ||
34 | + writer.writeString(this.message); | ||
35 | +}; |
1 | +var Types = require('../constants/types'); | ||
2 | + | ||
3 | +module.exports = Field; | ||
4 | +function Field(options) { | ||
5 | + options = options || {}; | ||
6 | + | ||
7 | + this.parser = options.parser; | ||
8 | + this.packet = options.packet; | ||
9 | + this.db = options.packet.db; | ||
10 | + this.table = options.packet.table; | ||
11 | + this.name = options.packet.name; | ||
12 | + this.type = Types[options.packet.type]; | ||
13 | + this.length = options.packet.length; | ||
14 | +} | ||
15 | + | ||
16 | +Field.prototype.string = function () { | ||
17 | + return this.parser.parseLengthCodedString(); | ||
18 | +}; | ||
19 | + | ||
20 | +Field.prototype.buffer = function () { | ||
21 | + return this.parser.parseLengthCodedBuffer(); | ||
22 | +}; | ||
23 | + | ||
24 | +Field.prototype.geometry = function () { | ||
25 | + return this.parser.parseGeometryValue(); | ||
26 | +}; |
1 | +module.exports = FieldPacket; | ||
2 | +function FieldPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.catalog = options.catalog; | ||
6 | + this.db = options.db; | ||
7 | + this.table = options.table; | ||
8 | + this.orgTable = options.orgTable; | ||
9 | + this.name = options.name; | ||
10 | + this.orgName = options.orgName; | ||
11 | + this.charsetNr = options.charsetNr; | ||
12 | + this.length = options.length; | ||
13 | + this.type = options.type; | ||
14 | + this.flags = options.flags; | ||
15 | + this.decimals = options.decimals; | ||
16 | + this.default = options.default; | ||
17 | + this.zeroFill = options.zeroFill; | ||
18 | + this.protocol41 = options.protocol41; | ||
19 | +} | ||
20 | + | ||
21 | +FieldPacket.prototype.parse = function(parser) { | ||
22 | + if (this.protocol41) { | ||
23 | + this.catalog = parser.parseLengthCodedString(); | ||
24 | + this.db = parser.parseLengthCodedString(); | ||
25 | + this.table = parser.parseLengthCodedString(); | ||
26 | + this.orgTable = parser.parseLengthCodedString(); | ||
27 | + this.name = parser.parseLengthCodedString(); | ||
28 | + this.orgName = parser.parseLengthCodedString(); | ||
29 | + | ||
30 | + if (parser.parseLengthCodedNumber() !== 0x0c) { | ||
31 | + var err = new TypeError('Received invalid field length'); | ||
32 | + err.code = 'PARSER_INVALID_FIELD_LENGTH'; | ||
33 | + throw err; | ||
34 | + } | ||
35 | + | ||
36 | + this.charsetNr = parser.parseUnsignedNumber(2); | ||
37 | + this.length = parser.parseUnsignedNumber(4); | ||
38 | + this.type = parser.parseUnsignedNumber(1); | ||
39 | + this.flags = parser.parseUnsignedNumber(2); | ||
40 | + this.decimals = parser.parseUnsignedNumber(1); | ||
41 | + | ||
42 | + var filler = parser.parseBuffer(2); | ||
43 | + if (filler[0] !== 0x0 || filler[1] !== 0x0) { | ||
44 | + var err = new TypeError('Received invalid filler'); | ||
45 | + err.code = 'PARSER_INVALID_FILLER'; | ||
46 | + throw err; | ||
47 | + } | ||
48 | + | ||
49 | + // parsed flags | ||
50 | + this.zeroFill = (this.flags & 0x0040 ? true : false); | ||
51 | + | ||
52 | + if (parser.reachedPacketEnd()) { | ||
53 | + return; | ||
54 | + } | ||
55 | + | ||
56 | + this.default = parser.parseLengthCodedString(); | ||
57 | + } else { | ||
58 | + this.table = parser.parseLengthCodedString(); | ||
59 | + this.name = parser.parseLengthCodedString(); | ||
60 | + this.length = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1)); | ||
61 | + this.type = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1)); | ||
62 | + } | ||
63 | +}; | ||
64 | + | ||
65 | +FieldPacket.prototype.write = function(writer) { | ||
66 | + if (this.protocol41) { | ||
67 | + writer.writeLengthCodedString(this.catalog); | ||
68 | + writer.writeLengthCodedString(this.db); | ||
69 | + writer.writeLengthCodedString(this.table); | ||
70 | + writer.writeLengthCodedString(this.orgTable); | ||
71 | + writer.writeLengthCodedString(this.name); | ||
72 | + writer.writeLengthCodedString(this.orgName); | ||
73 | + | ||
74 | + writer.writeLengthCodedNumber(0x0c); | ||
75 | + writer.writeUnsignedNumber(2, this.charsetNr || 0); | ||
76 | + writer.writeUnsignedNumber(4, this.length || 0); | ||
77 | + writer.writeUnsignedNumber(1, this.type || 0); | ||
78 | + writer.writeUnsignedNumber(2, this.flags || 0); | ||
79 | + writer.writeUnsignedNumber(1, this.decimals || 0); | ||
80 | + writer.writeFiller(2); | ||
81 | + | ||
82 | + if (this.default !== undefined) { | ||
83 | + writer.writeLengthCodedString(this.default); | ||
84 | + } | ||
85 | + } else { | ||
86 | + writer.writeLengthCodedString(this.table); | ||
87 | + writer.writeLengthCodedString(this.name); | ||
88 | + writer.writeUnsignedNumber(1, 0x01); | ||
89 | + writer.writeUnsignedNumber(1, this.length); | ||
90 | + writer.writeUnsignedNumber(1, 0x01); | ||
91 | + writer.writeUnsignedNumber(1, this.type); | ||
92 | + } | ||
93 | +}; |
1 | +var Buffer = require('safe-buffer').Buffer; | ||
2 | +var Client = require('../constants/client'); | ||
3 | + | ||
4 | +module.exports = HandshakeInitializationPacket; | ||
5 | +function HandshakeInitializationPacket(options) { | ||
6 | + options = options || {}; | ||
7 | + | ||
8 | + this.protocolVersion = options.protocolVersion; | ||
9 | + this.serverVersion = options.serverVersion; | ||
10 | + this.threadId = options.threadId; | ||
11 | + this.scrambleBuff1 = options.scrambleBuff1; | ||
12 | + this.filler1 = options.filler1; | ||
13 | + this.serverCapabilities1 = options.serverCapabilities1; | ||
14 | + this.serverLanguage = options.serverLanguage; | ||
15 | + this.serverStatus = options.serverStatus; | ||
16 | + this.serverCapabilities2 = options.serverCapabilities2; | ||
17 | + this.scrambleLength = options.scrambleLength; | ||
18 | + this.filler2 = options.filler2; | ||
19 | + this.scrambleBuff2 = options.scrambleBuff2; | ||
20 | + this.filler3 = options.filler3; | ||
21 | + this.pluginData = options.pluginData; | ||
22 | + this.protocol41 = options.protocol41; | ||
23 | + | ||
24 | + if (this.protocol41) { | ||
25 | + // force set the bit in serverCapabilities1 | ||
26 | + this.serverCapabilities1 |= Client.CLIENT_PROTOCOL_41; | ||
27 | + } | ||
28 | +} | ||
29 | + | ||
30 | +HandshakeInitializationPacket.prototype.parse = function(parser) { | ||
31 | + this.protocolVersion = parser.parseUnsignedNumber(1); | ||
32 | + this.serverVersion = parser.parseNullTerminatedString(); | ||
33 | + this.threadId = parser.parseUnsignedNumber(4); | ||
34 | + this.scrambleBuff1 = parser.parseBuffer(8); | ||
35 | + this.filler1 = parser.parseFiller(1); | ||
36 | + this.serverCapabilities1 = parser.parseUnsignedNumber(2); | ||
37 | + this.serverLanguage = parser.parseUnsignedNumber(1); | ||
38 | + this.serverStatus = parser.parseUnsignedNumber(2); | ||
39 | + | ||
40 | + this.protocol41 = (this.serverCapabilities1 & (1 << 9)) > 0; | ||
41 | + | ||
42 | + if (this.protocol41) { | ||
43 | + this.serverCapabilities2 = parser.parseUnsignedNumber(2); | ||
44 | + this.scrambleLength = parser.parseUnsignedNumber(1); | ||
45 | + this.filler2 = parser.parseFiller(10); | ||
46 | + // scrambleBuff2 should be 0x00 terminated, but sphinx does not do this | ||
47 | + // so we assume scrambleBuff2 to be 12 byte and treat the next byte as a | ||
48 | + // filler byte. | ||
49 | + this.scrambleBuff2 = parser.parseBuffer(12); | ||
50 | + this.filler3 = parser.parseFiller(1); | ||
51 | + } else { | ||
52 | + this.filler2 = parser.parseFiller(13); | ||
53 | + } | ||
54 | + | ||
55 | + if (parser.reachedPacketEnd()) { | ||
56 | + return; | ||
57 | + } | ||
58 | + | ||
59 | + // According to the docs this should be 0x00 terminated, but MariaDB does | ||
60 | + // not do this, so we assume this string to be packet terminated. | ||
61 | + this.pluginData = parser.parsePacketTerminatedString(); | ||
62 | + | ||
63 | + // However, if there is a trailing '\0', strip it | ||
64 | + var lastChar = this.pluginData.length - 1; | ||
65 | + if (this.pluginData[lastChar] === '\0') { | ||
66 | + this.pluginData = this.pluginData.substr(0, lastChar); | ||
67 | + } | ||
68 | +}; | ||
69 | + | ||
70 | +HandshakeInitializationPacket.prototype.write = function(writer) { | ||
71 | + writer.writeUnsignedNumber(1, this.protocolVersion); | ||
72 | + writer.writeNullTerminatedString(this.serverVersion); | ||
73 | + writer.writeUnsignedNumber(4, this.threadId); | ||
74 | + writer.writeBuffer(this.scrambleBuff1); | ||
75 | + writer.writeFiller(1); | ||
76 | + writer.writeUnsignedNumber(2, this.serverCapabilities1); | ||
77 | + writer.writeUnsignedNumber(1, this.serverLanguage); | ||
78 | + writer.writeUnsignedNumber(2, this.serverStatus); | ||
79 | + if (this.protocol41) { | ||
80 | + writer.writeUnsignedNumber(2, this.serverCapabilities2); | ||
81 | + writer.writeUnsignedNumber(1, this.scrambleLength); | ||
82 | + writer.writeFiller(10); | ||
83 | + } | ||
84 | + writer.writeNullTerminatedBuffer(this.scrambleBuff2); | ||
85 | + | ||
86 | + if (this.pluginData !== undefined) { | ||
87 | + writer.writeNullTerminatedString(this.pluginData); | ||
88 | + } | ||
89 | +}; | ||
90 | + | ||
91 | +HandshakeInitializationPacket.prototype.scrambleBuff = function() { | ||
92 | + var buffer = null; | ||
93 | + | ||
94 | + if (typeof this.scrambleBuff2 === 'undefined') { | ||
95 | + buffer = Buffer.from(this.scrambleBuff1); | ||
96 | + } else { | ||
97 | + buffer = Buffer.allocUnsafe(this.scrambleBuff1.length + this.scrambleBuff2.length); | ||
98 | + this.scrambleBuff1.copy(buffer, 0); | ||
99 | + this.scrambleBuff2.copy(buffer, this.scrambleBuff1.length); | ||
100 | + } | ||
101 | + | ||
102 | + return buffer; | ||
103 | +}; |
1 | +module.exports = LocalDataFilePacket; | ||
2 | + | ||
3 | +/** | ||
4 | + * Create a new LocalDataFilePacket | ||
5 | + * @constructor | ||
6 | + * @param {Buffer} data The data contents of the packet | ||
7 | + * @public | ||
8 | + */ | ||
9 | +function LocalDataFilePacket(data) { | ||
10 | + this.data = data; | ||
11 | +} | ||
12 | + | ||
13 | +LocalDataFilePacket.prototype.write = function(writer) { | ||
14 | + writer.writeBuffer(this.data); | ||
15 | +}; |
1 | +module.exports = LocalInfileRequestPacket; | ||
2 | +function LocalInfileRequestPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.filename = options.filename; | ||
6 | +} | ||
7 | + | ||
8 | +LocalInfileRequestPacket.prototype.parse = function parse(parser) { | ||
9 | + if (parser.parseLengthCodedNumber() !== null) { | ||
10 | + var err = new TypeError('Received invalid field length'); | ||
11 | + err.code = 'PARSER_INVALID_FIELD_LENGTH'; | ||
12 | + throw err; | ||
13 | + } | ||
14 | + | ||
15 | + this.filename = parser.parsePacketTerminatedString(); | ||
16 | +}; | ||
17 | + | ||
18 | +LocalInfileRequestPacket.prototype.write = function write(writer) { | ||
19 | + writer.writeLengthCodedNumber(null); | ||
20 | + writer.writeString(this.filename); | ||
21 | +}; |
1 | + | ||
2 | +// Language-neutral expression to match ER_UPDATE_INFO | ||
3 | +var ER_UPDATE_INFO_REGEXP = /^[^:0-9]+: [0-9]+[^:0-9]+: ([0-9]+)[^:0-9]+: [0-9]+[^:0-9]*$/; | ||
4 | + | ||
5 | +module.exports = OkPacket; | ||
6 | +function OkPacket(options) { | ||
7 | + options = options || {}; | ||
8 | + | ||
9 | + this.fieldCount = undefined; | ||
10 | + this.affectedRows = undefined; | ||
11 | + this.insertId = undefined; | ||
12 | + this.serverStatus = undefined; | ||
13 | + this.warningCount = undefined; | ||
14 | + this.message = undefined; | ||
15 | + this.protocol41 = options.protocol41; | ||
16 | +} | ||
17 | + | ||
18 | +OkPacket.prototype.parse = function(parser) { | ||
19 | + this.fieldCount = parser.parseUnsignedNumber(1); | ||
20 | + this.affectedRows = parser.parseLengthCodedNumber(); | ||
21 | + this.insertId = parser.parseLengthCodedNumber(); | ||
22 | + if (this.protocol41) { | ||
23 | + this.serverStatus = parser.parseUnsignedNumber(2); | ||
24 | + this.warningCount = parser.parseUnsignedNumber(2); | ||
25 | + } | ||
26 | + this.message = parser.parsePacketTerminatedString(); | ||
27 | + this.changedRows = 0; | ||
28 | + | ||
29 | + var m = ER_UPDATE_INFO_REGEXP.exec(this.message); | ||
30 | + if (m !== null) { | ||
31 | + this.changedRows = parseInt(m[1], 10); | ||
32 | + } | ||
33 | +}; | ||
34 | + | ||
35 | +OkPacket.prototype.write = function(writer) { | ||
36 | + writer.writeUnsignedNumber(1, 0x00); | ||
37 | + writer.writeLengthCodedNumber(this.affectedRows || 0); | ||
38 | + writer.writeLengthCodedNumber(this.insertId || 0); | ||
39 | + if (this.protocol41) { | ||
40 | + writer.writeUnsignedNumber(2, this.serverStatus || 0); | ||
41 | + writer.writeUnsignedNumber(2, this.warningCount || 0); | ||
42 | + } | ||
43 | + writer.writeString(this.message); | ||
44 | +}; |
1 | +module.exports = OldPasswordPacket; | ||
2 | +function OldPasswordPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.scrambleBuff = options.scrambleBuff; | ||
6 | +} | ||
7 | + | ||
8 | +OldPasswordPacket.prototype.parse = function(parser) { | ||
9 | + this.scrambleBuff = parser.parsePacketTerminatedBuffer(); | ||
10 | +}; | ||
11 | + | ||
12 | +OldPasswordPacket.prototype.write = function(writer) { | ||
13 | + writer.writeBuffer(this.scrambleBuff); | ||
14 | +}; |
1 | +module.exports = ResultSetHeaderPacket; | ||
2 | +function ResultSetHeaderPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.fieldCount = options.fieldCount; | ||
6 | +} | ||
7 | + | ||
8 | +ResultSetHeaderPacket.prototype.parse = function(parser) { | ||
9 | + this.fieldCount = parser.parseLengthCodedNumber(); | ||
10 | +}; | ||
11 | + | ||
12 | +ResultSetHeaderPacket.prototype.write = function(writer) { | ||
13 | + writer.writeLengthCodedNumber(this.fieldCount); | ||
14 | +}; |
1 | +var Types = require('../constants/types'); | ||
2 | +var Charsets = require('../constants/charsets'); | ||
3 | +var Field = require('./Field'); | ||
4 | +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53); | ||
5 | + | ||
6 | +module.exports = RowDataPacket; | ||
7 | +function RowDataPacket() { | ||
8 | +} | ||
9 | + | ||
10 | +Object.defineProperty(RowDataPacket.prototype, 'parse', { | ||
11 | + configurable : true, | ||
12 | + enumerable : false, | ||
13 | + value : parse | ||
14 | +}); | ||
15 | + | ||
16 | +Object.defineProperty(RowDataPacket.prototype, '_typeCast', { | ||
17 | + configurable : true, | ||
18 | + enumerable : false, | ||
19 | + value : typeCast | ||
20 | +}); | ||
21 | + | ||
22 | +function parse(parser, fieldPackets, typeCast, nestTables, connection) { | ||
23 | + var self = this; | ||
24 | + var next = function () { | ||
25 | + return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings); | ||
26 | + }; | ||
27 | + | ||
28 | + for (var i = 0; i < fieldPackets.length; i++) { | ||
29 | + var fieldPacket = fieldPackets[i]; | ||
30 | + var value; | ||
31 | + | ||
32 | + if (typeof typeCast === 'function') { | ||
33 | + value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]); | ||
34 | + } else { | ||
35 | + value = (typeCast) | ||
36 | + ? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings) | ||
37 | + : ( (fieldPacket.charsetNr === Charsets.BINARY) | ||
38 | + ? parser.parseLengthCodedBuffer() | ||
39 | + : parser.parseLengthCodedString() ); | ||
40 | + } | ||
41 | + | ||
42 | + if (typeof nestTables === 'string' && nestTables.length) { | ||
43 | + this[fieldPacket.table + nestTables + fieldPacket.name] = value; | ||
44 | + } else if (nestTables) { | ||
45 | + this[fieldPacket.table] = this[fieldPacket.table] || {}; | ||
46 | + this[fieldPacket.table][fieldPacket.name] = value; | ||
47 | + } else { | ||
48 | + this[fieldPacket.name] = value; | ||
49 | + } | ||
50 | + } | ||
51 | +} | ||
52 | + | ||
53 | +function typeCast(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) { | ||
54 | + var numberString; | ||
55 | + | ||
56 | + switch (field.type) { | ||
57 | + case Types.TIMESTAMP: | ||
58 | + case Types.TIMESTAMP2: | ||
59 | + case Types.DATE: | ||
60 | + case Types.DATETIME: | ||
61 | + case Types.DATETIME2: | ||
62 | + case Types.NEWDATE: | ||
63 | + var dateString = parser.parseLengthCodedString(); | ||
64 | + | ||
65 | + if (typeMatch(field.type, dateStrings)) { | ||
66 | + return dateString; | ||
67 | + } | ||
68 | + | ||
69 | + if (dateString === null) { | ||
70 | + return null; | ||
71 | + } | ||
72 | + | ||
73 | + var originalString = dateString; | ||
74 | + if (field.type === Types.DATE) { | ||
75 | + dateString += ' 00:00:00'; | ||
76 | + } | ||
77 | + | ||
78 | + if (timeZone !== 'local') { | ||
79 | + dateString += ' ' + timeZone; | ||
80 | + } | ||
81 | + | ||
82 | + var dt = new Date(dateString); | ||
83 | + if (isNaN(dt.getTime())) { | ||
84 | + return originalString; | ||
85 | + } | ||
86 | + | ||
87 | + return dt; | ||
88 | + case Types.TINY: | ||
89 | + case Types.SHORT: | ||
90 | + case Types.LONG: | ||
91 | + case Types.INT24: | ||
92 | + case Types.YEAR: | ||
93 | + case Types.FLOAT: | ||
94 | + case Types.DOUBLE: | ||
95 | + numberString = parser.parseLengthCodedString(); | ||
96 | + return (numberString === null || (field.zeroFill && numberString[0] === '0')) | ||
97 | + ? numberString : Number(numberString); | ||
98 | + case Types.NEWDECIMAL: | ||
99 | + case Types.LONGLONG: | ||
100 | + numberString = parser.parseLengthCodedString(); | ||
101 | + return (numberString === null || (field.zeroFill && numberString[0] === '0')) | ||
102 | + ? numberString | ||
103 | + : ((supportBigNumbers && (bigNumberStrings || (Number(numberString) >= IEEE_754_BINARY_64_PRECISION) || Number(numberString) <= -IEEE_754_BINARY_64_PRECISION)) | ||
104 | + ? numberString | ||
105 | + : Number(numberString)); | ||
106 | + case Types.BIT: | ||
107 | + return parser.parseLengthCodedBuffer(); | ||
108 | + case Types.STRING: | ||
109 | + case Types.VAR_STRING: | ||
110 | + case Types.TINY_BLOB: | ||
111 | + case Types.MEDIUM_BLOB: | ||
112 | + case Types.LONG_BLOB: | ||
113 | + case Types.BLOB: | ||
114 | + return (field.charsetNr === Charsets.BINARY) | ||
115 | + ? parser.parseLengthCodedBuffer() | ||
116 | + : parser.parseLengthCodedString(); | ||
117 | + case Types.GEOMETRY: | ||
118 | + return parser.parseGeometryValue(); | ||
119 | + default: | ||
120 | + return parser.parseLengthCodedString(); | ||
121 | + } | ||
122 | +} | ||
123 | + | ||
124 | +function typeMatch(type, list) { | ||
125 | + if (Array.isArray(list)) { | ||
126 | + return list.indexOf(Types[type]) !== -1; | ||
127 | + } else { | ||
128 | + return Boolean(list); | ||
129 | + } | ||
130 | +} |
1 | +// http://dev.mysql.com/doc/internals/en/ssl.html | ||
2 | +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest | ||
3 | + | ||
4 | +var ClientConstants = require('../constants/client'); | ||
5 | + | ||
6 | +module.exports = SSLRequestPacket; | ||
7 | + | ||
8 | +function SSLRequestPacket(options) { | ||
9 | + options = options || {}; | ||
10 | + this.clientFlags = options.clientFlags | ClientConstants.CLIENT_SSL; | ||
11 | + this.maxPacketSize = options.maxPacketSize; | ||
12 | + this.charsetNumber = options.charsetNumber; | ||
13 | +} | ||
14 | + | ||
15 | +SSLRequestPacket.prototype.parse = function(parser) { | ||
16 | + // TODO: check SSLRequest packet v41 vs pre v41 | ||
17 | + this.clientFlags = parser.parseUnsignedNumber(4); | ||
18 | + this.maxPacketSize = parser.parseUnsignedNumber(4); | ||
19 | + this.charsetNumber = parser.parseUnsignedNumber(1); | ||
20 | +}; | ||
21 | + | ||
22 | +SSLRequestPacket.prototype.write = function(writer) { | ||
23 | + writer.writeUnsignedNumber(4, this.clientFlags); | ||
24 | + writer.writeUnsignedNumber(4, this.maxPacketSize); | ||
25 | + writer.writeUnsignedNumber(1, this.charsetNumber); | ||
26 | + writer.writeFiller(23); | ||
27 | +}; |
1 | +module.exports = StatisticsPacket; | ||
2 | +function StatisticsPacket() { | ||
3 | + this.message = undefined; | ||
4 | +} | ||
5 | + | ||
6 | +StatisticsPacket.prototype.parse = function(parser) { | ||
7 | + this.message = parser.parsePacketTerminatedString(); | ||
8 | + | ||
9 | + var items = this.message.split(/\s\s/); | ||
10 | + for (var i = 0; i < items.length; i++) { | ||
11 | + var m = items[i].match(/^(.+)\:\s+(.+)$/); | ||
12 | + if (m !== null) { | ||
13 | + this[m[1].toLowerCase().replace(/\s/g, '_')] = Number(m[2]); | ||
14 | + } | ||
15 | + } | ||
16 | +}; | ||
17 | + | ||
18 | +StatisticsPacket.prototype.write = function(writer) { | ||
19 | + writer.writeString(this.message); | ||
20 | +}; |
1 | +module.exports = UseOldPasswordPacket; | ||
2 | +function UseOldPasswordPacket(options) { | ||
3 | + options = options || {}; | ||
4 | + | ||
5 | + this.firstByte = options.firstByte || 0xfe; | ||
6 | +} | ||
7 | + | ||
8 | +UseOldPasswordPacket.prototype.parse = function(parser) { | ||
9 | + this.firstByte = parser.parseUnsignedNumber(1); | ||
10 | +}; | ||
11 | + | ||
12 | +UseOldPasswordPacket.prototype.write = function(writer) { | ||
13 | + writer.writeUnsignedNumber(1, this.firstByte); | ||
14 | +}; |
1 | +exports.AuthSwitchRequestPacket = require('./AuthSwitchRequestPacket'); | ||
2 | +exports.AuthSwitchResponsePacket = require('./AuthSwitchResponsePacket'); | ||
3 | +exports.ClientAuthenticationPacket = require('./ClientAuthenticationPacket'); | ||
4 | +exports.ComChangeUserPacket = require('./ComChangeUserPacket'); | ||
5 | +exports.ComPingPacket = require('./ComPingPacket'); | ||
6 | +exports.ComQueryPacket = require('./ComQueryPacket'); | ||
7 | +exports.ComQuitPacket = require('./ComQuitPacket'); | ||
8 | +exports.ComStatisticsPacket = require('./ComStatisticsPacket'); | ||
9 | +exports.EmptyPacket = require('./EmptyPacket'); | ||
10 | +exports.EofPacket = require('./EofPacket'); | ||
11 | +exports.ErrorPacket = require('./ErrorPacket'); | ||
12 | +exports.Field = require('./Field'); | ||
13 | +exports.FieldPacket = require('./FieldPacket'); | ||
14 | +exports.HandshakeInitializationPacket = require('./HandshakeInitializationPacket'); | ||
15 | +exports.LocalDataFilePacket = require('./LocalDataFilePacket'); | ||
16 | +exports.LocalInfileRequestPacket = require('./LocalInfileRequestPacket'); | ||
17 | +exports.OkPacket = require('./OkPacket'); | ||
18 | +exports.OldPasswordPacket = require('./OldPasswordPacket'); | ||
19 | +exports.ResultSetHeaderPacket = require('./ResultSetHeaderPacket'); | ||
20 | +exports.RowDataPacket = require('./RowDataPacket'); | ||
21 | +exports.SSLRequestPacket = require('./SSLRequestPacket'); | ||
22 | +exports.StatisticsPacket = require('./StatisticsPacket'); | ||
23 | +exports.UseOldPasswordPacket = require('./UseOldPasswordPacket'); |
1 | +var Sequence = require('./Sequence'); | ||
2 | +var Util = require('util'); | ||
3 | +var Packets = require('../packets'); | ||
4 | +var Auth = require('../Auth'); | ||
5 | + | ||
6 | +module.exports = ChangeUser; | ||
7 | +Util.inherits(ChangeUser, Sequence); | ||
8 | +function ChangeUser(options, callback) { | ||
9 | + Sequence.call(this, options, callback); | ||
10 | + | ||
11 | + this._user = options.user; | ||
12 | + this._password = options.password; | ||
13 | + this._database = options.database; | ||
14 | + this._charsetNumber = options.charsetNumber; | ||
15 | + this._currentConfig = options.currentConfig; | ||
16 | +} | ||
17 | + | ||
18 | +ChangeUser.prototype.determinePacket = function determinePacket(firstByte) { | ||
19 | + switch (firstByte) { | ||
20 | + case 0xfe: return Packets.AuthSwitchRequestPacket; | ||
21 | + case 0xff: return Packets.ErrorPacket; | ||
22 | + default: return undefined; | ||
23 | + } | ||
24 | +}; | ||
25 | + | ||
26 | +ChangeUser.prototype.start = function(handshakeInitializationPacket) { | ||
27 | + var scrambleBuff = handshakeInitializationPacket.scrambleBuff(); | ||
28 | + scrambleBuff = Auth.token(this._password, scrambleBuff); | ||
29 | + | ||
30 | + var packet = new Packets.ComChangeUserPacket({ | ||
31 | + user : this._user, | ||
32 | + scrambleBuff : scrambleBuff, | ||
33 | + database : this._database, | ||
34 | + charsetNumber : this._charsetNumber | ||
35 | + }); | ||
36 | + | ||
37 | + this._currentConfig.user = this._user; | ||
38 | + this._currentConfig.password = this._password; | ||
39 | + this._currentConfig.database = this._database; | ||
40 | + this._currentConfig.charsetNumber = this._charsetNumber; | ||
41 | + | ||
42 | + this.emit('packet', packet); | ||
43 | +}; | ||
44 | + | ||
45 | +ChangeUser.prototype['AuthSwitchRequestPacket'] = function (packet) { | ||
46 | + var name = packet.authMethodName; | ||
47 | + var data = Auth.auth(name, packet.authMethodData, { | ||
48 | + password: this._password | ||
49 | + }); | ||
50 | + | ||
51 | + if (data !== undefined) { | ||
52 | + this.emit('packet', new Packets.AuthSwitchResponsePacket({ | ||
53 | + data: data | ||
54 | + })); | ||
55 | + } else { | ||
56 | + var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.'); | ||
57 | + err.code = 'UNSUPPORTED_AUTH_METHOD'; | ||
58 | + err.fatal = true; | ||
59 | + this.end(err); | ||
60 | + } | ||
61 | +}; | ||
62 | + | ||
63 | +ChangeUser.prototype['ErrorPacket'] = function(packet) { | ||
64 | + var err = this._packetToError(packet); | ||
65 | + err.fatal = true; | ||
66 | + this.end(err); | ||
67 | +}; |
1 | +var Sequence = require('./Sequence'); | ||
2 | +var Util = require('util'); | ||
3 | +var Packets = require('../packets'); | ||
4 | +var Auth = require('../Auth'); | ||
5 | +var ClientConstants = require('../constants/client'); | ||
6 | + | ||
7 | +module.exports = Handshake; | ||
8 | +Util.inherits(Handshake, Sequence); | ||
9 | +function Handshake(options, callback) { | ||
10 | + Sequence.call(this, options, callback); | ||
11 | + | ||
12 | + options = options || {}; | ||
13 | + | ||
14 | + this._config = options.config; | ||
15 | + this._handshakeInitializationPacket = null; | ||
16 | +} | ||
17 | + | ||
18 | +Handshake.prototype.determinePacket = function determinePacket(firstByte, parser) { | ||
19 | + if (firstByte === 0xff) { | ||
20 | + return Packets.ErrorPacket; | ||
21 | + } | ||
22 | + | ||
23 | + if (!this._handshakeInitializationPacket) { | ||
24 | + return Packets.HandshakeInitializationPacket; | ||
25 | + } | ||
26 | + | ||
27 | + if (firstByte === 0xfe) { | ||
28 | + return (parser.packetLength() === 1) | ||
29 | + ? Packets.UseOldPasswordPacket | ||
30 | + : Packets.AuthSwitchRequestPacket; | ||
31 | + } | ||
32 | + | ||
33 | + return undefined; | ||
34 | +}; | ||
35 | + | ||
36 | +Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) { | ||
37 | + var name = packet.authMethodName; | ||
38 | + var data = Auth.auth(name, packet.authMethodData, { | ||
39 | + password: this._config.password | ||
40 | + }); | ||
41 | + | ||
42 | + if (data !== undefined) { | ||
43 | + this.emit('packet', new Packets.AuthSwitchResponsePacket({ | ||
44 | + data: data | ||
45 | + })); | ||
46 | + } else { | ||
47 | + var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.'); | ||
48 | + err.code = 'UNSUPPORTED_AUTH_METHOD'; | ||
49 | + err.fatal = true; | ||
50 | + this.end(err); | ||
51 | + } | ||
52 | +}; | ||
53 | + | ||
54 | +Handshake.prototype['HandshakeInitializationPacket'] = function(packet) { | ||
55 | + this._handshakeInitializationPacket = packet; | ||
56 | + | ||
57 | + this._config.protocol41 = packet.protocol41; | ||
58 | + | ||
59 | + var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL; | ||
60 | + | ||
61 | + if (this._config.ssl) { | ||
62 | + if (!serverSSLSupport) { | ||
63 | + var err = new Error('Server does not support secure connection'); | ||
64 | + | ||
65 | + err.code = 'HANDSHAKE_NO_SSL_SUPPORT'; | ||
66 | + err.fatal = true; | ||
67 | + | ||
68 | + this.end(err); | ||
69 | + return; | ||
70 | + } | ||
71 | + | ||
72 | + this._config.clientFlags |= ClientConstants.CLIENT_SSL; | ||
73 | + this.emit('packet', new Packets.SSLRequestPacket({ | ||
74 | + clientFlags : this._config.clientFlags, | ||
75 | + maxPacketSize : this._config.maxPacketSize, | ||
76 | + charsetNumber : this._config.charsetNumber | ||
77 | + })); | ||
78 | + this.emit('start-tls'); | ||
79 | + } else { | ||
80 | + this._sendCredentials(); | ||
81 | + } | ||
82 | +}; | ||
83 | + | ||
84 | +Handshake.prototype._tlsUpgradeCompleteHandler = function() { | ||
85 | + this._sendCredentials(); | ||
86 | +}; | ||
87 | + | ||
88 | +Handshake.prototype._sendCredentials = function() { | ||
89 | + var packet = this._handshakeInitializationPacket; | ||
90 | + this.emit('packet', new Packets.ClientAuthenticationPacket({ | ||
91 | + clientFlags : this._config.clientFlags, | ||
92 | + maxPacketSize : this._config.maxPacketSize, | ||
93 | + charsetNumber : this._config.charsetNumber, | ||
94 | + user : this._config.user, | ||
95 | + database : this._config.database, | ||
96 | + protocol41 : packet.protocol41, | ||
97 | + scrambleBuff : (packet.protocol41) | ||
98 | + ? Auth.token(this._config.password, packet.scrambleBuff()) | ||
99 | + : Auth.scramble323(packet.scrambleBuff(), this._config.password) | ||
100 | + })); | ||
101 | +}; | ||
102 | + | ||
103 | +Handshake.prototype['UseOldPasswordPacket'] = function() { | ||
104 | + if (!this._config.insecureAuth) { | ||
105 | + var err = new Error( | ||
106 | + 'MySQL server is requesting the old and insecure pre-4.1 auth mechanism. ' + | ||
107 | + 'Upgrade the user password or use the {insecureAuth: true} option.' | ||
108 | + ); | ||
109 | + | ||
110 | + err.code = 'HANDSHAKE_INSECURE_AUTH'; | ||
111 | + err.fatal = true; | ||
112 | + | ||
113 | + this.end(err); | ||
114 | + return; | ||
115 | + } | ||
116 | + | ||
117 | + this.emit('packet', new Packets.OldPasswordPacket({ | ||
118 | + scrambleBuff: Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password) | ||
119 | + })); | ||
120 | +}; | ||
121 | + | ||
122 | +Handshake.prototype['ErrorPacket'] = function(packet) { | ||
123 | + var err = this._packetToError(packet, true); | ||
124 | + err.fatal = true; | ||
125 | + this.end(err); | ||
126 | +}; |
1 | +var Sequence = require('./Sequence'); | ||
2 | +var Util = require('util'); | ||
3 | +var Packets = require('../packets'); | ||
4 | + | ||
5 | +module.exports = Ping; | ||
6 | +Util.inherits(Ping, Sequence); | ||
7 | + | ||
8 | +function Ping(options, callback) { | ||
9 | + if (!callback && typeof options === 'function') { | ||
10 | + callback = options; | ||
11 | + options = {}; | ||
12 | + } | ||
13 | + | ||
14 | + Sequence.call(this, options, callback); | ||
15 | +} | ||
16 | + | ||
17 | +Ping.prototype.start = function() { | ||
18 | + this.emit('packet', new Packets.ComPingPacket()); | ||
19 | +}; |
1 | +var ClientConstants = require('../constants/client'); | ||
2 | +var fs = require('fs'); | ||
3 | +var Packets = require('../packets'); | ||
4 | +var ResultSet = require('../ResultSet'); | ||
5 | +var Sequence = require('./Sequence'); | ||
6 | +var ServerStatus = require('../constants/server_status'); | ||
7 | +var Readable = require('readable-stream'); | ||
8 | +var Util = require('util'); | ||
9 | + | ||
10 | +module.exports = Query; | ||
11 | +Util.inherits(Query, Sequence); | ||
12 | +function Query(options, callback) { | ||
13 | + Sequence.call(this, options, callback); | ||
14 | + | ||
15 | + this.sql = options.sql; | ||
16 | + this.values = options.values; | ||
17 | + this.typeCast = (options.typeCast === undefined) | ||
18 | + ? true | ||
19 | + : options.typeCast; | ||
20 | + this.nestTables = options.nestTables || false; | ||
21 | + | ||
22 | + this._resultSet = null; | ||
23 | + this._results = []; | ||
24 | + this._fields = []; | ||
25 | + this._index = 0; | ||
26 | + this._loadError = null; | ||
27 | +} | ||
28 | + | ||
29 | +Query.prototype.start = function() { | ||
30 | + this.emit('packet', new Packets.ComQueryPacket(this.sql)); | ||
31 | +}; | ||
32 | + | ||
33 | +Query.prototype.determinePacket = function determinePacket(byte, parser) { | ||
34 | + var resultSet = this._resultSet; | ||
35 | + | ||
36 | + if (!resultSet) { | ||
37 | + switch (byte) { | ||
38 | + case 0x00: return Packets.OkPacket; | ||
39 | + case 0xfb: return Packets.LocalInfileRequestPacket; | ||
40 | + case 0xff: return Packets.ErrorPacket; | ||
41 | + default: return Packets.ResultSetHeaderPacket; | ||
42 | + } | ||
43 | + } | ||
44 | + | ||
45 | + if (resultSet.eofPackets.length === 0) { | ||
46 | + return (resultSet.fieldPackets.length < resultSet.resultSetHeaderPacket.fieldCount) | ||
47 | + ? Packets.FieldPacket | ||
48 | + : Packets.EofPacket; | ||
49 | + } | ||
50 | + | ||
51 | + if (byte === 0xff) { | ||
52 | + return Packets.ErrorPacket; | ||
53 | + } | ||
54 | + | ||
55 | + if (byte === 0xfe && parser.packetLength() < 9) { | ||
56 | + return Packets.EofPacket; | ||
57 | + } | ||
58 | + | ||
59 | + return Packets.RowDataPacket; | ||
60 | +}; | ||
61 | + | ||
62 | +Query.prototype['OkPacket'] = function(packet) { | ||
63 | + // try...finally for exception safety | ||
64 | + try { | ||
65 | + if (!this._callback) { | ||
66 | + this.emit('result', packet, this._index); | ||
67 | + } else { | ||
68 | + this._results.push(packet); | ||
69 | + this._fields.push(undefined); | ||
70 | + } | ||
71 | + } finally { | ||
72 | + this._index++; | ||
73 | + this._resultSet = null; | ||
74 | + this._handleFinalResultPacket(packet); | ||
75 | + } | ||
76 | +}; | ||
77 | + | ||
78 | +Query.prototype['ErrorPacket'] = function(packet) { | ||
79 | + var err = this._packetToError(packet); | ||
80 | + | ||
81 | + var results = (this._results.length > 0) | ||
82 | + ? this._results | ||
83 | + : undefined; | ||
84 | + | ||
85 | + var fields = (this._fields.length > 0) | ||
86 | + ? this._fields | ||
87 | + : undefined; | ||
88 | + | ||
89 | + err.index = this._index; | ||
90 | + err.sql = this.sql; | ||
91 | + | ||
92 | + this.end(err, results, fields); | ||
93 | +}; | ||
94 | + | ||
95 | +Query.prototype['LocalInfileRequestPacket'] = function(packet) { | ||
96 | + if (this._connection.config.clientFlags & ClientConstants.CLIENT_LOCAL_FILES) { | ||
97 | + this._sendLocalDataFile(packet.filename); | ||
98 | + } else { | ||
99 | + this._loadError = new Error('Load local files command is disabled'); | ||
100 | + this._loadError.code = 'LOCAL_FILES_DISABLED'; | ||
101 | + this._loadError.fatal = false; | ||
102 | + | ||
103 | + this.emit('packet', new Packets.EmptyPacket()); | ||
104 | + } | ||
105 | +}; | ||
106 | + | ||
107 | +Query.prototype['ResultSetHeaderPacket'] = function(packet) { | ||
108 | + this._resultSet = new ResultSet(packet); | ||
109 | +}; | ||
110 | + | ||
111 | +Query.prototype['FieldPacket'] = function(packet) { | ||
112 | + this._resultSet.fieldPackets.push(packet); | ||
113 | +}; | ||
114 | + | ||
115 | +Query.prototype['EofPacket'] = function(packet) { | ||
116 | + this._resultSet.eofPackets.push(packet); | ||
117 | + | ||
118 | + if (this._resultSet.eofPackets.length === 1 && !this._callback) { | ||
119 | + this.emit('fields', this._resultSet.fieldPackets, this._index); | ||
120 | + } | ||
121 | + | ||
122 | + if (this._resultSet.eofPackets.length !== 2) { | ||
123 | + return; | ||
124 | + } | ||
125 | + | ||
126 | + if (this._callback) { | ||
127 | + this._results.push(this._resultSet.rows); | ||
128 | + this._fields.push(this._resultSet.fieldPackets); | ||
129 | + } | ||
130 | + | ||
131 | + this._index++; | ||
132 | + this._resultSet = null; | ||
133 | + this._handleFinalResultPacket(packet); | ||
134 | +}; | ||
135 | + | ||
136 | +Query.prototype._handleFinalResultPacket = function(packet) { | ||
137 | + if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) { | ||
138 | + return; | ||
139 | + } | ||
140 | + | ||
141 | + var results = (this._results.length > 1) | ||
142 | + ? this._results | ||
143 | + : this._results[0]; | ||
144 | + | ||
145 | + var fields = (this._fields.length > 1) | ||
146 | + ? this._fields | ||
147 | + : this._fields[0]; | ||
148 | + | ||
149 | + this.end(this._loadError, results, fields); | ||
150 | +}; | ||
151 | + | ||
152 | +Query.prototype['RowDataPacket'] = function(packet, parser, connection) { | ||
153 | + packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection); | ||
154 | + | ||
155 | + if (this._callback) { | ||
156 | + this._resultSet.rows.push(packet); | ||
157 | + } else { | ||
158 | + this.emit('result', packet, this._index); | ||
159 | + } | ||
160 | +}; | ||
161 | + | ||
162 | +Query.prototype._sendLocalDataFile = function(path) { | ||
163 | + var self = this; | ||
164 | + var localStream = fs.createReadStream(path, { | ||
165 | + flag : 'r', | ||
166 | + encoding : null, | ||
167 | + autoClose : true | ||
168 | + }); | ||
169 | + | ||
170 | + this.on('pause', function () { | ||
171 | + localStream.pause(); | ||
172 | + }); | ||
173 | + | ||
174 | + this.on('resume', function () { | ||
175 | + localStream.resume(); | ||
176 | + }); | ||
177 | + | ||
178 | + localStream.on('data', function (data) { | ||
179 | + self.emit('packet', new Packets.LocalDataFilePacket(data)); | ||
180 | + }); | ||
181 | + | ||
182 | + localStream.on('error', function (err) { | ||
183 | + self._loadError = err; | ||
184 | + localStream.emit('end'); | ||
185 | + }); | ||
186 | + | ||
187 | + localStream.on('end', function () { | ||
188 | + self.emit('packet', new Packets.EmptyPacket()); | ||
189 | + }); | ||
190 | +}; | ||
191 | + | ||
192 | +Query.prototype.stream = function(options) { | ||
193 | + var self = this; | ||
194 | + | ||
195 | + options = options || {}; | ||
196 | + options.objectMode = true; | ||
197 | + | ||
198 | + var stream = new Readable(options); | ||
199 | + | ||
200 | + stream._read = function() { | ||
201 | + self._connection && self._connection.resume(); | ||
202 | + }; | ||
203 | + | ||
204 | + stream.once('end', function() { | ||
205 | + process.nextTick(function () { | ||
206 | + stream.emit('close'); | ||
207 | + }); | ||
208 | + }); | ||
209 | + | ||
210 | + this.on('result', function(row, i) { | ||
211 | + if (!stream.push(row)) self._connection.pause(); | ||
212 | + stream.emit('result', row, i); // replicate old emitter | ||
213 | + }); | ||
214 | + | ||
215 | + this.on('error', function(err) { | ||
216 | + stream.emit('error', err); // Pass on any errors | ||
217 | + }); | ||
218 | + | ||
219 | + this.on('end', function() { | ||
220 | + stream.push(null); // pushing null, indicating EOF | ||
221 | + }); | ||
222 | + | ||
223 | + this.on('fields', function(fields, i) { | ||
224 | + stream.emit('fields', fields, i); // replicate old emitter | ||
225 | + }); | ||
226 | + | ||
227 | + return stream; | ||
228 | +}; |
1 | +var Sequence = require('./Sequence'); | ||
2 | +var Util = require('util'); | ||
3 | +var Packets = require('../packets'); | ||
4 | + | ||
5 | +module.exports = Quit; | ||
6 | +Util.inherits(Quit, Sequence); | ||
7 | +function Quit(options, callback) { | ||
8 | + if (!callback && typeof options === 'function') { | ||
9 | + callback = options; | ||
10 | + options = {}; | ||
11 | + } | ||
12 | + | ||
13 | + Sequence.call(this, options, callback); | ||
14 | + | ||
15 | + this._started = false; | ||
16 | +} | ||
17 | + | ||
18 | +Quit.prototype.end = function end(err) { | ||
19 | + if (this._ended) { | ||
20 | + return; | ||
21 | + } | ||
22 | + | ||
23 | + if (!this._started) { | ||
24 | + Sequence.prototype.end.call(this, err); | ||
25 | + return; | ||
26 | + } | ||
27 | + | ||
28 | + if (err && err.code === 'ECONNRESET' && err.syscall === 'read') { | ||
29 | + // Ignore read errors after packet sent | ||
30 | + Sequence.prototype.end.call(this); | ||
31 | + return; | ||
32 | + } | ||
33 | + | ||
34 | + Sequence.prototype.end.call(this, err); | ||
35 | +}; | ||
36 | + | ||
37 | +Quit.prototype.start = function() { | ||
38 | + this._started = true; | ||
39 | + this.emit('packet', new Packets.ComQuitPacket()); | ||
40 | +}; |
1 | +var Util = require('util'); | ||
2 | +var EventEmitter = require('events').EventEmitter; | ||
3 | +var Packets = require('../packets'); | ||
4 | +var ErrorConstants = require('../constants/errors'); | ||
5 | +var Timer = require('../Timer'); | ||
6 | + | ||
7 | +// istanbul ignore next: Node.js < 0.10 not covered | ||
8 | +var listenerCount = EventEmitter.listenerCount | ||
9 | + || function(emitter, type){ return emitter.listeners(type).length; }; | ||
10 | + | ||
11 | +var LONG_STACK_DELIMITER = '\n --------------------\n'; | ||
12 | + | ||
13 | +module.exports = Sequence; | ||
14 | +Util.inherits(Sequence, EventEmitter); | ||
15 | +function Sequence(options, callback) { | ||
16 | + if (typeof options === 'function') { | ||
17 | + callback = options; | ||
18 | + options = {}; | ||
19 | + } | ||
20 | + | ||
21 | + EventEmitter.call(this); | ||
22 | + | ||
23 | + options = options || {}; | ||
24 | + | ||
25 | + this._callback = callback; | ||
26 | + this._callSite = null; | ||
27 | + this._ended = false; | ||
28 | + this._timeout = options.timeout; | ||
29 | + this._timer = new Timer(this); | ||
30 | +} | ||
31 | + | ||
32 | +Sequence.determinePacket = function(byte) { | ||
33 | + switch (byte) { | ||
34 | + case 0x00: return Packets.OkPacket; | ||
35 | + case 0xfe: return Packets.EofPacket; | ||
36 | + case 0xff: return Packets.ErrorPacket; | ||
37 | + default: return undefined; | ||
38 | + } | ||
39 | +}; | ||
40 | + | ||
41 | +Sequence.prototype.hasErrorHandler = function() { | ||
42 | + return Boolean(this._callback) || listenerCount(this, 'error') > 1; | ||
43 | +}; | ||
44 | + | ||
45 | +Sequence.prototype._packetToError = function(packet) { | ||
46 | + var code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT'; | ||
47 | + var err = new Error(code + ': ' + packet.message); | ||
48 | + err.code = code; | ||
49 | + err.errno = packet.errno; | ||
50 | + | ||
51 | + err.sqlMessage = packet.message; | ||
52 | + err.sqlState = packet.sqlState; | ||
53 | + | ||
54 | + return err; | ||
55 | +}; | ||
56 | + | ||
57 | +Sequence.prototype.end = function(err) { | ||
58 | + if (this._ended) { | ||
59 | + return; | ||
60 | + } | ||
61 | + | ||
62 | + this._ended = true; | ||
63 | + | ||
64 | + if (err) { | ||
65 | + this._addLongStackTrace(err); | ||
66 | + } | ||
67 | + | ||
68 | + // Without this we are leaking memory. This problem was introduced in | ||
69 | + // 8189925374e7ce3819bbe88b64c7b15abac96b16. I suspect that the error object | ||
70 | + // causes a cyclic reference that the GC does not detect properly, but I was | ||
71 | + // unable to produce a standalone version of this leak. This would be a great | ||
72 | + // challenge for somebody interested in difficult problems : )! | ||
73 | + this._callSite = null; | ||
74 | + | ||
75 | + // try...finally for exception safety | ||
76 | + try { | ||
77 | + if (err) { | ||
78 | + this.emit('error', err); | ||
79 | + } | ||
80 | + } finally { | ||
81 | + try { | ||
82 | + if (this._callback) { | ||
83 | + this._callback.apply(this, arguments); | ||
84 | + } | ||
85 | + } finally { | ||
86 | + this.emit('end'); | ||
87 | + } | ||
88 | + } | ||
89 | +}; | ||
90 | + | ||
91 | +Sequence.prototype['OkPacket'] = function(packet) { | ||
92 | + this.end(null, packet); | ||
93 | +}; | ||
94 | + | ||
95 | +Sequence.prototype['ErrorPacket'] = function(packet) { | ||
96 | + this.end(this._packetToError(packet)); | ||
97 | +}; | ||
98 | + | ||
99 | +// Implemented by child classes | ||
100 | +Sequence.prototype.start = function() {}; | ||
101 | + | ||
102 | +Sequence.prototype._addLongStackTrace = function _addLongStackTrace(err) { | ||
103 | + var callSiteStack = this._callSite && this._callSite.stack; | ||
104 | + | ||
105 | + if (!callSiteStack || typeof callSiteStack !== 'string') { | ||
106 | + // No recorded call site | ||
107 | + return; | ||
108 | + } | ||
109 | + | ||
110 | + if (err.stack.indexOf(LONG_STACK_DELIMITER) !== -1) { | ||
111 | + // Error stack already looks long | ||
112 | + return; | ||
113 | + } | ||
114 | + | ||
115 | + var index = callSiteStack.indexOf('\n'); | ||
116 | + | ||
117 | + if (index !== -1) { | ||
118 | + // Append recorded call site | ||
119 | + err.stack += LONG_STACK_DELIMITER + callSiteStack.substr(index + 1); | ||
120 | + } | ||
121 | +}; | ||
122 | + | ||
123 | +Sequence.prototype._onTimeout = function _onTimeout() { | ||
124 | + this.emit('timeout'); | ||
125 | +}; |
1 | +var Sequence = require('./Sequence'); | ||
2 | +var Util = require('util'); | ||
3 | +var Packets = require('../packets'); | ||
4 | + | ||
5 | +module.exports = Statistics; | ||
6 | +Util.inherits(Statistics, Sequence); | ||
7 | +function Statistics(options, callback) { | ||
8 | + if (!callback && typeof options === 'function') { | ||
9 | + callback = options; | ||
10 | + options = {}; | ||
11 | + } | ||
12 | + | ||
13 | + Sequence.call(this, options, callback); | ||
14 | +} | ||
15 | + | ||
16 | +Statistics.prototype.start = function() { | ||
17 | + this.emit('packet', new Packets.ComStatisticsPacket()); | ||
18 | +}; | ||
19 | + | ||
20 | +Statistics.prototype['StatisticsPacket'] = function (packet) { | ||
21 | + this.end(null, packet); | ||
22 | +}; | ||
23 | + | ||
24 | +Statistics.prototype.determinePacket = function determinePacket(firstByte) { | ||
25 | + if (firstByte === 0x55) { | ||
26 | + return Packets.StatisticsPacket; | ||
27 | + } | ||
28 | + | ||
29 | + return undefined; | ||
30 | +}; |
1 | +exports.ChangeUser = require('./ChangeUser'); | ||
2 | +exports.Handshake = require('./Handshake'); | ||
3 | +exports.Ping = require('./Ping'); | ||
4 | +exports.Query = require('./Query'); | ||
5 | +exports.Quit = require('./Quit'); | ||
6 | +exports.Sequence = require('./Sequence'); | ||
7 | +exports.Statistics = require('./Statistics'); |
backend/node_modules/mysql/package.json
0 → 100644
1 | +{ | ||
2 | + "_from": "mysql", | ||
3 | + "_id": "mysql@2.18.1", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", | ||
6 | + "_location": "/mysql", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "tag", | ||
10 | + "registry": true, | ||
11 | + "raw": "mysql", | ||
12 | + "name": "mysql", | ||
13 | + "escapedName": "mysql", | ||
14 | + "rawSpec": "", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "latest" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "#USER", | ||
20 | + "/" | ||
21 | + ], | ||
22 | + "_resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", | ||
23 | + "_shasum": "2254143855c5a8c73825e4522baf2ea021766717", | ||
24 | + "_spec": "mysql", | ||
25 | + "_where": "C:\\Users\\worro\\OneDrive\\Desktop\\openSourceSoftware\\backend", | ||
26 | + "author": { | ||
27 | + "name": "Felix Geisendörfer", | ||
28 | + "email": "felix@debuggable.com", | ||
29 | + "url": "http://debuggable.com/" | ||
30 | + }, | ||
31 | + "bugs": { | ||
32 | + "url": "https://github.com/mysqljs/mysql/issues" | ||
33 | + }, | ||
34 | + "bundleDependencies": false, | ||
35 | + "contributors": [ | ||
36 | + { | ||
37 | + "name": "Andrey Sidorov", | ||
38 | + "email": "sidorares@yandex.ru" | ||
39 | + }, | ||
40 | + { | ||
41 | + "name": "Bradley Grainger", | ||
42 | + "email": "bgrainger@gmail.com" | ||
43 | + }, | ||
44 | + { | ||
45 | + "name": "Douglas Christopher Wilson", | ||
46 | + "email": "doug@somethingdoug.com" | ||
47 | + }, | ||
48 | + { | ||
49 | + "name": "Diogo Resende", | ||
50 | + "email": "dresende@thinkdigital.pt" | ||
51 | + }, | ||
52 | + { | ||
53 | + "name": "Nathan Woltman", | ||
54 | + "email": "nwoltman@outlook.com" | ||
55 | + } | ||
56 | + ], | ||
57 | + "dependencies": { | ||
58 | + "bignumber.js": "9.0.0", | ||
59 | + "readable-stream": "2.3.7", | ||
60 | + "safe-buffer": "5.1.2", | ||
61 | + "sqlstring": "2.3.1" | ||
62 | + }, | ||
63 | + "deprecated": false, | ||
64 | + "description": "A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.", | ||
65 | + "devDependencies": { | ||
66 | + "after": "0.8.2", | ||
67 | + "eslint": "5.16.0", | ||
68 | + "seedrandom": "3.0.5", | ||
69 | + "timezone-mock": "0.0.7", | ||
70 | + "urun": "0.0.8", | ||
71 | + "utest": "0.0.8" | ||
72 | + }, | ||
73 | + "engines": { | ||
74 | + "node": ">= 0.6" | ||
75 | + }, | ||
76 | + "files": [ | ||
77 | + "lib/", | ||
78 | + "Changes.md", | ||
79 | + "License", | ||
80 | + "Readme.md", | ||
81 | + "index.js" | ||
82 | + ], | ||
83 | + "homepage": "https://github.com/mysqljs/mysql#readme", | ||
84 | + "license": "MIT", | ||
85 | + "name": "mysql", | ||
86 | + "repository": { | ||
87 | + "type": "git", | ||
88 | + "url": "git+https://github.com/mysqljs/mysql.git" | ||
89 | + }, | ||
90 | + "scripts": { | ||
91 | + "lint": "eslint . && node tool/lint-readme.js", | ||
92 | + "test": "node test/run.js", | ||
93 | + "test-ci": "node tool/install-nyc.js --nyc-optional --reporter=text -- npm test", | ||
94 | + "test-cov": "node tool/install-nyc.js --reporter=html --reporter=text -- npm test", | ||
95 | + "version": "node tool/version-changes.js && git add Changes.md" | ||
96 | + }, | ||
97 | + "version": "2.18.1" | ||
98 | +} |
1 | +'use strict'; | ||
2 | + | ||
3 | +if (typeof process === 'undefined' || | ||
4 | + !process.version || | ||
5 | + process.version.indexOf('v0.') === 0 || | ||
6 | + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { | ||
7 | + module.exports = { nextTick: nextTick }; | ||
8 | +} else { | ||
9 | + module.exports = process | ||
10 | +} | ||
11 | + | ||
12 | +function nextTick(fn, arg1, arg2, arg3) { | ||
13 | + if (typeof fn !== 'function') { | ||
14 | + throw new TypeError('"callback" argument must be a function'); | ||
15 | + } | ||
16 | + var len = arguments.length; | ||
17 | + var args, i; | ||
18 | + switch (len) { | ||
19 | + case 0: | ||
20 | + case 1: | ||
21 | + return process.nextTick(fn); | ||
22 | + case 2: | ||
23 | + return process.nextTick(function afterTickOne() { | ||
24 | + fn.call(null, arg1); | ||
25 | + }); | ||
26 | + case 3: | ||
27 | + return process.nextTick(function afterTickTwo() { | ||
28 | + fn.call(null, arg1, arg2); | ||
29 | + }); | ||
30 | + case 4: | ||
31 | + return process.nextTick(function afterTickThree() { | ||
32 | + fn.call(null, arg1, arg2, arg3); | ||
33 | + }); | ||
34 | + default: | ||
35 | + args = new Array(len - 1); | ||
36 | + i = 0; | ||
37 | + while (i < args.length) { | ||
38 | + args[i++] = arguments[i]; | ||
39 | + } | ||
40 | + return process.nextTick(function afterTick() { | ||
41 | + fn.apply(null, args); | ||
42 | + }); | ||
43 | + } | ||
44 | +} | ||
45 | + |
1 | +# Copyright (c) 2015 Calvin Metcalf | ||
2 | + | ||
3 | +Permission is hereby granted, free of charge, to any person obtaining a copy | ||
4 | +of this software and associated documentation files (the "Software"), to deal | ||
5 | +in the Software without restriction, including without limitation the rights | ||
6 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
7 | +copies of the Software, and to permit persons to whom the Software is | ||
8 | +furnished to do so, subject to the following conditions: | ||
9 | + | ||
10 | +The above copyright notice and this permission notice shall be included in all | ||
11 | +copies or substantial portions of the Software. | ||
12 | + | ||
13 | +**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
16 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
17 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
18 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
19 | +SOFTWARE.** |
1 | +{ | ||
2 | + "_from": "process-nextick-args@~2.0.0", | ||
3 | + "_id": "process-nextick-args@2.0.1", | ||
4 | + "_inBundle": false, | ||
5 | + "_integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", | ||
6 | + "_location": "/process-nextick-args", | ||
7 | + "_phantomChildren": {}, | ||
8 | + "_requested": { | ||
9 | + "type": "range", | ||
10 | + "registry": true, | ||
11 | + "raw": "process-nextick-args@~2.0.0", | ||
12 | + "name": "process-nextick-args", | ||
13 | + "escapedName": "process-nextick-args", | ||
14 | + "rawSpec": "~2.0.0", | ||
15 | + "saveSpec": null, | ||
16 | + "fetchSpec": "~2.0.0" | ||
17 | + }, | ||
18 | + "_requiredBy": [ | ||
19 | + "/readable-stream" | ||
20 | + ], | ||
21 | + "_resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", | ||
22 | + "_shasum": "7820d9b16120cc55ca9ae7792680ae7dba6d7fe2", | ||
23 | + "_spec": "process-nextick-args@~2.0.0", | ||
24 | + "_where": "C:\\Users\\worro\\OneDrive\\Desktop\\openSourceSoftware\\backend\\node_modules\\readable-stream", | ||
25 | + "author": "", | ||
26 | + "bugs": { | ||
27 | + "url": "https://github.com/calvinmetcalf/process-nextick-args/issues" | ||
28 | + }, | ||
29 | + "bundleDependencies": false, | ||
30 | + "deprecated": false, | ||
31 | + "description": "process.nextTick but always with args", | ||
32 | + "devDependencies": { | ||
33 | + "tap": "~0.2.6" | ||
34 | + }, | ||
35 | + "files": [ | ||
36 | + "index.js" | ||
37 | + ], | ||
38 | + "homepage": "https://github.com/calvinmetcalf/process-nextick-args", | ||
39 | + "license": "MIT", | ||
40 | + "main": "index.js", | ||
41 | + "name": "process-nextick-args", | ||
42 | + "repository": { | ||
43 | + "type": "git", | ||
44 | + "url": "git+https://github.com/calvinmetcalf/process-nextick-args.git" | ||
45 | + }, | ||
46 | + "scripts": { | ||
47 | + "test": "node test.js" | ||
48 | + }, | ||
49 | + "version": "2.0.1" | ||
50 | +} |
1 | +process-nextick-args | ||
2 | +===== | ||
3 | + | ||
4 | +[![Build Status](https://travis-ci.org/calvinmetcalf/process-nextick-args.svg?branch=master)](https://travis-ci.org/calvinmetcalf/process-nextick-args) | ||
5 | + | ||
6 | +```bash | ||
7 | +npm install --save process-nextick-args | ||
8 | +``` | ||
9 | + | ||
10 | +Always be able to pass arguments to process.nextTick, no matter the platform | ||
11 | + | ||
12 | +```js | ||
13 | +var pna = require('process-nextick-args'); | ||
14 | + | ||
15 | +pna.nextTick(function (a, b, c) { | ||
16 | + console.log(a, b, c); | ||
17 | +}, 'step', 3, 'profit'); | ||
18 | +``` |
1 | +sudo: false | ||
2 | +language: node_js | ||
3 | +before_install: | ||
4 | + - (test $NPM_LEGACY && npm install -g npm@2 && npm install -g npm@3) || true | ||
5 | +notifications: | ||
6 | + email: false | ||
7 | +matrix: | ||
8 | + fast_finish: true | ||
9 | + include: | ||
10 | + - node_js: '0.8' | ||
11 | + env: NPM_LEGACY=true | ||
12 | + - node_js: '0.10' | ||
13 | + env: NPM_LEGACY=true | ||
14 | + - node_js: '0.11' | ||
15 | + env: NPM_LEGACY=true | ||
16 | + - node_js: '0.12' | ||
17 | + env: NPM_LEGACY=true | ||
18 | + - node_js: 1 | ||
19 | + env: NPM_LEGACY=true | ||
20 | + - node_js: 2 | ||
21 | + env: NPM_LEGACY=true | ||
22 | + - node_js: 3 | ||
23 | + env: NPM_LEGACY=true | ||
24 | + - node_js: 4 | ||
25 | + - node_js: 5 | ||
26 | + - node_js: 6 | ||
27 | + - node_js: 7 | ||
28 | + - node_js: 8 | ||
29 | + - node_js: 9 | ||
30 | +script: "npm run test" | ||
31 | +env: | ||
32 | + global: | ||
33 | + - secure: rE2Vvo7vnjabYNULNyLFxOyt98BoJexDqsiOnfiD6kLYYsiQGfr/sbZkPMOFm9qfQG7pjqx+zZWZjGSswhTt+626C0t/njXqug7Yps4c3dFblzGfreQHp7wNX5TFsvrxd6dAowVasMp61sJcRnB2w8cUzoe3RAYUDHyiHktwqMc= | ||
34 | + - secure: g9YINaKAdMatsJ28G9jCGbSaguXCyxSTy+pBO6Ch0Cf57ZLOTka3HqDj8p3nV28LUIHZ3ut5WO43CeYKwt4AUtLpBS3a0dndHdY6D83uY6b2qh5hXlrcbeQTq2cvw2y95F7hm4D1kwrgZ7ViqaKggRcEupAL69YbJnxeUDKWEdI= |
1 | +# Developer's Certificate of Origin 1.1 | ||
2 | + | ||
3 | +By making a contribution to this project, I certify that: | ||
4 | + | ||
5 | +* (a) The contribution was created in whole or in part by me and I | ||
6 | + have the right to submit it under the open source license | ||
7 | + indicated in the file; or | ||
8 | + | ||
9 | +* (b) The contribution is based upon previous work that, to the best | ||
10 | + of my knowledge, is covered under an appropriate open source | ||
11 | + license and I have the right under that license to submit that | ||
12 | + work with modifications, whether created in whole or in part | ||
13 | + by me, under the same open source license (unless I am | ||
14 | + permitted to submit under a different license), as indicated | ||
15 | + in the file; or | ||
16 | + | ||
17 | +* (c) The contribution was provided directly to me by some other | ||
18 | + person who certified (a), (b) or (c) and I have not modified | ||
19 | + it. | ||
20 | + | ||
21 | +* (d) I understand and agree that this project and the contribution | ||
22 | + are public and that a record of the contribution (including all | ||
23 | + personal information I submit with it, including my sign-off) is | ||
24 | + maintained indefinitely and may be redistributed consistent with | ||
25 | + this project or the open source license(s) involved. | ||
26 | + | ||
27 | +## Moderation Policy | ||
28 | + | ||
29 | +The [Node.js Moderation Policy] applies to this WG. | ||
30 | + | ||
31 | +## Code of Conduct | ||
32 | + | ||
33 | +The [Node.js Code of Conduct][] applies to this WG. | ||
34 | + | ||
35 | +[Node.js Code of Conduct]: | ||
36 | +https://github.com/nodejs/node/blob/master/CODE_OF_CONDUCT.md | ||
37 | +[Node.js Moderation Policy]: | ||
38 | +https://github.com/nodejs/TSC/blob/master/Moderation-Policy.md |
1 | +### Streams Working Group | ||
2 | + | ||
3 | +The Node.js Streams is jointly governed by a Working Group | ||
4 | +(WG) | ||
5 | +that is responsible for high-level guidance of the project. | ||
6 | + | ||
7 | +The WG has final authority over this project including: | ||
8 | + | ||
9 | +* Technical direction | ||
10 | +* Project governance and process (including this policy) | ||
11 | +* Contribution policy | ||
12 | +* GitHub repository hosting | ||
13 | +* Conduct guidelines | ||
14 | +* Maintaining the list of additional Collaborators | ||
15 | + | ||
16 | +For the current list of WG members, see the project | ||
17 | +[README.md](./README.md#current-project-team-members). | ||
18 | + | ||
19 | +### Collaborators | ||
20 | + | ||
21 | +The readable-stream GitHub repository is | ||
22 | +maintained by the WG and additional Collaborators who are added by the | ||
23 | +WG on an ongoing basis. | ||
24 | + | ||
25 | +Individuals making significant and valuable contributions are made | ||
26 | +Collaborators and given commit-access to the project. These | ||
27 | +individuals are identified by the WG and their addition as | ||
28 | +Collaborators is discussed during the WG meeting. | ||
29 | + | ||
30 | +_Note:_ If you make a significant contribution and are not considered | ||
31 | +for commit-access log an issue or contact a WG member directly and it | ||
32 | +will be brought up in the next WG meeting. | ||
33 | + | ||
34 | +Modifications of the contents of the readable-stream repository are | ||
35 | +made on | ||
36 | +a collaborative basis. Anybody with a GitHub account may propose a | ||
37 | +modification via pull request and it will be considered by the project | ||
38 | +Collaborators. All pull requests must be reviewed and accepted by a | ||
39 | +Collaborator with sufficient expertise who is able to take full | ||
40 | +responsibility for the change. In the case of pull requests proposed | ||
41 | +by an existing Collaborator, an additional Collaborator is required | ||
42 | +for sign-off. Consensus should be sought if additional Collaborators | ||
43 | +participate and there is disagreement around a particular | ||
44 | +modification. See _Consensus Seeking Process_ below for further detail | ||
45 | +on the consensus model used for governance. | ||
46 | + | ||
47 | +Collaborators may opt to elevate significant or controversial | ||
48 | +modifications, or modifications that have not found consensus to the | ||
49 | +WG for discussion by assigning the ***WG-agenda*** tag to a pull | ||
50 | +request or issue. The WG should serve as the final arbiter where | ||
51 | +required. | ||
52 | + | ||
53 | +For the current list of Collaborators, see the project | ||
54 | +[README.md](./README.md#members). | ||
55 | + | ||
56 | +### WG Membership | ||
57 | + | ||
58 | +WG seats are not time-limited. There is no fixed size of the WG. | ||
59 | +However, the expected target is between 6 and 12, to ensure adequate | ||
60 | +coverage of important areas of expertise, balanced with the ability to | ||
61 | +make decisions efficiently. | ||
62 | + | ||
63 | +There is no specific set of requirements or qualifications for WG | ||
64 | +membership beyond these rules. | ||
65 | + | ||
66 | +The WG may add additional members to the WG by unanimous consensus. | ||
67 | + | ||
68 | +A WG member may be removed from the WG by voluntary resignation, or by | ||
69 | +unanimous consensus of all other WG members. | ||
70 | + | ||
71 | +Changes to WG membership should be posted in the agenda, and may be | ||
72 | +suggested as any other agenda item (see "WG Meetings" below). | ||
73 | + | ||
74 | +If an addition or removal is proposed during a meeting, and the full | ||
75 | +WG is not in attendance to participate, then the addition or removal | ||
76 | +is added to the agenda for the subsequent meeting. This is to ensure | ||
77 | +that all members are given the opportunity to participate in all | ||
78 | +membership decisions. If a WG member is unable to attend a meeting | ||
79 | +where a planned membership decision is being made, then their consent | ||
80 | +is assumed. | ||
81 | + | ||
82 | +No more than 1/3 of the WG members may be affiliated with the same | ||
83 | +employer. If removal or resignation of a WG member, or a change of | ||
84 | +employment by a WG member, creates a situation where more than 1/3 of | ||
85 | +the WG membership shares an employer, then the situation must be | ||
86 | +immediately remedied by the resignation or removal of one or more WG | ||
87 | +members affiliated with the over-represented employer(s). | ||
88 | + | ||
89 | +### WG Meetings | ||
90 | + | ||
91 | +The WG meets occasionally on a Google Hangout On Air. A designated moderator | ||
92 | +approved by the WG runs the meeting. Each meeting should be | ||
93 | +published to YouTube. | ||
94 | + | ||
95 | +Items are added to the WG agenda that are considered contentious or | ||
96 | +are modifications of governance, contribution policy, WG membership, | ||
97 | +or release process. | ||
98 | + | ||
99 | +The intention of the agenda is not to approve or review all patches; | ||
100 | +that should happen continuously on GitHub and be handled by the larger | ||
101 | +group of Collaborators. | ||
102 | + | ||
103 | +Any community member or contributor can ask that something be added to | ||
104 | +the next meeting's agenda by logging a GitHub Issue. Any Collaborator, | ||
105 | +WG member or the moderator can add the item to the agenda by adding | ||
106 | +the ***WG-agenda*** tag to the issue. | ||
107 | + | ||
108 | +Prior to each WG meeting the moderator will share the Agenda with | ||
109 | +members of the WG. WG members can add any items they like to the | ||
110 | +agenda at the beginning of each meeting. The moderator and the WG | ||
111 | +cannot veto or remove items. | ||
112 | + | ||
113 | +The WG may invite persons or representatives from certain projects to | ||
114 | +participate in a non-voting capacity. | ||
115 | + | ||
116 | +The moderator is responsible for summarizing the discussion of each | ||
117 | +agenda item and sends it as a pull request after the meeting. | ||
118 | + | ||
119 | +### Consensus Seeking Process | ||
120 | + | ||
121 | +The WG follows a | ||
122 | +[Consensus | ||
123 | +Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making) | ||
124 | +decision-making model. | ||
125 | + | ||
126 | +When an agenda item has appeared to reach a consensus the moderator | ||
127 | +will ask "Does anyone object?" as a final call for dissent from the | ||
128 | +consensus. | ||
129 | + | ||
130 | +If an agenda item cannot reach a consensus a WG member can call for | ||
131 | +either a closing vote or a vote to table the issue to the next | ||
132 | +meeting. The call for a vote must be seconded by a majority of the WG | ||
133 | +or else the discussion will continue. Simple majority wins. | ||
134 | + | ||
135 | +Note that changes to WG membership require a majority consensus. See | ||
136 | +"WG Membership" above. |
backend/node_modules/readable-stream/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/node_modules/sqlstring/HISTORY.md
0 → 100644
This diff is collapsed. Click to expand it.
backend/node_modules/sqlstring/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
backend/node_modules/sqlstring/README.md
0 → 100644
This diff is collapsed. Click to expand it.
backend/node_modules/sqlstring/index.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/node_modules/sqlstring/package.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/node_modules/string_decoder/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/node_modules/util-deprecate/LICENSE
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/node_modules/util-deprecate/node.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
backend/routes/api/fetchNoticeList.js
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment