diff --git a/node_modules/mysql/.npmignore b/node_modules/mysql/.npmignore new file mode 100644 index 0000000..14aea2a --- /dev/null +++ b/node_modules/mysql/.npmignore @@ -0,0 +1,6 @@ +benchmark/ +coverage/ +lib-cov/ +test/ +tool/ +.travis.yml diff --git a/node_modules/mysql/Changes.md b/node_modules/mysql/Changes.md new file mode 100644 index 0000000..0a07058 --- /dev/null +++ b/node_modules/mysql/Changes.md @@ -0,0 +1,360 @@ +# Changes + +This file is a manually maintained list of changes for each release. Feel free +to add your changes here when sending pull requests. Also send corrections if +you spot any mistakes. + +## v2.5.2 (2014-10-10) + +* Fix receiving large text fields #922 + +## v2.5.1 (2014-09-22) + +* Fix `pool.end` race conditions #915 +* Fix `pool.getConnection` race conditions + +## v2.5.0 (2014-09-07) + +* Add code `POOL_ENQUEUELIMIT` to error reaching `queueLimit` +* Add `enqueue` event to pool #716 +* Add `enqueue` event to protocol and connection #381 +* Blacklist unsupported connection flags #881 +* Make only column names enumerable in `RowDataPacket` #549 #895 +* Support Node.js 0.6 #718 + +## v2.4.3 (2014-08-25) + +* Fix `pool.query` to use `typeCast` configuration + +## v2.4.2 (2014-08-03) + +* Fix incorrect sequence packet errors to be catchable #867 +* Fix stray protocol packet errors to be catchable #867 +* Fix timing of fatal protocol errors bubbling to user #879 + +## v2.4.1 (2014-07-17) + +* Fix `pool.query` not invoking callback on connection error #872 + +## v2.4.0 (2014-07-13) + +* Add code `POOL_NOEXIST` in PoolCluster error #846 +* Add `acquireTimeout` pool option to specify a timeout for acquiring a connection #821 #854 +* Add `connection.escapeId` +* Add `pool.escapeId` +* Add `timeout` option to all sequences #855 #863 +* Default `connectTimeout` to 10 seconds +* Fix domain binding with `conn.connect` +* Fix `packet.default` to actually be a string +* Fix `PARSER_*` errors to be catchable +* Fix `PROTOCOL_PACKETS_OUT_OF_ORDER` error to be catchable #844 +* Include packets that failed parsing under `debug` +* Return `Query` object from `pool.query` like `conn.query` #830 +* Use `EventEmitter.listenerCount` when possible for faster counting + +## v2.3.2 (2014-05-29) + +* Fix pool leaking connections after `conn.changeUser` #833 + +## v2.3.1 (2014-05-26) + +* Add database errors to error constants +* Add global errors to error constants +* Throw when calling `conn.release` multiple times #824 #827 +* Update known error codes + +## v2.3.0 (2014-05-16) + +* Accept MySQL charset (like `UTF8` or `UTF8MB4`) in `charset` option #808 +* Accept pool options in connection string to `mysql.createPool` #811 +* Clone connection config for new pool connections +* Default `connectTimeout` to 2 minutes +* Reject unauthorized SSL connections (use `ssl.rejectUnauthorized` to override) #816 +* Return last error when PoolCluster exhausts connection retries #818 +* Remove connection from pool after `conn.changeUser` is released #806 +* Throw on unknown SSL profile name #817 +* User newer TLS functions when available #809 + +## v2.2.0 (2014-04-27) + +* Use indexOf instead of for loops removing conn from pool #611 +* Make callback to `pool.query` optional like `conn.query` #585 +* Prevent enqueuing sequences after fatal error #400 +* Fix geometry parser for empty fields #742 +* Accept lower-case charset option +* Throw on unknown charset option #789 +* Update known charsets +* Remove console.warn from PoolCluster #744 +* Fix `pool.end` to handle queued connections #797 +* Fix `pool.releaseConnection` to keep connection queue flowing #797 +* Fix SSL handshake error to be catchable #800 +* Add `connection.threadId` to get MySQL connection ID #602 +* Ensure `pool.getConnection` retrieves good connections #434 #557 #778 +* Fix pool cluster wildcard matching #627 +* Pass query values through to `SqlString.format` #590 + +## v2.1.1 (2014-03-13) + +* fix authentication w/password failure for node.js 0.10.5 #746 #752 +* fix authentication w/password TypeError exception for node.js 0.10.0-0.10.4 #747 +* fix specifying `values` in `conn.query({...}).on(...)` pattern #755 +* fix long stack trace to include the `pool.query(...)` call #715 + +## v2.1.0 (2014-02-20) + +* crypto.createHash fix for node.js < 11 #735 +* Add `connectTimeout` option to specify a timeout for establishing a connection #726 +* SSL support #481 + +## v2.0.1 + +* internal parser speed improvement #702 +* domains support +* 'trace' connection option to control if long stack traces are generated #713 #710 #439 + +## v2.0.0 (2014-01-09) + +* stream improvements: + - node 0.8 support #692 + - Emit 'close' events from query streams #688 +* encoding fix in streaming LOAD DATA LOCAL INFILE #670 +* Doc improvements + +## v2.0.0-rc2 (2013-12-07) + +* Streaming LOAD DATA LOCAL INFILE #668 +* Doc improvements + +## v2.0.0-rc1 (2013-11-30) + +* Transaction support +* Expose SqlString.format as mysql.format() +* Many bug fixes +* Better support for dates in local time zone +* Doc improvements + +## v2.0.0-alpha9 (2013-08-27) + +* Add query to pool to execute queries directly using the pool +* Pool option to set queue limit +* Pool sends 'connection' event when it opens a new connection +* Added stringifyObjects option to treat input as strings rather than objects (#501) +* Support for poolClusters +* Datetime improvements +* Bug fixes + +## v2.0.0-alpha8 (2013-04-30) + +* Switch to old mode for Streams 2 (Node.js v 0.10.x) +* Add stream method to Query Wraps events from the query object into a node v0.10.x Readable stream +* DECIMAL should also be treated as big number +* Removed slow unnecessary stack access +* Added charsets +* Added bigNumberStrings option for forcing BIGINT columns as strings +* Changes date parsing to return String if not a valid JS Date +* Adds support for ?? escape sequence to escape identifiers +* Changes Auth.token() to force password to be in binary, not utf8 (#378) +* Restrict debugging by packet types +* Add 'multipleStatements' option tracking to ConnectionConfig. Fixes GH-408 +* Changes Pool to handle 'error' events and dispose connection +* Allows db.query({ sql: "..." }, [ val1, ... ], cb); (#390) +* Improved documentation +* Bug fixes + +## v2.0.0-alpha7 (2013-02-03) + +* Add connection pooling (#351) + +## v2.0.0-alpha6 (2013-01-31) + +* Add supportBigNumbers option (#381, #382) +* Accept prebuilt Query object in connection.query +* Bug fixes + +## v2.0.0-alpha5 (2012-12-03) + +* Add mysql.escapeId to escape identifiers (closes #342) +* Allow custom escaping mode (config.queryFormat) +* Convert DATE columns to configured timezone instead of UTC (#332) +* Convert LONGLONG and NEWDECIMAL to numbers (#333) +* Fix Connection.escape() (fixes #330) +* Changed Readme ambiguity about custom type cast fallback +* Change typeCast to receive Connection instead of Connection.config.timezone +* Fix drain event having useless err parameter +* Add Connection.statistics() back from v0.9 +* Add Connection.ping() back from v0.9 + +## v2.0.0-alpha4 (2012-10-03) + +* Fix some OOB errors on resume() +* Fix quick pause() / resume() usage +* Properly parse host denied / similar errors +* Add Connection.ChangeUser functionality +* Make sure changeUser errors are fatal +* Enable formatting nested arrays for bulk inserts +* Add Connection.escape functionality +* Renamed 'close' to 'end' event +* Return parsed object instead of Buffer for GEOMETRY types +* Allow nestTables inline (using a string instead of a boolean) +* Check for ZEROFILL_FLAG and format number accordingly +* Add timezone support (default: local) +* Add custom typeCast functionality +* Export mysql column types +* Add connection flags functionality (#237) +* Exports drain event when queue finishes processing (#272, #271, #306) + +## v2.0.0-alpha3 (2012-06-12) + +* Implement support for `LOAD DATA LOCAL INFILE` queries (#182). +* Support OLD\_PASSWORD() accounts like 0.9.x did. You should still upgrade any + user accounts in your your MySQL user table that has short (16 byte) Password + values. Connecting to those accounts is not secure. (#204) +* Ignore function values when escaping objects, allows to use RowDataPacket + objects as query arguments. (Alex Gorbatchev, #213) +* Handle initial error packets from server such as `ER_HOST_NOT_PRIVILEGED`. +* Treat `utf8\_bin` as a String, not Buffer. (#214) +* Handle empty strings in first row column value. (#222) +* Honor Connection#nestTables setting for queries. (#221) +* Remove `CLIENT_INTERACTIVE` flag from config. Improves #225. +* Improve docs for connections settings. +* Implement url string support for Connection configs. + +## v2.0.0-alpha2 (2012-05-31) + +* Specify escaping before for NaN / Infinity (they are as unquoted constants). +* Support for unix domain socket connections (use: {socketPath: '...'}). +* Fix type casting for NULL values for Date/Number fields +* Add `fields` argument to `query()` as well as `'fields'` event. This is + similar to what was available in 0.9.x. +* Support connecting to the sphinx searchd daemon as well as MariaDB (#199). +* Implement long stack trace support, will be removed / disabled if the node + core ever supports it natively. +* Implement `nestTables` option for queries, allows fetching JOIN result sets + with overlapping column names. +* Fix ? placeholder mechanism for values containing '?' characters (#205). +* Detect when `connect()` is called more than once on a connection and provide + the user with a good error message for it (#204). +* Switch to `UTF8_GENERAL_CI` (previously `UTF8_UNICODE_CI`) as the default + charset for all connections to avoid strange MySQL performance issues (#200), + and also make the charset user configurable. +* Fix BLOB type casting for `TINY_BLOB`, `MEDIUM_BLOB` and `LONG_BLOB`. +* Add support for sending and receiving large (> 16 MB) packets. + +## v2.0.0-alpha (2012-05-15) + +This release is a rewrite. You should carefully test your application after +upgrading to avoid problems. This release features many improvements, most +importantly: + +* ~5x faster than v0.9.x for parsing query results +* Support for pause() / resume() (for streaming rows) +* Support for multiple statement queries +* Support for stored procedures +* Support for transactions +* Support for binary columns (as blobs) +* Consistent & well documented error handling +* A new Connection class that has well defined semantics (unlike the old Client class). +* Convenient escaping of objects / arrays that allows for simpler query construction +* A significantly simpler code base +* Many bug fixes & other small improvements (Closed 62 out of 66 GitHub issues) + +Below are a few notes on the upgrade process itself: + +The first thing you will run into is that the old `Client` class is gone and +has been replaced with a less ambitious `Connection` class. So instead of +`mysql.createClient()`, you now have to: + +```js +var mysql = require('mysql'); +var connection = mysql.createConnection({ + host : 'localhost', + user : 'me', + password : 'secret', +}); + +connection.query('SELECT 1', function(err, rows) { + if (err) throw err; + + console.log('Query result: ', rows); +}); + +connection.end(); +``` + +The new `Connection` class does not try to handle re-connects, please study the +`Server disconnects` section in the new Readme. + +Other than that, the interface has stayed very similar. Here are a few things +to check out so: + +* BIGINT's are now cast into strings +* Binary data is now cast to buffers +* The `'row'` event on the `Query` object is now called `'result'` and will + also be emitted for queries that produce an OK/Error response. +* Error handling is consistently defined now, check the Readme +* Escaping has become more powerful which may break your code if you are + currently using objects to fill query placeholders. +* Connections can now be established explicitly again, so you may wish to do so + if you want to handle connection errors specifically. + +That should be most of it, if you run into anything else, please send a patch +or open an issue to improve this document. + +## v0.9.6 (2012-03-12) + +* Escape array values so they produce sql arrays (Roger Castells, Colin Smith) +* docs: mention mysql transaction stop gap solution (Blake Miner) +* docs: Mention affectedRows in FAQ (Michael Baldwin) + +## v0.9.5 (2011-11-26) + +* Fix #142 Driver stalls upon reconnect attempt that's immediately closed +* Add travis build +* Switch to urun as a test runner +* Switch to utest for unit tests +* Remove fast-or-slow dependency for tests +* Split integration tests into individual files again + +## v0.9.4 (2011-08-31) + +* Expose package.json as `mysql.PACKAGE` (#104) + +## v0.9.3 (2011-08-22) + +* Set default `client.user` to root +* Fix #91: Client#format should not mutate params array +* Fix #94: TypeError in client.js +* Parse decimals as string (vadimg) + +## v0.9.2 (2011-08-07) + +* The underlaying socket connection is now managed implicitly rather than explicitly. +* Check the [upgrading guide][] for a full list of changes. + +## v0.9.1 (2011-02-20) + +* Fix issue #49 / `client.escape()` throwing exceptions on objects. (Nick Payne) +* Drop < v0.4.x compatibility. From now on you need node v0.4.x to use this module. + +## Older releases + +These releases were done before maintaining this file: + +* [v0.9.0](https://github.com/felixge/node-mysql/compare/v0.8.0...v0.9.0) + (2011-01-04) +* [v0.8.0](https://github.com/felixge/node-mysql/compare/v0.7.0...v0.8.0) + (2010-10-30) +* [v0.7.0](https://github.com/felixge/node-mysql/compare/v0.6.0...v0.7.0) + (2010-10-14) +* [v0.6.0](https://github.com/felixge/node-mysql/compare/v0.5.0...v0.6.0) + (2010-09-28) +* [v0.5.0](https://github.com/felixge/node-mysql/compare/v0.4.0...v0.5.0) + (2010-09-17) +* [v0.4.0](https://github.com/felixge/node-mysql/compare/v0.3.0...v0.4.0) + (2010-09-02) +* [v0.3.0](https://github.com/felixge/node-mysql/compare/v0.2.0...v0.3.0) + (2010-08-25) +* [v0.2.0](https://github.com/felixge/node-mysql/compare/v0.1.0...v0.2.0) + (2010-08-22) +* [v0.1.0](https://github.com/felixge/node-mysql/commits/v0.1.0) + (2010-08-22) diff --git a/node_modules/mysql/License b/node_modules/mysql/License new file mode 100644 index 0000000..c7ff12a --- /dev/null +++ b/node_modules/mysql/License @@ -0,0 +1,19 @@ +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/mysql/Readme.md b/node_modules/mysql/Readme.md new file mode 100644 index 0000000..6508a13 --- /dev/null +++ b/node_modules/mysql/Readme.md @@ -0,0 +1,1203 @@ +# mysql + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +## Install + +```sh +$ npm install mysql +``` + +For information about the previous 0.9.x releases, visit the [v0.9 branch][]. + +Sometimes I may also ask you to install the latest version from Github to check +if a bugfix is working. In this case, please do: + +```sh +$ npm install felixge/node-mysql +``` + +[v0.9 branch]: https://github.com/felixge/node-mysql/tree/v0.9 + +## Introduction + +This is a node.js driver for mysql. It is written in JavaScript, does not +require compiling, and is 100% MIT licensed. + +Here is an example on how to use it: + +```js +var mysql = require('mysql'); +var connection = mysql.createConnection({ + host : 'localhost', + user : 'me', + password : 'secret' +}); + +connection.connect(); + +connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) { + if (err) throw err; + + console.log('The solution is: ', rows[0].solution); +}); + +connection.end(); +``` + +From this example, you can learn the following: + +* Every method you invoke on a connection is queued and executed in sequence. +* Closing the connection is done using `end()` which makes sure all remaining + queries are executed before sending a quit packet to the mysql server. + +## Contributors + +Thanks goes to the people who have contributed code to this module, see the +[GitHub Contributors page][]. + +[GitHub Contributors page]: https://github.com/felixge/node-mysql/graphs/contributors + +Additionally I'd like to thank the following people: + +* [Andrey Hristov][] (Oracle) - for helping me with protocol questions. +* [Ulf Wendel][] (Oracle) - for helping me with protocol questions. + +[Ulf Wendel]: http://blog.ulf-wendel.de/ +[Andrey Hristov]: http://andrey.hristov.com/ + +## Sponsors + +The following companies have supported this project financially, allowing me to +spend more time on it (ordered by time of contribution): + +* [Transloadit](http://transloadit.com) (my startup, we do file uploading & + video encoding as a service, check it out) +* [Joyent](http://www.joyent.com/) +* [pinkbike.com](http://pinkbike.com/) +* [Holiday Extras](http://www.holidayextras.co.uk/) (they are [hiring](http://join.holidayextras.co.uk/vacancy/software-engineer/)) +* [Newscope](http://newscope.com/) (they are [hiring](http://www.newscope.com/stellenangebote)) + +If you are interested in sponsoring a day or more of my time, please +[get in touch][]. + +[get in touch]: http://felixge.de/#consulting + +## Community + +If you'd like to discuss this module, or ask questions about it, please use one +of the following: + +* **Mailing list**: https://groups.google.com/forum/#!forum/node-mysql +* **IRC Channel**: #node.js (on freenode.net, I pay attention to any message + including the term `mysql`) + +## Establishing connections + +The recommended way to establish a connection is this: + +```js +var mysql = require('mysql'); +var connection = mysql.createConnection({ + host : 'example.org', + user : 'bob', + password : 'secret' +}); + +connection.connect(function(err) { + if (err) { + console.error('error connecting: ' + err.stack); + return; + } + + console.log('connected as id ' + connection.threadId); +}); +``` + +However, a connection can also be implicitly established by invoking a query: + +```js +var mysql = require('mysql'); +var connection = mysql.createConnection(...); + +connection.query('SELECT 1', function(err, rows) { + // connected! (unless `err` is set) +}); +``` + +Depending on how you like to handle your errors, either method may be +appropriate. Any type of connection error (handshake or network) is considered +a fatal error, see the [Error Handling](#error-handling) section for more +information. + +## Connection options + +When establishing a connection, you can set the following options: + +* `host`: The hostname of the database you are connecting to. (Default: + `localhost`) +* `port`: The port number to connect to. (Default: `3306`) +* `localAddress`: The source IP address to use for TCP connection. (Optional) +* `socketPath`: The path to a unix domain socket to connect to. When used `host` + and `port` are ignored. +* `user`: The MySQL user to authenticate as. +* `password`: The password of that MySQL user. +* `database`: Name of the database to use for this connection (Optional). +* `charset`: The charset for the connection. This is called "collation" in the SQL-level + of MySQL (like `utf8_general_ci`). If a SQL-level charset is specified (like `utf8mb4`) + then the default collation for that charset is used. (Default: `'UTF8_GENERAL_CI'`) +* `timezone`: The timezone used to store local dates. (Default: `'local'`) +* `connectTimeout`: The milliseconds before a timeout occurs during the initial connection + to the MySQL server. (Default: 10 seconds) +* `stringifyObjects`: Stringify objects instead of converting to values. See +issue [#501](https://github.com/felixge/node-mysql/issues/501). (Default: `'false'`) +* `insecureAuth`: Allow connecting to MySQL instances that ask for the old + (insecure) authentication method. (Default: `false`) +* `typeCast`: Determines if column values should be converted to native + JavaScript types. (Default: `true`) +* `queryFormat`: A custom query format function. See [Custom format](#custom-format). +* `supportBigNumbers`: When dealing with big numbers (BIGINT and DECIMAL columns) in the database, + you should enable this option (Default: `false`). +* `bigNumberStrings`: Enabling both `supportBigNumbers` and `bigNumberStrings` forces big numbers + (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: `false`). + Enabling `supportBigNumbers` but leaving `bigNumberStrings` disabled will return big numbers as String + objects only when they cannot be accurately represented with [JavaScript Number objects] (http://ecma262-5.com/ELS5_HTML.htm#Section_8.5) + (which happens when they exceed the [-2^53, +2^53] range), otherwise they will be returned as + Number objects. This option is ignored if `supportBigNumbers` is disabled. +* `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then + inflated into JavaScript Date objects. (Default: `false`) +* `debug`: Prints protocol details to stdout. (Default: `false`) +* `trace`: Generates stack traces on `Error` to include call site of library + entrance ("long stack traces"). Slight performance penalty for most calls. + (Default: `true`) +* `multipleStatements`: Allow multiple mysql statements per query. Be careful + with this, it exposes you to SQL injection attacks. (Default: `false`) +* `flags`: List of connection flags to use other than the default ones. It is + also possible to blacklist default ones. For more information, check + [Connection Flags](#connection-flags). +* `ssl`: object with ssl parameters or a string containing name of ssl profile. See [SSL options](#ssl-options). + + +In addition to passing these options as an object, you can also use a url +string. For example: + +```js +var connection = mysql.createConnection('mysql://user:pass@host/db?debug=true&charset=BIG5_CHINESE_CI&timezone=-0700'); +``` + +Note: The query values are first attempted to be parsed as JSON, and if that +fails assumed to be plaintext strings. + +### SSL options + +The `ssl` option in the connection options takes a string or an object. When given a string, +it uses one of the predefined SSL profiles included. The following profiles are included: + +* `"Amazon RDS"`: this profile is for connecting to an Amazon RDS server and contains the + ca from https://rds.amazonaws.com/doc/rds-ssl-ca-cert.pem + +When connecting to other servers, you will need to provide an object of options, in the +same format as [crypto.createCredentials](http://nodejs.org/api/crypto.html#crypto_crypto_createcredentials_details). +Please note the arguments expect a string of the certificate, not a file name to the +certificate. Here is a simple example: + +```js +var connection = mysql.createConnection({ + host : 'localhost', + ssl : { + ca : fs.readFileSync(__dirname + '/mysql-ca.crt') + } +}); +``` + +You can also connect to a MySQL server without properly providing the appropriate +CA to trust. _You should not do this_. + +```js +var connection = mysql.createConnection({ + host : 'localhost', + ssl : { + // DO NOT DO THIS + // set up your ca correctly to trust the connection + rejectUnauthorized: false + } +}); +``` + +## Terminating connections + +There are two ways to end a connection. Terminating a connection gracefully is +done by calling the `end()` method: + +```js +connection.end(function(err) { + // The connection is terminated now +}); +``` + +This will make sure all previously enqueued queries are still before sending a +`COM_QUIT` packet to the MySQL server. If a fatal error occurs before the +`COM_QUIT` packet can be sent, an `err` argument will be provided to the +callback, but the connection will be terminated regardless of that. + +An alternative way to end the connection is to call the `destroy()` method. +This will cause an immediate termination of the underlying socket. +Additionally `destroy()` guarantees that no more events or callbacks will be +triggered for the connection. + +```js +connection.destroy(); +``` + +Unlike `end()` the `destroy()` method does not take a callback argument. + +## Pooling connections + +Use pool directly. +```js +var mysql = require('mysql'); +var pool = mysql.createPool({ + connectionLimit : 10, + host : 'example.org', + user : 'bob', + password : 'secret' +}); + +pool.query('SELECT 1 + 1 AS solution', function(err, rows, fields) { + if (err) throw err; + + console.log('The solution is: ', rows[0].solution); +}); +``` + +Connections can be pooled to ease sharing a single connection, or managing +multiple connections. + +```js +var mysql = require('mysql'); +var pool = mysql.createPool({ + host : 'example.org', + user : 'bob', + password : 'secret' +}); + +pool.getConnection(function(err, connection) { + // connected! (unless `err` is set) +}); +``` + +When you are done with a connection, just call `connection.release()` and the +connection will return to the pool, ready to be used again by someone else. + +```js +var mysql = require('mysql'); +var pool = mysql.createPool(...); + +pool.getConnection(function(err, connection) { + // Use the connection + connection.query( 'SELECT something FROM sometable', function(err, rows) { + // And done with the connection. + connection.release(); + + // Don't use the connection here, it has been returned to the pool. + }); +}); +``` + +If you would like to close the connection and remove it from the pool, use +`connection.destroy()` instead. The pool will create a new connection the next +time one is needed. + +Connections are lazily created by the pool. If you configure the pool to allow +up to 100 connections, but only ever use 5 simultaneously, only 5 connections +will be made. Connections are also cycled round-robin style, with connections +being taken from the top of the pool and returning to the bottom. + +When a previous connection is retrieved from the pool, a ping packet is sent +to the server to check if the connection is still good. + +## Pool options + +Pools accept all the same options as a connection. When creating a new +connection, the options are simply passed to the connection constructor. In +addition to those options pools accept a few extras: + +* `acquireTimeout`: The milliseconds before a timeout occurs during the connection + acquisition. This is slightly different from `connectTimeout`, because acquiring + a pool connection does not always involve making a connection. (Default: 10 seconds) +* `waitForConnections`: Determines the pool's action when no connections are + available and the limit has been reached. If `true`, the pool will queue the + connection request and call it when one becomes available. If `false`, the + pool will immediately call back with an error. (Default: `true`) +* `connectionLimit`: The maximum number of connections to create at once. + (Default: `10`) +* `queueLimit`: The maximum number of connection requests the pool will queue + before returning an error from `getConnection`. If set to `0`, there is no + limit to the number of queued connection requests. (Default: `0`) + +## Pool events + +### connection + +The pool will emit a `connection` event when a new connection is made within the pool. +If you need to set session variables on the connection before it gets used, you can +listen to the `connection` event. + +```js +pool.on('connection', function (connection) { + connection.query('SET SESSION auto_increment_increment=1') +}); +``` + +### enqueue + +The pool will emit an `enqueue` event when a callback has been queued to wait for +an available connection. + +```js +pool.on('enqueue', function () { + console.log('Waiting for available connection slot'); +}); +``` + +## Closing all the connections in a pool + +When you are done using the pool, you have to end all the connections or the +Node.js event loop will stay active until the connections are closed by the +MySQL server. This is typically done if the pool is used in a script or when +trying to gracefully shutdown a server. To end all the connections in the +pool, use the `end` method on the pool: + +```js +pool.end(function (err) { + // all connections in the pool have ended +}); +``` + +The `end` method takes an _optional_ callback that you can use to know once +all the connections have ended. The connections end _gracefully_, so all +pending queries will still complete and the time to end the pool will vary. + +**Once `pool.end()` has been called, `pool.getConnection` and other operations +can no longer be performed** + +## PoolCluster + +PoolCluster provides multiple hosts connection. (group & retry & selector) + +```js +// create +var poolCluster = mysql.createPoolCluster(); + +poolCluster.add(config); // anonymous group +poolCluster.add('MASTER', masterConfig); +poolCluster.add('SLAVE1', slave1Config); +poolCluster.add('SLAVE2', slave2Config); + +// Target Group : ALL(anonymous, MASTER, SLAVE1-2), Selector : round-robin(default) +poolCluster.getConnection(function (err, connection) {}); + +// Target Group : MASTER, Selector : round-robin +poolCluster.getConnection('MASTER', function (err, connection) {}); + +// Target Group : SLAVE1-2, Selector : order +// If can't connect to SLAVE1, return SLAVE2. (remove SLAVE1 in the cluster) +poolCluster.on('remove', function (nodeId) { + console.log('REMOVED NODE : ' + nodeId); // nodeId = SLAVE1 +}); + +poolCluster.getConnection('SLAVE*', 'ORDER', function (err, connection) {}); + +// of namespace : of(pattern, selector) +poolCluster.of('*').getConnection(function (err, connection) {}); + +var pool = poolCluster.of('SLAVE*', 'RANDOM'); +pool.getConnection(function (err, connection) {}); +pool.getConnection(function (err, connection) {}); + +// destroy +poolCluster.end(); +``` + +## PoolCluster Option +* `canRetry`: If `true`, `PoolCluster` will attempt to reconnect when connection fails. (Default: `true`) +* `removeNodeErrorCount`: If connection fails, node's `errorCount` increases. + When `errorCount` is greater than `removeNodeErrorCount`, remove a node in the `PoolCluster`. (Default: `5`) +* `defaultSelector`: The default selector. (Default: `RR`) + * `RR`: Select one alternately. (Round-Robin) + * `RANDOM`: Select the node by random function. + * `ORDER`: Select the first node available unconditionally. + +```js +var clusterConfig = { + removeNodeErrorCount: 1, // Remove the node immediately when connection fails. + defaultSelector: 'ORDER' +}; + +var poolCluster = mysql.createPoolCluster(clusterConfig); +``` + +## Switching users / altering connection state + +MySQL offers a changeUser command that allows you to alter the current user and +other aspects of the connection without shutting down the underlying socket: + +```js +connection.changeUser({user : 'john'}, function(err) { + if (err) throw err; +}); +``` + +The available options for this feature are: + +* `user`: The name of the new user (defaults to the previous one). +* `password`: The password of the new user (defaults to the previous one). +* `charset`: The new charset (defaults to the previous one). +* `database`: The new database (defaults to the previous one). + +A sometimes useful side effect of this functionality is that this function also +resets any connection state (variables, transactions, etc.). + +Errors encountered during this operation are treated as fatal connection errors +by this module. + +## Server disconnects + +You may lose the connection to a MySQL server due to network problems, the +server timing you out, the server being restarted, or crashing. All of these +events are considered fatal errors, and will have the `err.code = +'PROTOCOL_CONNECTION_LOST'`. See the [Error Handling](#error-handling) section +for more information. + +Re-connecting a connection is done by establishing a new connection. Once +terminated, an existing connection object cannot be re-connected by design. + +With Pool, disconnected connections will be removed from the pool freeing up +space for a new connection to be created on the next getConnection call. + +## Escaping query values + +In order to avoid SQL Injection attacks, you should always escape any user +provided data before using it inside a SQL query. You can do so using the +`connection.escape()` or `pool.escape()` methods: + +```js +var userId = 'some user provided value'; +var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId); +connection.query(sql, function(err, results) { + // ... +}); +``` + +Alternatively, you can use `?` characters as placeholders for values you would +like to have escaped like this: + +```js +connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) { + // ... +}); +``` + +This looks similar to prepared statements in MySQL, however it really just uses +the same `connection.escape()` method internally. + +**Caution** This also differs from prepared statements in that all `?` are +replaced, even those contained in comments and strings. + +Different value types are escaped differently, here is how: + +* Numbers are left untouched +* Booleans are converted to `true` / `false` strings +* Date objects are converted to `'YYYY-mm-dd HH:ii:ss'` strings +* Buffers are converted to hex strings, e.g. `X'0fa5'` +* Strings are safely escaped +* Arrays are turned into list, e.g. `['a', 'b']` turns into `'a', 'b'` +* Nested arrays are turned into grouped lists (for bulk inserts), e.g. `[['a', + 'b'], ['c', 'd']]` turns into `('a', 'b'), ('c', 'd')` +* Objects are turned into `key = 'val'` pairs. Nested objects are cast to + strings. +* `undefined` / `null` are converted to `NULL` +* `NaN` / `Infinity` are left as-is. MySQL does not support these, and trying + to insert them as values will trigger MySQL errors until they implement + support. + +If you paid attention, you may have noticed that this escaping allows you +to do neat things like this: + +```js +var post = {id: 1, title: 'Hello MySQL'}; +var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) { + // Neat! +}); +console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL' + +``` + +If you feel the need to escape queries by yourself, you can also use the escaping +function directly: + +```js +var query = "SELECT * FROM posts WHERE title=" + mysql.escape("Hello MySQL"); + +console.log(query); // SELECT * FROM posts WHERE title='Hello MySQL' +``` + +## Escaping query identifiers + +If you can't trust an SQL identifier (database / table / column name) because it is +provided by a user, you should escape it with `mysql.escapeId(identifier)`, +`connection.escapeId(identifier)` or `pool.escapeId(identifier)` like this: + +```js +var sorter = 'date'; +var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId(sorter); +connection.query(sql, function(err, results) { + // ... +}); +``` + +It also supports adding qualified identifiers. It will escape both parts. + +```js +var sorter = 'date'; +var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId('posts.' + sorter); +connection.query(sql, function(err, results) { + // ... +}); +``` + +Alternatively, you can use `??` characters as placeholders for identifiers you would +like to have escaped like this: + +```js +var userId = 1; +var columns = ['username', 'email']; +var query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) { + // ... +}); + +console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1 +``` +**Please note that this last character sequence is experimental and syntax might change** + +When you pass an Object to `.escape()` or `.query()`, `.escapeId()` is used to avoid SQL injection in object keys. + +### Preparing Queries + +You can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows: + +```js +var sql = "SELECT * FROM ?? WHERE ?? = ?"; +var inserts = ['users', 'id', userId]; +sql = mysql.format(sql, inserts); +``` + +Following this you then have a valid, escaped query that you can then send to the database safely. This is useful if you are looking to prepare the query before actually sending it to the database. As mysql.format is exposed from SqlString.format you also have the option (but are not required) to pass in stringifyObject and timezone, allowing you provide a custom means of turning objects into strings, as well as a location-specific/timezone-aware Date. + +### Custom format + +If you prefer to have another type of query escape format, there's a connection configuration option you can use to define a custom format function. You can access the connection object if you want to use the built-in `.escape()` or any other connection function. + +Here's an example of how to implement another format: + +```js +connection.config.queryFormat = function (query, values) { + if (!values) return query; + return query.replace(/\:(\w+)/g, function (txt, key) { + if (values.hasOwnProperty(key)) { + return this.escape(values[key]); + } + return txt; + }.bind(this)); +}; + +connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" }); +``` + +## Getting the id of an inserted row + +If you are inserting a row into a table with an auto increment primary key, you +can retrieve the insert id like this: + +```js +connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) { + if (err) throw err; + + console.log(result.insertId); +}); +``` + +When dealing with big numbers (above JavaScript Number precision limit), you should +consider enabling `supportBigNumbers` option to be able to read the insert id as a +string, otherwise it will throw. + +This option is also required when fetching big numbers from the database, otherwise +you will get values rounded to hundreds or thousands due to the precision limit. + +## Getting the number of affected rows. + +You can get the number of affected rows from an insert, update or delete statement. + +```js +connection.query('DELETE FROM posts WHERE title = "wrong"', function (err, result) { + if (err) throw err; + + console.log('deleted ' + result.affectedRows + ' rows'); +}) +``` + +## Getting the number of changed rows. + +You can get the number of changed rows from an update statement. + +"changedRows" differs from "affectedRows" in that it does not count updated rows +whose values were not changed. + +```js +connection.query('UPDATE posts SET ...', function (err, result) { + if (err) throw err; + + console.log('changed ' + result.changedRows + ' rows'); +}) +``` + +## Getting the connection ID + +You can get the MySQL connection ID ("thread ID") of a given connection using the `threadId` +property. + +```js +connection.connect(function(err) { + if (err) throw err; + console.log('connected as id ' + connection.threadId); +}); +``` + +## Executing queries in parallel + +The MySQL protocol is sequential, this means that you need multiple connections +to execute queries in parallel. You can use a Pool to manage connections, one +simple approach is to create one connection per incoming http request. + +## Streaming query rows + +Sometimes you may want to select large quantities of rows and process each of +them as they are received. This can be done like this: + +```js +var query = connection.query('SELECT * FROM posts'); +query + .on('error', function(err) { + // Handle error, an 'end' event will be emitted after this as well + }) + .on('fields', function(fields) { + // the field packets for the rows to follow + }) + .on('result', function(row) { + // Pausing the connnection is useful if your processing involves I/O + connection.pause(); + + processRow(row, function() { + connection.resume(); + }); + }) + .on('end', function() { + // all rows have been received + }); +``` + +Please note a few things about the example above: + +* Usually you will want to receive a certain amount of rows before starting to + throttle the connection using `pause()`. This number will depend on the + amount and size of your rows. +* `pause()` / `resume()` operate on the underlying socket and parser. You are + guaranteed that no more `'result'` events will fire after calling `pause()`. +* You MUST NOT provide a callback to the `query()` method when streaming rows. +* The `'result'` event will fire for both rows as well as OK packets + confirming the success of a INSERT/UPDATE query. + +Additionally you may be interested to know that it is currently not possible to +stream individual row columns, they will always be buffered up entirely. If you +have a good use case for streaming large fields to and from MySQL, I'd love to +get your thoughts and contributions on this. + +### Piping results with [Streams2](http://blog.nodejs.org/2012/12/20/streams2/) + +The query object provides a convenience method `.stream([options])` that wraps +query events into a [Readable](http://nodejs.org/api/stream.html#stream_class_stream_readable) +Streams2 object. This stream can easily be piped downstream and provides +automatic pause/resume, based on downstream congestion and the optional +`highWaterMark`. The `objectMode` parameter of the stream is set to `true` by +default. + +For example, piping query results into another stream (with a max buffer of 5 +objects) is simply: + +```js +connection.query('SELECT * FROM posts') + .stream({highWaterMark: 5}) + .pipe(...); +``` + +## Multiple statement queries + +Support for multiple statements is disabled for security reasons (it allows for +SQL injection attacks if values are not properly escaped). To use this feature +you have to enable it for your connection: + +```js +var connection = mysql.createConnection({multipleStatements: true}); +``` + +Once enabled, you can execute multiple statement queries like any other query: + +```js +connection.query('SELECT 1; SELECT 2', function(err, results) { + if (err) throw err; + + // `results` is an array with one element for every statement in the query: + console.log(results[0]); // [{1: 1}] + console.log(results[1]); // [{2: 2}] +}); +``` + +Additionally you can also stream the results of multiple statement queries: + +```js +var query = connection.query('SELECT 1; SELECT 2'); + +query + .on('fields', function(fields, index) { + // the fields for the result rows that follow + }) + .on('result', function(row, index) { + // index refers to the statement this result belongs to (starts at 0) + }); +``` + +If one of the statements in your query causes an error, the resulting Error +object contains a `err.index` property which tells you which statement caused +it. MySQL will also stop executing any remaining statements when an error +occurs. + +Please note that the interface for streaming multiple statement queries is +experimental and I am looking forward to feedback on it. + +## Stored procedures + +You can call stored procedures from your queries as with any other mysql driver. +If the stored procedure produces several result sets, they are exposed to you +the same way as the results for multiple statement queries. + +## Joins with overlapping column names + +When executing joins, you are likely to get result sets with overlapping column +names. + +By default, node-mysql will overwrite colliding column names in the +order the columns are received from MySQL, causing some of the received values +to be unavailable. + +However, you can also specify that you want your columns to be nested below +the table name like this: + +```js +var options = {sql: '...', nestTables: true}; +connection.query(options, function(err, results) { + /* results will be an array like this now: + [{ + table1: { + fieldA: '...', + fieldB: '...', + }, + table2: { + fieldA: '...', + fieldB: '...', + }, + }, ...] + */ +}); +``` + +Or use a string separator to have your results merged. + +```js +var options = {sql: '...', nestTables: '_'}; +connection.query(options, function(err, results) { + /* results will be an array like this now: + [{ + table1_fieldA: '...', + table1_fieldB: '...', + table2_fieldA: '...', + table2_fieldB: '...', + }, ...] + */ +}); +``` + +## Transactions + +Simple transaction support is available at the connection level: + +```js +connection.beginTransaction(function(err) { + if (err) { throw err; } + connection.query('INSERT INTO posts SET title=?', title, function(err, result) { + if (err) { + connection.rollback(function() { + throw err; + }); + } + + var log = 'Post ' + result.insertId + ' added'; + + connection.query('INSERT INTO log SET data=?', log, function(err, result) { + if (err) { + connection.rollback(function() { + throw err; + }); + } + connection.commit(function(err) { + if (err) { + connection.rollback(function() { + throw err; + }); + } + console.log('success!'); + }); + }); + }); +}); +``` +Please note that beginTransaction(), commit() and rollback() are simply convenience +functions that execute the START TRANSACTION, COMMIT, and ROLLBACK commands respectively. +It is important to understand that many commands in MySQL can cause an implicit commit, +as described [in the MySQL documentation](http://dev.mysql.com/doc/refman/5.5/en/implicit-commit.html) + +## Timeouts + +Every operation takes an optional inactivity timeout option. This allows you to +specify appropriate timeouts for operations. It is important to note that these +timeouts are not part of the MySQL protocol, and rather timeout operations through +the client. This means that when a timeout is reached, the connection it occurred +on will be destroyed and no further operations can be performed. + +```js +// Kill query after 60s +connection.query({sql: 'SELECT COUNT(*) AS count FROM big_table', timeout: 60000}, function (err, rows) { + if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') { + throw new Error('too long to count table rows!'); + } + + if (err) { + throw err; + } + + console.log(rows[0].count + ' rows'); +}); +``` + +## Error handling + +This module comes with a consistent approach to error handling that you should +review carefully in order to write solid applications. + +All errors created by this module are instances of the JavaScript [Error][] +object. Additionally they come with two properties: + +* `err.code`: Either a [MySQL server error][] (e.g. + `'ER_ACCESS_DENIED_ERROR'`), a node.js error (e.g. `'ECONNREFUSED'`) or an + internal error (e.g. `'PROTOCOL_CONNECTION_LOST'`). +* `err.fatal`: Boolean, indicating if this error is terminal to the connection + object. + +[Error]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error +[MySQL server error]: http://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html + +Fatal errors are propagated to *all* pending callbacks. In the example below, a +fatal error is triggered by trying to connect to an invalid port. Therefore the +error object is propagated to both pending callbacks: + +```js +var connection = require('mysql').createConnection({ + port: 84943, // WRONG PORT +}); + +connection.connect(function(err) { + console.log(err.code); // 'ECONNREFUSED' + console.log(err.fatal); // true +}); + +connection.query('SELECT 1', function(err) { + console.log(err.code); // 'ECONNREFUSED' + console.log(err.fatal); // true +}); +``` + +Normal errors however are only delegated to the callback they belong to. So in +the example below, only the first callback receives an error, the second query +works as expected: + +```js +connection.query('USE name_of_db_that_does_not_exist', function(err, rows) { + console.log(err.code); // 'ER_BAD_DB_ERROR' +}); + +connection.query('SELECT 1', function(err, rows) { + console.log(err); // null + console.log(rows.length); // 1 +}); +``` + +Last but not least: If a fatal errors occurs and there are no pending +callbacks, or a normal error occurs which has no callback belonging to it, the +error is emitted as an `'error'` event on the connection object. This is +demonstrated in the example below: + +```js +connection.on('error', function(err) { + console.log(err.code); // 'ER_BAD_DB_ERROR' +}); + +connection.query('USE name_of_db_that_does_not_exist'); +``` + +Note: `'error'` are special in node. If they occur without an attached +listener, a stack trace is printed and your process is killed. + +**tl;dr:** This module does not want you to deal with silent failures. You +should always provide callbacks to your method calls. If you want to ignore +this advice and suppress unhandled errors, you can do this: + +```js +// I am Chuck Norris: +connection.on('error', function() {}); +``` + +## Exception Safety + +This module is exception safe. That means you can continue to use it, even if +one of your callback functions throws an error which you're catching using +'uncaughtException' or a domain. + +## Type casting + +For your convenience, this driver will cast mysql types into native JavaScript +types by default. The following mappings exist: + +### Number + +* TINYINT +* SMALLINT +* INT +* MEDIUMINT +* YEAR +* FLOAT +* DOUBLE + +### Date + +* TIMESTAMP +* DATE +* DATETIME + +### Buffer + +* TINYBLOB +* MEDIUMBLOB +* LONGBLOB +* BLOB +* BINARY +* VARBINARY +* BIT (last byte will be filled with 0 bits as necessary) + +### String + +* CHAR +* VARCHAR +* TINYTEXT +* MEDIUMTEXT +* LONGTEXT +* TEXT +* ENUM +* SET +* DECIMAL (may exceed float precision) +* BIGINT (may exceed float precision) +* TIME (could be mapped to Date, but what date would be set?) +* GEOMETRY (never used those, get in touch if you do) + +It is not recommended (and may go away / change in the future) to disable type +casting, but you can currently do so on either the connection: + +```js +var connection = require('mysql').createConnection({typeCast: false}); +``` + +Or on the query level: + +```js +var options = {sql: '...', typeCast: false}; +var query = connection.query(options, function(err, results) { + +}); +``` + +You can also pass a function and handle type casting yourself. You're given some +column information like database, table and name and also type and length. If you +just want to apply a custom type casting to a specific type you can do it and then +fallback to the default. Here's an example of converting `TINYINT(1)` to boolean: + +```js +connection.query({ + sql: '...', + typeCast: function (field, next) { + if (field.type == 'TINY' && field.length == 1) { + return (field.string() == '1'); // 1 = true, 0 = false + } + return next(); + } +}); +``` +__WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once.( see #539 for discussion)__ + +``` +field.string() +field.buffer() +field.geometry() +``` +are aliases for +``` +parser.parseLengthCodedString() +parser.parseLengthCodedBuffer() +parser.parseGeometryValue() +``` +__You can find which field function you need to use by looking at: [RowDataPacket.prototype._typeCast](https://github.com/felixge/node-mysql/blob/master/lib/protocol/packets/RowDataPacket.js#L41)__ + + +## Connection Flags + +If, for any reason, you would like to change the default connection flags, you +can use the connection option `flags`. Pass a string with a comma separated list +of items to add to the default flags. If you don't want a default flag to be used +prepend the flag with a minus sign. To add a flag that is not in the default list, +just write the flag name, or prefix it with a plus (case insensitive). + +**Please note that some available flags that are not not supported (e.g.: Compression), +are still not allowed to be specified.** + +### Example + +The next example blacklists FOUND_ROWS flag from default connection flags. + +```js +var connection = mysql.createConnection("mysql://localhost/test?flags=-FOUND_ROWS"); +``` + +### Default Flags + +The following flags are sent by default on a new connection: + +- `CONNECT_WITH_DB` - Ability to specify the database on connection. +- `FOUND_ROWS` - Send the found rows instead of the affected rows as `affectedRows`. +- `IGNORE_SIGPIPE` - Old; no effect. +- `IGNORE_SPACE` - Let the parser ignore spaces before the `(` in queries. +- `LOCAL_FILES` - Can use `LOAD DATA LOCAL`. +- `LONG_FLAG` +- `LONG_PASSWORD` - Use the improved version of Old Password Authentication. +- `MULTI_RESULTS` - Can handle multiple resultsets for COM_QUERY. +- `ODBC` Old; no effect. +- `PROTOCOL_41` - Uses the 4.1 protocol. +- `PS_MULTI_RESULTS` - Can handle multiple resultsets for COM_STMT_EXECUTE. +- `RESERVED` - Old flag for the 4.1 protocol. +- `SECURE_CONNECTION` - Support native 4.1 authentication. +- `TRANSACTIONS` - Asks for the transaction status flags. + +In addition, the following flag will be sent if the option `multipleStatements` +is set to `true`: + +- `MULTI_STATEMENTS` - The client may send multiple statement per query or + statement prepare. + +### Other Available Flags + +There are other flags available. They may or may not function, but are still +available to specify. + +- COMPRESS +- INTERACTIVE +- NO_SCHEMA +- PLUGIN_AUTH +- REMEMBER_OPTIONS +- SSL +- SSL_VERIFY_SERVER_CERT + +## Debugging and reporting problems + +If you are running into problems, one thing that may help is enabling the +`debug` mode for the connection: + +```js +var connection = mysql.createConnection({debug: true}); +``` + +This will print all incoming and outgoing packets on stdout. You can also restrict debugging to +packet types by passing an array of types to debug: + +```js +var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']}); +``` + +to restrict debugging to the query and data packets. + +If that does not help, feel free to open a GitHub issue. A good GitHub issue +will have: + +* The minimal amount of code required to reproduce the problem (if possible) +* As much debugging output and information about your environment (mysql + version, node version, os, etc.) as you can gather. + +## Running tests + +The test suite is split into two parts: unit tests and integration tests. +The unit tests run on any machine while the integration tests require a +MySQL server instance to be setup. + +### Running unit tests + +```sh +$ FILTER=unit npm test +``` + +### Running integration tests + +Set the environment variables `MYSQL_DATABASE`, `MYSQL_HOST`, `MYSQL_PORT`, +`MYSQL_USER` and `MYSQL_PASSWORD`. Then run `npm test`. + +For example, if you have an installation of mysql running on localhost:3306 +and no password set for the `root` user, run: + +```sh +$ mysql -u root -e "CREATE DATABASE IF NOT EXISTS node_mysql_test" +$ MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= FILTER=integration npm test +``` + +## Todo + +* Prepared statements +* Support for encodings other than UTF-8 / ASCII + +[npm-image]: https://img.shields.io/npm/v/mysql.svg?style=flat +[npm-url]: https://npmjs.org/package/mysql +[node-version-image]: https://img.shields.io/badge/node.js-%3E%3D_0.6-brightgreen.svg?style=flat +[node-version-url]: http://nodejs.org/download/ +[travis-image]: https://img.shields.io/travis/felixge/node-mysql.svg?style=flat +[travis-url]: https://travis-ci.org/felixge/node-mysql +[coveralls-image]: https://img.shields.io/coveralls/felixge/node-mysql.svg?style=flat +[coveralls-url]: https://coveralls.io/r/felixge/node-mysql?branch=master +[downloads-image]: https://img.shields.io/npm/dm/mysql.svg?style=flat +[downloads-url]: https://npmjs.org/package/mysql diff --git a/node_modules/mysql/fixtures/ssl-profiles.json b/node_modules/mysql/fixtures/ssl-profiles.json new file mode 100644 index 0000000..0629d5e --- /dev/null +++ b/node_modules/mysql/fixtures/ssl-profiles.json @@ -0,0 +1,5 @@ +{ + "Amazon RDS": { + "ca": "-----BEGIN CERTIFICATE-----\nMIIDQzCCAqygAwIBAgIJAOd1tlfiGoEoMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRMw\nEQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNSRFMxHDAaBgNVBAMTE2F3cy5h\nbWF6b24uY29tL3Jkcy8wHhcNMTAwNDA1MjI0NDMxWhcNMTUwNDA0MjI0NDMxWjB1\nMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh\ndHRsZTETMBEGA1UEChMKQW1hem9uLmNvbTEMMAoGA1UECxMDUkRTMRwwGgYDVQQD\nExNhd3MuYW1hem9uLmNvbS9yZHMvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\ngQDKhXGU7tizxUR5WaFoMTFcxNxa05PEjZaIOEN5ctkWrqYSRov0/nOMoZjqk8bC\nmed9vPFoQGD0OTakPs0jVe3wwmR735hyVwmKIPPsGlaBYj1O6llIpZeQVyupNx56\nUzqtiLaDzh1KcmfqP3qP2dInzBfJQKjiRudo1FWnpPt33QIDAQABo4HaMIHXMB0G\nA1UdDgQWBBT/H3x+cqSkR/ePSIinPtc4yWKe3DCBpwYDVR0jBIGfMIGcgBT/H3x+\ncqSkR/ePSIinPtc4yWKe3KF5pHcwdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh\nc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEzARBgNVBAoTCkFtYXpvbi5jb20x\nDDAKBgNVBAsTA1JEUzEcMBoGA1UEAxMTYXdzLmFtYXpvbi5jb20vcmRzL4IJAOd1\ntlfiGoEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvguZy/BDT66x\nGfgnJlyQwnFSeVLQm9u/FIvz4huGjbq9dqnD6h/Gm56QPFdyMEyDiZWaqY6V08lY\nLTBNb4kcIc9/6pc0/ojKciP5QJRm6OiZ4vgG05nF4fYjhU7WClUx7cxq1fKjNc2J\nUCmmYqgiVkAGWRETVo+byOSDZ4swb10=\n-----END CERTIFICATE-----\n" + } +} diff --git a/node_modules/mysql/index.js b/node_modules/mysql/index.js new file mode 100644 index 0000000..523eb53 --- /dev/null +++ b/node_modules/mysql/index.js @@ -0,0 +1,26 @@ +var Connection = require('./lib/Connection'); +var ConnectionConfig = require('./lib/ConnectionConfig'); +var Types = require('./lib/protocol/constants/types'); +var SqlString = require('./lib/protocol/SqlString'); +var Pool = require('./lib/Pool'); +var PoolConfig = require('./lib/PoolConfig'); +var PoolCluster = require('./lib/PoolCluster'); + +exports.createConnection = function(config) { + return new Connection({config: new ConnectionConfig(config)}); +}; + +exports.createPool = function(config) { + return new Pool({config: new PoolConfig(config)}); +}; + +exports.createPoolCluster = function(config) { + return new PoolCluster(config); +}; + +exports.createQuery = Connection.createQuery; + +exports.Types = Types; +exports.escape = SqlString.escape; +exports.escapeId = SqlString.escapeId; +exports.format = SqlString.format; diff --git a/node_modules/mysql/lib/Connection.js b/node_modules/mysql/lib/Connection.js new file mode 100644 index 0000000..600cbdd --- /dev/null +++ b/node_modules/mysql/lib/Connection.js @@ -0,0 +1,389 @@ +var Crypto = require('crypto'); +var Net = require('net'); +var tls = require('tls'); +var ConnectionConfig = require('./ConnectionConfig'); +var Protocol = require('./protocol/Protocol'); +var SqlString = require('./protocol/SqlString'); +var Query = require('./protocol/sequences/Query'); +var EventEmitter = require('events').EventEmitter; +var Util = require('util'); + +module.exports = Connection; +Util.inherits(Connection, EventEmitter); +function Connection(options) { + EventEmitter.call(this); + + this.config = options.config; + + this._socket = options.socket; + this._protocol = new Protocol({config: this.config, connection: this}); + this._connectCalled = false; + this.state = "disconnected"; + this.threadId = null; +} + +function bindToCurrentDomain(callback) { + if (!callback) return; + + var domain = process.domain; + + return domain + ? domain.bind(callback) + : callback; +} + +Connection.createQuery = function(sql, values, cb) { + if (sql instanceof Query) { + return sql; + } + + var options = {}; + + if (typeof sql === 'object') { + // query(options, cb) + options = sql; + if (typeof values === 'function') { + cb = values; + } else if (typeof values !== 'undefined') { + options.values = values; + } + } else if (typeof values === 'function') { + // query(sql, cb) + cb = values; + options.sql = sql; + options.values = undefined; + } else { + // query(sql, values, cb) + options.sql = sql; + options.values = values; + } + return new Query(options, bindToCurrentDomain(cb)); +}; + +Connection.prototype.connect = function connect(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + if (!this._connectCalled) { + this._connectCalled = true; + + // Connect either via a UNIX domain socket or a TCP socket. + this._socket = (this.config.socketPath) + ? Net.createConnection(this.config.socketPath) + : Net.createConnection(this.config.port, this.config.host); + + var connection = this; + this._protocol.on('data', function(data) { + connection._socket.write(data); + }); + this._socket.on('data', function(data) { + connection._protocol.write(data); + }); + this._protocol.on('end', function() { + connection._socket.end() + }); + this._socket.on('end', function(err) { + connection._protocol.end(); + }); + + this._socket.on('error', this._handleNetworkError.bind(this)); + this._socket.on('connect', this._handleProtocolConnect.bind(this)); + this._protocol.on('handshake', this._handleProtocolHandshake.bind(this)); + this._protocol.on('unhandledError', this._handleProtocolError.bind(this)); + this._protocol.on('drain', this._handleProtocolDrain.bind(this)); + this._protocol.on('end', this._handleProtocolEnd.bind(this)); + this._protocol.on('enqueue', this._handleProtocolEnqueue.bind(this)); + + if (this.config.connectTimeout) { + var handleConnectTimeout = this._handleConnectTimeout.bind(this); + + this._socket.setTimeout(this.config.connectTimeout, handleConnectTimeout); + this._socket.once('connect', function() { + this.setTimeout(0, handleConnectTimeout); + }); + } + } + + this._protocol.handshake(options, bindToCurrentDomain(callback)); +}; + +Connection.prototype.changeUser = function changeUser(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + this._implyConnect(); + + var charsetNumber = (options.charset) + ? ConnectionConfig.getCharsetNumber(options.charset) + : this.config.charsetNumber; + + return this._protocol.changeUser({ + user : options.user || this.config.user, + password : options.password || this.config.password, + database : options.database || this.config.database, + timeout : options.timeout, + charsetNumber : charsetNumber, + currentConfig : this.config + }, bindToCurrentDomain(callback)); +}; + +Connection.prototype.beginTransaction = function beginTransaction(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + options = options || {}; + options.sql = 'START TRANSACTION'; + options.values = null; + + return this.query(options, callback); +}; + +Connection.prototype.commit = function commit(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + options = options || {}; + options.sql = 'COMMIT'; + options.values = null; + + return this.query(options, callback); +}; + +Connection.prototype.rollback = function rollback(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + options = options || {}; + options.sql = 'ROLLBACK'; + options.values = null; + + return this.query(options, callback); +}; + +Connection.prototype.query = function(sql, values, cb) { + this._implyConnect(); + + var query = Connection.createQuery(sql, values, cb); + query._connection = this; + + if (!(typeof sql == 'object' && 'typeCast' in sql)) { + query.typeCast = this.config.typeCast; + } + + query.sql = this.format(query.sql, query.values); + + return this._protocol._enqueue(query); +}; + +Connection.prototype.ping = function ping(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + this._implyConnect(); + this._protocol.ping(options, bindToCurrentDomain(callback)); +}; + +Connection.prototype.statistics = function statistics(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + this._implyConnect(); + this._protocol.stats(options, bindToCurrentDomain(callback)); +}; + +Connection.prototype.end = function end(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + this._implyConnect(); + this._protocol.quit(options, bindToCurrentDomain(callback)); +}; + +Connection.prototype.destroy = function() { + this.state = "disconnected"; + this._implyConnect(); + this._socket.destroy(); + this._protocol.destroy(); +}; + +Connection.prototype.pause = function() { + this._socket.pause(); + this._protocol.pause(); +}; + +Connection.prototype.resume = function() { + this._socket.resume(); + this._protocol.resume(); +}; + +Connection.prototype.escape = function(value) { + return SqlString.escape(value, false, this.config.timezone); +}; + +Connection.prototype.escapeId = function escapeId(value) { + return SqlString.escapeId(value, false); +}; + +Connection.prototype.format = function(sql, values) { + if (typeof this.config.queryFormat == "function") { + return this.config.queryFormat.call(this, sql, values, this.config.timezone); + } + return SqlString.format(sql, values, this.config.stringifyObjects, this.config.timezone); +}; + +if (tls.TLSSocket) { + // 0.11+ environment + Connection.prototype._startTLS = function _startTLS(onSecure) { + var secureContext = tls.createSecureContext({ + key : this.config.ssl.key, + cert : this.config.ssl.cert, + passphrase : this.config.ssl.passphrase, + ca : this.config.ssl.ca + }); + + // "unpipe" + this._socket.removeAllListeners('data'); + this._protocol.removeAllListeners('data'); + + // socket <-> encrypted + var rejectUnauthorized = this.config.ssl.rejectUnauthorized; + var secureSocket = new tls.TLSSocket(this._socket, { + rejectUnauthorized : rejectUnauthorized, + requestCert : true, + secureContext : secureContext, + isServer : false + }); + + // cleartext <-> protocol + secureSocket.pipe(this._protocol); + this._protocol.on('data', function(data) { + secureSocket.write(data); + }); + + secureSocket.on('secure', function() { + onSecure(rejectUnauthorized ? this.ssl.verifyError() : null); + }); + + // start TLS communications + secureSocket._start(); + }; +} else { + // pre-0.11 environment + Connection.prototype._startTLS = function _startTLS(onSecure) { + // before TLS: + // _socket <-> _protocol + // after: + // _socket <-> securePair.encrypted <-> securePair.cleartext <-> _protocol + + var credentials = Crypto.createCredentials({ + key : this.config.ssl.key, + cert : this.config.ssl.cert, + passphrase : this.config.ssl.passphrase, + ca : this.config.ssl.ca + }); + + var rejectUnauthorized = this.config.ssl.rejectUnauthorized; + var securePair = tls.createSecurePair(credentials, false, true, rejectUnauthorized); + + // "unpipe" + this._socket.removeAllListeners('data'); + this._protocol.removeAllListeners('data'); + + // socket <-> encrypted + securePair.encrypted.pipe(this._socket); + this._socket.on('data', function(data) { + securePair.encrypted.write(data); + }); + + // cleartext <-> protocol + securePair.cleartext.pipe(this._protocol); + this._protocol.on('data', function(data) { + securePair.cleartext.write(data); + }); + + securePair.on('secure', function() { + if (!rejectUnauthorized) { + onSecure(); + return; + } + + var verifyError = this.ssl.verifyError(); + var err = verifyError; + + // node.js 0.6 support + if (typeof err === 'string') { + err = new Error(verifyError); + err.code = verifyError; + } + + onSecure(err); + }); + }; +} + +Connection.prototype._handleConnectTimeout = function() { + if (this._socket) { + this._socket.setTimeout(0); + this._socket.destroy(); + } + + var err = new Error('connect ETIMEDOUT'); + err.errorno = 'ETIMEDOUT'; + err.code = 'ETIMEDOUT'; + err.syscall = 'connect'; + + this._handleNetworkError(err); +}; + +Connection.prototype._handleNetworkError = function(err) { + this._protocol.handleNetworkError(err); +}; + +Connection.prototype._handleProtocolError = function(err) { + this.state = "protocol_error"; + this.emit('error', err); +}; + +Connection.prototype._handleProtocolDrain = function() { + this.emit('drain'); +}; + +Connection.prototype._handleProtocolConnect = function() { + this.state = "connected"; +}; + +Connection.prototype._handleProtocolHandshake = function _handleProtocolHandshake(packet) { + this.state = "authenticated"; + this.threadId = packet.threadId; +}; + +Connection.prototype._handleProtocolEnd = function(err) { + this.state = "disconnected"; + this.emit('end', err); +}; + +Connection.prototype._handleProtocolEnqueue = function _handleProtocolEnqueue(sequence) { + this.emit('enqueue', sequence); +}; + +Connection.prototype._implyConnect = function() { + if (!this._connectCalled) { + this.connect(); + } +}; diff --git a/node_modules/mysql/lib/ConnectionConfig.js b/node_modules/mysql/lib/ConnectionConfig.js new file mode 100644 index 0000000..294a538 --- /dev/null +++ b/node_modules/mysql/lib/ConnectionConfig.js @@ -0,0 +1,201 @@ +var urlParse = require('url').parse; +var ClientConstants = require('./protocol/constants/client'); +var Charsets = require('./protocol/constants/charsets'); +var SSLProfiles = null; + +module.exports = ConnectionConfig; +function ConnectionConfig(options) { + if (typeof options === 'string') { + options = ConnectionConfig.parseUrl(options); + } + + this.host = options.host || 'localhost'; + this.port = options.port || 3306; + this.localAddress = options.localAddress; + this.socketPath = options.socketPath; + this.user = options.user || undefined; + this.password = options.password || undefined; + this.database = options.database; + this.connectTimeout = (options.connectTimeout === undefined) + ? (10 * 1000) + : options.connectTimeout; + this.insecureAuth = options.insecureAuth || false; + this.supportBigNumbers = options.supportBigNumbers || false; + this.bigNumberStrings = options.bigNumberStrings || false; + this.dateStrings = options.dateStrings || false; + this.debug = options.debug; + this.trace = options.trace !== false; + this.stringifyObjects = options.stringifyObjects || false; + this.timezone = options.timezone || 'local'; + this.flags = options.flags || ''; + this.queryFormat = options.queryFormat; + this.pool = options.pool || undefined; + this.ssl = (typeof options.ssl === 'string') + ? ConnectionConfig.getSSLProfile(options.ssl) + : (options.ssl || false); + this.multipleStatements = options.multipleStatements || false; + this.typeCast = (options.typeCast === undefined) + ? true + : options.typeCast; + + if (this.timezone[0] == " ") { + // "+" is a url encoded char for space so it + // gets translated to space when giving a + // connection string.. + this.timezone = "+" + this.timezone.substr(1); + } + + if (this.ssl) { + // Default rejectUnauthorized to true + this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false; + } + + this.maxPacketSize = 0; + this.charsetNumber = (options.charset) + ? ConnectionConfig.getCharsetNumber(options.charset) + : options.charsetNumber||Charsets.UTF8_GENERAL_CI; + + // Set the client flags + var defaultFlags = ConnectionConfig.getDefaultFlags(options); + this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags) +} + +ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) { + var allFlags = ConnectionConfig.parseFlagList(defaultFlags); + var newFlags = ConnectionConfig.parseFlagList(userFlags); + + // Merge the new flags + for (var flag in newFlags) { + if (allFlags[flag] !== false) { + allFlags[flag] = newFlags[flag]; + } + } + + // Build flags + var flags = 0x0; + for (var flag in allFlags) { + if (allFlags[flag]) { + // TODO: Throw here on some future release + flags |= ClientConstants['CLIENT_' + flag] || 0x0; + } + } + + return flags; +}; + +ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) { + var num = Charsets[charset.toUpperCase()]; + + if (num === undefined) { + throw new TypeError('Unknown charset \'' + charset + '\''); + } + + return num; +}; + +ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) { + var defaultFlags = [ + '-COMPRESS', // Compression protocol *NOT* supported + '-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41 + '+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet + '+FOUND_ROWS', // Send found rows instead of affected rows + '+IGNORE_SIGPIPE', // Don't issue SIGPIPE if network failures + '+IGNORE_SPACE', // Let the parser ignore spaces before '(' + '+LOCAL_FILES', // Can use LOAD DATA LOCAL + '+LONG_FLAG', // Longer flags in Protocol::ColumnDefinition320 + '+LONG_PASSWORD', // Use the improved version of Old Password Authentication + '+MULTI_RESULTS', // Can handle multiple resultsets for COM_QUERY + '+ODBC', // Special handling of ODBC behaviour + '-PLUGIN_AUTH', // Does *NOT* support auth plugins + '+PROTOCOL_41', // Uses the 4.1 protocol + '+PS_MULTI_RESULTS', // Can handle multiple resultsets for COM_STMT_EXECUTE + '+RESERVED', // Unused + '+SECURE_CONNECTION', // Supports Authentication::Native41 + '+TRANSACTIONS' // Expects status flags + ]; + + if (options && options.multipleStatements) { + // May send multiple statements per COM_QUERY and COM_STMT_PREPARE + defaultFlags.push('+MULTI_STATEMENTS'); + } + + return defaultFlags; +}; + +ConnectionConfig.getSSLProfile = function getSSLProfile(name) { + if (!SSLProfiles) { + SSLProfiles = require('./../fixtures/ssl-profiles.json'); + } + + var ssl = SSLProfiles[name]; + + if (ssl === undefined) { + throw new TypeError('Unknown SSL profile \'' + name + '\''); + } + + return ssl; +}; + +ConnectionConfig.parseFlagList = function parseFlagList(flagList) { + var allFlags = Object.create(null); + + if (!flagList) { + return allFlags; + } + + var flags = !Array.isArray(flagList) + ? String(flagList || '').toUpperCase().split(/\s*,+\s*/) + : flagList; + + for (var i = 0; i < flags.length; i++) { + var flag = flags[i]; + var offset = 1; + var state = flag[0]; + + if (state === undefined) { + // TODO: throw here on some future release + continue; + } + + if (state !== '-' && state !== '+') { + offset = 0; + state = '+'; + } + + allFlags[flag.substr(offset)] = state === '+'; + } + + return allFlags; +}; + +ConnectionConfig.parseUrl = function(url) { + url = urlParse(url, true); + + var options = { + host : url.hostname, + port : url.port, + database : url.pathname.substr(1), + }; + + if (url.auth) { + var auth = url.auth.split(':'); + options.user = auth[0]; + options.password = auth[1]; + } + + if (url.query) { + for (var key in url.query) { + var value = url.query[key]; + + try { + // Try to parse this as a JSON expression first + options[key] = JSON.parse(value); + } catch (err) { + // Otherwise assume it is a plain string + options[key] = value; + } + } + } + + return options; +}; diff --git a/node_modules/mysql/lib/Pool.js b/node_modules/mysql/lib/Pool.js new file mode 100644 index 0000000..0e3000c --- /dev/null +++ b/node_modules/mysql/lib/Pool.js @@ -0,0 +1,264 @@ +var mysql = require('../'); +var Connection = require('./Connection'); +var EventEmitter = require('events').EventEmitter; +var Util = require('util'); +var PoolConnection = require('./PoolConnection'); + +module.exports = Pool; + +Util.inherits(Pool, EventEmitter); +function Pool(options) { + EventEmitter.call(this); + this.config = options.config; + this.config.connectionConfig.pool = this; + + this._acquiringConnections = []; + this._allConnections = []; + this._freeConnections = []; + this._connectionQueue = []; + this._closed = false; +} + +Pool.prototype.getConnection = function (cb) { + + if (this._closed) { + return process.nextTick(function(){ + return cb(new Error('Pool is closed.')); + }); + } + + var connection; + var pool = this; + + if (this._freeConnections.length > 0) { + connection = this._freeConnections.shift(); + + return this.acquireConnection(connection, cb); + } + + if (this.config.connectionLimit === 0 || this._allConnections.length < this.config.connectionLimit) { + connection = new PoolConnection(this, { config: this.config.newConnectionConfig() }); + + this._acquiringConnections.push(connection); + this._allConnections.push(connection); + + return connection.connect({timeout: this.config.acquireTimeout}, function onConnect(err) { + spliceConnection(pool._acquiringConnections, connection); + + if (pool._closed) { + err = new Error('Pool is closed.'); + } + + if (err) { + pool._purgeConnection(connection); + cb(err); + return; + } + + pool.emit('connection', connection); + cb(null, connection); + }); + } + + if (!this.config.waitForConnections) { + return process.nextTick(function(){ + return cb(new Error('No connections available.')); + }); + } + + this._enqueueCallback(cb); +}; + +Pool.prototype.acquireConnection = function acquireConnection(connection, cb) { + if (connection._pool !== this) { + throw new Error('Connection acquired from wrong pool.'); + } + + var pool = this; + + this._acquiringConnections.push(connection); + + connection.ping({timeout: this.config.acquireTimeout}, function onPing(err) { + spliceConnection(pool._acquiringConnections, connection); + + if (pool._closed) { + err = new Error('Pool is closed.'); + } + + if (err) { + pool._connectionQueue.unshift(cb); + pool._purgeConnection(connection); + return; + } + + cb(null, connection); + }); +}; + +Pool.prototype.releaseConnection = function releaseConnection(connection) { + var cb; + + if (this._acquiringConnections.indexOf(connection) !== -1) { + // connection is being acquired + return; + } + + if (connection._pool) { + if (connection._pool !== this) { + throw new Error('Connection released to wrong pool'); + } + + if (connection._purge) { + // purge connection from pool + this._purgeConnection(connection); + return; + } else if (this._freeConnections.indexOf(connection) !== -1) { + // connection already in free connection pool + // this won't catch all double-release cases + throw new Error('Connection already released'); + } else { + // add connection to end of free queue + this._freeConnections.push(connection); + } + } + + while (this._closed && this._connectionQueue.length) { + // empty the connection queue + cb = this._connectionQueue.shift(); + + process.nextTick(cb.bind(null, new Error('Pool is closed.'))); + } + + if (this._connectionQueue.length) { + cb = this._connectionQueue.shift(); + + this.getConnection(cb); + } +}; + +Pool.prototype.end = function (cb) { + this._closed = true; + + if (typeof cb != "function") { + cb = function (err) { + if (err) throw err; + }; + } + + var calledBack = false; + var waitingClose = this._allConnections.length; + + function onEnd(err) { + if (calledBack) { + return; + } + + if (err || --waitingClose === 0) { + calledBack = true; + return cb(err); + } + } + + if (waitingClose === 0) { + return process.nextTick(cb); + } + + while (this._allConnections.length !== 0) { + this._purgeConnection(this._allConnections[0], onEnd); + } +}; + +Pool.prototype.query = function (sql, values, cb) { + var query = Connection.createQuery(sql, values, cb); + + if (!(typeof sql === 'object' && 'typeCast' in sql)) { + query.typeCast = this.config.connectionConfig.typeCast; + } + + if (this.config.connectionConfig.trace) { + // Long stack trace support + query._callSite = new Error; + } + + this.getConnection(function (err, conn) { + if (err) { + var cb = query._callback; + cb && cb(err); + return; + } + + // Release connection based off event + query.once('end', function() { + conn.release(); + }); + + conn.query(query); + }); + + return query; +}; + +Pool.prototype._enqueueCallback = function _enqueueCallback(callback) { + + if (this.config.queueLimit && this._connectionQueue.length >= this.config.queueLimit) { + process.nextTick(function () { + var err = new Error('Queue limit reached.'); + err.code = 'POOL_ENQUEUELIMIT'; + callback(err); + }); + return; + } + + // Bind to domain, as dequeue will likely occur in a different domain + var cb = process.domain + ? process.domain.bind(callback) + : callback; + + this._connectionQueue.push(cb); + this.emit('enqueue'); +}; + +Pool.prototype._purgeConnection = function _purgeConnection(connection, callback) { + var cb = callback || function () {}; + + if (connection.state === 'disconnected') { + connection.destroy(); + } + + this._removeConnection(connection); + + if (connection.state !== 'disconnected' && !connection._protocol._quitSequence) { + connection._realEnd(cb); + return; + } + + process.nextTick(cb); +}; + +Pool.prototype._removeConnection = function(connection) { + connection._pool = null; + + // Remove connection from all connections + spliceConnection(this._allConnections, connection); + + // Remove connection from free connections + spliceConnection(this._freeConnections, connection); + + this.releaseConnection(connection); +}; + +Pool.prototype.escape = function(value) { + return mysql.escape(value, this.config.connectionConfig.stringifyObjects, this.config.connectionConfig.timezone); +}; + +Pool.prototype.escapeId = function escapeId(value) { + return mysql.escapeId(value, false); +}; + +function spliceConnection(array, connection) { + var index; + if ((index = array.indexOf(connection)) !== -1) { + // Remove connection from all connections + array.splice(index, 1); + } +} diff --git a/node_modules/mysql/lib/PoolCluster.js b/node_modules/mysql/lib/PoolCluster.js new file mode 100644 index 0000000..e2af239 --- /dev/null +++ b/node_modules/mysql/lib/PoolCluster.js @@ -0,0 +1,256 @@ +var Pool = require('./Pool'); +var PoolConfig = require('./PoolConfig'); +var Util = require('util'); +var EventEmitter = require('events').EventEmitter; + +module.exports = PoolCluster; + +/** + * PoolCluster + */ +function PoolCluster(config) { + EventEmitter.call(this); + + config = config || {}; + this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry; + this._removeNodeErrorCount = config.removeNodeErrorCount || 5; + this._defaultSelector = config.defaultSelector || 'RR'; + + this._closed = false; + this._lastId = 0; + this._nodes = {}; + this._serviceableNodeIds = []; + this._namespaces = {}; + this._findCaches = {}; +} + +Util.inherits(PoolCluster, EventEmitter); + +PoolCluster.prototype.of = function(pattern, selector) { + pattern = pattern || '*'; + + selector = selector || this._defaultSelector; + selector = selector.toUpperCase(); + if (typeof Selector[selector] === 'undefined') { + selector = this._defaultSelector; + } + + var key = pattern + selector; + + if (typeof this._namespaces[key] === 'undefined') { + this._namespaces[key] = new PoolNamespace(this, pattern, selector); + } + + return this._namespaces[key]; +}; + +PoolCluster.prototype.add = function(id, config) { + if (typeof id === 'object') { + config = id; + id = 'CLUSTER::' + (++this._lastId); + } + + if (typeof this._nodes[id] === 'undefined') { + this._nodes[id] = { + id: id, + errorCount: 0, + pool: new Pool({config: new PoolConfig(config)}) + }; + + this._serviceableNodeIds.push(id); + + this._clearFindCaches(); + } +}; + +PoolCluster.prototype.getConnection = function(pattern, selector, cb) { + var namespace; + if (typeof pattern === 'function') { + cb = pattern; + namespace = this.of(); + } else { + if (typeof selector === 'function') { + cb = selector; + selector = this._defaultSelector; + } + + namespace = this.of(pattern, selector); + } + + namespace.getConnection(cb); +}; + +PoolCluster.prototype.end = function() { + if (this._closed) { + return; + } + + this._closed = true; + + for (var id in this._nodes) { + this._nodes[id].pool.end(); + } +}; + +PoolCluster.prototype._findNodeIds = function(pattern) { + if (typeof this._findCaches[pattern] !== 'undefined') { + return this._findCaches[pattern]; + } + + var foundNodeIds; + + if (pattern === '*') { // all + foundNodeIds = this._serviceableNodeIds; + } else if (this._serviceableNodeIds.indexOf(pattern) != -1) { // one + foundNodeIds = [pattern]; + } else if (pattern[pattern.length - 1] === '*') { + // wild matching + var keyword = pattern.substring(pattern.length - 1, 0); + + foundNodeIds = this._serviceableNodeIds.filter(function (id) { + return id.indexOf(keyword) === 0; + }); + } else { + foundNodeIds = []; + } + + this._findCaches[pattern] = foundNodeIds; + + return foundNodeIds; +}; + +PoolCluster.prototype._getNode = function(id) { + return this._nodes[id] || null; +}; + +PoolCluster.prototype._increaseErrorCount = function(node) { + if (++node.errorCount >= this._removeNodeErrorCount) { + var index = this._serviceableNodeIds.indexOf(node.id); + if (index !== -1) { + this._serviceableNodeIds.splice(index, 1); + delete this._nodes[node.id]; + + this._clearFindCaches(); + + node.pool.end(); + + this.emit('remove', node.id); + } + } +}; + +PoolCluster.prototype._decreaseErrorCount = function(node) { + if (node.errorCount > 0) { + --node.errorCount; + } +}; + +PoolCluster.prototype._getConnection = function(node, cb) { + var self = this; + + node.pool.getConnection(function (err, connection) { + if (err) { + self._increaseErrorCount(node); + cb(err); + return; + } else { + self._decreaseErrorCount(node); + } + + connection._clusterId = node.id; + + cb(null, connection); + }); +}; + +PoolCluster.prototype._clearFindCaches = function() { + this._findCaches = {}; +}; + +/** + * PoolNamespace + */ +function PoolNamespace(cluster, pattern, selector) { + this._cluster = cluster; + this._pattern = pattern; + this._selector = new Selector[selector](); +} + +PoolNamespace.prototype.getConnection = function(cb) { + var clusterNode = this._getClusterNode(); + var cluster = this._cluster; + var namespace = this; + + if (clusterNode === null) { + var err = new Error('Pool does not exist.') + err.code = 'POOL_NOEXIST'; + return cb(err); + } + + cluster._getConnection(clusterNode, function(err, connection) { + var retry = err && cluster._canRetry + && cluster._findNodeIds(namespace._pattern).length !== 0; + + if (retry) { + return namespace.getConnection(cb); + } + + if (err) { + return cb(err); + } + + cb(null, connection); + }); +}; + +PoolNamespace.prototype._getClusterNode = function _getClusterNode() { + var foundNodeIds = this._cluster._findNodeIds(this._pattern); + var nodeId; + + switch (foundNodeIds.length) { + case 0: + nodeId = null; + break; + case 1: + nodeId = foundNodeIds[0]; + break; + default: + nodeId = this._selector(foundNodeIds); + break; + } + + return nodeId !== null + ? this._cluster._getNode(nodeId) + : null; +}; + +/** + * Selector + */ +var Selector = {}; + +Selector.RR = function () { + var index = 0; + + return function(clusterIds) { + if (index >= clusterIds.length) { + index = 0; + } + + var clusterId = clusterIds[index++]; + + return clusterId; + }; +}; + +Selector.RANDOM = function () { + return function(clusterIds) { + return clusterIds[Math.floor(Math.random() * clusterIds.length)]; + }; +}; + +Selector.ORDER = function () { + return function(clusterIds) { + return clusterIds[0]; + }; +}; diff --git a/node_modules/mysql/lib/PoolConfig.js b/node_modules/mysql/lib/PoolConfig.js new file mode 100644 index 0000000..8c5017a --- /dev/null +++ b/node_modules/mysql/lib/PoolConfig.js @@ -0,0 +1,32 @@ + +var ConnectionConfig = require('./ConnectionConfig'); + +module.exports = PoolConfig; +function PoolConfig(options) { + if (typeof options === 'string') { + options = ConnectionConfig.parseUrl(options); + } + + this.acquireTimeout = (options.acquireTimeout === undefined) + ? 10 * 1000 + : Number(options.acquireTimeout); + this.connectionConfig = new ConnectionConfig(options); + this.waitForConnections = (options.waitForConnections === undefined) + ? true + : Boolean(options.waitForConnections); + this.connectionLimit = (options.connectionLimit === undefined) + ? 10 + : Number(options.connectionLimit); + this.queueLimit = (options.queueLimit === undefined) + ? 0 + : Number(options.queueLimit); +} + +PoolConfig.prototype.newConnectionConfig = function newConnectionConfig() { + var connectionConfig = new ConnectionConfig(this.connectionConfig); + + connectionConfig.clientFlags = this.connectionConfig.clientFlags; + connectionConfig.maxPacketSize = this.connectionConfig.maxPacketSize; + + return connectionConfig; +}; diff --git a/node_modules/mysql/lib/PoolConnection.js b/node_modules/mysql/lib/PoolConnection.js new file mode 100644 index 0000000..a99fdb0 --- /dev/null +++ b/node_modules/mysql/lib/PoolConnection.js @@ -0,0 +1,62 @@ +var inherits = require('util').inherits; +var Connection = require('./Connection') +var __changeUser = Connection.prototype.changeUser; + +module.exports = PoolConnection; +inherits(PoolConnection, Connection); + +function PoolConnection(pool, options) { + Connection.call(this, options); + this._pool = pool; + this._purge = false + + // When a fatal error occurs the connection's protocol ends, which will cause + // the connection to end as well, thus we only need to watch for the end event + // and we will be notified of disconnects. + this.on('end', this._removeFromPool); + this.on('error', this._removeFromPool); +} + +PoolConnection.prototype.changeUser = function changeUser(options, callback) { + this._purge = true; + + return __changeUser.apply(this, arguments); +}; + +PoolConnection.prototype.release = function release() { + var pool = this._pool; + + if (!pool || pool._closed) { + return; + } + + return pool.releaseConnection(this); +}; + +// TODO: Remove this when we are removing PoolConnection#end +PoolConnection.prototype._realEnd = Connection.prototype.end; + +PoolConnection.prototype.end = function () { + console.warn( 'Calling conn.end() to release a pooled connection is ' + + 'deprecated. In next version calling conn.end() will be ' + + 'restored to default conn.end() behavior. Use ' + + 'conn.release() instead.' + ); + this.release(); +}; + +PoolConnection.prototype.destroy = function () { + this._removeFromPool(this); + return Connection.prototype.destroy.apply(this, arguments); +}; + +PoolConnection.prototype._removeFromPool = function(connection) { + if (!this._pool || this._pool._closed) { + return; + } + + var pool = this._pool; + this._pool = null; + + pool._removeConnection(this); +}; diff --git a/node_modules/mysql/lib/protocol/Auth.js b/node_modules/mysql/lib/protocol/Auth.js new file mode 100644 index 0000000..edf2f25 --- /dev/null +++ b/node_modules/mysql/lib/protocol/Auth.js @@ -0,0 +1,165 @@ +var Buffer = require('buffer').Buffer; +var Crypto = require('crypto'); +var Auth = exports; + +function sha1(msg) { + var hash = Crypto.createHash('sha1'); + hash.update(msg, 'binary'); + return hash.digest('binary'); +} +Auth.sha1 = sha1; + +function xor(a, b) { + a = new Buffer(a, 'binary'); + b = new Buffer(b, 'binary'); + var result = new Buffer(a.length); + for (var i = 0; i < a.length; i++) { + result[i] = (a[i] ^ b[i]); + } + return result; +}; +Auth.xor = xor; + +Auth.token = function(password, scramble) { + if (!password) { + return new Buffer(0); + } + + // password must be in binary format, not utf8 + var stage1 = sha1((new Buffer(password, "utf8")).toString("binary")); + var stage2 = sha1(stage1); + var stage3 = sha1(scramble.toString('binary') + stage2); + return xor(stage3, stage1); +}; + +// This is a port of sql/password.c:hash_password which needs to be used for +// pre-4.1 passwords. +Auth.hashPassword = function(password) { + var nr = [0x5030, 0x5735], + add = 7, + nr2 = [0x1234, 0x5671], + result = new Buffer(8); + + if (typeof password == 'string'){ + password = new Buffer(password); + } + + for (var i = 0; i < password.length; i++) { + var c = password[i]; + if (c == 32 || c == 9) { + // skip space in password + continue; + } + + // nr^= (((nr & 63)+add)*c)+ (nr << 8); + // nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8))) + nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0,63]), [0,add]), [0,c]), this.shl32(nr, 8))); + + // nr2+=(nr2 << 8) ^ nr; + // nr2 = add(nr2, xor(shl(nr2, 8), nr)) + nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr)); + + // add+=tmp; + add += c; + } + + this.int31Write(result, nr, 0); + this.int31Write(result, nr2, 4); + + return result; +}; + +Auth.randomInit = function(seed1, seed2) { + return { + max_value: 0x3FFFFFFF, + max_value_dbl: 0x3FFFFFFF, + seed1: seed1 % 0x3FFFFFFF, + seed2: seed2 % 0x3FFFFFFF + }; +}; + +Auth.myRnd = function(r){ + r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value; + r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value; + + return r.seed1 / r.max_value_dbl; +}; + +Auth.scramble323 = function(message, password) { + var to = new Buffer(8), + hashPass = this.hashPassword(password), + hashMessage = this.hashPassword(message.slice(0, 8)), + seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0), + seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4), + r = this.randomInit(seed1, seed2); + + for (var i = 0; i < 8; i++){ + to[i] = Math.floor(this.myRnd(r) * 31) + 64; + } + var extra = (Math.floor(this.myRnd(r) * 31)); + + for (var i = 0; i < 8; i++){ + to[i] ^= extra; + } + + return to; +}; + +Auth.fmt32 = function(x){ + var a = x[0].toString(16), + b = x[1].toString(16); + + if (a.length == 1) a = '000'+a; + if (a.length == 2) a = '00'+a; + if (a.length == 3) a = '0'+a; + if (b.length == 1) b = '000'+b; + if (b.length == 2) b = '00'+b; + if (b.length == 3) b = '0'+b; + return '' + a + '/' + b; +}; + +Auth.xor32 = function(a,b){ + return [a[0] ^ b[0], a[1] ^ b[1]]; +}; + +Auth.add32 = function(a,b){ + var w1 = a[1] + b[1], + w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16); + + return [w2 & 0xFFFF, w1 & 0xFFFF]; +}; + +Auth.mul32 = function(a,b){ + // based on this example of multiplying 32b ints using 16b + // http://www.dsprelated.com/showmessage/89790/1.php + var w1 = a[1] * b[1], + w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF); + + return [w2 & 0xFFFF, w1 & 0xFFFF]; +}; + +Auth.and32 = function(a,b){ + return [a[0] & b[0], a[1] & b[1]]; +}; + +Auth.shl32 = function(a,b){ + // assume b is 16 or less + var w1 = a[1] << b, + w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16); + + return [w2 & 0xFFFF, w1 & 0xFFFF]; +}; + +Auth.int31Write = function(buffer, number, offset) { + buffer[offset] = (number[0] >> 8) & 0x7F; + buffer[offset + 1] = (number[0]) & 0xFF; + buffer[offset + 2] = (number[1] >> 8) & 0xFF; + buffer[offset + 3] = (number[1]) & 0xFF; +}; + +Auth.int32Read = function(buffer, offset){ + return (buffer[offset] << 24) + + (buffer[offset+1] << 16) + + (buffer[offset+2] << 8) + + (buffer[offset+3]); +}; diff --git a/node_modules/mysql/lib/protocol/PacketHeader.js b/node_modules/mysql/lib/protocol/PacketHeader.js new file mode 100644 index 0000000..1bb282e --- /dev/null +++ b/node_modules/mysql/lib/protocol/PacketHeader.js @@ -0,0 +1,5 @@ +module.exports = PacketHeader; +function PacketHeader(length, number) { + this.length = length; + this.number = number; +} diff --git a/node_modules/mysql/lib/protocol/PacketWriter.js b/node_modules/mysql/lib/protocol/PacketWriter.js new file mode 100644 index 0000000..7de4e5a --- /dev/null +++ b/node_modules/mysql/lib/protocol/PacketWriter.js @@ -0,0 +1,197 @@ +var BIT_16 = Math.pow(2, 16); +var BIT_24 = Math.pow(2, 24); +// The maximum precision JS Numbers can hold precisely +// Don't panic: Good enough to represent byte values up to 8192 TB +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53); +var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; + +module.exports = PacketWriter; +function PacketWriter() { + this._buffer = new Buffer(0); + this._offset = 0; +} + +PacketWriter.prototype.toBuffer = function(parser) { + var packets = Math.floor(this._buffer.length / MAX_PACKET_LENGTH) + 1; + var buffer = this._buffer; + this._buffer = new Buffer(this._buffer.length + packets * 4); + + for (var packet = 0; packet < packets; packet++) { + this._offset = packet * (MAX_PACKET_LENGTH + 4); + + var isLast = (packet + 1 === packets); + var packetLength = (isLast) + ? buffer.length % MAX_PACKET_LENGTH + : MAX_PACKET_LENGTH; + + var packetNumber = parser.incrementPacketNumber(); + + this.writeUnsignedNumber(3, packetLength); + this.writeUnsignedNumber(1, packetNumber); + + var start = packet * MAX_PACKET_LENGTH; + var end = start + packetLength; + + this.writeBuffer(buffer.slice(start, end)); + } + + return this._buffer; +}; + +PacketWriter.prototype.writeUnsignedNumber = function(bytes, value) { + this._allocate(bytes); + + for (var i = 0; i < bytes; i++) { + this._buffer[this._offset++] = (value >> (i * 8)) & 0xff; + } +}; + +PacketWriter.prototype.writeFiller = function(bytes) { + this._allocate(bytes); + + for (var i = 0; i < bytes; i++) { + this._buffer[this._offset++] = 0x00; + } +}; + +PacketWriter.prototype.writeNullTerminatedString = function(value, encoding) { + // Typecast undefined into '' and numbers into strings + value = value || ''; + value = value + ''; + + var bytes = Buffer.byteLength(value, encoding || 'utf-8') + 1; + this._allocate(bytes); + + this._buffer.write(value, this._offset, encoding); + this._buffer[this._offset + bytes - 1] = 0x00; + + this._offset += bytes; +}; + +PacketWriter.prototype.writeString = function(value) { + // Typecast undefined into '' and numbers into strings + value = value || ''; + value = value + ''; + + var bytes = Buffer.byteLength(value, 'utf-8'); + this._allocate(bytes); + + this._buffer.write(value, this._offset, 'utf-8'); + + this._offset += bytes; +}; + +PacketWriter.prototype.writeBuffer = function(value) { + var bytes = value.length; + + this._allocate(bytes); + value.copy(this._buffer, this._offset); + this._offset += bytes; +}; + +PacketWriter.prototype.writeLengthCodedNumber = function(value) { + if (value === null) { + this._allocate(1); + this._buffer[this._offset++] = 251; + return; + } + + if (value <= 250) { + this._allocate(1); + this._buffer[this._offset++] = value; + return; + } + + if (value > IEEE_754_BINARY_64_PRECISION) { + throw new Error( + 'writeLengthCodedNumber: JS precision range exceeded, your ' + + 'number is > 53 bit: "' + value + '"' + ); + } + + if (value <= BIT_16) { + this._allocate(3) + this._buffer[this._offset++] = 252; + } else if (value <= BIT_24) { + this._allocate(4) + this._buffer[this._offset++] = 253; + } else { + this._allocate(9); + this._buffer[this._offset++] = 254; + } + + // 16 Bit + this._buffer[this._offset++] = value & 0xff; + this._buffer[this._offset++] = (value >> 8) & 0xff; + + if (value <= BIT_16) return; + + // 24 Bit + this._buffer[this._offset++] = (value >> 16) & 0xff; + + if (value <= BIT_24) return; + + this._buffer[this._offset++] = (value >> 24) & 0xff; + + // Hack: Get the most significant 32 bit (JS bitwise operators are 32 bit) + value = value.toString(2); + value = value.substr(0, value.length - 32); + value = parseInt(value, 2); + + this._buffer[this._offset++] = value & 0xff; + this._buffer[this._offset++] = (value >> 8) & 0xff; + this._buffer[this._offset++] = (value >> 16) & 0xff; + + // Set last byte to 0, as we can only support 53 bits in JS (see above) + this._buffer[this._offset++] = 0; +}; + +PacketWriter.prototype.writeLengthCodedBuffer = function(value) { + var bytes = value.length; + this.writeLengthCodedNumber(bytes); + this.writeBuffer(value); +}; + +PacketWriter.prototype.writeNullTerminatedBuffer = function(value) { + this.writeBuffer(value); + this.writeFiller(1); // 0x00 terminator +}; + +PacketWriter.prototype.writeLengthCodedString = function(value) { + if (value === null) { + this.writeLengthCodedNumber(null); + return; + } + + value = (value === undefined) + ? '' + : String(value); + + var bytes = Buffer.byteLength(value, 'utf-8'); + this.writeLengthCodedNumber(bytes); + + if (!bytes) { + return; + } + + this._allocate(bytes); + this._buffer.write(value, this._offset, 'utf-8'); + this._offset += bytes; +}; + +PacketWriter.prototype._allocate = function(bytes) { + if (!this._buffer) { + this._buffer = new Buffer(bytes); + return; + } + + var bytesRemaining = this._buffer.length - this._offset; + if (bytesRemaining >= bytes) { + return; + } + + var oldBuffer = this._buffer; + + this._buffer = new Buffer(oldBuffer.length + bytes); + oldBuffer.copy(this._buffer); +}; diff --git a/node_modules/mysql/lib/protocol/Parser.js b/node_modules/mysql/lib/protocol/Parser.js new file mode 100644 index 0000000..bf8e65a --- /dev/null +++ b/node_modules/mysql/lib/protocol/Parser.js @@ -0,0 +1,423 @@ +var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1; +var MUL_32BIT = Math.pow(2, 32); +var PacketHeader = require('./PacketHeader'); +var BigNumber = require('bignumber.js'); + +module.exports = Parser; +function Parser(options) { + options = options || {}; + + this._supportBigNumbers = options.config && options.config.supportBigNumbers; + this._buffer = new Buffer(0); + this._longPacketBuffers = []; + this._offset = 0; + this._packetEnd = null; + this._packetHeader = null; + this._packetOffset = null; + this._onError = options.onError || function(err) { throw err; }; + this._onPacket = options.onPacket || function() {}; + this._nextPacketNumber = 0; + this._encoding = 'utf-8'; + this._paused = false; +} + +Parser.prototype.write = function(buffer) { + this.append(buffer); + + while (true) { + if (this._paused) { + return; + } + + if (!this._packetHeader) { + if (this._bytesRemaining() < 4) { + break; + } + + this._packetHeader = new PacketHeader( + this.parseUnsignedNumber(3), + this.parseUnsignedNumber(1) + ); + + if (this._packetHeader.number !== this._nextPacketNumber) { + var err = new Error( + 'Packets out of order. Got: ' + this._packetHeader.number + ' ' + + 'Expected: ' + this._nextPacketNumber + ); + + err.code = 'PROTOCOL_PACKETS_OUT_OF_ORDER'; + err.fatal = true; + + this._onError(err); + } + + this.incrementPacketNumber(); + } + + if (this._bytesRemaining() < this._packetHeader.length) { + break; + } + + this._packetEnd = this._offset + this._packetHeader.length; + this._packetOffset = this._offset; + + if (this._packetHeader.length === MAX_PACKET_LENGTH) { + this._longPacketBuffers.push(this._buffer.slice(this._packetOffset, this._packetEnd)); + + this._advanceToNextPacket(); + continue; + } + + this._combineLongPacketBuffers(); + + // Try...finally to ensure exception safety. Unfortunately this is costing + // us up to ~10% performance in some benchmarks. + var hadException = true; + try { + this._onPacket(this._packetHeader); + hadException = false; + } catch (err) { + if (typeof err.code !== 'string' || err.code.substr(0, 7) !== 'PARSER_') { + // Rethrow unknown errors + throw err; + } + + // Pass down parser errors + this._onError(err); + hadException = false; + } finally { + this._advanceToNextPacket(); + + // If we had an exception, the parser while loop will be broken out + // of after the finally block. So we need to make sure to re-enter it + // to continue parsing any bytes that may already have been received. + if (hadException) { + process.nextTick(this.write.bind(this)); + } + } + } +}; + +Parser.prototype.append = function append(chunk) { + if (!chunk || chunk.length === 0) { + return; + } + + var buffer = chunk; + var sliceEnd = this._buffer.length; + var sliceStart = this._packetOffset === null + ? this._offset + : this._packetOffset; + var sliceLength = sliceEnd - sliceStart; + + if (sliceLength !== 0) { + // Create a new Buffer + buffer = new Buffer(sliceLength + chunk.length); + + // Copy data + this._buffer.copy(buffer, 0, sliceStart, sliceEnd); + chunk.copy(buffer, sliceLength); + } + + // Adjust data-tracking pointers + this._buffer = buffer; + this._offset = this._offset - sliceStart; + this._packetEnd = this._packetEnd !== null + ? this._packetEnd - sliceStart + : null; + this._packetOffset = this._packetOffset !== null + ? this._packetOffset - sliceStart + : null; +}; + +Parser.prototype.pause = function() { + this._paused = true; +}; + +Parser.prototype.resume = function() { + this._paused = false; + + // nextTick() to avoid entering write() multiple times within the same stack + // which would cause problems as write manipulates the state of the object. + process.nextTick(this.write.bind(this)); +}; + +Parser.prototype.peak = function() { + return this._buffer[this._offset]; +}; + +Parser.prototype.parseUnsignedNumber = function(bytes) { + if (bytes === 1) { + return this._buffer[this._offset++]; + } + + var buffer = this._buffer; + var offset = this._offset + bytes - 1; + var value = 0; + + if (bytes > 4) { + var err = new Error('parseUnsignedNumber: Supports only up to 4 bytes'); + err.offset = (this._offset - this._packetOffset - 1); + err.code = 'PARSER_UNSIGNED_TOO_LONG'; + throw err; + } + + while (offset >= this._offset) { + value = ((value << 8) | buffer[offset]) >>> 0; + offset--; + } + + this._offset += bytes; + + return value; +}; + +Parser.prototype.parseLengthCodedString = function() { + var length = this.parseLengthCodedNumber(); + + if (length === null) { + return null; + } + + return this.parseString(length); +}; + +Parser.prototype.parseLengthCodedBuffer = function() { + var length = this.parseLengthCodedNumber(); + + if (length === null) { + return null; + } + + return this.parseBuffer(length); +}; + +Parser.prototype.parseLengthCodedNumber = function parseLengthCodedNumber() { + if (this._offset >= this._buffer.length) { + var err = new Error('Parser: read past end'); + err.offset = (this._offset - this._packetOffset); + err.code = 'PARSER_READ_PAST_END'; + throw err; + } + + var bits = this._buffer[this._offset++]; + + if (bits <= 250) { + return bits; + } + + switch (bits) { + case 251: + return null; + case 252: + return this.parseUnsignedNumber(2); + case 253: + return this.parseUnsignedNumber(3); + case 254: + break; + default: + var err = new Error('Unexpected first byte' + (bits ? ': 0x' + bits.toString(16) : '')); + err.offset = (this._offset - this._packetOffset - 1); + err.code = 'PARSER_BAD_LENGTH_BYTE'; + throw err; + } + + var low = this.parseUnsignedNumber(4); + var high = this.parseUnsignedNumber(4); + var value; + + if (high >>> 21) { + value = (new BigNumber(low)).plus((new BigNumber(MUL_32BIT)).times(high)).toString(); + + if (this._supportBigNumbers) { + return value; + } + + var err = new Error( + 'parseLengthCodedNumber: JS precision range exceeded, ' + + 'number is >= 53 bit: "' + value + '"' + ); + err.offset = (this._offset - this._packetOffset - 8); + err.code = 'PARSER_JS_PRECISION_RANGE_EXCEEDED'; + throw err; + } + + value = low + (MUL_32BIT * high); + + return value; +}; + +Parser.prototype.parseFiller = function(length) { + return this.parseBuffer(length); +}; + +Parser.prototype.parseNullTerminatedBuffer = function() { + var end = this._nullByteOffset(); + var value = this._buffer.slice(this._offset, end); + this._offset = end + 1; + + return value; +}; + +Parser.prototype.parseNullTerminatedString = function() { + var end = this._nullByteOffset(); + var value = this._buffer.toString(this._encoding, this._offset, end); + this._offset = end + 1; + + return value; +}; + +Parser.prototype._nullByteOffset = function() { + var offset = this._offset; + + while (this._buffer[offset] !== 0x00) { + offset++; + + if (offset >= this._buffer.length) { + var err = new Error('Offset of null terminated string not found.'); + err.offset = (this._offset - this._packetOffset); + err.code = 'PARSER_MISSING_NULL_BYTE'; + throw err; + } + } + + return offset; +}; + +Parser.prototype.parsePacketTerminatedString = function() { + var length = this._packetEnd - this._offset; + return this.parseString(length); +}; + +Parser.prototype.parseBuffer = function(length) { + var response = new Buffer(length); + this._buffer.copy(response, 0, this._offset, this._offset + length); + + this._offset += length; + return response; +}; + +Parser.prototype.parseString = function(length) { + var offset = this._offset; + var end = offset + length; + var value = this._buffer.toString(this._encoding, offset, end); + + this._offset = end; + return value; +}; + +Parser.prototype.parseGeometryValue = function() { + var buffer = this.parseLengthCodedBuffer(); + var offset = 4; + + if (buffer === null || !buffer.length) { + return null; + } + + function parseGeometry() { + var result = null; + var byteOrder = buffer.readUInt8(offset); offset += 1; + var wkbType = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + switch(wkbType) { + case 1: // WKBPoint + var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + result = {x: x, y: y}; + break; + case 2: // WKBLineString + var numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + result = []; + for(var i=numPoints;i>0;i--) { + var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + result.push({x: x, y: y}); + } + break; + case 3: // WKBPolygon + var numRings = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + result = []; + for(var i=numRings;i>0;i--) { + var numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + var line = []; + for(var j=numPoints;j>0;j--) { + var x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + var y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + line.push({x: x, y: y}); + } + result.push(line); + } + break; + case 4: // WKBMultiPoint + case 5: // WKBMultiLineString + case 6: // WKBMultiPolygon + case 7: // WKBGeometryCollection + var num = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + var result = []; + for(var i=num;i>0;i--) { + result.push(parseGeometry()); + } + break; + } + return result; + } + return parseGeometry(); +}; + +Parser.prototype.reachedPacketEnd = function() { + return this._offset === this._packetEnd; +}; + +Parser.prototype._bytesRemaining = function() { + return this._buffer.length - this._offset; +}; + +Parser.prototype.incrementPacketNumber = function() { + var currentPacketNumber = this._nextPacketNumber; + this._nextPacketNumber = (this._nextPacketNumber + 1) % 256; + + return currentPacketNumber; +}; + +Parser.prototype.resetPacketNumber = function() { + this._nextPacketNumber = 0; +}; + +Parser.prototype.packetLength = function() { + return this._longPacketBuffers.reduce(function(length, buffer) { + return length + buffer.length; + }, this._packetHeader.length); +}; + +Parser.prototype._combineLongPacketBuffers = function() { + if (!this._longPacketBuffers.length) { + return; + } + + var trailingPacketBytes = this._buffer.length - this._packetEnd; + + var length = this._longPacketBuffers.reduce(function(length, buffer) { + return length + buffer.length; + }, this._bytesRemaining()); + + var combinedBuffer = new Buffer(length); + + var offset = this._longPacketBuffers.reduce(function(offset, buffer) { + buffer.copy(combinedBuffer, offset); + return offset + buffer.length; + }, 0); + + this._buffer.copy(combinedBuffer, offset, this._offset); + + this._buffer = combinedBuffer; + this._longPacketBuffers = []; + this._offset = 0; + this._packetEnd = this._buffer.length - trailingPacketBytes; + this._packetOffset = 0; +}; + +Parser.prototype._advanceToNextPacket = function() { + this._offset = this._packetEnd; + this._packetHeader = null; + this._packetEnd = null; + this._packetOffset = null; +}; diff --git a/node_modules/mysql/lib/protocol/Protocol.js b/node_modules/mysql/lib/protocol/Protocol.js new file mode 100644 index 0000000..35bf0ef --- /dev/null +++ b/node_modules/mysql/lib/protocol/Protocol.js @@ -0,0 +1,446 @@ +var Parser = require('./Parser'); +var Sequences = require('./sequences'); +var Packets = require('./packets'); +var Timers = require('timers'); +var Stream = require('stream').Stream; +var Util = require('util'); +var PacketWriter = require('./PacketWriter'); + +module.exports = Protocol; +Util.inherits(Protocol, Stream); +function Protocol(options) { + Stream.call(this); + + options = options || {}; + + this.readable = true; + this.writable = true; + + this._config = options.config || {}; + this._connection = options.connection; + this._callback = null; + this._fatalError = null; + this._quitSequence = null; + this._handshakeSequence = null; + this._handshaked = false; + this._ended = false; + this._destroyed = false; + this._queue = []; + this._handshakeInitializationPacket = null; + + this._parser = new Parser({ + onError : this.handleParserError.bind(this), + onPacket : this._parsePacket.bind(this), + config : this._config + }); +} + +Protocol.prototype.write = function(buffer) { + this._parser.write(buffer); + return true; +}; + +Protocol.prototype.handshake = function handshake(options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + options = options || {}; + options.config = this._config; + + return this._handshakeSequence = this._enqueue(new Sequences.Handshake(options, callback)); +}; + +Protocol.prototype.query = function query(options, callback) { + return this._enqueue(new Sequences.Query(options, callback)); +}; + +Protocol.prototype.changeUser = function changeUser(options, callback) { + return this._enqueue(new Sequences.ChangeUser(options, callback)); +}; + +Protocol.prototype.ping = function ping(options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + return this._enqueue(new Sequences.Ping(options, callback)); +}; + +Protocol.prototype.stats = function stats(options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + return this._enqueue(new Sequences.Statistics(options, callback)); +}; + +Protocol.prototype.quit = function quit(options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + return this._quitSequence = this._enqueue(new Sequences.Quit(options, callback)); +}; + +Protocol.prototype.end = function() { + if(this._ended) { + return; + } + this._ended = true; + + var expected = (this._quitSequence && this._queue[0] === this._quitSequence); + if (expected) { + this._quitSequence.end(); + this.emit('end'); + return; + } + + var err = new Error('Connection lost: The server closed the connection.'); + err.fatal = true; + err.code = 'PROTOCOL_CONNECTION_LOST'; + + this._delegateError(err); +}; + +Protocol.prototype.pause = function() { + this._parser.pause(); + // Since there is a file stream in query, we must transmit pause/resume event to current sequence. + var seq = this._queue[0]; + if (seq && seq.emit) { + seq.emit('pause'); + } +}; + +Protocol.prototype.resume = function() { + this._parser.resume(); + // Since there is a file stream in query, we must transmit pause/resume event to current sequence. + var seq = this._queue[0]; + if (seq && seq.emit) { + seq.emit('resume'); + } +}; + +Protocol.prototype._enqueue = function(sequence) { + if (!this._validateEnqueue(sequence)) { + return sequence; + } + + if (this._config.trace) { + // Long stack trace support + sequence._callSite = sequence._callSite || new Error; + } + + this._queue.push(sequence); + this.emit('enqueue', sequence); + + var self = this; + sequence + .on('error', function(err) { + self._delegateError(err, sequence); + }) + .on('packet', function(packet) { + Timers.active(sequence); + self._emitPacket(packet); + }) + .on('end', function() { + self._dequeue(sequence); + }) + .on('timeout', function() { + var err = new Error(sequence.constructor.name + ' inactivity timeout'); + + err.code = 'PROTOCOL_SEQUENCE_TIMEOUT'; + err.fatal = true; + err.timeout = sequence._timeout; + + self._delegateError(err, sequence); + }) + .on('start-tls', function() { + Timers.active(sequence); + self._connection._startTLS(function(err) { + if (err) { + // SSL negotiation error are fatal + err.code = 'HANDSHAKE_SSL_ERROR'; + err.fatal = true; + sequence.end(err); + return + } + + Timers.active(sequence); + sequence._tlsUpgradeCompleteHandler(); + }) + }); + + if (this._queue.length === 1) { + this._parser.resetPacketNumber(); + this._startSequence(sequence); + } + + return sequence; +}; + +Protocol.prototype._validateEnqueue = function(sequence) { + var err; + var prefix = 'Cannot enqueue ' + sequence.constructor.name; + var prefixBefore = prefix + ' before '; + var prefixAfter = prefix + ' after '; + + if (this._fatalError) { + err = new Error(prefixAfter + 'fatal error.'); + err.code = 'PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR'; + } else if (this._quitSequence) { + err = new Error(prefixAfter + 'invoking quit.'); + err.code = 'PROTOCOL_ENQUEUE_AFTER_QUIT'; + } else if (this._destroyed) { + err = new Error(prefixAfter + 'being destroyed.'); + err.code = 'PROTOCOL_ENQUEUE_AFTER_DESTROY'; + } else if (this._handshakeSequence && sequence.constructor === Sequences.Handshake) { + err = new Error(prefixAfter + 'already enqueuing a Handshake.'); + err.code = 'PROTOCOL_ENQUEUE_HANDSHAKE_TWICE'; + } else if (!this._handshakeSequence && sequence.constructor === Sequences.ChangeUser) { + err = new Error(prefixBefore + 'a Handshake.'); + err.code = 'PROTOCOL_ENQUEUE_BEFORE_HANDSHAKE'; + } else { + return true; + } + + var self = this; + err.fatal = false; + + sequence + .on('error', function(err) { + self._delegateError(err, sequence); + }) + .end(err); + + return false; +}; + +Protocol.prototype._parsePacket = function() { + var sequence = this._queue[0]; + + if (!sequence) { + var err = new Error('Received packet with no active sequence.'); + err.code = 'PROTOCOL_STRAY_PACKET'; + err.fatal = true; + + this._delegateError(err); + return; + } + + var Packet = this._determinePacket(sequence); + var packet = new Packet({protocol41: this._config.protocol41}); + var packetName = Packet.name; + + // Special case: Faster dispatch, and parsing done inside sequence + if (Packet === Packets.RowDataPacket) { + sequence.RowDataPacket(packet, this._parser, this._connection); + + if (this._config.debug) { + this._debugPacket(true, packet); + } + + return; + } + + if (this._config.debug) { + this._parsePacketDebug(packet); + } else { + packet.parse(this._parser); + } + + if (Packet === Packets.HandshakeInitializationPacket) { + this._handshakeInitializationPacket = packet; + } + + Timers.active(sequence); + + if (!sequence[packetName]) { + var err = new Error('Received packet in the wrong sequence.'); + err.code = 'PROTOCOL_INCORRECT_PACKET_SEQUENCE'; + err.fatal = true; + + this._delegateError(err); + return; + } + + sequence[packetName](packet); +}; + +Protocol.prototype._parsePacketDebug = function _parsePacketDebug(packet) { + try { + packet.parse(this._parser); + } finally { + this._debugPacket(true, packet); + } +}; + +Protocol.prototype._emitPacket = function(packet) { + var packetWriter = new PacketWriter(); + packet.write(packetWriter); + this.emit('data', packetWriter.toBuffer(this._parser)); + + if (this._config.debug) { + this._debugPacket(false, packet); + } +}; + +Protocol.prototype._determinePacket = function(sequence) { + var firstByte = this._parser.peak(); + + if (sequence.determinePacket) { + var Packet = sequence.determinePacket(firstByte, this._parser); + if (Packet) { + return Packet; + } + } + + switch (firstByte) { + case 0x00: + if (!this._handshaked) { + this._handshaked = true; + this.emit('handshake', this._handshakeInitializationPacket); + } + return Packets.OkPacket; + case 0xfe: return Packets.EofPacket; + case 0xff: return Packets.ErrorPacket; + } + + throw new Error('Could not determine packet, firstByte = ' + firstByte); +}; + +Protocol.prototype._dequeue = function(sequence) { + Timers.unenroll(sequence); + + // No point in advancing the queue, we are dead + if (this._fatalError) { + return; + } + + this._queue.shift(); + + var sequence = this._queue[0]; + if (!sequence) { + this.emit('drain'); + return; + } + + this._parser.resetPacketNumber(); + + this._startSequence(sequence); +}; + +Protocol.prototype._startSequence = function(sequence) { + if (sequence._timeout > 0 && isFinite(sequence._timeout)) { + Timers.enroll(sequence, sequence._timeout); + Timers.active(sequence); + } + + if (sequence.constructor === Sequences.ChangeUser) { + sequence.start(this._handshakeInitializationPacket); + } else { + sequence.start(); + } +}; + +Protocol.prototype.handleNetworkError = function(err) { + err.fatal = true; + + var sequence = this._queue[0]; + if (sequence) { + sequence.end(err); + } else { + this._delegateError(err); + } +}; + +Protocol.prototype.handleParserError = function handleParserError(err) { + var sequence = this._queue[0]; + if (sequence) { + sequence.end(err); + } else { + this._delegateError(err); + } +}; + +Protocol.prototype._delegateError = function(err, sequence) { + // Stop delegating errors after the first fatal error + if (this._fatalError) { + return; + } + + if (err.fatal) { + this._fatalError = err; + } + + if (this._shouldErrorBubbleUp(err, sequence)) { + // Can't use regular 'error' event here as that always destroys the pipe + // between socket and protocol which is not what we want (unless the + // exception was fatal). + this.emit('unhandledError', err); + } else if (err.fatal) { + // Send fatal error to all sequences in the queue + var queue = this._queue; + process.nextTick(function () { + queue.forEach(function (sequence) { + sequence.end(err); + }); + queue.length = 0; + }); + } + + // Make sure the stream we are piping to is getting closed + if (err.fatal) { + this.emit('end', err); + } +}; + +Protocol.prototype._shouldErrorBubbleUp = function(err, sequence) { + if (sequence) { + if (sequence.hasErrorHandler()) { + return false; + } else if (!err.fatal) { + return true; + } + } + + return (err.fatal && !this._hasPendingErrorHandlers()); +}; + +Protocol.prototype._hasPendingErrorHandlers = function() { + return this._queue.some(function(sequence) { + return sequence.hasErrorHandler(); + }); +}; + +Protocol.prototype.destroy = function() { + this._destroyed = true; + this._parser.pause(); + + if (this._connection.state !== "disconnected") { + if(!this._ended) { + this.end(); + } + } +}; + +Protocol.prototype._debugPacket = function(incoming, packet) { + var headline = (incoming) + ? '<-- ' + : '--> '; + + headline = headline + packet.constructor.name; + + // check for debug packet restriction + if (Array.isArray(this._config.debug) && this._config.debug.indexOf(packet.constructor.name) === -1) { + return; + } + + console.log(headline); + console.log(packet); + console.log(''); +}; diff --git a/node_modules/mysql/lib/protocol/ResultSet.js b/node_modules/mysql/lib/protocol/ResultSet.js new file mode 100644 index 0000000..f58d74f --- /dev/null +++ b/node_modules/mysql/lib/protocol/ResultSet.js @@ -0,0 +1,7 @@ +module.exports = ResultSet; +function ResultSet(resultSetHeaderPacket) { + this.resultSetHeaderPacket = resultSetHeaderPacket; + this.fieldPackets = []; + this.eofPackets = []; + this.rows = []; +} diff --git a/node_modules/mysql/lib/protocol/SqlString.js b/node_modules/mysql/lib/protocol/SqlString.js new file mode 100644 index 0000000..c9883da --- /dev/null +++ b/node_modules/mysql/lib/protocol/SqlString.js @@ -0,0 +1,140 @@ +var SqlString = exports; + +SqlString.escapeId = function (val, forbidQualified) { + if (Array.isArray(val)) { + return val.map(function(v) { + return SqlString.escapeId(v, forbidQualified); + }).join(', '); + } + + if (forbidQualified) { + return '`' + val.replace(/`/g, '``') + '`'; + } + return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`'; +}; + +SqlString.escape = function(val, stringifyObjects, timeZone) { + if (val === undefined || val === null) { + return 'NULL'; + } + + switch (typeof val) { + case 'boolean': return (val) ? 'true' : 'false'; + case 'number': return val+''; + } + + if (val instanceof Date) { + val = SqlString.dateToString(val, timeZone || 'local'); + } + + if (Buffer.isBuffer(val)) { + return SqlString.bufferToString(val); + } + + if (Array.isArray(val)) { + return SqlString.arrayToList(val, timeZone); + } + + if (typeof val === 'object') { + if (stringifyObjects) { + val = val.toString(); + } else { + return SqlString.objectToValues(val, timeZone); + } + } + + val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) { + switch(s) { + case "\0": return "\\0"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\b": return "\\b"; + case "\t": return "\\t"; + case "\x1a": return "\\Z"; + default: return "\\"+s; + } + }); + return "'"+val+"'"; +}; + +SqlString.arrayToList = function(array, timeZone) { + return array.map(function(v) { + if (Array.isArray(v)) return '(' + SqlString.arrayToList(v, timeZone) + ')'; + return SqlString.escape(v, true, timeZone); + }).join(', '); +}; + +SqlString.format = function(sql, values, stringifyObjects, timeZone) { + values = values == null ? [] : [].concat(values); + + return sql.replace(/\?\??/g, function(match) { + if (!values.length) { + return match; + } + + if (match == "??") { + return SqlString.escapeId(values.shift()); + } + return SqlString.escape(values.shift(), stringifyObjects, timeZone); + }); +}; + +SqlString.dateToString = function(date, timeZone) { + var dt = new Date(date); + + if (timeZone != 'local') { + var tz = convertTimezone(timeZone); + + dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000)); + if (tz !== false) { + dt.setTime(dt.getTime() + (tz * 60000)); + } + } + + var year = dt.getFullYear(); + var month = zeroPad(dt.getMonth() + 1, 2); + var day = zeroPad(dt.getDate(), 2); + var hour = zeroPad(dt.getHours(), 2); + var minute = zeroPad(dt.getMinutes(), 2); + var second = zeroPad(dt.getSeconds(), 2); + var millisecond = zeroPad(dt.getMilliseconds(), 3); + + return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond; +}; + +SqlString.bufferToString = function bufferToString(buffer) { + return "X'" + buffer.toString('hex') + "'"; +}; + +SqlString.objectToValues = function(object, timeZone) { + var values = []; + for (var key in object) { + var value = object[key]; + if(typeof value === 'function') { + continue; + } + + values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone)); + } + + return values.join(', '); +}; + +function zeroPad(number, length) { + number = number.toString(); + while (number.length < length) { + number = '0' + number; + } + + return number; +} + +function convertTimezone(tz) { + if (tz == "Z") return 0; + + var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/); + if (m) { + return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60; + } + return false; +} diff --git a/node_modules/mysql/lib/protocol/constants/charsets.js b/node_modules/mysql/lib/protocol/constants/charsets.js new file mode 100644 index 0000000..98b88ea --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/charsets.js @@ -0,0 +1,262 @@ +exports.BIG5_CHINESE_CI = 1; +exports.LATIN2_CZECH_CS = 2; +exports.DEC8_SWEDISH_CI = 3; +exports.CP850_GENERAL_CI = 4; +exports.LATIN1_GERMAN1_CI = 5; +exports.HP8_ENGLISH_CI = 6; +exports.KOI8R_GENERAL_CI = 7; +exports.LATIN1_SWEDISH_CI = 8; +exports.LATIN2_GENERAL_CI = 9; +exports.SWE7_SWEDISH_CI = 10; +exports.ASCII_GENERAL_CI = 11; +exports.UJIS_JAPANESE_CI = 12; +exports.SJIS_JAPANESE_CI = 13; +exports.CP1251_BULGARIAN_CI = 14; +exports.LATIN1_DANISH_CI = 15; +exports.HEBREW_GENERAL_CI = 16; +exports.TIS620_THAI_CI = 18; +exports.EUCKR_KOREAN_CI = 19; +exports.LATIN7_ESTONIAN_CS = 20; +exports.LATIN2_HUNGARIAN_CI = 21; +exports.KOI8U_GENERAL_CI = 22; +exports.CP1251_UKRAINIAN_CI = 23; +exports.GB2312_CHINESE_CI = 24; +exports.GREEK_GENERAL_CI = 25; +exports.CP1250_GENERAL_CI = 26; +exports.LATIN2_CROATIAN_CI = 27; +exports.GBK_CHINESE_CI = 28; +exports.CP1257_LITHUANIAN_CI = 29; +exports.LATIN5_TURKISH_CI = 30; +exports.LATIN1_GERMAN2_CI = 31; +exports.ARMSCII8_GENERAL_CI = 32; +exports.UTF8_GENERAL_CI = 33; +exports.CP1250_CZECH_CS = 34; +exports.UCS2_GENERAL_CI = 35; +exports.CP866_GENERAL_CI = 36; +exports.KEYBCS2_GENERAL_CI = 37; +exports.MACCE_GENERAL_CI = 38; +exports.MACROMAN_GENERAL_CI = 39; +exports.CP852_GENERAL_CI = 40; +exports.LATIN7_GENERAL_CI = 41; +exports.LATIN7_GENERAL_CS = 42; +exports.MACCE_BIN = 43; +exports.CP1250_CROATIAN_CI = 44; +exports.UTF8MB4_GENERAL_CI = 45; +exports.UTF8MB4_BIN = 46; +exports.LATIN1_BIN = 47; +exports.LATIN1_GENERAL_CI = 48; +exports.LATIN1_GENERAL_CS = 49; +exports.CP1251_BIN = 50; +exports.CP1251_GENERAL_CI = 51; +exports.CP1251_GENERAL_CS = 52; +exports.MACROMAN_BIN = 53; +exports.UTF16_GENERAL_CI = 54; +exports.UTF16_BIN = 55; +exports.UTF16LE_GENERAL_CI = 56; +exports.CP1256_GENERAL_CI = 57; +exports.CP1257_BIN = 58; +exports.CP1257_GENERAL_CI = 59; +exports.UTF32_GENERAL_CI = 60; +exports.UTF32_BIN = 61; +exports.UTF16LE_BIN = 62; +exports.BINARY = 63; +exports.ARMSCII8_BIN = 64; +exports.ASCII_BIN = 65; +exports.CP1250_BIN = 66; +exports.CP1256_BIN = 67; +exports.CP866_BIN = 68; +exports.DEC8_BIN = 69; +exports.GREEK_BIN = 70; +exports.HEBREW_BIN = 71; +exports.HP8_BIN = 72; +exports.KEYBCS2_BIN = 73; +exports.KOI8R_BIN = 74; +exports.KOI8U_BIN = 75; +exports.LATIN2_BIN = 77; +exports.LATIN5_BIN = 78; +exports.LATIN7_BIN = 79; +exports.CP850_BIN = 80; +exports.CP852_BIN = 81; +exports.SWE7_BIN = 82; +exports.UTF8_BIN = 83; +exports.BIG5_BIN = 84; +exports.EUCKR_BIN = 85; +exports.GB2312_BIN = 86; +exports.GBK_BIN = 87; +exports.SJIS_BIN = 88; +exports.TIS620_BIN = 89; +exports.UCS2_BIN = 90; +exports.UJIS_BIN = 91; +exports.GEOSTD8_GENERAL_CI = 92; +exports.GEOSTD8_BIN = 93; +exports.LATIN1_SPANISH_CI = 94; +exports.CP932_JAPANESE_CI = 95; +exports.CP932_BIN = 96; +exports.EUCJPMS_JAPANESE_CI = 97; +exports.EUCJPMS_BIN = 98; +exports.CP1250_POLISH_CI = 99; +exports.UTF16_UNICODE_CI = 101; +exports.UTF16_ICELANDIC_CI = 102; +exports.UTF16_LATVIAN_CI = 103; +exports.UTF16_ROMANIAN_CI = 104; +exports.UTF16_SLOVENIAN_CI = 105; +exports.UTF16_POLISH_CI = 106; +exports.UTF16_ESTONIAN_CI = 107; +exports.UTF16_SPANISH_CI = 108; +exports.UTF16_SWEDISH_CI = 109; +exports.UTF16_TURKISH_CI = 110; +exports.UTF16_CZECH_CI = 111; +exports.UTF16_DANISH_CI = 112; +exports.UTF16_LITHUANIAN_CI = 113; +exports.UTF16_SLOVAK_CI = 114; +exports.UTF16_SPANISH2_CI = 115; +exports.UTF16_ROMAN_CI = 116; +exports.UTF16_PERSIAN_CI = 117; +exports.UTF16_ESPERANTO_CI = 118; +exports.UTF16_HUNGARIAN_CI = 119; +exports.UTF16_SINHALA_CI = 120; +exports.UTF16_GERMAN2_CI = 121; +exports.UTF16_CROATIAN_MYSQL561_CI = 122; +exports.UTF16_UNICODE_520_CI = 123; +exports.UTF16_VIETNAMESE_CI = 124; +exports.UCS2_UNICODE_CI = 128; +exports.UCS2_ICELANDIC_CI = 129; +exports.UCS2_LATVIAN_CI = 130; +exports.UCS2_ROMANIAN_CI = 131; +exports.UCS2_SLOVENIAN_CI = 132; +exports.UCS2_POLISH_CI = 133; +exports.UCS2_ESTONIAN_CI = 134; +exports.UCS2_SPANISH_CI = 135; +exports.UCS2_SWEDISH_CI = 136; +exports.UCS2_TURKISH_CI = 137; +exports.UCS2_CZECH_CI = 138; +exports.UCS2_DANISH_CI = 139; +exports.UCS2_LITHUANIAN_CI = 140; +exports.UCS2_SLOVAK_CI = 141; +exports.UCS2_SPANISH2_CI = 142; +exports.UCS2_ROMAN_CI = 143; +exports.UCS2_PERSIAN_CI = 144; +exports.UCS2_ESPERANTO_CI = 145; +exports.UCS2_HUNGARIAN_CI = 146; +exports.UCS2_SINHALA_CI = 147; +exports.UCS2_GERMAN2_CI = 148; +exports.UCS2_CROATIAN_MYSQL561_CI = 149; +exports.UCS2_UNICODE_520_CI = 150; +exports.UCS2_VIETNAMESE_CI = 151; +exports.UCS2_GENERAL_MYSQL500_CI = 159; +exports.UTF32_UNICODE_CI = 160; +exports.UTF32_ICELANDIC_CI = 161; +exports.UTF32_LATVIAN_CI = 162; +exports.UTF32_ROMANIAN_CI = 163; +exports.UTF32_SLOVENIAN_CI = 164; +exports.UTF32_POLISH_CI = 165; +exports.UTF32_ESTONIAN_CI = 166; +exports.UTF32_SPANISH_CI = 167; +exports.UTF32_SWEDISH_CI = 168; +exports.UTF32_TURKISH_CI = 169; +exports.UTF32_CZECH_CI = 170; +exports.UTF32_DANISH_CI = 171; +exports.UTF32_LITHUANIAN_CI = 172; +exports.UTF32_SLOVAK_CI = 173; +exports.UTF32_SPANISH2_CI = 174; +exports.UTF32_ROMAN_CI = 175; +exports.UTF32_PERSIAN_CI = 176; +exports.UTF32_ESPERANTO_CI = 177; +exports.UTF32_HUNGARIAN_CI = 178; +exports.UTF32_SINHALA_CI = 179; +exports.UTF32_GERMAN2_CI = 180; +exports.UTF32_CROATIAN_MYSQL561_CI = 181; +exports.UTF32_UNICODE_520_CI = 182; +exports.UTF32_VIETNAMESE_CI = 183; +exports.UTF8_UNICODE_CI = 192; +exports.UTF8_ICELANDIC_CI = 193; +exports.UTF8_LATVIAN_CI = 194; +exports.UTF8_ROMANIAN_CI = 195; +exports.UTF8_SLOVENIAN_CI = 196; +exports.UTF8_POLISH_CI = 197; +exports.UTF8_ESTONIAN_CI = 198; +exports.UTF8_SPANISH_CI = 199; +exports.UTF8_SWEDISH_CI = 200; +exports.UTF8_TURKISH_CI = 201; +exports.UTF8_CZECH_CI = 202; +exports.UTF8_DANISH_CI = 203; +exports.UTF8_LITHUANIAN_CI = 204; +exports.UTF8_SLOVAK_CI = 205; +exports.UTF8_SPANISH2_CI = 206; +exports.UTF8_ROMAN_CI = 207; +exports.UTF8_PERSIAN_CI = 208; +exports.UTF8_ESPERANTO_CI = 209; +exports.UTF8_HUNGARIAN_CI = 210; +exports.UTF8_SINHALA_CI = 211; +exports.UTF8_GERMAN2_CI = 212; +exports.UTF8_CROATIAN_MYSQL561_CI = 213; +exports.UTF8_UNICODE_520_CI = 214; +exports.UTF8_VIETNAMESE_CI = 215; +exports.UTF8_GENERAL_MYSQL500_CI = 223; +exports.UTF8MB4_UNICODE_CI = 224; +exports.UTF8MB4_ICELANDIC_CI = 225; +exports.UTF8MB4_LATVIAN_CI = 226; +exports.UTF8MB4_ROMANIAN_CI = 227; +exports.UTF8MB4_SLOVENIAN_CI = 228; +exports.UTF8MB4_POLISH_CI = 229; +exports.UTF8MB4_ESTONIAN_CI = 230; +exports.UTF8MB4_SPANISH_CI = 231; +exports.UTF8MB4_SWEDISH_CI = 232; +exports.UTF8MB4_TURKISH_CI = 233; +exports.UTF8MB4_CZECH_CI = 234; +exports.UTF8MB4_DANISH_CI = 235; +exports.UTF8MB4_LITHUANIAN_CI = 236; +exports.UTF8MB4_SLOVAK_CI = 237; +exports.UTF8MB4_SPANISH2_CI = 238; +exports.UTF8MB4_ROMAN_CI = 239; +exports.UTF8MB4_PERSIAN_CI = 240; +exports.UTF8MB4_ESPERANTO_CI = 241; +exports.UTF8MB4_HUNGARIAN_CI = 242; +exports.UTF8MB4_SINHALA_CI = 243; +exports.UTF8MB4_GERMAN2_CI = 244; +exports.UTF8MB4_CROATIAN_MYSQL561_CI = 245; +exports.UTF8MB4_UNICODE_520_CI = 246; +exports.UTF8MB4_VIETNAMESE_CI = 247; +exports.UTF8_GENERAL50_CI = 253; + +// short aliases +exports.ARMSCII8 = exports.ARMSCII8_GENERAL_CI; +exports.ASCII = exports.ASCII_GENERAL_CI; +exports.BIG5 = exports.BIG5_CHINESE_CI; +exports.BINARY = exports.BINARY; +exports.CP1250 = exports.CP1250_GENERAL_CI; +exports.CP1251 = exports.CP1251_GENERAL_CI; +exports.CP1256 = exports.CP1256_GENERAL_CI; +exports.CP1257 = exports.CP1257_GENERAL_CI; +exports.CP866 = exports.CP866_GENERAL_CI; +exports.CP850 = exports.CP850_GENERAL_CI; +exports.CP852 = exports.CP852_GENERAL_CI; +exports.CP932 = exports.CP932_JAPANESE_CI; +exports.DEC8 = exports.DEC8_SWEDISH_CI; +exports.EUCJPMS = exports.EUCJPMS_JAPANESE_CI; +exports.EUCKR = exports.EUCKR_KOREAN_CI; +exports.GB2312 = exports.GB2312_CHINESE_CI; +exports.GBK = exports.GBK_CHINESE_CI; +exports.GEOSTD8 = exports.GEOSTD8_GENERAL_CI; +exports.GREEK = exports.GREEK_GENERAL_CI; +exports.HEBREW = exports.HEBREW_GENERAL_CI; +exports.HP8 = exports.HP8_ENGLISH_CI; +exports.KEYBCS2 = exports.KEYBCS2_GENERAL_CI; +exports.KOI8R = exports.KOI8R_GENERAL_CI; +exports.KOI8U = exports.KOI8U_GENERAL_CI; +exports.LATIN1 = exports.LATIN1_SWEDISH_CI; +exports.LATIN2 = exports.LATIN2_GENERAL_CI; +exports.LATIN5 = exports.LATIN5_TURKISH_CI; +exports.LATIN7 = exports.LATIN7_GENERAL_CI; +exports.MACCE = exports.MACCE_GENERAL_CI; +exports.MACROMAN = exports.MACROMAN_GENERAL_CI; +exports.SJIS = exports.SJIS_JAPANESE_CI; +exports.SWE7 = exports.SWE7_SWEDISH_CI; +exports.TIS620 = exports.TIS620_THAI_CI; +exports.UCS2 = exports.UCS2_GENERAL_CI; +exports.UJIS = exports.UJIS_JAPANESE_CI; +exports.UTF16 = exports.UTF16_GENERAL_CI; +exports.UTF16LE = exports.UTF16LE_GENERAL_CI; +exports.UTF8 = exports.UTF8_GENERAL_CI; +exports.UTF8MB4 = exports.UTF8MB4_GENERAL_CI; +exports.UTF32 = exports.UTF32_GENERAL_CI; diff --git a/node_modules/mysql/lib/protocol/constants/client.js b/node_modules/mysql/lib/protocol/constants/client.js new file mode 100644 index 0000000..59aadc6 --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/client.js @@ -0,0 +1,26 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */ +exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */ +exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */ +exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */ +exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */ +exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */ +exports.CLIENT_ODBC = 64; /* Odbc client */ +exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ +exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */ +exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */ +exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */ +exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */ +exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */ +exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */ +exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */ +exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */ + +exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */ +exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */ +exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */ + +exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */ + +exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824; +exports.CLIENT_REMEMBER_OPTIONS = 2147483648; diff --git a/node_modules/mysql/lib/protocol/constants/errors.js b/node_modules/mysql/lib/protocol/constants/errors.js new file mode 100644 index 0000000..8856456 --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/errors.js @@ -0,0 +1,1978 @@ +/** + * MySQL error constants + * + * !! Generated by generate-error-constants.js, do not modify by hand !! + */ + +exports.EE_CANTCREATEFILE = 1; +exports.EE_READ = 2; +exports.EE_WRITE = 3; +exports.EE_BADCLOSE = 4; +exports.EE_OUTOFMEMORY = 5; +exports.EE_DELETE = 6; +exports.EE_LINK = 7; +exports.EE_EOFERR = 9; +exports.EE_CANTLOCK = 10; +exports.EE_CANTUNLOCK = 11; +exports.EE_DIR = 12; +exports.EE_STAT = 13; +exports.EE_CANT_CHSIZE = 14; +exports.EE_CANT_OPEN_STREAM = 15; +exports.EE_GETWD = 16; +exports.EE_SETWD = 17; +exports.EE_LINK_WARNING = 18; +exports.EE_OPEN_WARNING = 19; +exports.EE_DISK_FULL = 20; +exports.EE_CANT_MKDIR = 21; +exports.EE_UNKNOWN_CHARSET = 22; +exports.EE_OUT_OF_FILERESOURCES = 23; +exports.EE_CANT_READLINK = 24; +exports.EE_CANT_SYMLINK = 25; +exports.EE_REALPATH = 26; +exports.EE_SYNC = 27; +exports.EE_UNKNOWN_COLLATION = 28; +exports.EE_FILENOTFOUND = 29; +exports.EE_FILE_NOT_CLOSED = 30; +exports.EE_CHANGE_OWNERSHIP = 31; +exports.EE_CHANGE_PERMISSIONS = 32; +exports.EE_CANT_SEEK = 33; +exports.HA_ERR_KEY_NOT_FOUND = 120; +exports.HA_ERR_FOUND_DUPP_KEY = 121; +exports.HA_ERR_INTERNAL_ERROR = 122; +exports.HA_ERR_RECORD_CHANGED = 123; +exports.HA_ERR_WRONG_INDEX = 124; +exports.HA_ERR_CRASHED = 126; +exports.HA_ERR_WRONG_IN_RECORD = 127; +exports.HA_ERR_OUT_OF_MEM = 128; +exports.HA_ERR_NOT_A_TABLE = 130; +exports.HA_ERR_WRONG_COMMAND = 131; +exports.HA_ERR_OLD_FILE = 132; +exports.HA_ERR_NO_ACTIVE_RECORD = 133; +exports.HA_ERR_RECORD_DELETED = 134; +exports.HA_ERR_RECORD_FILE_FULL = 135; +exports.HA_ERR_INDEX_FILE_FULL = 136; +exports.HA_ERR_END_OF_FILE = 137; +exports.HA_ERR_UNSUPPORTED = 138; +exports.HA_ERR_TO_BIG_ROW = 139; +exports.HA_WRONG_CREATE_OPTION = 140; +exports.HA_ERR_FOUND_DUPP_UNIQUE = 141; +exports.HA_ERR_UNKNOWN_CHARSET = 142; +exports.HA_ERR_WRONG_MRG_TABLE_DEF = 143; +exports.HA_ERR_CRASHED_ON_REPAIR = 144; +exports.HA_ERR_CRASHED_ON_USAGE = 145; +exports.HA_ERR_LOCK_WAIT_TIMEOUT = 146; +exports.HA_ERR_LOCK_TABLE_FULL = 147; +exports.HA_ERR_READ_ONLY_TRANSACTION = 148; +exports.HA_ERR_LOCK_DEADLOCK = 149; +exports.HA_ERR_CANNOT_ADD_FOREIGN = 150; +exports.HA_ERR_NO_REFERENCED_ROW = 151; +exports.HA_ERR_ROW_IS_REFERENCED = 152; +exports.HA_ERR_NO_SAVEPOINT = 153; +exports.HA_ERR_NON_UNIQUE_BLOCK_SIZE = 154; +exports.HA_ERR_NO_SUCH_TABLE = 155; +exports.HA_ERR_TABLE_EXIST = 156; +exports.HA_ERR_NO_CONNECTION = 157; +exports.HA_ERR_NULL_IN_SPATIAL = 158; +exports.HA_ERR_TABLE_DEF_CHANGED = 159; +exports.HA_ERR_NO_PARTITION_FOUND = 160; +exports.HA_ERR_RBR_LOGGING_FAILED = 161; +exports.HA_ERR_DROP_INDEX_FK = 162; +exports.HA_ERR_FOREIGN_DUPLICATE_KEY = 163; +exports.HA_ERR_TABLE_NEEDS_UPGRADE = 164; +exports.HA_ERR_TABLE_READONLY = 165; +exports.HA_ERR_AUTOINC_READ_FAILED = 166; +exports.HA_ERR_AUTOINC_ERANGE = 167; +exports.HA_ERR_GENERIC = 168; +exports.HA_ERR_RECORD_IS_THE_SAME = 169; +exports.HA_ERR_LOGGING_IMPOSSIBLE = 170; +exports.HA_ERR_CORRUPT_EVENT = 171; +exports.HA_ERR_NEW_FILE = 172; +exports.HA_ERR_ROWS_EVENT_APPLY = 173; +exports.HA_ERR_INITIALIZATION = 174; +exports.HA_ERR_FILE_TOO_SHORT = 175; +exports.HA_ERR_WRONG_CRC = 176; +exports.HA_ERR_TOO_MANY_CONCURRENT_TRXS = 177; +exports.HA_ERR_NOT_IN_LOCK_PARTITIONS = 178; +exports.HA_ERR_INDEX_COL_TOO_LONG = 179; +exports.HA_ERR_INDEX_CORRUPT = 180; +exports.HA_ERR_UNDO_REC_TOO_BIG = 181; +exports.HA_FTS_INVALID_DOCID = 182; +exports.HA_ERR_TABLE_IN_FK_CHECK = 183; +exports.HA_ERR_TABLESPACE_EXISTS = 184; +exports.HA_ERR_TOO_MANY_FIELDS = 185; +exports.HA_ERR_ROW_IN_WRONG_PARTITION = 186; +exports.HA_ERR_INNODB_READ_ONLY = 187; +exports.HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT = 188; +exports.HA_ERR_TEMP_FILE_WRITE_FAILURE = 189; +exports.HA_ERR_INNODB_FORCED_RECOVERY = 190; +exports.HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE = 191; +exports.ER_HASHCHK = 1000; +exports.ER_NISAMCHK = 1001; +exports.ER_NO = 1002; +exports.ER_YES = 1003; +exports.ER_CANT_CREATE_FILE = 1004; +exports.ER_CANT_CREATE_TABLE = 1005; +exports.ER_CANT_CREATE_DB = 1006; +exports.ER_DB_CREATE_EXISTS = 1007; +exports.ER_DB_DROP_EXISTS = 1008; +exports.ER_DB_DROP_DELETE = 1009; +exports.ER_DB_DROP_RMDIR = 1010; +exports.ER_CANT_DELETE_FILE = 1011; +exports.ER_CANT_FIND_SYSTEM_REC = 1012; +exports.ER_CANT_GET_STAT = 1013; +exports.ER_CANT_GET_WD = 1014; +exports.ER_CANT_LOCK = 1015; +exports.ER_CANT_OPEN_FILE = 1016; +exports.ER_FILE_NOT_FOUND = 1017; +exports.ER_CANT_READ_DIR = 1018; +exports.ER_CANT_SET_WD = 1019; +exports.ER_CHECKREAD = 1020; +exports.ER_DISK_FULL = 1021; +exports.ER_DUP_KEY = 1022; +exports.ER_ERROR_ON_CLOSE = 1023; +exports.ER_ERROR_ON_READ = 1024; +exports.ER_ERROR_ON_RENAME = 1025; +exports.ER_ERROR_ON_WRITE = 1026; +exports.ER_FILE_USED = 1027; +exports.ER_FILSORT_ABORT = 1028; +exports.ER_FORM_NOT_FOUND = 1029; +exports.ER_GET_ERRNO = 1030; +exports.ER_ILLEGAL_HA = 1031; +exports.ER_KEY_NOT_FOUND = 1032; +exports.ER_NOT_FORM_FILE = 1033; +exports.ER_NOT_KEYFILE = 1034; +exports.ER_OLD_KEYFILE = 1035; +exports.ER_OPEN_AS_READONLY = 1036; +exports.ER_OUTOFMEMORY = 1037; +exports.ER_OUT_OF_SORTMEMORY = 1038; +exports.ER_UNEXPECTED_EOF = 1039; +exports.ER_CON_COUNT_ERROR = 1040; +exports.ER_OUT_OF_RESOURCES = 1041; +exports.ER_BAD_HOST_ERROR = 1042; +exports.ER_HANDSHAKE_ERROR = 1043; +exports.ER_DBACCESS_DENIED_ERROR = 1044; +exports.ER_ACCESS_DENIED_ERROR = 1045; +exports.ER_NO_DB_ERROR = 1046; +exports.ER_UNKNOWN_COM_ERROR = 1047; +exports.ER_BAD_NULL_ERROR = 1048; +exports.ER_BAD_DB_ERROR = 1049; +exports.ER_TABLE_EXISTS_ERROR = 1050; +exports.ER_BAD_TABLE_ERROR = 1051; +exports.ER_NON_UNIQ_ERROR = 1052; +exports.ER_SERVER_SHUTDOWN = 1053; +exports.ER_BAD_FIELD_ERROR = 1054; +exports.ER_WRONG_FIELD_WITH_GROUP = 1055; +exports.ER_WRONG_GROUP_FIELD = 1056; +exports.ER_WRONG_SUM_SELECT = 1057; +exports.ER_WRONG_VALUE_COUNT = 1058; +exports.ER_TOO_LONG_IDENT = 1059; +exports.ER_DUP_FIELDNAME = 1060; +exports.ER_DUP_KEYNAME = 1061; +exports.ER_DUP_ENTRY = 1062; +exports.ER_WRONG_FIELD_SPEC = 1063; +exports.ER_PARSE_ERROR = 1064; +exports.ER_EMPTY_QUERY = 1065; +exports.ER_NONUNIQ_TABLE = 1066; +exports.ER_INVALID_DEFAULT = 1067; +exports.ER_MULTIPLE_PRI_KEY = 1068; +exports.ER_TOO_MANY_KEYS = 1069; +exports.ER_TOO_MANY_KEY_PARTS = 1070; +exports.ER_TOO_LONG_KEY = 1071; +exports.ER_KEY_COLUMN_DOES_NOT_EXITS = 1072; +exports.ER_BLOB_USED_AS_KEY = 1073; +exports.ER_TOO_BIG_FIELDLENGTH = 1074; +exports.ER_WRONG_AUTO_KEY = 1075; +exports.ER_READY = 1076; +exports.ER_NORMAL_SHUTDOWN = 1077; +exports.ER_GOT_SIGNAL = 1078; +exports.ER_SHUTDOWN_COMPLETE = 1079; +exports.ER_FORCING_CLOSE = 1080; +exports.ER_IPSOCK_ERROR = 1081; +exports.ER_NO_SUCH_INDEX = 1082; +exports.ER_WRONG_FIELD_TERMINATORS = 1083; +exports.ER_BLOBS_AND_NO_TERMINATED = 1084; +exports.ER_TEXTFILE_NOT_READABLE = 1085; +exports.ER_FILE_EXISTS_ERROR = 1086; +exports.ER_LOAD_INFO = 1087; +exports.ER_ALTER_INFO = 1088; +exports.ER_WRONG_SUB_KEY = 1089; +exports.ER_CANT_REMOVE_ALL_FIELDS = 1090; +exports.ER_CANT_DROP_FIELD_OR_KEY = 1091; +exports.ER_INSERT_INFO = 1092; +exports.ER_UPDATE_TABLE_USED = 1093; +exports.ER_NO_SUCH_THREAD = 1094; +exports.ER_KILL_DENIED_ERROR = 1095; +exports.ER_NO_TABLES_USED = 1096; +exports.ER_TOO_BIG_SET = 1097; +exports.ER_NO_UNIQUE_LOGFILE = 1098; +exports.ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099; +exports.ER_TABLE_NOT_LOCKED = 1100; +exports.ER_BLOB_CANT_HAVE_DEFAULT = 1101; +exports.ER_WRONG_DB_NAME = 1102; +exports.ER_WRONG_TABLE_NAME = 1103; +exports.ER_TOO_BIG_SELECT = 1104; +exports.ER_UNKNOWN_ERROR = 1105; +exports.ER_UNKNOWN_PROCEDURE = 1106; +exports.ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107; +exports.ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108; +exports.ER_UNKNOWN_TABLE = 1109; +exports.ER_FIELD_SPECIFIED_TWICE = 1110; +exports.ER_INVALID_GROUP_FUNC_USE = 1111; +exports.ER_UNSUPPORTED_EXTENSION = 1112; +exports.ER_TABLE_MUST_HAVE_COLUMNS = 1113; +exports.ER_RECORD_FILE_FULL = 1114; +exports.ER_UNKNOWN_CHARACTER_SET = 1115; +exports.ER_TOO_MANY_TABLES = 1116; +exports.ER_TOO_MANY_FIELDS = 1117; +exports.ER_TOO_BIG_ROWSIZE = 1118; +exports.ER_STACK_OVERRUN = 1119; +exports.ER_WRONG_OUTER_JOIN = 1120; +exports.ER_NULL_COLUMN_IN_INDEX = 1121; +exports.ER_CANT_FIND_UDF = 1122; +exports.ER_CANT_INITIALIZE_UDF = 1123; +exports.ER_UDF_NO_PATHS = 1124; +exports.ER_UDF_EXISTS = 1125; +exports.ER_CANT_OPEN_LIBRARY = 1126; +exports.ER_CANT_FIND_DL_ENTRY = 1127; +exports.ER_FUNCTION_NOT_DEFINED = 1128; +exports.ER_HOST_IS_BLOCKED = 1129; +exports.ER_HOST_NOT_PRIVILEGED = 1130; +exports.ER_PASSWORD_ANONYMOUS_USER = 1131; +exports.ER_PASSWORD_NOT_ALLOWED = 1132; +exports.ER_PASSWORD_NO_MATCH = 1133; +exports.ER_UPDATE_INFO = 1134; +exports.ER_CANT_CREATE_THREAD = 1135; +exports.ER_WRONG_VALUE_COUNT_ON_ROW = 1136; +exports.ER_CANT_REOPEN_TABLE = 1137; +exports.ER_INVALID_USE_OF_NULL = 1138; +exports.ER_REGEXP_ERROR = 1139; +exports.ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140; +exports.ER_NONEXISTING_GRANT = 1141; +exports.ER_TABLEACCESS_DENIED_ERROR = 1142; +exports.ER_COLUMNACCESS_DENIED_ERROR = 1143; +exports.ER_ILLEGAL_GRANT_FOR_TABLE = 1144; +exports.ER_GRANT_WRONG_HOST_OR_USER = 1145; +exports.ER_NO_SUCH_TABLE = 1146; +exports.ER_NONEXISTING_TABLE_GRANT = 1147; +exports.ER_NOT_ALLOWED_COMMAND = 1148; +exports.ER_SYNTAX_ERROR = 1149; +exports.ER_DELAYED_CANT_CHANGE_LOCK = 1150; +exports.ER_TOO_MANY_DELAYED_THREADS = 1151; +exports.ER_ABORTING_CONNECTION = 1152; +exports.ER_NET_PACKET_TOO_LARGE = 1153; +exports.ER_NET_READ_ERROR_FROM_PIPE = 1154; +exports.ER_NET_FCNTL_ERROR = 1155; +exports.ER_NET_PACKETS_OUT_OF_ORDER = 1156; +exports.ER_NET_UNCOMPRESS_ERROR = 1157; +exports.ER_NET_READ_ERROR = 1158; +exports.ER_NET_READ_INTERRUPTED = 1159; +exports.ER_NET_ERROR_ON_WRITE = 1160; +exports.ER_NET_WRITE_INTERRUPTED = 1161; +exports.ER_TOO_LONG_STRING = 1162; +exports.ER_TABLE_CANT_HANDLE_BLOB = 1163; +exports.ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164; +exports.ER_DELAYED_INSERT_TABLE_LOCKED = 1165; +exports.ER_WRONG_COLUMN_NAME = 1166; +exports.ER_WRONG_KEY_COLUMN = 1167; +exports.ER_WRONG_MRG_TABLE = 1168; +exports.ER_DUP_UNIQUE = 1169; +exports.ER_BLOB_KEY_WITHOUT_LENGTH = 1170; +exports.ER_PRIMARY_CANT_HAVE_NULL = 1171; +exports.ER_TOO_MANY_ROWS = 1172; +exports.ER_REQUIRES_PRIMARY_KEY = 1173; +exports.ER_NO_RAID_COMPILED = 1174; +exports.ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175; +exports.ER_KEY_DOES_NOT_EXITS = 1176; +exports.ER_CHECK_NO_SUCH_TABLE = 1177; +exports.ER_CHECK_NOT_IMPLEMENTED = 1178; +exports.ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179; +exports.ER_ERROR_DURING_COMMIT = 1180; +exports.ER_ERROR_DURING_ROLLBACK = 1181; +exports.ER_ERROR_DURING_FLUSH_LOGS = 1182; +exports.ER_ERROR_DURING_CHECKPOINT = 1183; +exports.ER_NEW_ABORTING_CONNECTION = 1184; +exports.ER_DUMP_NOT_IMPLEMENTED = 1185; +exports.ER_FLUSH_MASTER_BINLOG_CLOSED = 1186; +exports.ER_INDEX_REBUILD = 1187; +exports.ER_MASTER = 1188; +exports.ER_MASTER_NET_READ = 1189; +exports.ER_MASTER_NET_WRITE = 1190; +exports.ER_FT_MATCHING_KEY_NOT_FOUND = 1191; +exports.ER_LOCK_OR_ACTIVE_TRANSACTION = 1192; +exports.ER_UNKNOWN_SYSTEM_VARIABLE = 1193; +exports.ER_CRASHED_ON_USAGE = 1194; +exports.ER_CRASHED_ON_REPAIR = 1195; +exports.ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196; +exports.ER_TRANS_CACHE_FULL = 1197; +exports.ER_SLAVE_MUST_STOP = 1198; +exports.ER_SLAVE_NOT_RUNNING = 1199; +exports.ER_BAD_SLAVE = 1200; +exports.ER_MASTER_INFO = 1201; +exports.ER_SLAVE_THREAD = 1202; +exports.ER_TOO_MANY_USER_CONNECTIONS = 1203; +exports.ER_SET_CONSTANTS_ONLY = 1204; +exports.ER_LOCK_WAIT_TIMEOUT = 1205; +exports.ER_LOCK_TABLE_FULL = 1206; +exports.ER_READ_ONLY_TRANSACTION = 1207; +exports.ER_DROP_DB_WITH_READ_LOCK = 1208; +exports.ER_CREATE_DB_WITH_READ_LOCK = 1209; +exports.ER_WRONG_ARGUMENTS = 1210; +exports.ER_NO_PERMISSION_TO_CREATE_USER = 1211; +exports.ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212; +exports.ER_LOCK_DEADLOCK = 1213; +exports.ER_TABLE_CANT_HANDLE_FT = 1214; +exports.ER_CANNOT_ADD_FOREIGN = 1215; +exports.ER_NO_REFERENCED_ROW = 1216; +exports.ER_ROW_IS_REFERENCED = 1217; +exports.ER_CONNECT_TO_MASTER = 1218; +exports.ER_QUERY_ON_MASTER = 1219; +exports.ER_ERROR_WHEN_EXECUTING_COMMAND = 1220; +exports.ER_WRONG_USAGE = 1221; +exports.ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222; +exports.ER_CANT_UPDATE_WITH_READLOCK = 1223; +exports.ER_MIXING_NOT_ALLOWED = 1224; +exports.ER_DUP_ARGUMENT = 1225; +exports.ER_USER_LIMIT_REACHED = 1226; +exports.ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227; +exports.ER_LOCAL_VARIABLE = 1228; +exports.ER_GLOBAL_VARIABLE = 1229; +exports.ER_NO_DEFAULT = 1230; +exports.ER_WRONG_VALUE_FOR_VAR = 1231; +exports.ER_WRONG_TYPE_FOR_VAR = 1232; +exports.ER_VAR_CANT_BE_READ = 1233; +exports.ER_CANT_USE_OPTION_HERE = 1234; +exports.ER_NOT_SUPPORTED_YET = 1235; +exports.ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236; +exports.ER_SLAVE_IGNORED_TABLE = 1237; +exports.ER_INCORRECT_GLOBAL_LOCAL_VAR = 1238; +exports.ER_WRONG_FK_DEF = 1239; +exports.ER_KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240; +exports.ER_OPERAND_COLUMNS = 1241; +exports.ER_SUBQUERY_NO_ = 1242; +exports.ER_UNKNOWN_STMT_HANDLER = 1243; +exports.ER_CORRUPT_HELP_DB = 1244; +exports.ER_CYCLIC_REFERENCE = 1245; +exports.ER_AUTO_CONVERT = 1246; +exports.ER_ILLEGAL_REFERENCE = 1247; +exports.ER_DERIVED_MUST_HAVE_ALIAS = 1248; +exports.ER_SELECT_REDUCED = 1249; +exports.ER_TABLENAME_NOT_ALLOWED_HERE = 1250; +exports.ER_NOT_SUPPORTED_AUTH_MODE = 1251; +exports.ER_SPATIAL_CANT_HAVE_NULL = 1252; +exports.ER_COLLATION_CHARSET_MISMATCH = 1253; +exports.ER_SLAVE_WAS_RUNNING = 1254; +exports.ER_SLAVE_WAS_NOT_RUNNING = 1255; +exports.ER_TOO_BIG_FOR_UNCOMPRESS = 1256; +exports.ER_ZLIB_Z_MEM_ERROR = 1257; +exports.ER_ZLIB_Z_BUF_ERROR = 1258; +exports.ER_ZLIB_Z_DATA_ERROR = 1259; +exports.ER_CUT_VALUE_GROUP_CONCAT = 1260; +exports.ER_WARN_TOO_FEW_RECORDS = 1261; +exports.ER_WARN_TOO_MANY_RECORDS = 1262; +exports.ER_WARN_NULL_TO_NOTNULL = 1263; +exports.ER_WARN_DATA_OUT_OF_RANGE = 1264; +exports.WARN_DATA_TRUNCATED = 1265; +exports.ER_WARN_USING_OTHER_HANDLER = 1266; +exports.ER_CANT_AGGREGATE_ = 1267; +exports.ER_DROP_USER = 1268; +exports.ER_REVOKE_GRANTS = 1269; +exports.ER_CANT_AGGREGATE_ = 1270; +exports.ER_CANT_AGGREGATE_NCOLLATIONS = 1271; +exports.ER_VARIABLE_IS_NOT_STRUCT = 1272; +exports.ER_UNKNOWN_COLLATION = 1273; +exports.ER_SLAVE_IGNORED_SSL_PARAMS = 1274; +exports.ER_SERVER_IS_IN_SECURE_AUTH_MODE = 1275; +exports.ER_WARN_FIELD_RESOLVED = 1276; +exports.ER_BAD_SLAVE_UNTIL_COND = 1277; +exports.ER_MISSING_SKIP_SLAVE = 1278; +exports.ER_UNTIL_COND_IGNORED = 1279; +exports.ER_WRONG_NAME_FOR_INDEX = 1280; +exports.ER_WRONG_NAME_FOR_CATALOG = 1281; +exports.ER_WARN_QC_RESIZE = 1282; +exports.ER_BAD_FT_COLUMN = 1283; +exports.ER_UNKNOWN_KEY_CACHE = 1284; +exports.ER_WARN_HOSTNAME_WONT_WORK = 1285; +exports.ER_UNKNOWN_STORAGE_ENGINE = 1286; +exports.ER_WARN_DEPRECATED_SYNTAX = 1287; +exports.ER_NON_UPDATABLE_TABLE = 1288; +exports.ER_FEATURE_DISABLED = 1289; +exports.ER_OPTION_PREVENTS_STATEMENT = 1290; +exports.ER_DUPLICATED_VALUE_IN_TYPE = 1291; +exports.ER_TRUNCATED_WRONG_VALUE = 1292; +exports.ER_TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293; +exports.ER_INVALID_ON_UPDATE = 1294; +exports.ER_UNSUPPORTED_PS = 1295; +exports.ER_GET_ERRMSG = 1296; +exports.ER_GET_TEMPORARY_ERRMSG = 1297; +exports.ER_UNKNOWN_TIME_ZONE = 1298; +exports.ER_WARN_INVALID_TIMESTAMP = 1299; +exports.ER_INVALID_CHARACTER_STRING = 1300; +exports.ER_WARN_ALLOWED_PACKET_OVERFLOWED = 1301; +exports.ER_CONFLICTING_DECLARATIONS = 1302; +exports.ER_SP_NO_RECURSIVE_CREATE = 1303; +exports.ER_SP_ALREADY_EXISTS = 1304; +exports.ER_SP_DOES_NOT_EXIST = 1305; +exports.ER_SP_DROP_FAILED = 1306; +exports.ER_SP_STORE_FAILED = 1307; +exports.ER_SP_LILABEL_MISMATCH = 1308; +exports.ER_SP_LABEL_REDEFINE = 1309; +exports.ER_SP_LABEL_MISMATCH = 1310; +exports.ER_SP_UNINIT_VAR = 1311; +exports.ER_SP_BADSELECT = 1312; +exports.ER_SP_BADRETURN = 1313; +exports.ER_SP_BADSTATEMENT = 1314; +exports.ER_UPDATE_LOG_DEPRECATED_IGNORED = 1315; +exports.ER_UPDATE_LOG_DEPRECATED_TRANSLATED = 1316; +exports.ER_QUERY_INTERRUPTED = 1317; +exports.ER_SP_WRONG_NO_OF_ARGS = 1318; +exports.ER_SP_COND_MISMATCH = 1319; +exports.ER_SP_NORETURN = 1320; +exports.ER_SP_NORETURNEND = 1321; +exports.ER_SP_BAD_CURSOR_QUERY = 1322; +exports.ER_SP_BAD_CURSOR_SELECT = 1323; +exports.ER_SP_CURSOR_MISMATCH = 1324; +exports.ER_SP_CURSOR_ALREADY_OPEN = 1325; +exports.ER_SP_CURSOR_NOT_OPEN = 1326; +exports.ER_SP_UNDECLARED_VAR = 1327; +exports.ER_SP_WRONG_NO_OF_FETCH_ARGS = 1328; +exports.ER_SP_FETCH_NO_DATA = 1329; +exports.ER_SP_DUP_PARAM = 1330; +exports.ER_SP_DUP_VAR = 1331; +exports.ER_SP_DUP_COND = 1332; +exports.ER_SP_DUP_CURS = 1333; +exports.ER_SP_CANT_ALTER = 1334; +exports.ER_SP_SUBSELECT_NYI = 1335; +exports.ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336; +exports.ER_SP_VARCOND_AFTER_CURSHNDLR = 1337; +exports.ER_SP_CURSOR_AFTER_HANDLER = 1338; +exports.ER_SP_CASE_NOT_FOUND = 1339; +exports.ER_FPARSER_TOO_BIG_FILE = 1340; +exports.ER_FPARSER_BAD_HEADER = 1341; +exports.ER_FPARSER_EOF_IN_COMMENT = 1342; +exports.ER_FPARSER_ERROR_IN_PARAMETER = 1343; +exports.ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344; +exports.ER_VIEW_NO_EXPLAIN = 1345; +exports.ER_FRM_UNKNOWN_TYPE = 1346; +exports.ER_WRONG_OBJECT = 1347; +exports.ER_NONUPDATEABLE_COLUMN = 1348; +exports.ER_VIEW_SELECT_DERIVED = 1349; +exports.ER_VIEW_SELECT_CLAUSE = 1350; +exports.ER_VIEW_SELECT_VARIABLE = 1351; +exports.ER_VIEW_SELECT_TMPTABLE = 1352; +exports.ER_VIEW_WRONG_LIST = 1353; +exports.ER_WARN_VIEW_MERGE = 1354; +exports.ER_WARN_VIEW_WITHOUT_KEY = 1355; +exports.ER_VIEW_INVALID = 1356; +exports.ER_SP_NO_DROP_SP = 1357; +exports.ER_SP_GOTO_IN_HNDLR = 1358; +exports.ER_TRG_ALREADY_EXISTS = 1359; +exports.ER_TRG_DOES_NOT_EXIST = 1360; +exports.ER_TRG_ON_VIEW_OR_TEMP_TABLE = 1361; +exports.ER_TRG_CANT_CHANGE_ROW = 1362; +exports.ER_TRG_NO_SUCH_ROW_IN_TRG = 1363; +exports.ER_NO_DEFAULT_FOR_FIELD = 1364; +exports.ER_DIVISION_BY_ZERO = 1365; +exports.ER_TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366; +exports.ER_ILLEGAL_VALUE_FOR_TYPE = 1367; +exports.ER_VIEW_NONUPD_CHECK = 1368; +exports.ER_VIEW_CHECK_FAILED = 1369; +exports.ER_PROCACCESS_DENIED_ERROR = 1370; +exports.ER_RELAY_LOG_FAIL = 1371; +exports.ER_PASSWD_LENGTH = 1372; +exports.ER_UNKNOWN_TARGET_BINLOG = 1373; +exports.ER_IO_ERR_LOG_INDEX_READ = 1374; +exports.ER_BINLOG_PURGE_PROHIBITED = 1375; +exports.ER_FSEEK_FAIL = 1376; +exports.ER_BINLOG_PURGE_FATAL_ERR = 1377; +exports.ER_LOG_IN_USE = 1378; +exports.ER_LOG_PURGE_UNKNOWN_ERR = 1379; +exports.ER_RELAY_LOG_INIT = 1380; +exports.ER_NO_BINARY_LOGGING = 1381; +exports.ER_RESERVED_SYNTAX = 1382; +exports.ER_WSAS_FAILED = 1383; +exports.ER_DIFF_GROUPS_PROC = 1384; +exports.ER_NO_GROUP_FOR_PROC = 1385; +exports.ER_ORDER_WITH_PROC = 1386; +exports.ER_LOGGING_PROHIBIT_CHANGING_OF = 1387; +exports.ER_NO_FILE_MAPPING = 1388; +exports.ER_WRONG_MAGIC = 1389; +exports.ER_PS_MANY_PARAM = 1390; +exports.ER_KEY_PART_ = 1391; +exports.ER_VIEW_CHECKSUM = 1392; +exports.ER_VIEW_MULTIUPDATE = 1393; +exports.ER_VIEW_NO_INSERT_FIELD_LIST = 1394; +exports.ER_VIEW_DELETE_MERGE_VIEW = 1395; +exports.ER_CANNOT_USER = 1396; +exports.ER_XAER_NOTA = 1397; +exports.ER_XAER_INVAL = 1398; +exports.ER_XAER_RMFAIL = 1399; +exports.ER_XAER_OUTSIDE = 1400; +exports.ER_XAER_RMERR = 1401; +exports.ER_XA_RBROLLBACK = 1402; +exports.ER_NONEXISTING_PROC_GRANT = 1403; +exports.ER_PROC_AUTO_GRANT_FAIL = 1404; +exports.ER_PROC_AUTO_REVOKE_FAIL = 1405; +exports.ER_DATA_TOO_LONG = 1406; +exports.ER_SP_BAD_SQLSTATE = 1407; +exports.ER_STARTUP = 1408; +exports.ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409; +exports.ER_CANT_CREATE_USER_WITH_GRANT = 1410; +exports.ER_WRONG_VALUE_FOR_TYPE = 1411; +exports.ER_TABLE_DEF_CHANGED = 1412; +exports.ER_SP_DUP_HANDLER = 1413; +exports.ER_SP_NOT_VAR_ARG = 1414; +exports.ER_SP_NO_RETSET = 1415; +exports.ER_CANT_CREATE_GEOMETRY_OBJECT = 1416; +exports.ER_FAILED_ROUTINE_BREAK_BINLOG = 1417; +exports.ER_BINLOG_UNSAFE_ROUTINE = 1418; +exports.ER_BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419; +exports.ER_EXEC_STMT_WITH_OPEN_CURSOR = 1420; +exports.ER_STMT_HAS_NO_OPEN_CURSOR = 1421; +exports.ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422; +exports.ER_NO_DEFAULT_FOR_VIEW_FIELD = 1423; +exports.ER_SP_NO_RECURSION = 1424; +exports.ER_TOO_BIG_SCALE = 1425; +exports.ER_TOO_BIG_PRECISION = 1426; +exports.ER_M_BIGGER_THAN_D = 1427; +exports.ER_WRONG_LOCK_OF_SYSTEM_TABLE = 1428; +exports.ER_CONNECT_TO_FOREIGN_DATA_SOURCE = 1429; +exports.ER_QUERY_ON_FOREIGN_DATA_SOURCE = 1430; +exports.ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431; +exports.ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432; +exports.ER_FOREIGN_DATA_STRING_INVALID = 1433; +exports.ER_CANT_CREATE_FEDERATED_TABLE = 1434; +exports.ER_TRG_IN_WRONG_SCHEMA = 1435; +exports.ER_STACK_OVERRUN_NEED_MORE = 1436; +exports.ER_TOO_LONG_BODY = 1437; +exports.ER_WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438; +exports.ER_TOO_BIG_DISPLAYWIDTH = 1439; +exports.ER_XAER_DUPID = 1440; +exports.ER_DATETIME_FUNCTION_OVERFLOW = 1441; +exports.ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442; +exports.ER_VIEW_PREVENT_UPDATE = 1443; +exports.ER_PS_NO_RECURSION = 1444; +exports.ER_SP_CANT_SET_AUTOCOMMIT = 1445; +exports.ER_MALFORMED_DEFINER = 1446; +exports.ER_VIEW_FRM_NO_USER = 1447; +exports.ER_VIEW_OTHER_USER = 1448; +exports.ER_NO_SUCH_USER = 1449; +exports.ER_FORBID_SCHEMA_CHANGE = 1450; +exports.ER_ROW_IS_REFERENCED_ = 1451; +exports.ER_NO_REFERENCED_ROW_ = 1452; +exports.ER_SP_BAD_VAR_SHADOW = 1453; +exports.ER_TRG_NO_DEFINER = 1454; +exports.ER_OLD_FILE_FORMAT = 1455; +exports.ER_SP_RECURSION_LIMIT = 1456; +exports.ER_SP_PROC_TABLE_CORRUPT = 1457; +exports.ER_SP_WRONG_NAME = 1458; +exports.ER_TABLE_NEEDS_UPGRADE = 1459; +exports.ER_SP_NO_AGGREGATE = 1460; +exports.ER_MAX_PREPARED_STMT_COUNT_REACHED = 1461; +exports.ER_VIEW_RECURSIVE = 1462; +exports.ER_NON_GROUPING_FIELD_USED = 1463; +exports.ER_TABLE_CANT_HANDLE_SPKEYS = 1464; +exports.ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465; +exports.ER_REMOVED_SPACES = 1466; +exports.ER_AUTOINC_READ_FAILED = 1467; +exports.ER_USERNAME = 1468; +exports.ER_HOSTNAME = 1469; +exports.ER_WRONG_STRING_LENGTH = 1470; +exports.ER_NON_INSERTABLE_TABLE = 1471; +exports.ER_ADMIN_WRONG_MRG_TABLE = 1472; +exports.ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT = 1473; +exports.ER_NAME_BECOMES_EMPTY = 1474; +exports.ER_AMBIGUOUS_FIELD_TERM = 1475; +exports.ER_FOREIGN_SERVER_EXISTS = 1476; +exports.ER_FOREIGN_SERVER_DOESNT_EXIST = 1477; +exports.ER_ILLEGAL_HA_CREATE_OPTION = 1478; +exports.ER_PARTITION_REQUIRES_VALUES_ERROR = 1479; +exports.ER_PARTITION_WRONG_VALUES_ERROR = 1480; +exports.ER_PARTITION_MAXVALUE_ERROR = 1481; +exports.ER_PARTITION_SUBPARTITION_ERROR = 1482; +exports.ER_PARTITION_SUBPART_MIX_ERROR = 1483; +exports.ER_PARTITION_WRONG_NO_PART_ERROR = 1484; +exports.ER_PARTITION_WRONG_NO_SUBPART_ERROR = 1485; +exports.ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR = 1486; +exports.ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR = 1487; +exports.ER_FIELD_NOT_FOUND_PART_ERROR = 1488; +exports.ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR = 1489; +exports.ER_INCONSISTENT_PARTITION_INFO_ERROR = 1490; +exports.ER_PARTITION_FUNC_NOT_ALLOWED_ERROR = 1491; +exports.ER_PARTITIONS_MUST_BE_DEFINED_ERROR = 1492; +exports.ER_RANGE_NOT_INCREASING_ERROR = 1493; +exports.ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR = 1494; +exports.ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR = 1495; +exports.ER_PARTITION_ENTRY_ERROR = 1496; +exports.ER_MIX_HANDLER_ERROR = 1497; +exports.ER_PARTITION_NOT_DEFINED_ERROR = 1498; +exports.ER_TOO_MANY_PARTITIONS_ERROR = 1499; +exports.ER_SUBPARTITION_ERROR = 1500; +exports.ER_CANT_CREATE_HANDLER_FILE = 1501; +exports.ER_BLOB_FIELD_IN_PART_FUNC_ERROR = 1502; +exports.ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF = 1503; +exports.ER_NO_PARTS_ERROR = 1504; +exports.ER_PARTITION_MGMT_ON_NONPARTITIONED = 1505; +exports.ER_FOREIGN_KEY_ON_PARTITIONED = 1506; +exports.ER_DROP_PARTITION_NON_EXISTENT = 1507; +exports.ER_DROP_LAST_PARTITION = 1508; +exports.ER_COALESCE_ONLY_ON_HASH_PARTITION = 1509; +exports.ER_REORG_HASH_ONLY_ON_SAME_NO = 1510; +exports.ER_REORG_NO_PARAM_ERROR = 1511; +exports.ER_ONLY_ON_RANGE_LIST_PARTITION = 1512; +exports.ER_ADD_PARTITION_SUBPART_ERROR = 1513; +exports.ER_ADD_PARTITION_NO_NEW_PARTITION = 1514; +exports.ER_COALESCE_PARTITION_NO_PARTITION = 1515; +exports.ER_REORG_PARTITION_NOT_EXIST = 1516; +exports.ER_SAME_NAME_PARTITION = 1517; +exports.ER_NO_BINLOG_ERROR = 1518; +exports.ER_CONSECUTIVE_REORG_PARTITIONS = 1519; +exports.ER_REORG_OUTSIDE_RANGE = 1520; +exports.ER_PARTITION_FUNCTION_FAILURE = 1521; +exports.ER_PART_STATE_ERROR = 1522; +exports.ER_LIMITED_PART_RANGE = 1523; +exports.ER_PLUGIN_IS_NOT_LOADED = 1524; +exports.ER_WRONG_VALUE = 1525; +exports.ER_NO_PARTITION_FOR_GIVEN_VALUE = 1526; +exports.ER_FILEGROUP_OPTION_ONLY_ONCE = 1527; +exports.ER_CREATE_FILEGROUP_FAILED = 1528; +exports.ER_DROP_FILEGROUP_FAILED = 1529; +exports.ER_TABLESPACE_AUTO_EXTEND_ERROR = 1530; +exports.ER_WRONG_SIZE_NUMBER = 1531; +exports.ER_SIZE_OVERFLOW_ERROR = 1532; +exports.ER_ALTER_FILEGROUP_FAILED = 1533; +exports.ER_BINLOG_ROW_LOGGING_FAILED = 1534; +exports.ER_BINLOG_ROW_WRONG_TABLE_DEF = 1535; +exports.ER_BINLOG_ROW_RBR_TO_SBR = 1536; +exports.ER_EVENT_ALREADY_EXISTS = 1537; +exports.ER_EVENT_STORE_FAILED = 1538; +exports.ER_EVENT_DOES_NOT_EXIST = 1539; +exports.ER_EVENT_CANT_ALTER = 1540; +exports.ER_EVENT_DROP_FAILED = 1541; +exports.ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG = 1542; +exports.ER_EVENT_ENDS_BEFORE_STARTS = 1543; +exports.ER_EVENT_EXEC_TIME_IN_THE_PAST = 1544; +exports.ER_EVENT_OPEN_TABLE_FAILED = 1545; +exports.ER_EVENT_NEITHER_M_EXPR_NOR_M_AT = 1546; +exports.ER_COL_COUNT_DOESNT_MATCH_CORRUPTED = 1547; +exports.ER_CANNOT_LOAD_FROM_TABLE = 1548; +exports.ER_EVENT_CANNOT_DELETE = 1549; +exports.ER_EVENT_COMPILE_ERROR = 1550; +exports.ER_EVENT_SAME_NAME = 1551; +exports.ER_EVENT_DATA_TOO_LONG = 1552; +exports.ER_DROP_INDEX_FK = 1553; +exports.ER_WARN_DEPRECATED_SYNTAX_WITH_VER = 1554; +exports.ER_CANT_WRITE_LOCK_LOG_TABLE = 1555; +exports.ER_CANT_LOCK_LOG_TABLE = 1556; +exports.ER_FOREIGN_DUPLICATE_KEY = 1557; +exports.ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE = 1558; +exports.ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR = 1559; +exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1560; +exports.ER_NDB_CANT_SWITCH_BINLOG_FORMAT = 1561; +exports.ER_PARTITION_NO_TEMPORARY = 1562; +exports.ER_PARTITION_CONST_DOMAIN_ERROR = 1563; +exports.ER_PARTITION_FUNCTION_IS_NOT_ALLOWED = 1564; +exports.ER_DDL_LOG_ERROR = 1565; +exports.ER_NULL_IN_VALUES_LESS_THAN = 1566; +exports.ER_WRONG_PARTITION_NAME = 1567; +exports.ER_CANT_CHANGE_TX_CHARACTERISTICS = 1568; +exports.ER_DUP_ENTRY_AUTOINCREMENT_CASE = 1569; +exports.ER_EVENT_MODIFY_QUEUE_ERROR = 1570; +exports.ER_EVENT_SET_VAR_ERROR = 1571; +exports.ER_PARTITION_MERGE_ERROR = 1572; +exports.ER_CANT_ACTIVATE_LOG = 1573; +exports.ER_RBR_NOT_AVAILABLE = 1574; +exports.ER_BASE = 1575; +exports.ER_EVENT_RECURSION_FORBIDDEN = 1576; +exports.ER_EVENTS_DB_ERROR = 1577; +exports.ER_ONLY_INTEGERS_ALLOWED = 1578; +exports.ER_UNSUPORTED_LOG_ENGINE = 1579; +exports.ER_BAD_LOG_STATEMENT = 1580; +exports.ER_CANT_RENAME_LOG_TABLE = 1581; +exports.ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT = 1582; +exports.ER_WRONG_PARAMETERS_TO_NATIVE_FCT = 1583; +exports.ER_WRONG_PARAMETERS_TO_STORED_FCT = 1584; +exports.ER_NATIVE_FCT_NAME_COLLISION = 1585; +exports.ER_DUP_ENTRY_WITH_KEY_NAME = 1586; +exports.ER_BINLOG_PURGE_EMFILE = 1587; +exports.ER_EVENT_CANNOT_CREATE_IN_THE_PAST = 1588; +exports.ER_EVENT_CANNOT_ALTER_IN_THE_PAST = 1589; +exports.ER_SLAVE_INCIDENT = 1590; +exports.ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT = 1591; +exports.ER_BINLOG_UNSAFE_STATEMENT = 1592; +exports.ER_SLAVE_FATAL_ERROR = 1593; +exports.ER_SLAVE_RELAY_LOG_READ_FAILURE = 1594; +exports.ER_SLAVE_RELAY_LOG_WRITE_FAILURE = 1595; +exports.ER_SLAVE_CREATE_EVENT_FAILURE = 1596; +exports.ER_SLAVE_MASTER_COM_FAILURE = 1597; +exports.ER_BINLOG_LOGGING_IMPOSSIBLE = 1598; +exports.ER_VIEW_NO_CREATION_CTX = 1599; +exports.ER_VIEW_INVALID_CREATION_CTX = 1600; +exports.ER_SR_INVALID_CREATION_CTX = 1601; +exports.ER_TRG_CORRUPTED_FILE = 1602; +exports.ER_TRG_NO_CREATION_CTX = 1603; +exports.ER_TRG_INVALID_CREATION_CTX = 1604; +exports.ER_EVENT_INVALID_CREATION_CTX = 1605; +exports.ER_TRG_CANT_OPEN_TABLE = 1606; +exports.ER_CANT_CREATE_SROUTINE = 1607; +exports.ER_NEVER_USED = 1608; +exports.ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT = 1609; +exports.ER_SLAVE_CORRUPT_EVENT = 1610; +exports.ER_LOAD_DATA_INVALID_COLUMN = 1611; +exports.ER_LOG_PURGE_NO_FILE = 1612; +exports.ER_XA_RBTIMEOUT = 1613; +exports.ER_XA_RBDEADLOCK = 1614; +exports.ER_NEED_REPREPARE = 1615; +exports.ER_DELAYED_NOT_SUPPORTED = 1616; +exports.WARN_NO_MASTER_INFO = 1617; +exports.WARN_OPTION_IGNORED = 1618; +exports.WARN_PLUGIN_DELETE_BUILTIN = 1619; +exports.WARN_PLUGIN_BUSY = 1620; +exports.ER_VARIABLE_IS_READONLY = 1621; +exports.ER_WARN_ENGINE_TRANSACTION_ROLLBACK = 1622; +exports.ER_SLAVE_HEARTBEAT_FAILURE = 1623; +exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE = 1624; +exports.ER_NDB_REPLICATION_SCHEMA_ERROR = 1625; +exports.ER_CONFLICT_FN_PARSE_ERROR = 1626; +exports.ER_EXCEPTIONS_WRITE_ERROR = 1627; +exports.ER_TOO_LONG_TABLE_COMMENT = 1628; +exports.ER_TOO_LONG_FIELD_COMMENT = 1629; +exports.ER_FUNC_INEXISTENT_NAME_COLLISION = 1630; +exports.ER_DATABASE_NAME = 1631; +exports.ER_TABLE_NAME = 1632; +exports.ER_PARTITION_NAME = 1633; +exports.ER_SUBPARTITION_NAME = 1634; +exports.ER_TEMPORARY_NAME = 1635; +exports.ER_RENAMED_NAME = 1636; +exports.ER_TOO_MANY_CONCURRENT_TRXS = 1637; +exports.WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED = 1638; +exports.ER_DEBUG_SYNC_TIMEOUT = 1639; +exports.ER_DEBUG_SYNC_HIT_LIMIT = 1640; +exports.ER_DUP_SIGNAL_SET = 1641; +exports.ER_SIGNAL_WARN = 1642; +exports.ER_SIGNAL_NOT_FOUND = 1643; +exports.ER_SIGNAL_EXCEPTION = 1644; +exports.ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER = 1645; +exports.ER_SIGNAL_BAD_CONDITION_TYPE = 1646; +exports.WARN_COND_ITEM_TRUNCATED = 1647; +exports.ER_COND_ITEM_TOO_LONG = 1648; +exports.ER_UNKNOWN_LOCALE = 1649; +exports.ER_SLAVE_IGNORE_SERVER_IDS = 1650; +exports.ER_QUERY_CACHE_DISABLED = 1651; +exports.ER_SAME_NAME_PARTITION_FIELD = 1652; +exports.ER_PARTITION_COLUMN_LIST_ERROR = 1653; +exports.ER_WRONG_TYPE_COLUMN_VALUE_ERROR = 1654; +exports.ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR = 1655; +exports.ER_MAXVALUE_IN_VALUES_IN = 1656; +exports.ER_TOO_MANY_VALUES_ERROR = 1657; +exports.ER_ROW_SINGLE_PARTITION_FIELD_ERROR = 1658; +exports.ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD = 1659; +exports.ER_PARTITION_FIELDS_TOO_LONG = 1660; +exports.ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE = 1661; +exports.ER_BINLOG_ROW_MODE_AND_STMT_ENGINE = 1662; +exports.ER_BINLOG_UNSAFE_AND_STMT_ENGINE = 1663; +exports.ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE = 1664; +exports.ER_BINLOG_STMT_MODE_AND_ROW_ENGINE = 1665; +exports.ER_BINLOG_ROW_INJECTION_AND_STMT_MODE = 1666; +exports.ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1667; +exports.ER_BINLOG_UNSAFE_LIMIT = 1668; +exports.ER_BINLOG_UNSAFE_INSERT_DELAYED = 1669; +exports.ER_BINLOG_UNSAFE_SYSTEM_TABLE = 1670; +exports.ER_BINLOG_UNSAFE_AUTOINC_COLUMNS = 1671; +exports.ER_BINLOG_UNSAFE_UDF = 1672; +exports.ER_BINLOG_UNSAFE_SYSTEM_VARIABLE = 1673; +exports.ER_BINLOG_UNSAFE_SYSTEM_FUNCTION = 1674; +exports.ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS = 1675; +exports.ER_MESSAGE_AND_STATEMENT = 1676; +exports.ER_SLAVE_CONVERSION_FAILED = 1677; +exports.ER_SLAVE_CANT_CREATE_CONVERSION = 1678; +exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1679; +exports.ER_PATH_LENGTH = 1680; +exports.ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT = 1681; +exports.ER_WRONG_NATIVE_TABLE_STRUCTURE = 1682; +exports.ER_WRONG_PERFSCHEMA_USAGE = 1683; +exports.ER_WARN_I_S_SKIPPED_TABLE = 1684; +exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1685; +exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1686; +exports.ER_SPATIAL_MUST_HAVE_GEOM_COL = 1687; +exports.ER_TOO_LONG_INDEX_COMMENT = 1688; +exports.ER_LOCK_ABORTED = 1689; +exports.ER_DATA_OUT_OF_RANGE = 1690; +exports.ER_WRONG_SPVAR_TYPE_IN_LIMIT = 1691; +exports.ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1692; +exports.ER_BINLOG_UNSAFE_MIXED_STATEMENT = 1693; +exports.ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1694; +exports.ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1695; +exports.ER_FAILED_READ_FROM_PAR_FILE = 1696; +exports.ER_VALUES_IS_NOT_INT_TYPE_ERROR = 1697; +exports.ER_ACCESS_DENIED_NO_PASSWORD_ERROR = 1698; +exports.ER_SET_PASSWORD_AUTH_PLUGIN = 1699; +exports.ER_GRANT_PLUGIN_USER_EXISTS = 1700; +exports.ER_TRUNCATE_ILLEGAL_FK = 1701; +exports.ER_PLUGIN_IS_PERMANENT = 1702; +exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN = 1703; +exports.ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX = 1704; +exports.ER_STMT_CACHE_FULL = 1705; +exports.ER_MULTI_UPDATE_KEY_CONFLICT = 1706; +exports.ER_TABLE_NEEDS_REBUILD = 1707; +exports.WARN_OPTION_BELOW_LIMIT = 1708; +exports.ER_INDEX_COLUMN_TOO_LONG = 1709; +exports.ER_ERROR_IN_TRIGGER_BODY = 1710; +exports.ER_ERROR_IN_UNKNOWN_TRIGGER_BODY = 1711; +exports.ER_INDEX_CORRUPT = 1712; +exports.ER_UNDO_RECORD_TOO_BIG = 1713; +exports.ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT = 1714; +exports.ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE = 1715; +exports.ER_BINLOG_UNSAFE_REPLACE_SELECT = 1716; +exports.ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT = 1717; +exports.ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT = 1718; +exports.ER_BINLOG_UNSAFE_UPDATE_IGNORE = 1719; +exports.ER_PLUGIN_NO_UNINSTALL = 1720; +exports.ER_PLUGIN_NO_INSTALL = 1721; +exports.ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT = 1722; +exports.ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC = 1723; +exports.ER_BINLOG_UNSAFE_INSERT_TWO_KEYS = 1724; +exports.ER_TABLE_IN_FK_CHECK = 1725; +exports.ER_UNSUPPORTED_ENGINE = 1726; +exports.ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST = 1727; +exports.ER_CANNOT_LOAD_FROM_TABLE_V = 1728; +exports.ER_MASTER_DELAY_VALUE_OUT_OF_RANGE = 1729; +exports.ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT = 1730; +exports.ER_PARTITION_EXCHANGE_DIFFERENT_OPTION = 1731; +exports.ER_PARTITION_EXCHANGE_PART_TABLE = 1732; +exports.ER_PARTITION_EXCHANGE_TEMP_TABLE = 1733; +exports.ER_PARTITION_INSTEAD_OF_SUBPARTITION = 1734; +exports.ER_UNKNOWN_PARTITION = 1735; +exports.ER_TABLES_DIFFERENT_METADATA = 1736; +exports.ER_ROW_DOES_NOT_MATCH_PARTITION = 1737; +exports.ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX = 1738; +exports.ER_WARN_INDEX_NOT_APPLICABLE = 1739; +exports.ER_PARTITION_EXCHANGE_FOREIGN_KEY = 1740; +exports.ER_NO_SUCH_KEY_VALUE = 1741; +exports.ER_RPL_INFO_DATA_TOO_LONG = 1742; +exports.ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE = 1743; +exports.ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE = 1744; +exports.ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX = 1745; +exports.ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT = 1746; +exports.ER_PARTITION_CLAUSE_ON_NONPARTITIONED = 1747; +exports.ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET = 1748; +exports.ER_NO_SUCH_PARTITION = 1749; +exports.ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE = 1750; +exports.ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE = 1751; +exports.ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE = 1752; +exports.ER_MTS_FEATURE_IS_NOT_SUPPORTED = 1753; +exports.ER_MTS_UPDATED_DBS_GREATER_MAX = 1754; +exports.ER_MTS_CANT_PARALLEL = 1755; +exports.ER_MTS_INCONSISTENT_DATA = 1756; +exports.ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING = 1757; +exports.ER_DA_INVALID_CONDITION_NUMBER = 1758; +exports.ER_INSECURE_PLAIN_TEXT = 1759; +exports.ER_INSECURE_CHANGE_MASTER = 1760; +exports.ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO = 1761; +exports.ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO = 1762; +exports.ER_SQLTHREAD_WITH_SECURE_SLAVE = 1763; +exports.ER_TABLE_HAS_NO_FT = 1764; +exports.ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER = 1765; +exports.ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION = 1766; +exports.ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST = 1767; +exports.ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL = 1768; +exports.ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION = 1769; +exports.ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL = 1770; +exports.ER_SKIPPING_LOGGED_TRANSACTION = 1771; +exports.ER_MALFORMED_GTID_SET_SPECIFICATION = 1772; +exports.ER_MALFORMED_GTID_SET_ENCODING = 1773; +exports.ER_MALFORMED_GTID_SPECIFICATION = 1774; +exports.ER_GNO_EXHAUSTED = 1775; +exports.ER_BAD_SLAVE_AUTO_POSITION = 1776; +exports.ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON = 1777; +exports.ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET = 1778; +exports.ER_GTID_MODE_ = 1779; +exports.ER_GTID_MODE_REQUIRES_BINLOG = 1780; +exports.ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF = 1781; +exports.ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON = 1782; +exports.ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF = 1783; +exports.ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF = 1784; +exports.ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE = 1785; +exports.ER_GTID_UNSAFE_CREATE_SELECT = 1786; +exports.ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION = 1787; +exports.ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME = 1788; +exports.ER_MASTER_HAS_PURGED_REQUIRED_GTIDS = 1789; +exports.ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID = 1790; +exports.ER_UNKNOWN_EXPLAIN_FORMAT = 1791; +exports.ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION = 1792; +exports.ER_TOO_LONG_TABLE_PARTITION_COMMENT = 1793; +exports.ER_SLAVE_CONFIGURATION = 1794; +exports.ER_INNODB_FT_LIMIT = 1795; +exports.ER_INNODB_NO_FT_TEMP_TABLE = 1796; +exports.ER_INNODB_FT_WRONG_DOCID_COLUMN = 1797; +exports.ER_INNODB_FT_WRONG_DOCID_INDEX = 1798; +exports.ER_INNODB_ONLINE_LOG_TOO_BIG = 1799; +exports.ER_UNKNOWN_ALTER_ALGORITHM = 1800; +exports.ER_UNKNOWN_ALTER_LOCK = 1801; +exports.ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS = 1802; +exports.ER_MTS_RECOVERY_FAILURE = 1803; +exports.ER_MTS_RESET_WORKERS = 1804; +exports.ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V = 1805; +exports.ER_SLAVE_SILENT_RETRY_TRANSACTION = 1806; +exports.ER_DISCARD_FK_CHECKS_RUNNING = 1807; +exports.ER_TABLE_SCHEMA_MISMATCH = 1808; +exports.ER_TABLE_IN_SYSTEM_TABLESPACE = 1809; +exports.ER_IO_READ_ERROR = 1810; +exports.ER_IO_WRITE_ERROR = 1811; +exports.ER_TABLESPACE_MISSING = 1812; +exports.ER_TABLESPACE_EXISTS = 1813; +exports.ER_TABLESPACE_DISCARDED = 1814; +exports.ER_INTERNAL_ERROR = 1815; +exports.ER_INNODB_IMPORT_ERROR = 1816; +exports.ER_INNODB_INDEX_CORRUPT = 1817; +exports.ER_INVALID_YEAR_COLUMN_LENGTH = 1818; +exports.ER_NOT_VALID_PASSWORD = 1819; +exports.ER_MUST_CHANGE_PASSWORD = 1820; +exports.ER_FK_NO_INDEX_CHILD = 1821; +exports.ER_FK_NO_INDEX_PARENT = 1822; +exports.ER_FK_FAIL_ADD_SYSTEM = 1823; +exports.ER_FK_CANNOT_OPEN_PARENT = 1824; +exports.ER_FK_INCORRECT_OPTION = 1825; +exports.ER_FK_DUP_NAME = 1826; +exports.ER_PASSWORD_FORMAT = 1827; +exports.ER_FK_COLUMN_CANNOT_DROP = 1828; +exports.ER_FK_COLUMN_CANNOT_DROP_CHILD = 1829; +exports.ER_FK_COLUMN_NOT_NULL = 1830; +exports.ER_DUP_INDEX = 1831; +exports.ER_FK_COLUMN_CANNOT_CHANGE = 1832; +exports.ER_FK_COLUMN_CANNOT_CHANGE_CHILD = 1833; +exports.ER_FK_CANNOT_DELETE_PARENT = 1834; +exports.ER_MALFORMED_PACKET = 1835; +exports.ER_READ_ONLY_MODE = 1836; +exports.ER_GTID_NEXT_TYPE_UNDEFINED_GROUP = 1837; +exports.ER_VARIABLE_NOT_SETTABLE_IN_SP = 1838; +exports.ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF = 1839; +exports.ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY = 1840; +exports.ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY = 1841; +exports.ER_GTID_PURGED_WAS_CHANGED = 1842; +exports.ER_GTID_EXECUTED_WAS_CHANGED = 1843; +exports.ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES = 1844; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED = 1845; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON = 1846; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY = 1847; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION = 1848; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME = 1849; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE = 1850; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK = 1851; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE = 1852; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK = 1853; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC = 1854; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS = 1855; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS = 1856; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS = 1857; +exports.ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE = 1858; +exports.ER_DUP_UNKNOWN_IN_INDEX = 1859; +exports.ER_IDENT_CAUSES_TOO_LONG_PATH = 1860; +exports.ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL = 1861; +exports.ER_MUST_CHANGE_PASSWORD_LOGIN = 1862; +exports.ER_ROW_IN_WRONG_PARTITION = 1863; +exports.ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX = 1864; +exports.ER_INNODB_NO_FT_USES_PARSER = 1865; +exports.ER_BINLOG_LOGICAL_CORRUPTION = 1866; +exports.ER_WARN_PURGE_LOG_IN_USE = 1867; +exports.ER_WARN_PURGE_LOG_IS_ACTIVE = 1868; +exports.ER_AUTO_INCREMENT_CONFLICT = 1869; +exports.WARN_ON_BLOCKHOLE_IN_RBR = 1870; +exports.ER_SLAVE_MI_INIT_REPOSITORY = 1871; +exports.ER_SLAVE_RLI_INIT_REPOSITORY = 1872; +exports.ER_ACCESS_DENIED_CHANGE_USER_ERROR = 1873; +exports.ER_INNODB_READ_ONLY = 1874; +exports.ER_STOP_SLAVE_SQL_THREAD_TIMEOUT = 1875; +exports.ER_STOP_SLAVE_IO_THREAD_TIMEOUT = 1876; +exports.ER_TABLE_CORRUPT = 1877; +exports.ER_TEMP_FILE_WRITE_FAILURE = 1878; +exports.ER_INNODB_FT_AUX_NOT_HEX_ID = 1879; +exports.ER_OLD_TEMPORALS_UPGRADED = 1880; +exports.ER_INNODB_FORCED_RECOVERY = 1881; +exports.ER_AES_INVALID_IV = 1882; + +// Lookup-by-number table +exports[1] = 'EE_CANTCREATEFILE'; +exports[2] = 'EE_READ'; +exports[3] = 'EE_WRITE'; +exports[4] = 'EE_BADCLOSE'; +exports[5] = 'EE_OUTOFMEMORY'; +exports[6] = 'EE_DELETE'; +exports[7] = 'EE_LINK'; +exports[9] = 'EE_EOFERR'; +exports[10] = 'EE_CANTLOCK'; +exports[11] = 'EE_CANTUNLOCK'; +exports[12] = 'EE_DIR'; +exports[13] = 'EE_STAT'; +exports[14] = 'EE_CANT_CHSIZE'; +exports[15] = 'EE_CANT_OPEN_STREAM'; +exports[16] = 'EE_GETWD'; +exports[17] = 'EE_SETWD'; +exports[18] = 'EE_LINK_WARNING'; +exports[19] = 'EE_OPEN_WARNING'; +exports[20] = 'EE_DISK_FULL'; +exports[21] = 'EE_CANT_MKDIR'; +exports[22] = 'EE_UNKNOWN_CHARSET'; +exports[23] = 'EE_OUT_OF_FILERESOURCES'; +exports[24] = 'EE_CANT_READLINK'; +exports[25] = 'EE_CANT_SYMLINK'; +exports[26] = 'EE_REALPATH'; +exports[27] = 'EE_SYNC'; +exports[28] = 'EE_UNKNOWN_COLLATION'; +exports[29] = 'EE_FILENOTFOUND'; +exports[30] = 'EE_FILE_NOT_CLOSED'; +exports[31] = 'EE_CHANGE_OWNERSHIP'; +exports[32] = 'EE_CHANGE_PERMISSIONS'; +exports[33] = 'EE_CANT_SEEK'; +exports[120] = 'HA_ERR_KEY_NOT_FOUND'; +exports[121] = 'HA_ERR_FOUND_DUPP_KEY'; +exports[122] = 'HA_ERR_INTERNAL_ERROR'; +exports[123] = 'HA_ERR_RECORD_CHANGED'; +exports[124] = 'HA_ERR_WRONG_INDEX'; +exports[126] = 'HA_ERR_CRASHED'; +exports[127] = 'HA_ERR_WRONG_IN_RECORD'; +exports[128] = 'HA_ERR_OUT_OF_MEM'; +exports[130] = 'HA_ERR_NOT_A_TABLE'; +exports[131] = 'HA_ERR_WRONG_COMMAND'; +exports[132] = 'HA_ERR_OLD_FILE'; +exports[133] = 'HA_ERR_NO_ACTIVE_RECORD'; +exports[134] = 'HA_ERR_RECORD_DELETED'; +exports[135] = 'HA_ERR_RECORD_FILE_FULL'; +exports[136] = 'HA_ERR_INDEX_FILE_FULL'; +exports[137] = 'HA_ERR_END_OF_FILE'; +exports[138] = 'HA_ERR_UNSUPPORTED'; +exports[139] = 'HA_ERR_TO_BIG_ROW'; +exports[140] = 'HA_WRONG_CREATE_OPTION'; +exports[141] = 'HA_ERR_FOUND_DUPP_UNIQUE'; +exports[142] = 'HA_ERR_UNKNOWN_CHARSET'; +exports[143] = 'HA_ERR_WRONG_MRG_TABLE_DEF'; +exports[144] = 'HA_ERR_CRASHED_ON_REPAIR'; +exports[145] = 'HA_ERR_CRASHED_ON_USAGE'; +exports[146] = 'HA_ERR_LOCK_WAIT_TIMEOUT'; +exports[147] = 'HA_ERR_LOCK_TABLE_FULL'; +exports[148] = 'HA_ERR_READ_ONLY_TRANSACTION'; +exports[149] = 'HA_ERR_LOCK_DEADLOCK'; +exports[150] = 'HA_ERR_CANNOT_ADD_FOREIGN'; +exports[151] = 'HA_ERR_NO_REFERENCED_ROW'; +exports[152] = 'HA_ERR_ROW_IS_REFERENCED'; +exports[153] = 'HA_ERR_NO_SAVEPOINT'; +exports[154] = 'HA_ERR_NON_UNIQUE_BLOCK_SIZE'; +exports[155] = 'HA_ERR_NO_SUCH_TABLE'; +exports[156] = 'HA_ERR_TABLE_EXIST'; +exports[157] = 'HA_ERR_NO_CONNECTION'; +exports[158] = 'HA_ERR_NULL_IN_SPATIAL'; +exports[159] = 'HA_ERR_TABLE_DEF_CHANGED'; +exports[160] = 'HA_ERR_NO_PARTITION_FOUND'; +exports[161] = 'HA_ERR_RBR_LOGGING_FAILED'; +exports[162] = 'HA_ERR_DROP_INDEX_FK'; +exports[163] = 'HA_ERR_FOREIGN_DUPLICATE_KEY'; +exports[164] = 'HA_ERR_TABLE_NEEDS_UPGRADE'; +exports[165] = 'HA_ERR_TABLE_READONLY'; +exports[166] = 'HA_ERR_AUTOINC_READ_FAILED'; +exports[167] = 'HA_ERR_AUTOINC_ERANGE'; +exports[168] = 'HA_ERR_GENERIC'; +exports[169] = 'HA_ERR_RECORD_IS_THE_SAME'; +exports[170] = 'HA_ERR_LOGGING_IMPOSSIBLE'; +exports[171] = 'HA_ERR_CORRUPT_EVENT'; +exports[172] = 'HA_ERR_NEW_FILE'; +exports[173] = 'HA_ERR_ROWS_EVENT_APPLY'; +exports[174] = 'HA_ERR_INITIALIZATION'; +exports[175] = 'HA_ERR_FILE_TOO_SHORT'; +exports[176] = 'HA_ERR_WRONG_CRC'; +exports[177] = 'HA_ERR_TOO_MANY_CONCURRENT_TRXS'; +exports[178] = 'HA_ERR_NOT_IN_LOCK_PARTITIONS'; +exports[179] = 'HA_ERR_INDEX_COL_TOO_LONG'; +exports[180] = 'HA_ERR_INDEX_CORRUPT'; +exports[181] = 'HA_ERR_UNDO_REC_TOO_BIG'; +exports[182] = 'HA_FTS_INVALID_DOCID'; +exports[183] = 'HA_ERR_TABLE_IN_FK_CHECK'; +exports[184] = 'HA_ERR_TABLESPACE_EXISTS'; +exports[185] = 'HA_ERR_TOO_MANY_FIELDS'; +exports[186] = 'HA_ERR_ROW_IN_WRONG_PARTITION'; +exports[187] = 'HA_ERR_INNODB_READ_ONLY'; +exports[188] = 'HA_ERR_FTS_EXCEED_RESULT_CACHE_LIMIT'; +exports[189] = 'HA_ERR_TEMP_FILE_WRITE_FAILURE'; +exports[190] = 'HA_ERR_INNODB_FORCED_RECOVERY'; +exports[191] = 'HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE'; +exports[1000] = 'ER_HASHCHK'; +exports[1001] = 'ER_NISAMCHK'; +exports[1002] = 'ER_NO'; +exports[1003] = 'ER_YES'; +exports[1004] = 'ER_CANT_CREATE_FILE'; +exports[1005] = 'ER_CANT_CREATE_TABLE'; +exports[1006] = 'ER_CANT_CREATE_DB'; +exports[1007] = 'ER_DB_CREATE_EXISTS'; +exports[1008] = 'ER_DB_DROP_EXISTS'; +exports[1009] = 'ER_DB_DROP_DELETE'; +exports[1010] = 'ER_DB_DROP_RMDIR'; +exports[1011] = 'ER_CANT_DELETE_FILE'; +exports[1012] = 'ER_CANT_FIND_SYSTEM_REC'; +exports[1013] = 'ER_CANT_GET_STAT'; +exports[1014] = 'ER_CANT_GET_WD'; +exports[1015] = 'ER_CANT_LOCK'; +exports[1016] = 'ER_CANT_OPEN_FILE'; +exports[1017] = 'ER_FILE_NOT_FOUND'; +exports[1018] = 'ER_CANT_READ_DIR'; +exports[1019] = 'ER_CANT_SET_WD'; +exports[1020] = 'ER_CHECKREAD'; +exports[1021] = 'ER_DISK_FULL'; +exports[1022] = 'ER_DUP_KEY'; +exports[1023] = 'ER_ERROR_ON_CLOSE'; +exports[1024] = 'ER_ERROR_ON_READ'; +exports[1025] = 'ER_ERROR_ON_RENAME'; +exports[1026] = 'ER_ERROR_ON_WRITE'; +exports[1027] = 'ER_FILE_USED'; +exports[1028] = 'ER_FILSORT_ABORT'; +exports[1029] = 'ER_FORM_NOT_FOUND'; +exports[1030] = 'ER_GET_ERRNO'; +exports[1031] = 'ER_ILLEGAL_HA'; +exports[1032] = 'ER_KEY_NOT_FOUND'; +exports[1033] = 'ER_NOT_FORM_FILE'; +exports[1034] = 'ER_NOT_KEYFILE'; +exports[1035] = 'ER_OLD_KEYFILE'; +exports[1036] = 'ER_OPEN_AS_READONLY'; +exports[1037] = 'ER_OUTOFMEMORY'; +exports[1038] = 'ER_OUT_OF_SORTMEMORY'; +exports[1039] = 'ER_UNEXPECTED_EOF'; +exports[1040] = 'ER_CON_COUNT_ERROR'; +exports[1041] = 'ER_OUT_OF_RESOURCES'; +exports[1042] = 'ER_BAD_HOST_ERROR'; +exports[1043] = 'ER_HANDSHAKE_ERROR'; +exports[1044] = 'ER_DBACCESS_DENIED_ERROR'; +exports[1045] = 'ER_ACCESS_DENIED_ERROR'; +exports[1046] = 'ER_NO_DB_ERROR'; +exports[1047] = 'ER_UNKNOWN_COM_ERROR'; +exports[1048] = 'ER_BAD_NULL_ERROR'; +exports[1049] = 'ER_BAD_DB_ERROR'; +exports[1050] = 'ER_TABLE_EXISTS_ERROR'; +exports[1051] = 'ER_BAD_TABLE_ERROR'; +exports[1052] = 'ER_NON_UNIQ_ERROR'; +exports[1053] = 'ER_SERVER_SHUTDOWN'; +exports[1054] = 'ER_BAD_FIELD_ERROR'; +exports[1055] = 'ER_WRONG_FIELD_WITH_GROUP'; +exports[1056] = 'ER_WRONG_GROUP_FIELD'; +exports[1057] = 'ER_WRONG_SUM_SELECT'; +exports[1058] = 'ER_WRONG_VALUE_COUNT'; +exports[1059] = 'ER_TOO_LONG_IDENT'; +exports[1060] = 'ER_DUP_FIELDNAME'; +exports[1061] = 'ER_DUP_KEYNAME'; +exports[1062] = 'ER_DUP_ENTRY'; +exports[1063] = 'ER_WRONG_FIELD_SPEC'; +exports[1064] = 'ER_PARSE_ERROR'; +exports[1065] = 'ER_EMPTY_QUERY'; +exports[1066] = 'ER_NONUNIQ_TABLE'; +exports[1067] = 'ER_INVALID_DEFAULT'; +exports[1068] = 'ER_MULTIPLE_PRI_KEY'; +exports[1069] = 'ER_TOO_MANY_KEYS'; +exports[1070] = 'ER_TOO_MANY_KEY_PARTS'; +exports[1071] = 'ER_TOO_LONG_KEY'; +exports[1072] = 'ER_KEY_COLUMN_DOES_NOT_EXITS'; +exports[1073] = 'ER_BLOB_USED_AS_KEY'; +exports[1074] = 'ER_TOO_BIG_FIELDLENGTH'; +exports[1075] = 'ER_WRONG_AUTO_KEY'; +exports[1076] = 'ER_READY'; +exports[1077] = 'ER_NORMAL_SHUTDOWN'; +exports[1078] = 'ER_GOT_SIGNAL'; +exports[1079] = 'ER_SHUTDOWN_COMPLETE'; +exports[1080] = 'ER_FORCING_CLOSE'; +exports[1081] = 'ER_IPSOCK_ERROR'; +exports[1082] = 'ER_NO_SUCH_INDEX'; +exports[1083] = 'ER_WRONG_FIELD_TERMINATORS'; +exports[1084] = 'ER_BLOBS_AND_NO_TERMINATED'; +exports[1085] = 'ER_TEXTFILE_NOT_READABLE'; +exports[1086] = 'ER_FILE_EXISTS_ERROR'; +exports[1087] = 'ER_LOAD_INFO'; +exports[1088] = 'ER_ALTER_INFO'; +exports[1089] = 'ER_WRONG_SUB_KEY'; +exports[1090] = 'ER_CANT_REMOVE_ALL_FIELDS'; +exports[1091] = 'ER_CANT_DROP_FIELD_OR_KEY'; +exports[1092] = 'ER_INSERT_INFO'; +exports[1093] = 'ER_UPDATE_TABLE_USED'; +exports[1094] = 'ER_NO_SUCH_THREAD'; +exports[1095] = 'ER_KILL_DENIED_ERROR'; +exports[1096] = 'ER_NO_TABLES_USED'; +exports[1097] = 'ER_TOO_BIG_SET'; +exports[1098] = 'ER_NO_UNIQUE_LOGFILE'; +exports[1099] = 'ER_TABLE_NOT_LOCKED_FOR_WRITE'; +exports[1100] = 'ER_TABLE_NOT_LOCKED'; +exports[1101] = 'ER_BLOB_CANT_HAVE_DEFAULT'; +exports[1102] = 'ER_WRONG_DB_NAME'; +exports[1103] = 'ER_WRONG_TABLE_NAME'; +exports[1104] = 'ER_TOO_BIG_SELECT'; +exports[1105] = 'ER_UNKNOWN_ERROR'; +exports[1106] = 'ER_UNKNOWN_PROCEDURE'; +exports[1107] = 'ER_WRONG_PARAMCOUNT_TO_PROCEDURE'; +exports[1108] = 'ER_WRONG_PARAMETERS_TO_PROCEDURE'; +exports[1109] = 'ER_UNKNOWN_TABLE'; +exports[1110] = 'ER_FIELD_SPECIFIED_TWICE'; +exports[1111] = 'ER_INVALID_GROUP_FUNC_USE'; +exports[1112] = 'ER_UNSUPPORTED_EXTENSION'; +exports[1113] = 'ER_TABLE_MUST_HAVE_COLUMNS'; +exports[1114] = 'ER_RECORD_FILE_FULL'; +exports[1115] = 'ER_UNKNOWN_CHARACTER_SET'; +exports[1116] = 'ER_TOO_MANY_TABLES'; +exports[1117] = 'ER_TOO_MANY_FIELDS'; +exports[1118] = 'ER_TOO_BIG_ROWSIZE'; +exports[1119] = 'ER_STACK_OVERRUN'; +exports[1120] = 'ER_WRONG_OUTER_JOIN'; +exports[1121] = 'ER_NULL_COLUMN_IN_INDEX'; +exports[1122] = 'ER_CANT_FIND_UDF'; +exports[1123] = 'ER_CANT_INITIALIZE_UDF'; +exports[1124] = 'ER_UDF_NO_PATHS'; +exports[1125] = 'ER_UDF_EXISTS'; +exports[1126] = 'ER_CANT_OPEN_LIBRARY'; +exports[1127] = 'ER_CANT_FIND_DL_ENTRY'; +exports[1128] = 'ER_FUNCTION_NOT_DEFINED'; +exports[1129] = 'ER_HOST_IS_BLOCKED'; +exports[1130] = 'ER_HOST_NOT_PRIVILEGED'; +exports[1131] = 'ER_PASSWORD_ANONYMOUS_USER'; +exports[1132] = 'ER_PASSWORD_NOT_ALLOWED'; +exports[1133] = 'ER_PASSWORD_NO_MATCH'; +exports[1134] = 'ER_UPDATE_INFO'; +exports[1135] = 'ER_CANT_CREATE_THREAD'; +exports[1136] = 'ER_WRONG_VALUE_COUNT_ON_ROW'; +exports[1137] = 'ER_CANT_REOPEN_TABLE'; +exports[1138] = 'ER_INVALID_USE_OF_NULL'; +exports[1139] = 'ER_REGEXP_ERROR'; +exports[1140] = 'ER_MIX_OF_GROUP_FUNC_AND_FIELDS'; +exports[1141] = 'ER_NONEXISTING_GRANT'; +exports[1142] = 'ER_TABLEACCESS_DENIED_ERROR'; +exports[1143] = 'ER_COLUMNACCESS_DENIED_ERROR'; +exports[1144] = 'ER_ILLEGAL_GRANT_FOR_TABLE'; +exports[1145] = 'ER_GRANT_WRONG_HOST_OR_USER'; +exports[1146] = 'ER_NO_SUCH_TABLE'; +exports[1147] = 'ER_NONEXISTING_TABLE_GRANT'; +exports[1148] = 'ER_NOT_ALLOWED_COMMAND'; +exports[1149] = 'ER_SYNTAX_ERROR'; +exports[1150] = 'ER_DELAYED_CANT_CHANGE_LOCK'; +exports[1151] = 'ER_TOO_MANY_DELAYED_THREADS'; +exports[1152] = 'ER_ABORTING_CONNECTION'; +exports[1153] = 'ER_NET_PACKET_TOO_LARGE'; +exports[1154] = 'ER_NET_READ_ERROR_FROM_PIPE'; +exports[1155] = 'ER_NET_FCNTL_ERROR'; +exports[1156] = 'ER_NET_PACKETS_OUT_OF_ORDER'; +exports[1157] = 'ER_NET_UNCOMPRESS_ERROR'; +exports[1158] = 'ER_NET_READ_ERROR'; +exports[1159] = 'ER_NET_READ_INTERRUPTED'; +exports[1160] = 'ER_NET_ERROR_ON_WRITE'; +exports[1161] = 'ER_NET_WRITE_INTERRUPTED'; +exports[1162] = 'ER_TOO_LONG_STRING'; +exports[1163] = 'ER_TABLE_CANT_HANDLE_BLOB'; +exports[1164] = 'ER_TABLE_CANT_HANDLE_AUTO_INCREMENT'; +exports[1165] = 'ER_DELAYED_INSERT_TABLE_LOCKED'; +exports[1166] = 'ER_WRONG_COLUMN_NAME'; +exports[1167] = 'ER_WRONG_KEY_COLUMN'; +exports[1168] = 'ER_WRONG_MRG_TABLE'; +exports[1169] = 'ER_DUP_UNIQUE'; +exports[1170] = 'ER_BLOB_KEY_WITHOUT_LENGTH'; +exports[1171] = 'ER_PRIMARY_CANT_HAVE_NULL'; +exports[1172] = 'ER_TOO_MANY_ROWS'; +exports[1173] = 'ER_REQUIRES_PRIMARY_KEY'; +exports[1174] = 'ER_NO_RAID_COMPILED'; +exports[1175] = 'ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE'; +exports[1176] = 'ER_KEY_DOES_NOT_EXITS'; +exports[1177] = 'ER_CHECK_NO_SUCH_TABLE'; +exports[1178] = 'ER_CHECK_NOT_IMPLEMENTED'; +exports[1179] = 'ER_CANT_DO_THIS_DURING_AN_TRANSACTION'; +exports[1180] = 'ER_ERROR_DURING_COMMIT'; +exports[1181] = 'ER_ERROR_DURING_ROLLBACK'; +exports[1182] = 'ER_ERROR_DURING_FLUSH_LOGS'; +exports[1183] = 'ER_ERROR_DURING_CHECKPOINT'; +exports[1184] = 'ER_NEW_ABORTING_CONNECTION'; +exports[1185] = 'ER_DUMP_NOT_IMPLEMENTED'; +exports[1186] = 'ER_FLUSH_MASTER_BINLOG_CLOSED'; +exports[1187] = 'ER_INDEX_REBUILD'; +exports[1188] = 'ER_MASTER'; +exports[1189] = 'ER_MASTER_NET_READ'; +exports[1190] = 'ER_MASTER_NET_WRITE'; +exports[1191] = 'ER_FT_MATCHING_KEY_NOT_FOUND'; +exports[1192] = 'ER_LOCK_OR_ACTIVE_TRANSACTION'; +exports[1193] = 'ER_UNKNOWN_SYSTEM_VARIABLE'; +exports[1194] = 'ER_CRASHED_ON_USAGE'; +exports[1195] = 'ER_CRASHED_ON_REPAIR'; +exports[1196] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK'; +exports[1197] = 'ER_TRANS_CACHE_FULL'; +exports[1198] = 'ER_SLAVE_MUST_STOP'; +exports[1199] = 'ER_SLAVE_NOT_RUNNING'; +exports[1200] = 'ER_BAD_SLAVE'; +exports[1201] = 'ER_MASTER_INFO'; +exports[1202] = 'ER_SLAVE_THREAD'; +exports[1203] = 'ER_TOO_MANY_USER_CONNECTIONS'; +exports[1204] = 'ER_SET_CONSTANTS_ONLY'; +exports[1205] = 'ER_LOCK_WAIT_TIMEOUT'; +exports[1206] = 'ER_LOCK_TABLE_FULL'; +exports[1207] = 'ER_READ_ONLY_TRANSACTION'; +exports[1208] = 'ER_DROP_DB_WITH_READ_LOCK'; +exports[1209] = 'ER_CREATE_DB_WITH_READ_LOCK'; +exports[1210] = 'ER_WRONG_ARGUMENTS'; +exports[1211] = 'ER_NO_PERMISSION_TO_CREATE_USER'; +exports[1212] = 'ER_UNION_TABLES_IN_DIFFERENT_DIR'; +exports[1213] = 'ER_LOCK_DEADLOCK'; +exports[1214] = 'ER_TABLE_CANT_HANDLE_FT'; +exports[1215] = 'ER_CANNOT_ADD_FOREIGN'; +exports[1216] = 'ER_NO_REFERENCED_ROW'; +exports[1217] = 'ER_ROW_IS_REFERENCED'; +exports[1218] = 'ER_CONNECT_TO_MASTER'; +exports[1219] = 'ER_QUERY_ON_MASTER'; +exports[1220] = 'ER_ERROR_WHEN_EXECUTING_COMMAND'; +exports[1221] = 'ER_WRONG_USAGE'; +exports[1222] = 'ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT'; +exports[1223] = 'ER_CANT_UPDATE_WITH_READLOCK'; +exports[1224] = 'ER_MIXING_NOT_ALLOWED'; +exports[1225] = 'ER_DUP_ARGUMENT'; +exports[1226] = 'ER_USER_LIMIT_REACHED'; +exports[1227] = 'ER_SPECIFIC_ACCESS_DENIED_ERROR'; +exports[1228] = 'ER_LOCAL_VARIABLE'; +exports[1229] = 'ER_GLOBAL_VARIABLE'; +exports[1230] = 'ER_NO_DEFAULT'; +exports[1231] = 'ER_WRONG_VALUE_FOR_VAR'; +exports[1232] = 'ER_WRONG_TYPE_FOR_VAR'; +exports[1233] = 'ER_VAR_CANT_BE_READ'; +exports[1234] = 'ER_CANT_USE_OPTION_HERE'; +exports[1235] = 'ER_NOT_SUPPORTED_YET'; +exports[1236] = 'ER_MASTER_FATAL_ERROR_READING_BINLOG'; +exports[1237] = 'ER_SLAVE_IGNORED_TABLE'; +exports[1238] = 'ER_INCORRECT_GLOBAL_LOCAL_VAR'; +exports[1239] = 'ER_WRONG_FK_DEF'; +exports[1240] = 'ER_KEY_REF_DO_NOT_MATCH_TABLE_REF'; +exports[1241] = 'ER_OPERAND_COLUMNS'; +exports[1242] = 'ER_SUBQUERY_NO_'; +exports[1243] = 'ER_UNKNOWN_STMT_HANDLER'; +exports[1244] = 'ER_CORRUPT_HELP_DB'; +exports[1245] = 'ER_CYCLIC_REFERENCE'; +exports[1246] = 'ER_AUTO_CONVERT'; +exports[1247] = 'ER_ILLEGAL_REFERENCE'; +exports[1248] = 'ER_DERIVED_MUST_HAVE_ALIAS'; +exports[1249] = 'ER_SELECT_REDUCED'; +exports[1250] = 'ER_TABLENAME_NOT_ALLOWED_HERE'; +exports[1251] = 'ER_NOT_SUPPORTED_AUTH_MODE'; +exports[1252] = 'ER_SPATIAL_CANT_HAVE_NULL'; +exports[1253] = 'ER_COLLATION_CHARSET_MISMATCH'; +exports[1254] = 'ER_SLAVE_WAS_RUNNING'; +exports[1255] = 'ER_SLAVE_WAS_NOT_RUNNING'; +exports[1256] = 'ER_TOO_BIG_FOR_UNCOMPRESS'; +exports[1257] = 'ER_ZLIB_Z_MEM_ERROR'; +exports[1258] = 'ER_ZLIB_Z_BUF_ERROR'; +exports[1259] = 'ER_ZLIB_Z_DATA_ERROR'; +exports[1260] = 'ER_CUT_VALUE_GROUP_CONCAT'; +exports[1261] = 'ER_WARN_TOO_FEW_RECORDS'; +exports[1262] = 'ER_WARN_TOO_MANY_RECORDS'; +exports[1263] = 'ER_WARN_NULL_TO_NOTNULL'; +exports[1264] = 'ER_WARN_DATA_OUT_OF_RANGE'; +exports[1265] = 'WARN_DATA_TRUNCATED'; +exports[1266] = 'ER_WARN_USING_OTHER_HANDLER'; +exports[1267] = 'ER_CANT_AGGREGATE_'; +exports[1268] = 'ER_DROP_USER'; +exports[1269] = 'ER_REVOKE_GRANTS'; +exports[1270] = 'ER_CANT_AGGREGATE_'; +exports[1271] = 'ER_CANT_AGGREGATE_NCOLLATIONS'; +exports[1272] = 'ER_VARIABLE_IS_NOT_STRUCT'; +exports[1273] = 'ER_UNKNOWN_COLLATION'; +exports[1274] = 'ER_SLAVE_IGNORED_SSL_PARAMS'; +exports[1275] = 'ER_SERVER_IS_IN_SECURE_AUTH_MODE'; +exports[1276] = 'ER_WARN_FIELD_RESOLVED'; +exports[1277] = 'ER_BAD_SLAVE_UNTIL_COND'; +exports[1278] = 'ER_MISSING_SKIP_SLAVE'; +exports[1279] = 'ER_UNTIL_COND_IGNORED'; +exports[1280] = 'ER_WRONG_NAME_FOR_INDEX'; +exports[1281] = 'ER_WRONG_NAME_FOR_CATALOG'; +exports[1282] = 'ER_WARN_QC_RESIZE'; +exports[1283] = 'ER_BAD_FT_COLUMN'; +exports[1284] = 'ER_UNKNOWN_KEY_CACHE'; +exports[1285] = 'ER_WARN_HOSTNAME_WONT_WORK'; +exports[1286] = 'ER_UNKNOWN_STORAGE_ENGINE'; +exports[1287] = 'ER_WARN_DEPRECATED_SYNTAX'; +exports[1288] = 'ER_NON_UPDATABLE_TABLE'; +exports[1289] = 'ER_FEATURE_DISABLED'; +exports[1290] = 'ER_OPTION_PREVENTS_STATEMENT'; +exports[1291] = 'ER_DUPLICATED_VALUE_IN_TYPE'; +exports[1292] = 'ER_TRUNCATED_WRONG_VALUE'; +exports[1293] = 'ER_TOO_MUCH_AUTO_TIMESTAMP_COLS'; +exports[1294] = 'ER_INVALID_ON_UPDATE'; +exports[1295] = 'ER_UNSUPPORTED_PS'; +exports[1296] = 'ER_GET_ERRMSG'; +exports[1297] = 'ER_GET_TEMPORARY_ERRMSG'; +exports[1298] = 'ER_UNKNOWN_TIME_ZONE'; +exports[1299] = 'ER_WARN_INVALID_TIMESTAMP'; +exports[1300] = 'ER_INVALID_CHARACTER_STRING'; +exports[1301] = 'ER_WARN_ALLOWED_PACKET_OVERFLOWED'; +exports[1302] = 'ER_CONFLICTING_DECLARATIONS'; +exports[1303] = 'ER_SP_NO_RECURSIVE_CREATE'; +exports[1304] = 'ER_SP_ALREADY_EXISTS'; +exports[1305] = 'ER_SP_DOES_NOT_EXIST'; +exports[1306] = 'ER_SP_DROP_FAILED'; +exports[1307] = 'ER_SP_STORE_FAILED'; +exports[1308] = 'ER_SP_LILABEL_MISMATCH'; +exports[1309] = 'ER_SP_LABEL_REDEFINE'; +exports[1310] = 'ER_SP_LABEL_MISMATCH'; +exports[1311] = 'ER_SP_UNINIT_VAR'; +exports[1312] = 'ER_SP_BADSELECT'; +exports[1313] = 'ER_SP_BADRETURN'; +exports[1314] = 'ER_SP_BADSTATEMENT'; +exports[1315] = 'ER_UPDATE_LOG_DEPRECATED_IGNORED'; +exports[1316] = 'ER_UPDATE_LOG_DEPRECATED_TRANSLATED'; +exports[1317] = 'ER_QUERY_INTERRUPTED'; +exports[1318] = 'ER_SP_WRONG_NO_OF_ARGS'; +exports[1319] = 'ER_SP_COND_MISMATCH'; +exports[1320] = 'ER_SP_NORETURN'; +exports[1321] = 'ER_SP_NORETURNEND'; +exports[1322] = 'ER_SP_BAD_CURSOR_QUERY'; +exports[1323] = 'ER_SP_BAD_CURSOR_SELECT'; +exports[1324] = 'ER_SP_CURSOR_MISMATCH'; +exports[1325] = 'ER_SP_CURSOR_ALREADY_OPEN'; +exports[1326] = 'ER_SP_CURSOR_NOT_OPEN'; +exports[1327] = 'ER_SP_UNDECLARED_VAR'; +exports[1328] = 'ER_SP_WRONG_NO_OF_FETCH_ARGS'; +exports[1329] = 'ER_SP_FETCH_NO_DATA'; +exports[1330] = 'ER_SP_DUP_PARAM'; +exports[1331] = 'ER_SP_DUP_VAR'; +exports[1332] = 'ER_SP_DUP_COND'; +exports[1333] = 'ER_SP_DUP_CURS'; +exports[1334] = 'ER_SP_CANT_ALTER'; +exports[1335] = 'ER_SP_SUBSELECT_NYI'; +exports[1336] = 'ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG'; +exports[1337] = 'ER_SP_VARCOND_AFTER_CURSHNDLR'; +exports[1338] = 'ER_SP_CURSOR_AFTER_HANDLER'; +exports[1339] = 'ER_SP_CASE_NOT_FOUND'; +exports[1340] = 'ER_FPARSER_TOO_BIG_FILE'; +exports[1341] = 'ER_FPARSER_BAD_HEADER'; +exports[1342] = 'ER_FPARSER_EOF_IN_COMMENT'; +exports[1343] = 'ER_FPARSER_ERROR_IN_PARAMETER'; +exports[1344] = 'ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER'; +exports[1345] = 'ER_VIEW_NO_EXPLAIN'; +exports[1346] = 'ER_FRM_UNKNOWN_TYPE'; +exports[1347] = 'ER_WRONG_OBJECT'; +exports[1348] = 'ER_NONUPDATEABLE_COLUMN'; +exports[1349] = 'ER_VIEW_SELECT_DERIVED'; +exports[1350] = 'ER_VIEW_SELECT_CLAUSE'; +exports[1351] = 'ER_VIEW_SELECT_VARIABLE'; +exports[1352] = 'ER_VIEW_SELECT_TMPTABLE'; +exports[1353] = 'ER_VIEW_WRONG_LIST'; +exports[1354] = 'ER_WARN_VIEW_MERGE'; +exports[1355] = 'ER_WARN_VIEW_WITHOUT_KEY'; +exports[1356] = 'ER_VIEW_INVALID'; +exports[1357] = 'ER_SP_NO_DROP_SP'; +exports[1358] = 'ER_SP_GOTO_IN_HNDLR'; +exports[1359] = 'ER_TRG_ALREADY_EXISTS'; +exports[1360] = 'ER_TRG_DOES_NOT_EXIST'; +exports[1361] = 'ER_TRG_ON_VIEW_OR_TEMP_TABLE'; +exports[1362] = 'ER_TRG_CANT_CHANGE_ROW'; +exports[1363] = 'ER_TRG_NO_SUCH_ROW_IN_TRG'; +exports[1364] = 'ER_NO_DEFAULT_FOR_FIELD'; +exports[1365] = 'ER_DIVISION_BY_ZERO'; +exports[1366] = 'ER_TRUNCATED_WRONG_VALUE_FOR_FIELD'; +exports[1367] = 'ER_ILLEGAL_VALUE_FOR_TYPE'; +exports[1368] = 'ER_VIEW_NONUPD_CHECK'; +exports[1369] = 'ER_VIEW_CHECK_FAILED'; +exports[1370] = 'ER_PROCACCESS_DENIED_ERROR'; +exports[1371] = 'ER_RELAY_LOG_FAIL'; +exports[1372] = 'ER_PASSWD_LENGTH'; +exports[1373] = 'ER_UNKNOWN_TARGET_BINLOG'; +exports[1374] = 'ER_IO_ERR_LOG_INDEX_READ'; +exports[1375] = 'ER_BINLOG_PURGE_PROHIBITED'; +exports[1376] = 'ER_FSEEK_FAIL'; +exports[1377] = 'ER_BINLOG_PURGE_FATAL_ERR'; +exports[1378] = 'ER_LOG_IN_USE'; +exports[1379] = 'ER_LOG_PURGE_UNKNOWN_ERR'; +exports[1380] = 'ER_RELAY_LOG_INIT'; +exports[1381] = 'ER_NO_BINARY_LOGGING'; +exports[1382] = 'ER_RESERVED_SYNTAX'; +exports[1383] = 'ER_WSAS_FAILED'; +exports[1384] = 'ER_DIFF_GROUPS_PROC'; +exports[1385] = 'ER_NO_GROUP_FOR_PROC'; +exports[1386] = 'ER_ORDER_WITH_PROC'; +exports[1387] = 'ER_LOGGING_PROHIBIT_CHANGING_OF'; +exports[1388] = 'ER_NO_FILE_MAPPING'; +exports[1389] = 'ER_WRONG_MAGIC'; +exports[1390] = 'ER_PS_MANY_PARAM'; +exports[1391] = 'ER_KEY_PART_'; +exports[1392] = 'ER_VIEW_CHECKSUM'; +exports[1393] = 'ER_VIEW_MULTIUPDATE'; +exports[1394] = 'ER_VIEW_NO_INSERT_FIELD_LIST'; +exports[1395] = 'ER_VIEW_DELETE_MERGE_VIEW'; +exports[1396] = 'ER_CANNOT_USER'; +exports[1397] = 'ER_XAER_NOTA'; +exports[1398] = 'ER_XAER_INVAL'; +exports[1399] = 'ER_XAER_RMFAIL'; +exports[1400] = 'ER_XAER_OUTSIDE'; +exports[1401] = 'ER_XAER_RMERR'; +exports[1402] = 'ER_XA_RBROLLBACK'; +exports[1403] = 'ER_NONEXISTING_PROC_GRANT'; +exports[1404] = 'ER_PROC_AUTO_GRANT_FAIL'; +exports[1405] = 'ER_PROC_AUTO_REVOKE_FAIL'; +exports[1406] = 'ER_DATA_TOO_LONG'; +exports[1407] = 'ER_SP_BAD_SQLSTATE'; +exports[1408] = 'ER_STARTUP'; +exports[1409] = 'ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR'; +exports[1410] = 'ER_CANT_CREATE_USER_WITH_GRANT'; +exports[1411] = 'ER_WRONG_VALUE_FOR_TYPE'; +exports[1412] = 'ER_TABLE_DEF_CHANGED'; +exports[1413] = 'ER_SP_DUP_HANDLER'; +exports[1414] = 'ER_SP_NOT_VAR_ARG'; +exports[1415] = 'ER_SP_NO_RETSET'; +exports[1416] = 'ER_CANT_CREATE_GEOMETRY_OBJECT'; +exports[1417] = 'ER_FAILED_ROUTINE_BREAK_BINLOG'; +exports[1418] = 'ER_BINLOG_UNSAFE_ROUTINE'; +exports[1419] = 'ER_BINLOG_CREATE_ROUTINE_NEED_SUPER'; +exports[1420] = 'ER_EXEC_STMT_WITH_OPEN_CURSOR'; +exports[1421] = 'ER_STMT_HAS_NO_OPEN_CURSOR'; +exports[1422] = 'ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG'; +exports[1423] = 'ER_NO_DEFAULT_FOR_VIEW_FIELD'; +exports[1424] = 'ER_SP_NO_RECURSION'; +exports[1425] = 'ER_TOO_BIG_SCALE'; +exports[1426] = 'ER_TOO_BIG_PRECISION'; +exports[1427] = 'ER_M_BIGGER_THAN_D'; +exports[1428] = 'ER_WRONG_LOCK_OF_SYSTEM_TABLE'; +exports[1429] = 'ER_CONNECT_TO_FOREIGN_DATA_SOURCE'; +exports[1430] = 'ER_QUERY_ON_FOREIGN_DATA_SOURCE'; +exports[1431] = 'ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST'; +exports[1432] = 'ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE'; +exports[1433] = 'ER_FOREIGN_DATA_STRING_INVALID'; +exports[1434] = 'ER_CANT_CREATE_FEDERATED_TABLE'; +exports[1435] = 'ER_TRG_IN_WRONG_SCHEMA'; +exports[1436] = 'ER_STACK_OVERRUN_NEED_MORE'; +exports[1437] = 'ER_TOO_LONG_BODY'; +exports[1438] = 'ER_WARN_CANT_DROP_DEFAULT_KEYCACHE'; +exports[1439] = 'ER_TOO_BIG_DISPLAYWIDTH'; +exports[1440] = 'ER_XAER_DUPID'; +exports[1441] = 'ER_DATETIME_FUNCTION_OVERFLOW'; +exports[1442] = 'ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG'; +exports[1443] = 'ER_VIEW_PREVENT_UPDATE'; +exports[1444] = 'ER_PS_NO_RECURSION'; +exports[1445] = 'ER_SP_CANT_SET_AUTOCOMMIT'; +exports[1446] = 'ER_MALFORMED_DEFINER'; +exports[1447] = 'ER_VIEW_FRM_NO_USER'; +exports[1448] = 'ER_VIEW_OTHER_USER'; +exports[1449] = 'ER_NO_SUCH_USER'; +exports[1450] = 'ER_FORBID_SCHEMA_CHANGE'; +exports[1451] = 'ER_ROW_IS_REFERENCED_'; +exports[1452] = 'ER_NO_REFERENCED_ROW_'; +exports[1453] = 'ER_SP_BAD_VAR_SHADOW'; +exports[1454] = 'ER_TRG_NO_DEFINER'; +exports[1455] = 'ER_OLD_FILE_FORMAT'; +exports[1456] = 'ER_SP_RECURSION_LIMIT'; +exports[1457] = 'ER_SP_PROC_TABLE_CORRUPT'; +exports[1458] = 'ER_SP_WRONG_NAME'; +exports[1459] = 'ER_TABLE_NEEDS_UPGRADE'; +exports[1460] = 'ER_SP_NO_AGGREGATE'; +exports[1461] = 'ER_MAX_PREPARED_STMT_COUNT_REACHED'; +exports[1462] = 'ER_VIEW_RECURSIVE'; +exports[1463] = 'ER_NON_GROUPING_FIELD_USED'; +exports[1464] = 'ER_TABLE_CANT_HANDLE_SPKEYS'; +exports[1465] = 'ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA'; +exports[1466] = 'ER_REMOVED_SPACES'; +exports[1467] = 'ER_AUTOINC_READ_FAILED'; +exports[1468] = 'ER_USERNAME'; +exports[1469] = 'ER_HOSTNAME'; +exports[1470] = 'ER_WRONG_STRING_LENGTH'; +exports[1471] = 'ER_NON_INSERTABLE_TABLE'; +exports[1472] = 'ER_ADMIN_WRONG_MRG_TABLE'; +exports[1473] = 'ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT'; +exports[1474] = 'ER_NAME_BECOMES_EMPTY'; +exports[1475] = 'ER_AMBIGUOUS_FIELD_TERM'; +exports[1476] = 'ER_FOREIGN_SERVER_EXISTS'; +exports[1477] = 'ER_FOREIGN_SERVER_DOESNT_EXIST'; +exports[1478] = 'ER_ILLEGAL_HA_CREATE_OPTION'; +exports[1479] = 'ER_PARTITION_REQUIRES_VALUES_ERROR'; +exports[1480] = 'ER_PARTITION_WRONG_VALUES_ERROR'; +exports[1481] = 'ER_PARTITION_MAXVALUE_ERROR'; +exports[1482] = 'ER_PARTITION_SUBPARTITION_ERROR'; +exports[1483] = 'ER_PARTITION_SUBPART_MIX_ERROR'; +exports[1484] = 'ER_PARTITION_WRONG_NO_PART_ERROR'; +exports[1485] = 'ER_PARTITION_WRONG_NO_SUBPART_ERROR'; +exports[1486] = 'ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR'; +exports[1487] = 'ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR'; +exports[1488] = 'ER_FIELD_NOT_FOUND_PART_ERROR'; +exports[1489] = 'ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR'; +exports[1490] = 'ER_INCONSISTENT_PARTITION_INFO_ERROR'; +exports[1491] = 'ER_PARTITION_FUNC_NOT_ALLOWED_ERROR'; +exports[1492] = 'ER_PARTITIONS_MUST_BE_DEFINED_ERROR'; +exports[1493] = 'ER_RANGE_NOT_INCREASING_ERROR'; +exports[1494] = 'ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR'; +exports[1495] = 'ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR'; +exports[1496] = 'ER_PARTITION_ENTRY_ERROR'; +exports[1497] = 'ER_MIX_HANDLER_ERROR'; +exports[1498] = 'ER_PARTITION_NOT_DEFINED_ERROR'; +exports[1499] = 'ER_TOO_MANY_PARTITIONS_ERROR'; +exports[1500] = 'ER_SUBPARTITION_ERROR'; +exports[1501] = 'ER_CANT_CREATE_HANDLER_FILE'; +exports[1502] = 'ER_BLOB_FIELD_IN_PART_FUNC_ERROR'; +exports[1503] = 'ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF'; +exports[1504] = 'ER_NO_PARTS_ERROR'; +exports[1505] = 'ER_PARTITION_MGMT_ON_NONPARTITIONED'; +exports[1506] = 'ER_FOREIGN_KEY_ON_PARTITIONED'; +exports[1507] = 'ER_DROP_PARTITION_NON_EXISTENT'; +exports[1508] = 'ER_DROP_LAST_PARTITION'; +exports[1509] = 'ER_COALESCE_ONLY_ON_HASH_PARTITION'; +exports[1510] = 'ER_REORG_HASH_ONLY_ON_SAME_NO'; +exports[1511] = 'ER_REORG_NO_PARAM_ERROR'; +exports[1512] = 'ER_ONLY_ON_RANGE_LIST_PARTITION'; +exports[1513] = 'ER_ADD_PARTITION_SUBPART_ERROR'; +exports[1514] = 'ER_ADD_PARTITION_NO_NEW_PARTITION'; +exports[1515] = 'ER_COALESCE_PARTITION_NO_PARTITION'; +exports[1516] = 'ER_REORG_PARTITION_NOT_EXIST'; +exports[1517] = 'ER_SAME_NAME_PARTITION'; +exports[1518] = 'ER_NO_BINLOG_ERROR'; +exports[1519] = 'ER_CONSECUTIVE_REORG_PARTITIONS'; +exports[1520] = 'ER_REORG_OUTSIDE_RANGE'; +exports[1521] = 'ER_PARTITION_FUNCTION_FAILURE'; +exports[1522] = 'ER_PART_STATE_ERROR'; +exports[1523] = 'ER_LIMITED_PART_RANGE'; +exports[1524] = 'ER_PLUGIN_IS_NOT_LOADED'; +exports[1525] = 'ER_WRONG_VALUE'; +exports[1526] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE'; +exports[1527] = 'ER_FILEGROUP_OPTION_ONLY_ONCE'; +exports[1528] = 'ER_CREATE_FILEGROUP_FAILED'; +exports[1529] = 'ER_DROP_FILEGROUP_FAILED'; +exports[1530] = 'ER_TABLESPACE_AUTO_EXTEND_ERROR'; +exports[1531] = 'ER_WRONG_SIZE_NUMBER'; +exports[1532] = 'ER_SIZE_OVERFLOW_ERROR'; +exports[1533] = 'ER_ALTER_FILEGROUP_FAILED'; +exports[1534] = 'ER_BINLOG_ROW_LOGGING_FAILED'; +exports[1535] = 'ER_BINLOG_ROW_WRONG_TABLE_DEF'; +exports[1536] = 'ER_BINLOG_ROW_RBR_TO_SBR'; +exports[1537] = 'ER_EVENT_ALREADY_EXISTS'; +exports[1538] = 'ER_EVENT_STORE_FAILED'; +exports[1539] = 'ER_EVENT_DOES_NOT_EXIST'; +exports[1540] = 'ER_EVENT_CANT_ALTER'; +exports[1541] = 'ER_EVENT_DROP_FAILED'; +exports[1542] = 'ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG'; +exports[1543] = 'ER_EVENT_ENDS_BEFORE_STARTS'; +exports[1544] = 'ER_EVENT_EXEC_TIME_IN_THE_PAST'; +exports[1545] = 'ER_EVENT_OPEN_TABLE_FAILED'; +exports[1546] = 'ER_EVENT_NEITHER_M_EXPR_NOR_M_AT'; +exports[1547] = 'ER_COL_COUNT_DOESNT_MATCH_CORRUPTED'; +exports[1548] = 'ER_CANNOT_LOAD_FROM_TABLE'; +exports[1549] = 'ER_EVENT_CANNOT_DELETE'; +exports[1550] = 'ER_EVENT_COMPILE_ERROR'; +exports[1551] = 'ER_EVENT_SAME_NAME'; +exports[1552] = 'ER_EVENT_DATA_TOO_LONG'; +exports[1553] = 'ER_DROP_INDEX_FK'; +exports[1554] = 'ER_WARN_DEPRECATED_SYNTAX_WITH_VER'; +exports[1555] = 'ER_CANT_WRITE_LOCK_LOG_TABLE'; +exports[1556] = 'ER_CANT_LOCK_LOG_TABLE'; +exports[1557] = 'ER_FOREIGN_DUPLICATE_KEY'; +exports[1558] = 'ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE'; +exports[1559] = 'ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR'; +exports[1560] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT'; +exports[1561] = 'ER_NDB_CANT_SWITCH_BINLOG_FORMAT'; +exports[1562] = 'ER_PARTITION_NO_TEMPORARY'; +exports[1563] = 'ER_PARTITION_CONST_DOMAIN_ERROR'; +exports[1564] = 'ER_PARTITION_FUNCTION_IS_NOT_ALLOWED'; +exports[1565] = 'ER_DDL_LOG_ERROR'; +exports[1566] = 'ER_NULL_IN_VALUES_LESS_THAN'; +exports[1567] = 'ER_WRONG_PARTITION_NAME'; +exports[1568] = 'ER_CANT_CHANGE_TX_CHARACTERISTICS'; +exports[1569] = 'ER_DUP_ENTRY_AUTOINCREMENT_CASE'; +exports[1570] = 'ER_EVENT_MODIFY_QUEUE_ERROR'; +exports[1571] = 'ER_EVENT_SET_VAR_ERROR'; +exports[1572] = 'ER_PARTITION_MERGE_ERROR'; +exports[1573] = 'ER_CANT_ACTIVATE_LOG'; +exports[1574] = 'ER_RBR_NOT_AVAILABLE'; +exports[1575] = 'ER_BASE'; +exports[1576] = 'ER_EVENT_RECURSION_FORBIDDEN'; +exports[1577] = 'ER_EVENTS_DB_ERROR'; +exports[1578] = 'ER_ONLY_INTEGERS_ALLOWED'; +exports[1579] = 'ER_UNSUPORTED_LOG_ENGINE'; +exports[1580] = 'ER_BAD_LOG_STATEMENT'; +exports[1581] = 'ER_CANT_RENAME_LOG_TABLE'; +exports[1582] = 'ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT'; +exports[1583] = 'ER_WRONG_PARAMETERS_TO_NATIVE_FCT'; +exports[1584] = 'ER_WRONG_PARAMETERS_TO_STORED_FCT'; +exports[1585] = 'ER_NATIVE_FCT_NAME_COLLISION'; +exports[1586] = 'ER_DUP_ENTRY_WITH_KEY_NAME'; +exports[1587] = 'ER_BINLOG_PURGE_EMFILE'; +exports[1588] = 'ER_EVENT_CANNOT_CREATE_IN_THE_PAST'; +exports[1589] = 'ER_EVENT_CANNOT_ALTER_IN_THE_PAST'; +exports[1590] = 'ER_SLAVE_INCIDENT'; +exports[1591] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT'; +exports[1592] = 'ER_BINLOG_UNSAFE_STATEMENT'; +exports[1593] = 'ER_SLAVE_FATAL_ERROR'; +exports[1594] = 'ER_SLAVE_RELAY_LOG_READ_FAILURE'; +exports[1595] = 'ER_SLAVE_RELAY_LOG_WRITE_FAILURE'; +exports[1596] = 'ER_SLAVE_CREATE_EVENT_FAILURE'; +exports[1597] = 'ER_SLAVE_MASTER_COM_FAILURE'; +exports[1598] = 'ER_BINLOG_LOGGING_IMPOSSIBLE'; +exports[1599] = 'ER_VIEW_NO_CREATION_CTX'; +exports[1600] = 'ER_VIEW_INVALID_CREATION_CTX'; +exports[1601] = 'ER_SR_INVALID_CREATION_CTX'; +exports[1602] = 'ER_TRG_CORRUPTED_FILE'; +exports[1603] = 'ER_TRG_NO_CREATION_CTX'; +exports[1604] = 'ER_TRG_INVALID_CREATION_CTX'; +exports[1605] = 'ER_EVENT_INVALID_CREATION_CTX'; +exports[1606] = 'ER_TRG_CANT_OPEN_TABLE'; +exports[1607] = 'ER_CANT_CREATE_SROUTINE'; +exports[1608] = 'ER_NEVER_USED'; +exports[1609] = 'ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT'; +exports[1610] = 'ER_SLAVE_CORRUPT_EVENT'; +exports[1611] = 'ER_LOAD_DATA_INVALID_COLUMN'; +exports[1612] = 'ER_LOG_PURGE_NO_FILE'; +exports[1613] = 'ER_XA_RBTIMEOUT'; +exports[1614] = 'ER_XA_RBDEADLOCK'; +exports[1615] = 'ER_NEED_REPREPARE'; +exports[1616] = 'ER_DELAYED_NOT_SUPPORTED'; +exports[1617] = 'WARN_NO_MASTER_INFO'; +exports[1618] = 'WARN_OPTION_IGNORED'; +exports[1619] = 'WARN_PLUGIN_DELETE_BUILTIN'; +exports[1620] = 'WARN_PLUGIN_BUSY'; +exports[1621] = 'ER_VARIABLE_IS_READONLY'; +exports[1622] = 'ER_WARN_ENGINE_TRANSACTION_ROLLBACK'; +exports[1623] = 'ER_SLAVE_HEARTBEAT_FAILURE'; +exports[1624] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE'; +exports[1625] = 'ER_NDB_REPLICATION_SCHEMA_ERROR'; +exports[1626] = 'ER_CONFLICT_FN_PARSE_ERROR'; +exports[1627] = 'ER_EXCEPTIONS_WRITE_ERROR'; +exports[1628] = 'ER_TOO_LONG_TABLE_COMMENT'; +exports[1629] = 'ER_TOO_LONG_FIELD_COMMENT'; +exports[1630] = 'ER_FUNC_INEXISTENT_NAME_COLLISION'; +exports[1631] = 'ER_DATABASE_NAME'; +exports[1632] = 'ER_TABLE_NAME'; +exports[1633] = 'ER_PARTITION_NAME'; +exports[1634] = 'ER_SUBPARTITION_NAME'; +exports[1635] = 'ER_TEMPORARY_NAME'; +exports[1636] = 'ER_RENAMED_NAME'; +exports[1637] = 'ER_TOO_MANY_CONCURRENT_TRXS'; +exports[1638] = 'WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED'; +exports[1639] = 'ER_DEBUG_SYNC_TIMEOUT'; +exports[1640] = 'ER_DEBUG_SYNC_HIT_LIMIT'; +exports[1641] = 'ER_DUP_SIGNAL_SET'; +exports[1642] = 'ER_SIGNAL_WARN'; +exports[1643] = 'ER_SIGNAL_NOT_FOUND'; +exports[1644] = 'ER_SIGNAL_EXCEPTION'; +exports[1645] = 'ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER'; +exports[1646] = 'ER_SIGNAL_BAD_CONDITION_TYPE'; +exports[1647] = 'WARN_COND_ITEM_TRUNCATED'; +exports[1648] = 'ER_COND_ITEM_TOO_LONG'; +exports[1649] = 'ER_UNKNOWN_LOCALE'; +exports[1650] = 'ER_SLAVE_IGNORE_SERVER_IDS'; +exports[1651] = 'ER_QUERY_CACHE_DISABLED'; +exports[1652] = 'ER_SAME_NAME_PARTITION_FIELD'; +exports[1653] = 'ER_PARTITION_COLUMN_LIST_ERROR'; +exports[1654] = 'ER_WRONG_TYPE_COLUMN_VALUE_ERROR'; +exports[1655] = 'ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR'; +exports[1656] = 'ER_MAXVALUE_IN_VALUES_IN'; +exports[1657] = 'ER_TOO_MANY_VALUES_ERROR'; +exports[1658] = 'ER_ROW_SINGLE_PARTITION_FIELD_ERROR'; +exports[1659] = 'ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD'; +exports[1660] = 'ER_PARTITION_FIELDS_TOO_LONG'; +exports[1661] = 'ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE'; +exports[1662] = 'ER_BINLOG_ROW_MODE_AND_STMT_ENGINE'; +exports[1663] = 'ER_BINLOG_UNSAFE_AND_STMT_ENGINE'; +exports[1664] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE'; +exports[1665] = 'ER_BINLOG_STMT_MODE_AND_ROW_ENGINE'; +exports[1666] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_MODE'; +exports[1667] = 'ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE'; +exports[1668] = 'ER_BINLOG_UNSAFE_LIMIT'; +exports[1669] = 'ER_BINLOG_UNSAFE_INSERT_DELAYED'; +exports[1670] = 'ER_BINLOG_UNSAFE_SYSTEM_TABLE'; +exports[1671] = 'ER_BINLOG_UNSAFE_AUTOINC_COLUMNS'; +exports[1672] = 'ER_BINLOG_UNSAFE_UDF'; +exports[1673] = 'ER_BINLOG_UNSAFE_SYSTEM_VARIABLE'; +exports[1674] = 'ER_BINLOG_UNSAFE_SYSTEM_FUNCTION'; +exports[1675] = 'ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS'; +exports[1676] = 'ER_MESSAGE_AND_STATEMENT'; +exports[1677] = 'ER_SLAVE_CONVERSION_FAILED'; +exports[1678] = 'ER_SLAVE_CANT_CREATE_CONVERSION'; +exports[1679] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT'; +exports[1680] = 'ER_PATH_LENGTH'; +exports[1681] = 'ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT'; +exports[1682] = 'ER_WRONG_NATIVE_TABLE_STRUCTURE'; +exports[1683] = 'ER_WRONG_PERFSCHEMA_USAGE'; +exports[1684] = 'ER_WARN_I_S_SKIPPED_TABLE'; +exports[1685] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT'; +exports[1686] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT'; +exports[1687] = 'ER_SPATIAL_MUST_HAVE_GEOM_COL'; +exports[1688] = 'ER_TOO_LONG_INDEX_COMMENT'; +exports[1689] = 'ER_LOCK_ABORTED'; +exports[1690] = 'ER_DATA_OUT_OF_RANGE'; +exports[1691] = 'ER_WRONG_SPVAR_TYPE_IN_LIMIT'; +exports[1692] = 'ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE'; +exports[1693] = 'ER_BINLOG_UNSAFE_MIXED_STATEMENT'; +exports[1694] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN'; +exports[1695] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN'; +exports[1696] = 'ER_FAILED_READ_FROM_PAR_FILE'; +exports[1697] = 'ER_VALUES_IS_NOT_INT_TYPE_ERROR'; +exports[1698] = 'ER_ACCESS_DENIED_NO_PASSWORD_ERROR'; +exports[1699] = 'ER_SET_PASSWORD_AUTH_PLUGIN'; +exports[1700] = 'ER_GRANT_PLUGIN_USER_EXISTS'; +exports[1701] = 'ER_TRUNCATE_ILLEGAL_FK'; +exports[1702] = 'ER_PLUGIN_IS_PERMANENT'; +exports[1703] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN'; +exports[1704] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX'; +exports[1705] = 'ER_STMT_CACHE_FULL'; +exports[1706] = 'ER_MULTI_UPDATE_KEY_CONFLICT'; +exports[1707] = 'ER_TABLE_NEEDS_REBUILD'; +exports[1708] = 'WARN_OPTION_BELOW_LIMIT'; +exports[1709] = 'ER_INDEX_COLUMN_TOO_LONG'; +exports[1710] = 'ER_ERROR_IN_TRIGGER_BODY'; +exports[1711] = 'ER_ERROR_IN_UNKNOWN_TRIGGER_BODY'; +exports[1712] = 'ER_INDEX_CORRUPT'; +exports[1713] = 'ER_UNDO_RECORD_TOO_BIG'; +exports[1714] = 'ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT'; +exports[1715] = 'ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE'; +exports[1716] = 'ER_BINLOG_UNSAFE_REPLACE_SELECT'; +exports[1717] = 'ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT'; +exports[1718] = 'ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT'; +exports[1719] = 'ER_BINLOG_UNSAFE_UPDATE_IGNORE'; +exports[1720] = 'ER_PLUGIN_NO_UNINSTALL'; +exports[1721] = 'ER_PLUGIN_NO_INSTALL'; +exports[1722] = 'ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT'; +exports[1723] = 'ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC'; +exports[1724] = 'ER_BINLOG_UNSAFE_INSERT_TWO_KEYS'; +exports[1725] = 'ER_TABLE_IN_FK_CHECK'; +exports[1726] = 'ER_UNSUPPORTED_ENGINE'; +exports[1727] = 'ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST'; +exports[1728] = 'ER_CANNOT_LOAD_FROM_TABLE_V'; +exports[1729] = 'ER_MASTER_DELAY_VALUE_OUT_OF_RANGE'; +exports[1730] = 'ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT'; +exports[1731] = 'ER_PARTITION_EXCHANGE_DIFFERENT_OPTION'; +exports[1732] = 'ER_PARTITION_EXCHANGE_PART_TABLE'; +exports[1733] = 'ER_PARTITION_EXCHANGE_TEMP_TABLE'; +exports[1734] = 'ER_PARTITION_INSTEAD_OF_SUBPARTITION'; +exports[1735] = 'ER_UNKNOWN_PARTITION'; +exports[1736] = 'ER_TABLES_DIFFERENT_METADATA'; +exports[1737] = 'ER_ROW_DOES_NOT_MATCH_PARTITION'; +exports[1738] = 'ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX'; +exports[1739] = 'ER_WARN_INDEX_NOT_APPLICABLE'; +exports[1740] = 'ER_PARTITION_EXCHANGE_FOREIGN_KEY'; +exports[1741] = 'ER_NO_SUCH_KEY_VALUE'; +exports[1742] = 'ER_RPL_INFO_DATA_TOO_LONG'; +exports[1743] = 'ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE'; +exports[1744] = 'ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE'; +exports[1745] = 'ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX'; +exports[1746] = 'ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT'; +exports[1747] = 'ER_PARTITION_CLAUSE_ON_NONPARTITIONED'; +exports[1748] = 'ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET'; +exports[1749] = 'ER_NO_SUCH_PARTITION'; +exports[1750] = 'ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE'; +exports[1751] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE'; +exports[1752] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE'; +exports[1753] = 'ER_MTS_FEATURE_IS_NOT_SUPPORTED'; +exports[1754] = 'ER_MTS_UPDATED_DBS_GREATER_MAX'; +exports[1755] = 'ER_MTS_CANT_PARALLEL'; +exports[1756] = 'ER_MTS_INCONSISTENT_DATA'; +exports[1757] = 'ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING'; +exports[1758] = 'ER_DA_INVALID_CONDITION_NUMBER'; +exports[1759] = 'ER_INSECURE_PLAIN_TEXT'; +exports[1760] = 'ER_INSECURE_CHANGE_MASTER'; +exports[1761] = 'ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO'; +exports[1762] = 'ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO'; +exports[1763] = 'ER_SQLTHREAD_WITH_SECURE_SLAVE'; +exports[1764] = 'ER_TABLE_HAS_NO_FT'; +exports[1765] = 'ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER'; +exports[1766] = 'ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION'; +exports[1767] = 'ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST'; +exports[1768] = 'ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL'; +exports[1769] = 'ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION'; +exports[1770] = 'ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL'; +exports[1771] = 'ER_SKIPPING_LOGGED_TRANSACTION'; +exports[1772] = 'ER_MALFORMED_GTID_SET_SPECIFICATION'; +exports[1773] = 'ER_MALFORMED_GTID_SET_ENCODING'; +exports[1774] = 'ER_MALFORMED_GTID_SPECIFICATION'; +exports[1775] = 'ER_GNO_EXHAUSTED'; +exports[1776] = 'ER_BAD_SLAVE_AUTO_POSITION'; +exports[1777] = 'ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON'; +exports[1778] = 'ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET'; +exports[1779] = 'ER_GTID_MODE_'; +exports[1780] = 'ER_GTID_MODE_REQUIRES_BINLOG'; +exports[1781] = 'ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF'; +exports[1782] = 'ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON'; +exports[1783] = 'ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF'; +exports[1784] = 'ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF'; +exports[1785] = 'ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE'; +exports[1786] = 'ER_GTID_UNSAFE_CREATE_SELECT'; +exports[1787] = 'ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION'; +exports[1788] = 'ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME'; +exports[1789] = 'ER_MASTER_HAS_PURGED_REQUIRED_GTIDS'; +exports[1790] = 'ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID'; +exports[1791] = 'ER_UNKNOWN_EXPLAIN_FORMAT'; +exports[1792] = 'ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION'; +exports[1793] = 'ER_TOO_LONG_TABLE_PARTITION_COMMENT'; +exports[1794] = 'ER_SLAVE_CONFIGURATION'; +exports[1795] = 'ER_INNODB_FT_LIMIT'; +exports[1796] = 'ER_INNODB_NO_FT_TEMP_TABLE'; +exports[1797] = 'ER_INNODB_FT_WRONG_DOCID_COLUMN'; +exports[1798] = 'ER_INNODB_FT_WRONG_DOCID_INDEX'; +exports[1799] = 'ER_INNODB_ONLINE_LOG_TOO_BIG'; +exports[1800] = 'ER_UNKNOWN_ALTER_ALGORITHM'; +exports[1801] = 'ER_UNKNOWN_ALTER_LOCK'; +exports[1802] = 'ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS'; +exports[1803] = 'ER_MTS_RECOVERY_FAILURE'; +exports[1804] = 'ER_MTS_RESET_WORKERS'; +exports[1805] = 'ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V'; +exports[1806] = 'ER_SLAVE_SILENT_RETRY_TRANSACTION'; +exports[1807] = 'ER_DISCARD_FK_CHECKS_RUNNING'; +exports[1808] = 'ER_TABLE_SCHEMA_MISMATCH'; +exports[1809] = 'ER_TABLE_IN_SYSTEM_TABLESPACE'; +exports[1810] = 'ER_IO_READ_ERROR'; +exports[1811] = 'ER_IO_WRITE_ERROR'; +exports[1812] = 'ER_TABLESPACE_MISSING'; +exports[1813] = 'ER_TABLESPACE_EXISTS'; +exports[1814] = 'ER_TABLESPACE_DISCARDED'; +exports[1815] = 'ER_INTERNAL_ERROR'; +exports[1816] = 'ER_INNODB_IMPORT_ERROR'; +exports[1817] = 'ER_INNODB_INDEX_CORRUPT'; +exports[1818] = 'ER_INVALID_YEAR_COLUMN_LENGTH'; +exports[1819] = 'ER_NOT_VALID_PASSWORD'; +exports[1820] = 'ER_MUST_CHANGE_PASSWORD'; +exports[1821] = 'ER_FK_NO_INDEX_CHILD'; +exports[1822] = 'ER_FK_NO_INDEX_PARENT'; +exports[1823] = 'ER_FK_FAIL_ADD_SYSTEM'; +exports[1824] = 'ER_FK_CANNOT_OPEN_PARENT'; +exports[1825] = 'ER_FK_INCORRECT_OPTION'; +exports[1826] = 'ER_FK_DUP_NAME'; +exports[1827] = 'ER_PASSWORD_FORMAT'; +exports[1828] = 'ER_FK_COLUMN_CANNOT_DROP'; +exports[1829] = 'ER_FK_COLUMN_CANNOT_DROP_CHILD'; +exports[1830] = 'ER_FK_COLUMN_NOT_NULL'; +exports[1831] = 'ER_DUP_INDEX'; +exports[1832] = 'ER_FK_COLUMN_CANNOT_CHANGE'; +exports[1833] = 'ER_FK_COLUMN_CANNOT_CHANGE_CHILD'; +exports[1834] = 'ER_FK_CANNOT_DELETE_PARENT'; +exports[1835] = 'ER_MALFORMED_PACKET'; +exports[1836] = 'ER_READ_ONLY_MODE'; +exports[1837] = 'ER_GTID_NEXT_TYPE_UNDEFINED_GROUP'; +exports[1838] = 'ER_VARIABLE_NOT_SETTABLE_IN_SP'; +exports[1839] = 'ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF'; +exports[1840] = 'ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY'; +exports[1841] = 'ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY'; +exports[1842] = 'ER_GTID_PURGED_WAS_CHANGED'; +exports[1843] = 'ER_GTID_EXECUTED_WAS_CHANGED'; +exports[1844] = 'ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES'; +exports[1845] = 'ER_ALTER_OPERATION_NOT_SUPPORTED'; +exports[1846] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON'; +exports[1847] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY'; +exports[1848] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION'; +exports[1849] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME'; +exports[1850] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE'; +exports[1851] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK'; +exports[1852] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE'; +exports[1853] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK'; +exports[1854] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC'; +exports[1855] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS'; +exports[1856] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS'; +exports[1857] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS'; +exports[1858] = 'ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE'; +exports[1859] = 'ER_DUP_UNKNOWN_IN_INDEX'; +exports[1860] = 'ER_IDENT_CAUSES_TOO_LONG_PATH'; +exports[1861] = 'ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL'; +exports[1862] = 'ER_MUST_CHANGE_PASSWORD_LOGIN'; +exports[1863] = 'ER_ROW_IN_WRONG_PARTITION'; +exports[1864] = 'ER_MTS_EVENT_BIGGER_PENDING_JOBS_SIZE_MAX'; +exports[1865] = 'ER_INNODB_NO_FT_USES_PARSER'; +exports[1866] = 'ER_BINLOG_LOGICAL_CORRUPTION'; +exports[1867] = 'ER_WARN_PURGE_LOG_IN_USE'; +exports[1868] = 'ER_WARN_PURGE_LOG_IS_ACTIVE'; +exports[1869] = 'ER_AUTO_INCREMENT_CONFLICT'; +exports[1870] = 'WARN_ON_BLOCKHOLE_IN_RBR'; +exports[1871] = 'ER_SLAVE_MI_INIT_REPOSITORY'; +exports[1872] = 'ER_SLAVE_RLI_INIT_REPOSITORY'; +exports[1873] = 'ER_ACCESS_DENIED_CHANGE_USER_ERROR'; +exports[1874] = 'ER_INNODB_READ_ONLY'; +exports[1875] = 'ER_STOP_SLAVE_SQL_THREAD_TIMEOUT'; +exports[1876] = 'ER_STOP_SLAVE_IO_THREAD_TIMEOUT'; +exports[1877] = 'ER_TABLE_CORRUPT'; +exports[1878] = 'ER_TEMP_FILE_WRITE_FAILURE'; +exports[1879] = 'ER_INNODB_FT_AUX_NOT_HEX_ID'; +exports[1880] = 'ER_OLD_TEMPORALS_UPGRADED'; +exports[1881] = 'ER_INNODB_FORCED_RECOVERY'; +exports[1882] = 'ER_AES_INVALID_IV'; diff --git a/node_modules/mysql/lib/protocol/constants/field_flags.js b/node_modules/mysql/lib/protocol/constants/field_flags.js new file mode 100644 index 0000000..c698da5 --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/field_flags.js @@ -0,0 +1,18 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +exports.NOT_NULL_FLAG = 1; /* Field can't be NULL */ +exports.PRI_KEY_FLAG = 2; /* Field is part of a primary key */ +exports.UNIQUE_KEY_FLAG = 4; /* Field is part of a unique key */ +exports.MULTIPLE_KEY_FLAG = 8; /* Field is part of a key */ +exports.BLOB_FLAG = 16; /* Field is a blob */ +exports.UNSIGNED_FLAG = 32; /* Field is unsigned */ +exports.ZEROFILL_FLAG = 64; /* Field is zerofill */ +exports.BINARY_FLAG = 128; /* Field is binary */ + +/* The following are only sent to new clients */ +exports.ENUM_FLAG = 256; /* field is an enum */ +exports.AUTO_INCREMENT_FLAG = 512; /* field is a autoincrement field */ +exports.TIMESTAMP_FLAG = 1024; /* Field is a timestamp */ +exports.SET_FLAG = 2048; /* field is a set */ +exports.NO_DEFAULT_VALUE_FLAG = 4096; /* Field doesn't have default value */ +exports.ON_UPDATE_NOW_FLAG = 8192; /* Field is set to NOW on UPDATE */ +exports.NUM_FLAG = 32768; /* Field is num (for clients) */ diff --git a/node_modules/mysql/lib/protocol/constants/server_status.js b/node_modules/mysql/lib/protocol/constants/server_status.js new file mode 100644 index 0000000..5537ee5 --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/server_status.js @@ -0,0 +1,39 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h + +/** + Is raised when a multi-statement transaction + has been started, either explicitly, by means + of BEGIN or COMMIT AND CHAIN, or + implicitly, by the first transactional + statement, when autocommit=off. +*/ +exports.SERVER_STATUS_IN_TRANS = 1; +exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */ +exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */ +exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16; +exports.SERVER_QUERY_NO_INDEX_USED = 32; +/** + The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. +*/ +exports.SERVER_STATUS_CURSOR_EXISTS = 64; +/** + This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. +*/ +exports.SERVER_STATUS_LAST_ROW_SENT = 128; +exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */ +exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512; +/** + Sent to the client if after a prepared statement reprepare + we discovered that the new statement returns a different + number of result set columns. +*/ +exports.SERVER_STATUS_METADATA_CHANGED = 1024; +exports.SERVER_QUERY_WAS_SLOW = 2048; + +/** + To mark ResultSet containing output parameter values. +*/ +exports.SERVER_PS_OUT_PARAMS = 4096; diff --git a/node_modules/mysql/lib/protocol/constants/types.js b/node_modules/mysql/lib/protocol/constants/types.js new file mode 100644 index 0000000..21c4000 --- /dev/null +++ b/node_modules/mysql/lib/protocol/constants/types.js @@ -0,0 +1,29 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html +exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) +exports.TINY = 0x01; // aka TINYINT, 1 byte +exports.SHORT = 0x02; // aka SMALLINT, 2 bytes +exports.LONG = 0x03; // aka INT, 4 bytes +exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes +exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes +exports.NULL = 0x06; // NULL (used for prepared statements, I think) +exports.TIMESTAMP = 0x07; // aka TIMESTAMP +exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes +exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes +exports.DATE = 0x0a; // aka DATE +exports.TIME = 0x0b; // aka TIME +exports.DATETIME = 0x0c; // aka DATETIME +exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask) +exports.NEWDATE = 0x0e; // aka ? +exports.VARCHAR = 0x0f; // aka VARCHAR (?) +exports.BIT = 0x10; // aka BIT, 1-8 byte +exports.NEWDECIMAL = 0xf6; // aka DECIMAL +exports.ENUM = 0xf7; // aka ENUM +exports.SET = 0xf8; // aka SET +exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT +exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT +exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT +exports.BLOB = 0xfc; // aka BLOB, TEXT +exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY +exports.STRING = 0xfe; // aka CHAR, BINARY +exports.GEOMETRY = 0xff; // aka GEOMETRY diff --git a/node_modules/mysql/lib/protocol/packets/ClientAuthenticationPacket.js b/node_modules/mysql/lib/protocol/packets/ClientAuthenticationPacket.js new file mode 100644 index 0000000..a66d28b --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ClientAuthenticationPacket.js @@ -0,0 +1,52 @@ +module.exports = ClientAuthenticationPacket; +function ClientAuthenticationPacket(options) { + options = options || {}; + + this.clientFlags = options.clientFlags; + this.maxPacketSize = options.maxPacketSize; + this.charsetNumber = options.charsetNumber; + this.filler = undefined; + this.user = options.user; + this.scrambleBuff = options.scrambleBuff; + this.database = options.database; + this.protocol41 = options.protocol41; +} + +ClientAuthenticationPacket.prototype.parse = function(parser) { + if (this.protocol41) { + this.clientFlags = parser.parseUnsignedNumber(4); + this.maxPacketSize = parser.parseUnsignedNumber(4); + this.charsetNumber = parser.parseUnsignedNumber(1); + this.filler = parser.parseFiller(23); + this.user = parser.parseNullTerminatedString(); + this.scrambleBuff = parser.parseLengthCodedBuffer(); + this.database = parser.parseNullTerminatedString(); + } else { + this.clientFlags = parser.parseUnsignedNumber(2); + this.maxPacketSize = parser.parseUnsignedNumber(3); + this.user = parser.parseNullTerminatedString(); + this.scrambleBuff = parser.parseBuffer(8); + this.database = parser.parseLengthCodedBuffer(); + } +}; + +ClientAuthenticationPacket.prototype.write = function(writer) { + if (this.protocol41) { + writer.writeUnsignedNumber(4, this.clientFlags); + writer.writeUnsignedNumber(4, this.maxPacketSize); + writer.writeUnsignedNumber(1, this.charsetNumber); + writer.writeFiller(23); + writer.writeNullTerminatedString(this.user); + writer.writeLengthCodedBuffer(this.scrambleBuff); + writer.writeNullTerminatedString(this.database); + } else { + writer.writeUnsignedNumber(2, this.clientFlags); + writer.writeUnsignedNumber(3, this.maxPacketSize); + writer.writeNullTerminatedString(this.user); + writer.writeBuffer(this.scrambleBuff); + if (this.database && this.database.length) { + writer.writeFiller(1); + writer.writeBuffer(new Buffer(this.database)); + } + } +}; diff --git a/node_modules/mysql/lib/protocol/packets/ComChangeUserPacket.js b/node_modules/mysql/lib/protocol/packets/ComChangeUserPacket.js new file mode 100644 index 0000000..3278842 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ComChangeUserPacket.js @@ -0,0 +1,26 @@ +module.exports = ComChangeUserPacket; +function ComChangeUserPacket(options) { + options = options || {}; + + this.command = 0x11; + this.user = options.user; + this.scrambleBuff = options.scrambleBuff; + this.database = options.database; + this.charsetNumber = options.charsetNumber; +} + +ComChangeUserPacket.prototype.parse = function(parser) { + this.command = parser.parseUnsignedNumber(1); + this.user = parser.parseNullTerminatedString(); + this.scrambleBuff = parser.parseLengthCodedBuffer(); + this.database = parser.parseNullTerminatedString(); + this.charsetNumber = parser.parseUnsignedNumber(1); +}; + +ComChangeUserPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.command); + writer.writeNullTerminatedString(this.user); + writer.writeLengthCodedBuffer(this.scrambleBuff); + writer.writeNullTerminatedString(this.database); + writer.writeUnsignedNumber(2, this.charsetNumber); +}; diff --git a/node_modules/mysql/lib/protocol/packets/ComPingPacket.js b/node_modules/mysql/lib/protocol/packets/ComPingPacket.js new file mode 100644 index 0000000..359eef5 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ComPingPacket.js @@ -0,0 +1,12 @@ +module.exports = ComPingPacket; +function ComPingPacket(sql) { + this.command = 0x0e; +} + +ComPingPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.command); +}; + +ComPingPacket.prototype.parse = function(parser) { + this.command = parser.parseUnsignedNumber(1); +}; diff --git a/node_modules/mysql/lib/protocol/packets/ComQueryPacket.js b/node_modules/mysql/lib/protocol/packets/ComQueryPacket.js new file mode 100644 index 0000000..7ac191f --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ComQueryPacket.js @@ -0,0 +1,15 @@ +module.exports = ComQueryPacket; +function ComQueryPacket(sql) { + this.command = 0x03; + this.sql = sql; +} + +ComQueryPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.command); + writer.writeString(this.sql); +}; + +ComQueryPacket.prototype.parse = function(parser) { + this.command = parser.parseUnsignedNumber(1); + this.sql = parser.parsePacketTerminatedString(); +}; diff --git a/node_modules/mysql/lib/protocol/packets/ComQuitPacket.js b/node_modules/mysql/lib/protocol/packets/ComQuitPacket.js new file mode 100644 index 0000000..26a08f8 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ComQuitPacket.js @@ -0,0 +1,12 @@ +module.exports = ComQuitPacket; +function ComQuitPacket(sql) { + this.command = 0x01; +} + +ComQuitPacket.prototype.parse = function parse(parser) { + this.command = parser.parseUnsignedNumber(1); +}; + +ComQuitPacket.prototype.write = function write(writer) { + writer.writeUnsignedNumber(1, this.command); +}; diff --git a/node_modules/mysql/lib/protocol/packets/ComStatisticsPacket.js b/node_modules/mysql/lib/protocol/packets/ComStatisticsPacket.js new file mode 100644 index 0000000..fe11d18 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ComStatisticsPacket.js @@ -0,0 +1,12 @@ +module.exports = ComStatisticsPacket; +function ComStatisticsPacket(sql) { + this.command = 0x09; +} + +ComStatisticsPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.command); +}; + +ComStatisticsPacket.prototype.parse = function(parser) { + this.command = parser.parseUnsignedNumber(1); +}; diff --git a/node_modules/mysql/lib/protocol/packets/EmptyPacket.js b/node_modules/mysql/lib/protocol/packets/EmptyPacket.js new file mode 100644 index 0000000..f02189c --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/EmptyPacket.js @@ -0,0 +1,6 @@ +module.exports = EmptyPacket; +function EmptyPacket() { +} + +EmptyPacket.prototype.write = function(writer) { +}; diff --git a/node_modules/mysql/lib/protocol/packets/EofPacket.js b/node_modules/mysql/lib/protocol/packets/EofPacket.js new file mode 100644 index 0000000..b80ca5e --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/EofPacket.js @@ -0,0 +1,25 @@ +module.exports = EofPacket; +function EofPacket(options) { + options = options || {}; + + this.fieldCount = undefined; + this.warningCount = options.warningCount; + this.serverStatus = options.serverStatus; + this.protocol41 = options.protocol41; +} + +EofPacket.prototype.parse = function(parser) { + this.fieldCount = parser.parseUnsignedNumber(1); + if (this.protocol41) { + this.warningCount = parser.parseUnsignedNumber(2); + this.serverStatus = parser.parseUnsignedNumber(2); + } +}; + +EofPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, 0xfe); + if (this.protocol41) { + writer.writeUnsignedNumber(2, this.warningCount); + writer.writeUnsignedNumber(2, this.serverStatus); + } +}; diff --git a/node_modules/mysql/lib/protocol/packets/ErrorPacket.js b/node_modules/mysql/lib/protocol/packets/ErrorPacket.js new file mode 100644 index 0000000..e03de00 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ErrorPacket.js @@ -0,0 +1,35 @@ +module.exports = ErrorPacket; +function ErrorPacket(options) { + options = options || {}; + + this.fieldCount = options.fieldCount; + this.errno = options.errno; + this.sqlStateMarker = options.sqlStateMarker; + this.sqlState = options.sqlState; + this.message = options.message; +} + +ErrorPacket.prototype.parse = function(parser) { + this.fieldCount = parser.parseUnsignedNumber(1); + this.errno = parser.parseUnsignedNumber(2); + + // sqlStateMarker ('#' = 0x23) indicates error packet format + if (parser.peak() === 0x23) { + this.sqlStateMarker = parser.parseString(1); + this.sqlState = parser.parseString(5); + } + + this.message = parser.parsePacketTerminatedString(); +}; + +ErrorPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, 0xff); + writer.writeUnsignedNumber(2, this.errno); + + if (this.sqlStateMarker) { + writer.writeString(this.sqlStateMarker); + writer.writeString(this.sqlState); + } + + writer.writeString(this.message); +}; diff --git a/node_modules/mysql/lib/protocol/packets/Field.js b/node_modules/mysql/lib/protocol/packets/Field.js new file mode 100644 index 0000000..b686a88 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/Field.js @@ -0,0 +1,32 @@ +var Types = require('../constants/types'); + +module.exports = Field; +function Field(options) { + options = options || {}; + + this.parser = options.parser; + this.packet = options.packet; + this.db = options.packet.db; + this.table = options.packet.table; + this.name = options.packet.name; + this.type = typeToString(options.packet.type); + this.length = options.packet.length; +} + +Field.prototype.string = function () { + return this.parser.parseLengthCodedString(); +}; + +Field.prototype.buffer = function () { + return this.parser.parseLengthCodedBuffer(); +}; + +Field.prototype.geometry = function () { + return this.parser.parseGeometryValue(); +}; + +function typeToString(t) { + for (var k in Types) { + if (Types[k] == t) return k; + } +} diff --git a/node_modules/mysql/lib/protocol/packets/FieldPacket.js b/node_modules/mysql/lib/protocol/packets/FieldPacket.js new file mode 100644 index 0000000..d8fd68f --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/FieldPacket.js @@ -0,0 +1,93 @@ +module.exports = FieldPacket; +function FieldPacket(options) { + options = options || {}; + + this.catalog = options.catalog; + this.db = options.db; + this.table = options.table; + this.orgTable = options.orgTable; + this.name = options.name; + this.orgName = options.orgName; + this.charsetNr = options.charsetNr; + this.length = options.length; + this.type = options.type; + this.flags = options.flags; + this.decimals = options.decimals; + this.default = options.default; + this.zeroFill = options.zeroFill; + this.protocol41 = options.protocol41 +} + +FieldPacket.prototype.parse = function(parser) { + if (this.protocol41) { + this.catalog = parser.parseLengthCodedString(); + this.db = parser.parseLengthCodedString(); + this.table = parser.parseLengthCodedString(); + this.orgTable = parser.parseLengthCodedString(); + this.name = parser.parseLengthCodedString(); + this.orgName = parser.parseLengthCodedString(); + + if (parser.parseLengthCodedNumber() !== 0x0c) { + var err = new TypeError('Received invalid field length'); + err.code = 'PARSER_INVALID_FIELD_LENGTH'; + throw err; + } + + this.charsetNr = parser.parseUnsignedNumber(2); + this.length = parser.parseUnsignedNumber(4); + this.type = parser.parseUnsignedNumber(1); + this.flags = parser.parseUnsignedNumber(2); + this.decimals = parser.parseUnsignedNumber(1); + + var filler = parser.parseBuffer(2); + if (filler[0] !== 0x0 || filler[1] !== 0x0) { + var err = new TypeError('Received invalid filler'); + err.code = 'PARSER_INVALID_FILLER'; + throw err; + } + + // parsed flags + this.zeroFill = (this.flags & 0x0040 ? true : false); + + if (parser.reachedPacketEnd()) { + return; + } + + this.default = parser.parseLengthCodedString(); + } else { + this.table = parser.parseLengthCodedString(); + this.name = parser.parseLengthCodedString(); + this.length = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1)); + this.type = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1)); + } +}; + +FieldPacket.prototype.write = function(writer) { + if (this.protocol41) { + writer.writeLengthCodedString(this.catalog); + writer.writeLengthCodedString(this.db); + writer.writeLengthCodedString(this.table); + writer.writeLengthCodedString(this.orgTable); + writer.writeLengthCodedString(this.name); + writer.writeLengthCodedString(this.orgName); + + writer.writeLengthCodedNumber(0x0c); + writer.writeUnsignedNumber(2, this.charsetNr || 0); + writer.writeUnsignedNumber(4, this.length || 0); + writer.writeUnsignedNumber(1, this.type || 0); + writer.writeUnsignedNumber(2, this.flags || 0); + writer.writeUnsignedNumber(1, this.decimals || 0); + writer.writeFiller(2); + + if (this.default !== undefined) { + writer.writeLengthCodedString(this.default); + } + } else { + writer.writeLengthCodedString(this.table); + writer.writeLengthCodedString(this.name); + writer.writeUnsignedNumber(1, 0x01); + writer.writeUnsignedNumber(1, this.length); + writer.writeUnsignedNumber(1, 0x01); + writer.writeUnsignedNumber(1, this.type); + } +}; diff --git a/node_modules/mysql/lib/protocol/packets/HandshakeInitializationPacket.js b/node_modules/mysql/lib/protocol/packets/HandshakeInitializationPacket.js new file mode 100644 index 0000000..a55372a --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/HandshakeInitializationPacket.js @@ -0,0 +1,100 @@ +var Client = require('../constants/client'); + +module.exports = HandshakeInitializationPacket; +function HandshakeInitializationPacket(options) { + options = options || {}; + + this.protocolVersion = options.protocolVersion; + this.serverVersion = options.serverVersion; + this.threadId = options.threadId; + this.scrambleBuff1 = options.scrambleBuff1; + this.filler1 = options.filler1; + this.serverCapabilities1 = options.serverCapabilities1; + this.serverLanguage = options.serverLanguage; + this.serverStatus = options.serverStatus; + this.serverCapabilities2 = options.serverCapabilities2; + this.scrambleLength = options.scrambleLength; + this.filler2 = options.filler2; + this.scrambleBuff2 = options.scrambleBuff2; + this.filler3 = options.filler3; + this.pluginData = options.pluginData; + this.protocol41 = options.protocol41; + + if (this.protocol41) { + // force set the bit in serverCapabilities1 + this.serverCapabilities1 |= Client.CLIENT_PROTOCOL_41; + } +} + +HandshakeInitializationPacket.prototype.parse = function(parser) { + this.protocolVersion = parser.parseUnsignedNumber(1); + this.serverVersion = parser.parseNullTerminatedString(); + this.threadId = parser.parseUnsignedNumber(4); + this.scrambleBuff1 = parser.parseBuffer(8); + this.filler1 = parser.parseFiller(1); + this.serverCapabilities1 = parser.parseUnsignedNumber(2); + this.serverLanguage = parser.parseUnsignedNumber(1); + this.serverStatus = parser.parseUnsignedNumber(2); + + this.protocol41 = (this.serverCapabilities1 & (1 << 9)) > 0; + + if (this.protocol41) { + this.serverCapabilities2 = parser.parseUnsignedNumber(2); + this.scrambleLength = parser.parseUnsignedNumber(1); + this.filler2 = parser.parseFiller(10); + // scrambleBuff2 should be 0x00 terminated, but sphinx does not do this + // so we assume scrambleBuff2 to be 12 byte and treat the next byte as a + // filler byte. + this.scrambleBuff2 = parser.parseBuffer(12); + this.filler3 = parser.parseFiller(1); + } else { + this.filler2 = parser.parseFiller(13); + } + + if (parser.reachedPacketEnd()) { + return; + } + + // According to the docs this should be 0x00 terminated, but MariaDB does + // not do this, so we assume this string to be packet terminated. + this.pluginData = parser.parsePacketTerminatedString(); + + // However, if there is a trailing '\0', strip it + var lastChar = this.pluginData.length - 1; + if (this.pluginData[lastChar] === '\0') { + this.pluginData = this.pluginData.substr(0, lastChar); + } +}; + +HandshakeInitializationPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.protocolVersion); + writer.writeNullTerminatedString(this.serverVersion); + writer.writeUnsignedNumber(4, this.threadId); + writer.writeBuffer(this.scrambleBuff1); + writer.writeFiller(1); + writer.writeUnsignedNumber(2, this.serverCapabilities1); + writer.writeUnsignedNumber(1, this.serverLanguage); + writer.writeUnsignedNumber(2, this.serverStatus); + if (this.protocol41) { + writer.writeUnsignedNumber(2, this.serverCapabilities2); + writer.writeUnsignedNumber(1, this.scrambleLength); + writer.writeFiller(10); + } + writer.writeNullTerminatedBuffer(this.scrambleBuff2); + + if (this.pluginData !== undefined) { + writer.writeNullTerminatedString(this.pluginData); + } +}; + +HandshakeInitializationPacket.prototype.scrambleBuff = function() { + var buffer = new Buffer(this.scrambleBuff1.length + + (typeof this.scrambleBuff2 != "undefined" ? this.scrambleBuff2.length : 0)); + + this.scrambleBuff1.copy(buffer); + if (typeof this.scrambleBuff2 != "undefined") { + this.scrambleBuff2.copy(buffer, this.scrambleBuff1.length); + } + + return buffer; +}; diff --git a/node_modules/mysql/lib/protocol/packets/LocalDataFilePacket.js b/node_modules/mysql/lib/protocol/packets/LocalDataFilePacket.js new file mode 100644 index 0000000..8a79a08 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/LocalDataFilePacket.js @@ -0,0 +1,11 @@ +module.exports = LocalDataFilePacket; +/** + * @param {Buffer} data + */ +function LocalDataFilePacket(data) { + this.data = data; +} + +LocalDataFilePacket.prototype.write = function(writer) { + writer.writeBuffer(this.data); +}; diff --git a/node_modules/mysql/lib/protocol/packets/OkPacket.js b/node_modules/mysql/lib/protocol/packets/OkPacket.js new file mode 100644 index 0000000..0d9a096 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/OkPacket.js @@ -0,0 +1,41 @@ +module.exports = OkPacket; +function OkPacket(options) { + options = options || {}; + + this.fieldCount = undefined; + this.affectedRows = undefined; + this.insertId = undefined; + this.serverStatus = undefined; + this.warningCount = undefined; + this.message = undefined; + this.protocol41 = options.protocol41; +} + +OkPacket.prototype.parse = function(parser) { + this.fieldCount = parser.parseUnsignedNumber(1); + this.affectedRows = parser.parseLengthCodedNumber(); + this.insertId = parser.parseLengthCodedNumber(); + if (this.protocol41) { + this.serverStatus = parser.parseUnsignedNumber(2); + this.warningCount = parser.parseUnsignedNumber(2); + } + this.message = parser.parsePacketTerminatedString(); + this.changedRows = 0; + + var m = this.message.match(/\schanged:\s*(\d+)/i); + + if (m !== null) { + this.changedRows = parseInt(m[1], 10); + } +}; + +OkPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, 0x00); + writer.writeLengthCodedNumber(this.affectedRows || 0); + writer.writeLengthCodedNumber(this.insertId || 0); + if (this.protocol41) { + writer.writeUnsignedNumber(2, this.serverStatus || 0); + writer.writeUnsignedNumber(2, this.warningCount || 0); + } + writer.writeString(this.message); +}; diff --git a/node_modules/mysql/lib/protocol/packets/OldPasswordPacket.js b/node_modules/mysql/lib/protocol/packets/OldPasswordPacket.js new file mode 100644 index 0000000..1ff78ec --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/OldPasswordPacket.js @@ -0,0 +1,15 @@ +module.exports = OldPasswordPacket; +function OldPasswordPacket(options) { + options = options || {}; + + this.scrambleBuff = options.scrambleBuff; +} + +OldPasswordPacket.prototype.parse = function(parser) { + this.scrambleBuff = parser.parseNullTerminatedBuffer(); +}; + +OldPasswordPacket.prototype.write = function(writer) { + writer.writeBuffer(this.scrambleBuff); + writer.writeFiller(1); +}; diff --git a/node_modules/mysql/lib/protocol/packets/ResultSetHeaderPacket.js b/node_modules/mysql/lib/protocol/packets/ResultSetHeaderPacket.js new file mode 100644 index 0000000..25b8002 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/ResultSetHeaderPacket.js @@ -0,0 +1,25 @@ +module.exports = ResultSetHeaderPacket; +function ResultSetHeaderPacket(options) { + options = options || {}; + + this.fieldCount = options.fieldCount; + this.extra = options.extra; +} + +ResultSetHeaderPacket.prototype.parse = function(parser) { + this.fieldCount = parser.parseLengthCodedNumber(); + + if (parser.reachedPacketEnd()) return; + + this.extra = (this.fieldCount === null) + ? parser.parsePacketTerminatedString() + : parser.parseLengthCodedNumber(); +}; + +ResultSetHeaderPacket.prototype.write = function(writer) { + writer.writeLengthCodedNumber(this.fieldCount); + + if (this.extra !== undefined) { + writer.writeLengthCodedNumber(this.extra); + } +}; diff --git a/node_modules/mysql/lib/protocol/packets/RowDataPacket.js b/node_modules/mysql/lib/protocol/packets/RowDataPacket.js new file mode 100644 index 0000000..82fa134 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/RowDataPacket.js @@ -0,0 +1,120 @@ +var Types = require('../constants/types'); +var Charsets = require('../constants/charsets'); +var Field = require('./Field'); +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53); + +module.exports = RowDataPacket; +function RowDataPacket() { +} + +Object.defineProperty(RowDataPacket.prototype, 'parse', { + configurable: true, + enumerable: false, + value: parse +}); + +Object.defineProperty(RowDataPacket.prototype, '_typeCast', { + configurable: true, + enumerable: false, + value: typeCast +}); + +function parse(parser, fieldPackets, typeCast, nestTables, connection) { + var self = this; + var next = function () { + return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings); + }; + + for (var i = 0; i < fieldPackets.length; i++) { + var fieldPacket = fieldPackets[i]; + var value; + + if (typeof typeCast == "function") { + value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]); + } else { + value = (typeCast) + ? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings) + : ( (fieldPacket.charsetNr === Charsets.BINARY) + ? parser.parseLengthCodedBuffer() + : parser.parseLengthCodedString() ); + } + + if (typeof nestTables == "string" && nestTables.length) { + this[fieldPacket.table + nestTables + fieldPacket.name] = value; + } else if (nestTables) { + this[fieldPacket.table] = this[fieldPacket.table] || {}; + this[fieldPacket.table][fieldPacket.name] = value; + } else { + this[fieldPacket.name] = value; + } + } +} + +function typeCast(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) { + var numberString; + + switch (field.type) { + case Types.TIMESTAMP: + case Types.DATE: + case Types.DATETIME: + case Types.NEWDATE: + var dateString = parser.parseLengthCodedString(); + if (dateStrings) { + return dateString; + } + var dt; + + if (dateString === null) { + return null; + } + + var originalString = dateString; + if (field.type === Types.DATE) { + dateString += ' 00:00:00'; + } + + if (timeZone !== 'local') { + dateString += ' ' + timeZone; + } + + dt = new Date(dateString); + if (isNaN(dt.getTime())) { + return originalString; + } + + return dt; + case Types.TINY: + case Types.SHORT: + case Types.LONG: + case Types.INT24: + case Types.YEAR: + case Types.FLOAT: + case Types.DOUBLE: + numberString = parser.parseLengthCodedString(); + return (numberString === null || (field.zeroFill && numberString[0] == "0")) + ? numberString : Number(numberString); + case Types.NEWDECIMAL: + case Types.LONGLONG: + numberString = parser.parseLengthCodedString(); + return (numberString === null || (field.zeroFill && numberString[0] == "0")) + ? numberString + : ((supportBigNumbers && (bigNumberStrings || (Number(numberString) > IEEE_754_BINARY_64_PRECISION))) + ? numberString + : Number(numberString)); + case Types.BIT: + return parser.parseLengthCodedBuffer(); + case Types.STRING: + case Types.VAR_STRING: + case Types.TINY_BLOB: + case Types.MEDIUM_BLOB: + case Types.LONG_BLOB: + case Types.BLOB: + return (field.charsetNr === Charsets.BINARY) + ? parser.parseLengthCodedBuffer() + : parser.parseLengthCodedString(); + case Types.GEOMETRY: + return parser.parseGeometryValue(); + default: + return parser.parseLengthCodedString(); + } +} diff --git a/node_modules/mysql/lib/protocol/packets/SSLRequestPacket.js b/node_modules/mysql/lib/protocol/packets/SSLRequestPacket.js new file mode 100644 index 0000000..a57cfc1 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/SSLRequestPacket.js @@ -0,0 +1,27 @@ +// http://dev.mysql.com/doc/internals/en/ssl.html +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest + +var ClientConstants = require('../constants/client'); + +module.exports = SSLRequestPacket; + +function SSLRequestPacket(options) { + options = options || {}; + this.clientFlags = options.clientFlags | ClientConstants.CLIENT_SSL; + this.maxPacketSize = options.maxPacketSize; + this.charsetNumber = options.charsetNumber; +} + +SSLRequestPacket.prototype.parse = function(parser) { + // TODO: check SSLRequest packet v41 vs pre v41 + this.clientFlags = parser.parseUnsignedNumber(4); + this.maxPacketSize = parser.parseUnsignedNumber(4); + this.charsetNumber = parser.parseUnsignedNumber(1); +}; + +SSLRequestPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(4, this.clientFlags); + writer.writeUnsignedNumber(4, this.maxPacketSize); + writer.writeUnsignedNumber(1, this.charsetNumber); + writer.writeFiller(23); +}; diff --git a/node_modules/mysql/lib/protocol/packets/StatisticsPacket.js b/node_modules/mysql/lib/protocol/packets/StatisticsPacket.js new file mode 100644 index 0000000..5f70b3b --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/StatisticsPacket.js @@ -0,0 +1,20 @@ +module.exports = StatisticsPacket; +function StatisticsPacket() { + this.message = undefined; +} + +StatisticsPacket.prototype.parse = function(parser) { + this.message = parser.parsePacketTerminatedString(); + + var items = this.message.split(/\s\s/); + for (var i = 0; i < items.length; i++) { + var m = items[i].match(/^(.+)\:\s+(.+)$/); + if (m !== null) { + this[m[1].toLowerCase().replace(/\s/g, '_')] = Number(m[2]); + } + } +}; + +StatisticsPacket.prototype.write = function(writer) { + writer.writeString(this.message); +}; diff --git a/node_modules/mysql/lib/protocol/packets/UseOldPasswordPacket.js b/node_modules/mysql/lib/protocol/packets/UseOldPasswordPacket.js new file mode 100644 index 0000000..d73bf44 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/UseOldPasswordPacket.js @@ -0,0 +1,14 @@ +module.exports = UseOldPasswordPacket; +function UseOldPasswordPacket(options) { + options = options || {}; + + this.firstByte = options.firstByte || 0xfe; +} + +UseOldPasswordPacket.prototype.parse = function(parser) { + this.firstByte = parser.parseUnsignedNumber(1); +}; + +UseOldPasswordPacket.prototype.write = function(writer) { + writer.writeUnsignedNumber(1, this.firstByte); +}; diff --git a/node_modules/mysql/lib/protocol/packets/index.js b/node_modules/mysql/lib/protocol/packets/index.js new file mode 100644 index 0000000..a13d469 --- /dev/null +++ b/node_modules/mysql/lib/protocol/packets/index.js @@ -0,0 +1,4 @@ +var Elements = module.exports = require('require-all')({ + dirname : __dirname, + filter : /([A-Z].+)\.js$/, +}); diff --git a/node_modules/mysql/lib/protocol/sequences/ChangeUser.js b/node_modules/mysql/lib/protocol/sequences/ChangeUser.js new file mode 100644 index 0000000..e3f0640 --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/ChangeUser.js @@ -0,0 +1,41 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); +var Auth = require('../Auth'); + +module.exports = ChangeUser; +Util.inherits(ChangeUser, Sequence); +function ChangeUser(options, callback) { + Sequence.call(this, options, callback); + + this._user = options.user; + this._password = options.password; + this._database = options.database; + this._charsetNumber = options.charsetNumber; + this._currentConfig = options.currentConfig; +} + +ChangeUser.prototype.start = function(handshakeInitializationPacket) { + var scrambleBuff = handshakeInitializationPacket.scrambleBuff(); + scrambleBuff = Auth.token(this._password, scrambleBuff); + + var packet = new Packets.ComChangeUserPacket({ + user : this._user, + scrambleBuff : scrambleBuff, + database : this._database, + charsetNumber : this._charsetNumber, + }); + + this._currentConfig.user = this._user; + this._currentConfig.password = this._password; + this._currentConfig.database = this._database; + this._currentConfig.charsetNumber = this._charsetNumber; + + this.emit('packet', packet); +}; + +ChangeUser.prototype['ErrorPacket'] = function(packet) { + var err = this._packetToError(packet); + err.fatal = true; + this.end(err); +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Handshake.js b/node_modules/mysql/lib/protocol/sequences/Handshake.js new file mode 100644 index 0000000..b26988c --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Handshake.js @@ -0,0 +1,104 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); +var Auth = require('../Auth'); +var ClientConstants = require('../constants/client'); + +module.exports = Handshake; +Util.inherits(Handshake, Sequence); +function Handshake(options, callback) { + Sequence.call(this, options, callback); + + options = options || {}; + + this._config = options.config; + this._handshakeInitializationPacket = null; +} + +Handshake.prototype.determinePacket = function(firstByte) { + if (firstByte === 0xff) { + return Packets.ErrorPacket; + } + + if (!this._handshakeInitializationPacket) { + return Packets.HandshakeInitializationPacket; + } + + if (firstByte === 0xfe) { + return Packets.UseOldPasswordPacket; + } +}; + +Handshake.prototype['HandshakeInitializationPacket'] = function(packet) { + this._handshakeInitializationPacket = packet; + + this._config.protocol41 = packet.protocol41; + + var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL; + + if (this._config.ssl) { + if (!serverSSLSupport) { + var err = new Error('Server does not support secure connnection'); + + err.code = 'HANDSHAKE_NO_SSL_SUPPORT'; + err.fatal = true; + + this.end(err); + return; + } + + this._config.clientFlags |= ClientConstants.CLIENT_SSL; + this.emit('packet', new Packets.SSLRequestPacket({ + clientFlags : this._config.clientFlags, + maxPacketSize : this._config.maxPacketSize, + charsetNumber : this._config.charsetNumber + })); + this.emit('start-tls'); + } else { + this._sendCredentials(); + } +}; + +Handshake.prototype._tlsUpgradeCompleteHandler = function() { + this._sendCredentials(); +}; + +Handshake.prototype._sendCredentials = function(serverHello) { + var packet = this._handshakeInitializationPacket; + this.emit('packet', new Packets.ClientAuthenticationPacket({ + clientFlags : this._config.clientFlags, + maxPacketSize : this._config.maxPacketSize, + charsetNumber : this._config.charsetNumber, + user : this._config.user, + scrambleBuff : (packet.protocol41) + ? Auth.token(this._config.password, packet.scrambleBuff()) + : Auth.scramble323(packet.scrambleBuff(), this._config.password), + database : this._config.database, + protocol41 : packet.protocol41 + })); +}; + +Handshake.prototype['UseOldPasswordPacket'] = function(packet) { + if (!this._config.insecureAuth) { + var err = new Error( + 'MySQL server is requesting the old and insecure pre-4.1 auth mechanism.' + + 'Upgrade the user password or use the {insecureAuth: true} option.' + ); + + err.code = 'HANDSHAKE_INSECURE_AUTH'; + err.fatal = true; + + this.end(err); + return; + } + + this.emit('packet', new Packets.OldPasswordPacket({ + scrambleBuff : Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password), + })); +}; + +Handshake.prototype['ErrorPacket'] = function(packet) { + var err = this._packetToError(packet, true); + err.fatal = true; + this.end(err); +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Ping.js b/node_modules/mysql/lib/protocol/sequences/Ping.js new file mode 100644 index 0000000..b298c92 --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Ping.js @@ -0,0 +1,19 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); + +module.exports = Ping; +Util.inherits(Ping, Sequence); + +function Ping(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + Sequence.call(this, options, callback); +} + +Ping.prototype.start = function() { + this.emit('packet', new Packets.ComPingPacket); +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Query.js b/node_modules/mysql/lib/protocol/sequences/Query.js new file mode 100644 index 0000000..0be2914 --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Query.js @@ -0,0 +1,218 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); +var ResultSet = require('../ResultSet'); +var ServerStatus = require('../constants/server_status'); +var fs = require('fs'); +var Readable = require('readable-stream'); + +module.exports = Query; +Util.inherits(Query, Sequence); +function Query(options, callback) { + Sequence.call(this, options, callback); + + this.sql = options.sql; + this.values = options.values; + this.typeCast = (options.typeCast === undefined) + ? true + : options.typeCast; + this.nestTables = options.nestTables || false; + + this._resultSet = null; + this._results = []; + this._fields = []; + this._index = 0; + this._loadError = null; +} + +Query.prototype.start = function() { + this.emit('packet', new Packets.ComQueryPacket(this.sql)); +}; + +Query.prototype.determinePacket = function(firstByte, parser) { + if (firstByte === 0) { + // If we have a resultSet and got one eofPacket + if (this._resultSet && this._resultSet.eofPackets.length === 1) { + // Then this is a RowDataPacket with an empty string in the first column. + // See: https://github.com/felixge/node-mysql/issues/222 + } else if (this._resultSet && this._resultSet.resultSetHeaderPacket + && this._resultSet.resultSetHeaderPacket.fieldCount !== null) { + return Packets.FieldPacket; + } else { + return; + } + } + + if (firstByte === 255) { + return; + } + + // EofPacket's are 5 bytes in mysql >= 4.1 + // This is the only / best way to differentiate their firstByte from a 9 + // byte length coded binary. + if (firstByte === 0xfe && parser.packetLength() < 9) { + return Packets.EofPacket; + } + + if (!this._resultSet) { + return Packets.ResultSetHeaderPacket; + } + + return (this._resultSet.eofPackets.length === 0) + ? Packets.FieldPacket + : Packets.RowDataPacket; +}; + +Query.prototype['OkPacket'] = function(packet) { + // try...finally for exception safety + try { + if (!this._callback) { + this.emit('result', packet, this._index); + } else { + this._results.push(packet); + this._fields.push(undefined); + } + } finally { + this._index++; + this._handleFinalResultPacket(packet); + } +}; + +Query.prototype['ErrorPacket'] = function(packet) { + var err = this._packetToError(packet); + + var results = (this._results.length > 0) + ? this._results + : undefined; + + var fields = (this._fields.length > 0) + ? this._fields + : undefined; + + err.index = this._index; + this.end(err, results, fields); +}; + +Query.prototype['ResultSetHeaderPacket'] = function(packet) { + this._resultSet = new ResultSet(packet); + + // used by LOAD DATA LOCAL INFILE queries + if (packet.fieldCount === null) { + this._sendLocalDataFile(packet.extra); + } +}; + +Query.prototype['FieldPacket'] = function(packet) { + this._resultSet.fieldPackets.push(packet); +}; + +Query.prototype['EofPacket'] = function(packet) { + this._resultSet.eofPackets.push(packet); + + if (this._resultSet.eofPackets.length === 1 && !this._callback) { + this.emit('fields', this._resultSet.fieldPackets, this._index); + } + + if (this._resultSet.eofPackets.length !== 2) { + return; + } + + if (this._callback) { + this._results.push(this._resultSet.rows); + this._fields.push(this._resultSet.fieldPackets); + } + + this._index++; + this._resultSet = null; + this._handleFinalResultPacket(packet); +}; + +Query.prototype._handleFinalResultPacket = function(packet) { + if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) { + return; + } + + var results = (this._results.length > 1) + ? this._results + : this._results[0]; + + var fields = (this._fields.length > 1) + ? this._fields + : this._fields[0]; + + this.end(this._loadError, results, fields); +}; + +Query.prototype['RowDataPacket'] = function(packet, parser, connection) { + packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection); + + if (this._callback) { + this._resultSet.rows.push(packet); + } else { + this.emit('result', packet, this._index); + } +}; + +Query.prototype._sendLocalDataFile = function(path) { + var self = this; + var localStream = fs.createReadStream(path, { + 'flag': 'r', + 'encoding': null, + 'autoClose': true + }); + + + this.on('pause', function () { + localStream.pause(); + }); + + this.on('resume', function () { + localStream.resume(); + }); + + localStream.on('data', function (data) { + self.emit('packet', new Packets.LocalDataFilePacket(data)); + }); + + localStream.on('error', function (err) { + self._loadError = err; + localStream.emit('end'); + }); + + localStream.on('end', function () { + self.emit('packet', new Packets.EmptyPacket()); + }); +}; + +Query.prototype.stream = function(options) { + var self = this, + stream; + + options = options || {}; + options.objectMode = true; + stream = new Readable(options); + + stream._read = function() { + self._connection && self._connection.resume(); + }; + + this.on('result',function(row,i) { + if (!stream.push(row)) self._connection.pause(); + stream.emit('result',row,i); // replicate old emitter + }); + + this.on('error',function(err) { + stream.emit('error',err); // Pass on any errors + }); + + this.on('end', function() { + stream.emit('close'); // notify readers that query has completed + stream.push(null); // pushing null, indicating EOF + }); + + this.on('fields',function(fields,i) { + stream.emit('fields',fields,i); // replicate old emitter + }); + + return stream; +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Quit.js b/node_modules/mysql/lib/protocol/sequences/Quit.js new file mode 100644 index 0000000..68ed876 --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Quit.js @@ -0,0 +1,18 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); + +module.exports = Quit; +Util.inherits(Quit, Sequence); +function Quit(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + Sequence.call(this, options, callback); +} + +Quit.prototype.start = function() { + this.emit('packet', new Packets.ComQuitPacket); +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Sequence.js b/node_modules/mysql/lib/protocol/sequences/Sequence.js new file mode 100644 index 0000000..9c2f6bf --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Sequence.js @@ -0,0 +1,117 @@ +var Util = require('util'); +var EventEmitter = require('events').EventEmitter; +var Packets = require('../packets'); +var ErrorConstants = require('../constants/errors'); + +var listenerCount = EventEmitter.listenerCount + || function(emitter, type){ return emitter.listeners(type).length; }; + +module.exports = Sequence; +Util.inherits(Sequence, EventEmitter); +function Sequence(options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + + EventEmitter.call(this); + + options = options || {}; + + this._callback = callback; + this._callSite = null; + this._ended = false; + this._timeout = options.timeout; + + // For Timers + this._idleNext = null; + this._idlePrev = null; + this._idleStart = null; + this._idleTimeout = undefined; + this._repeat = null; +} + +Sequence.determinePacket = function(byte) { + switch (byte) { + case 0x00: return Packets.OkPacket; + case 0xfe: return Packets.EofPacket; + case 0xff: return Packets.ErrorPacket; + } +}; + +Sequence.prototype.hasErrorHandler = function() { + return Boolean(this._callback) || listenerCount(this, 'error') > 1; +}; + +Sequence.prototype._packetToError = function(packet) { + var code = ErrorConstants[packet.errno] || 'UNKNOWN_CODE_PLEASE_REPORT'; + var err = new Error(code + ': ' + packet.message); + err.code = code; + err.errno = packet.errno; + err.sqlState = packet.sqlState; + + return err; +}; + +Sequence.prototype._addLongStackTrace = function(err) { + if (!this._callSite) { + return; + } + + var delimiter = '\n --------------------\n' ; + + if (err.stack.indexOf(delimiter) > -1) { + return; + } + + err.stack += delimiter + this._callSite.stack.replace(/.+\n/, ''); +}; + +Sequence.prototype.end = function(err) { + if (this._ended) { + return; + } + + this._ended = true; + + if (err) { + this._addLongStackTrace(err); + } + + // Without this we are leaking memory. This problem was introduced in + // 8189925374e7ce3819bbe88b64c7b15abac96b16. I suspect that the error object + // causes a cyclic reference that the GC does not detect properly, but I was + // unable to produce a standalone version of this leak. This would be a great + // challenge for somebody interested in difficult problems : )! + this._callSite = null; + + // try...finally for exception safety + try { + if (err) { + this.emit('error', err); + } + } finally { + try { + if (this._callback) { + this._callback.apply(this, arguments); + } + } finally { + this.emit('end'); + } + } +}; + +Sequence.prototype['OkPacket'] = function(packet) { + this.end(null, packet); +}; + +Sequence.prototype['ErrorPacket'] = function(packet) { + this.end(this._packetToError(packet)); +}; + +// Implemented by child classes +Sequence.prototype.start = function() {}; + +Sequence.prototype._onTimeout = function _onTimeout() { + this.emit('timeout'); +}; diff --git a/node_modules/mysql/lib/protocol/sequences/Statistics.js b/node_modules/mysql/lib/protocol/sequences/Statistics.js new file mode 100644 index 0000000..50157ce --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/Statistics.js @@ -0,0 +1,28 @@ +var Sequence = require('./Sequence'); +var Util = require('util'); +var Packets = require('../packets'); + +module.exports = Statistics; +Util.inherits(Statistics, Sequence); +function Statistics(options, callback) { + if (!callback && typeof options === 'function') { + callback = options; + options = {}; + } + + Sequence.call(this, options, callback); +} + +Statistics.prototype.start = function() { + this.emit('packet', new Packets.ComStatisticsPacket); +}; + +Statistics.prototype['StatisticsPacket'] = function (packet) { + this.end(null, packet); +}; + +Statistics.prototype.determinePacket = function(firstByte, parser) { + if (firstByte === 0x55) { + return Packets.StatisticsPacket; + } +}; diff --git a/node_modules/mysql/lib/protocol/sequences/index.js b/node_modules/mysql/lib/protocol/sequences/index.js new file mode 100644 index 0000000..a13d469 --- /dev/null +++ b/node_modules/mysql/lib/protocol/sequences/index.js @@ -0,0 +1,4 @@ +var Elements = module.exports = require('require-all')({ + dirname : __dirname, + filter : /([A-Z].+)\.js$/, +}); diff --git a/node_modules/mysql/node_modules/bignumber.js/.npmignore b/node_modules/mysql/node_modules/bignumber.js/.npmignore new file mode 100644 index 0000000..2a7fbd1 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/.npmignore @@ -0,0 +1,2 @@ +test +perf diff --git a/node_modules/mysql/node_modules/bignumber.js/.travis.yml b/node_modules/mysql/node_modules/bignumber.js/.travis.yml new file mode 100644 index 0000000..c696551 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.11" + - "0.10" + - "0.8" + - "0.6" \ No newline at end of file diff --git a/node_modules/mysql/node_modules/bignumber.js/LICENCE b/node_modules/mysql/node_modules/bignumber.js/LICENCE new file mode 100644 index 0000000..c045569 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/LICENCE @@ -0,0 +1,23 @@ +The MIT Expat Licence. + +Copyright (c) 2012 Michael Mclaughlin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/node_modules/mysql/node_modules/bignumber.js/README.md b/node_modules/mysql/node_modules/bignumber.js/README.md new file mode 100644 index 0000000..3b72ea4 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/README.md @@ -0,0 +1,242 @@ +[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.png)](https://travis-ci.org/MikeMcl/bignumber.js) + +# bignumber.js # + +A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic. + +## Features + + - Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal + - 5 KB minified and gzipped + - Simple API but full-featured + - Works with numbers with or without fraction digits in bases from 2 to 64 inclusive + - Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type + - Includes a `toFraction` and a correctly-rounded `squareRoot` method + - Stores values in an accessible decimal floating point format + - No dependencies + - Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set + +If an even smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/). +It's half the size but only works with decimal numbers and only has half the methods. +It also does not allow `NaN` or `Infinity`, or have the configuration options of this library. +See also [decimal.js](https://github.com/MikeMcl/decimal.js/). + +## Load + +The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*). + +It can be loaded via a script tag in an HTML document for the browser + + + +or as a CommonJS, [Node.js](http://nodejs.org) or AMD module using `require`. + +For Node, put the *bignumber.js* file into the same directory as the file that is requiring it and use + + var BigNumber = require('./bignumber.js'); + +or put it in a *node_modules* directory within the directory and use `require('bignumber.js')`. + +The library is also available from the [npm](https://npmjs.org/) registry, so + + $ npm install bignumber.js + +will install this directory in a *node_modules* directory within the current directory. + +To load with AMD loader libraries such as [requireJS](http://requirejs.org/): + + require(['path/to/bignumber'], function(BigNumber) { + // Use BigNumber here in local scope. No global BigNumber. + }); + +## Use + +*In all examples below, `var`, 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.* + +The library exports a single function: BigNumber, the constructor of BigNumber instances. +It accepts a value of type Number *(up to 15 significant digits only)*, String or BigNumber Object, + + x = new BigNumber(123.4567) + y = BigNumber('123456.7e-3') // 'new' is optional + z = new BigNumber(x) + x.equals(y) && y.equals(z) && x.equals(z) // true + +and a base from 2 to 64 inclusive can be specified. + + x = new BigNumber(1011, 2) // "11" + y = new BigNumber('zz.9', 36) // "1295.25" + z = x.plus(y) // "1306.25" + +A BigNumber is immutable in the sense that it is not changed by its methods. + + 0.3 - 0.1 // 0.19999999999999998 + x = new BigNumber(0.3) + x.minus(0.1) // "0.2" + x // "0.3" + +The methods that return a BigNumber can be chained. + + x.dividedBy(y).plus(z).times(9).floor() + x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').ceil() + +Method names over 5 letters in length have a shorter alias. + + x.squareRoot().dividedBy(y).toPower(3).equals(x.sqrt().div(y).pow(3)) // true + x.cmp(y.mod(z).neg()) == 1 && x.comparedTo(y.modulo(z).negated()) == 1 // true + +Like JavaScript's Number type, there are `toExponential`, `toFixed` and `toPrecision` methods + + x = new BigNumber(255.5) + x.toExponential(5) // "2.55500e+2" + x.toFixed(5) // "255.50000" + x.toPrecision(5) // "255.50" + x.toNumber() // 255.5 + + and a base can be specified for `toString`. + + x.toString(16) // "ff.8" + +The maximum number of decimal places of, and the rounding mode applied to, the results of operations involving division (i.e. division, square root, base conversion, and negative power operations) is set by a configuration object passed to the `config` method of the `BigNumber` constructor. +The other arithmetic operations always give the exact result. + + BigNumber.config({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 }) + // Alternatively, BigNumber.config( 10, 4 ); + + x = new BigNumber(2); + y = new BigNumber(3); + z = x.div(y) // "0.6666666667" + z.sqrt() // "0.8164965809" + z.pow(-3) // "3.3749999995" + z.toString(2) // "0.1010101011" + z.times(z) // "0.44444444448888888889" + z.times(z).round(10) // "0.4444444445" + +There is a `toFraction` method with an optional *maximum denominator* argument + + y = new BigNumber(355) + pi = y.dividedBy(113) // "3.1415929204" + pi.toFraction() // [ "7853982301", "2500000000" ] + pi.toFraction(1000) // [ "355", "113" ] + +and `isNaN` and `isFinite` methods, as `NaN` and `Infinity` are valid `BigNumber` values. + + x = new BigNumber(NaN) // "NaN" + y = new BigNumber(Infinity) // "Infinity" + x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true + +The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign. + + x = new BigNumber(-123.456); + x.c // "1,2,3,4,5,6" coefficient (i.e. significand) + x.e // 2 exponent + x.s // -1 sign + +For futher information see the [API](http://mikemcl.github.io/bignumber.js/) reference from the *doc* folder. + +## Test + +The *test* directory contains the test scripts for each method. + +The tests can be run with Node or a browser. + +For a quick test of all the methods, from a command-line shell at the *test/* directory + + $ node quick-test + +To test a single method in more depth, e.g. + + $ node toFraction + +To test all the methods in more depth + + $ node every-test + +For the browser, see *quick-test.html*, *single-test.html* and *every-test.html* in the *test/browser* directory. + +*bignumber-vs-number.html* enables some of the methods of bignumber.js to be compared with those of JavaScript's Number type. + +## Performance + +The *perf* directory contains two applications and a *lib* directory containing the BigDecimal libraries used by both. + +*bignumber-vs-bigdecimal.html* tests the performance of bignumber.js against the JavaScript translations of two versions of BigDecimal, its use should be more or less self-explanatory. +(The GWT version doesn't work in IE 6.) + +* GWT: java.math.BigDecimal + +* ICU4J: com.ibm.icu.math.BigDecimal + + +The BigDecimal in Node's npm registry is the GWT version. Despite its seeming popularity I have found it to have some serious bugs, see the Node script *perf/lib/bigdecimal_GWT/bugs.js* for examples of flaws in its *remainder*, *divide* and *compareTo* methods. + +*bigtime.js* is a Node command-line application which tests the performance of bignumber.js against the GWT version of BigDecimal from the npm registry. + +For example, to compare the time taken by the bignumber.js `plus` method and the BigDecimal `add` method: + + $ node bigtime plus 10000 40 + +This will time 10000 calls to each, using operands of up to 40 random digits and will check that the results match. + +For help: + + $ node bigtime -h + +See the README in the directory for more information. + +## Build + +I.e. minify. + +For Node, if uglify-js is installed globally ( `npm install uglify-js -g` ) then + + npm run build + +will create *bignumber.min.js*. + +## Feedback + +Open an issue, or email + +Michael +M8ch88l@gmail.com + +Bitcoin donation to: +**1CauoGYrEoJFhcyxGVaiLTE6f3WCaSUjnm** +Thank you + +## Licence + +MIT. + +See LICENCE. + +## Change Log + +####1.4.1 +* 08/06/2014 Amend README. + +####1.4.0 +* 08/05/2014 Added `toNumber`. + +####1.3.0 +* 08/11/2013 Ensure correct rounding of `sqrt` in all, rather than almost all, cases. +* Maximum radix to 64. + +####1.2.1 +* 17/10/2013 Sign of zero when x < 0 and x + (-x) = 0. + +####1.2.0 +* 19/9/2013 Throw Error objects for stack. + +####1.1.1 +* 22/8/2013 Show original value in constructor error message. + +####1.1.0 +* 1/8/2013 Allow numbers with trailing radix point. + +####1.0.1 +* Bugfix: error messages with incorrect method name + +####1.0.0 +* 8/11/2012 Initial release diff --git a/node_modules/mysql/node_modules/bignumber.js/bignumber.js b/node_modules/mysql/node_modules/bignumber.js/bignumber.js new file mode 100644 index 0000000..9bddb38 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/bignumber.js @@ -0,0 +1,2017 @@ +/*! bignumber.js v1.4.1 https://github.com/MikeMcl/bignumber.js/LICENCE */ + +;(function ( global ) { + 'use strict'; + + /* + bignumber.js v1.4.1 + A JavaScript library for arbitrary-precision arithmetic. + https://github.com/MikeMcl/bignumber.js + Copyright (c) 2012 Michael Mclaughlin + MIT Expat Licence + */ + + /*********************************** DEFAULTS ************************************/ + + /* + * The default values below must be integers within the stated ranges (inclusive). + * Most of these values can be changed during run-time using BigNumber.config(). + */ + + /* + * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, + * MAX_EXP, and the argument to toFixed, toPrecision and toExponential, beyond + * which an exception is thrown (if ERRORS is true). + */ + var MAX = 1E9, // 0 to 1e+9 + + // Limit of magnitude of exponent argument to toPower. + MAX_POWER = 1E6, // 1 to 1e+6 + + // The maximum number of decimal places for operations involving division. + DECIMAL_PLACES = 20, // 0 to MAX + + /* + * The rounding mode used when rounding to the above decimal places, and when + * using toFixed, toPrecision and toExponential, and round (default value). + * UP 0 Away from zero. + * DOWN 1 Towards zero. + * CEIL 2 Towards +Infinity. + * FLOOR 3 Towards -Infinity. + * HALF_UP 4 Towards nearest neighbour. If equidistant, up. + * HALF_DOWN 5 Towards nearest neighbour. If equidistant, down. + * HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour. + * HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity. + * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity. + */ + ROUNDING_MODE = 4, // 0 to 8 + + // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS] + + // The exponent value at and beneath which toString returns exponential notation. + // Number type: -7 + TO_EXP_NEG = -7, // 0 to -MAX + + // The exponent value at and above which toString returns exponential notation. + // Number type: 21 + TO_EXP_POS = 21, // 0 to MAX + + // RANGE : [MIN_EXP, MAX_EXP] + + // The minimum exponent value, beneath which underflow to zero occurs. + // Number type: -324 (5e-324) + MIN_EXP = -MAX, // -1 to -MAX + + // The maximum exponent value, above which overflow to Infinity occurs. + // Number type: 308 (1.7976931348623157e+308) + MAX_EXP = MAX, // 1 to MAX + + // Whether BigNumber Errors are ever thrown. + // CHANGE parseInt to parseFloat if changing ERRORS to false. + ERRORS = true, // true or false + parse = parseInt, // parseInt or parseFloat + + /***********************************************************************************/ + + P = BigNumber.prototype, + DIGITS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_', + outOfRange, + id = 0, + isValid = /^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i, + trim = String.prototype.trim || function () {return this.replace(/^\s+|\s+$/g, '')}, + ONE = BigNumber(1); + + + // CONSTRUCTOR + + + /* + * The exported function. + * Create and return a new instance of a BigNumber object. + * + * n {number|string|BigNumber} A numeric value. + * [b] {number} The base of n. Integer, 2 to 64 inclusive. + */ + function BigNumber( n, b ) { + var e, i, isNum, digits, valid, orig, + x = this; + + // Enable constructor usage without new. + if ( !(x instanceof BigNumber) ) { + return new BigNumber( n, b ) + } + + // Duplicate. + if ( n instanceof BigNumber ) { + id = 0; + + // e is undefined. + if ( b !== e ) { + n += '' + } else { + x['s'] = n['s']; + x['e'] = n['e']; + x['c'] = ( n = n['c'] ) ? n.slice() : n; + return; + } + } + + // If number, check if minus zero. + if ( typeof n != 'string' ) { + n = ( isNum = typeof n == 'number' || + Object.prototype.toString.call(n) == '[object Number]' ) && + n === 0 && 1 / n < 0 ? '-0' : n + ''; + } + + orig = n; + + if ( b === e && isValid.test(n) ) { + + // Determine sign. + x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1; + + // Either n is not a valid BigNumber or a base has been specified. + } else { + + // Enable exponential notation to be used with base 10 argument. + // Ensure return value is rounded to DECIMAL_PLACES as with other bases. + if ( b == 10 ) { + + return setMode( n, DECIMAL_PLACES, ROUNDING_MODE ); + } + + n = trim.call(n).replace( /^\+(?!-)/, '' ); + + x['s'] = n.charAt(0) == '-' ? ( n = n.replace( /^-(?!-)/, '' ), -1 ) : 1; + + if ( b != null ) { + + if ( ( b == (b | 0) || !ERRORS ) && + !( outOfRange = !( b >= 2 && b < 65 ) ) ) { + + digits = '[' + DIGITS.slice( 0, b = b | 0 ) + ']+'; + + // Before non-decimal number validity test and base conversion + // remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'. + n = n.replace( /\.$/, '' ).replace( /^\./, '0.' ); + + // Any number in exponential form will fail due to the e+/-. + if ( valid = new RegExp( + '^' + digits + '(?:\\.' + digits + ')?$', b < 37 ? 'i' : '' ).test(n) ) { + + if ( isNum ) { + + if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) { + + // 'new BigNumber() number type has more than 15 significant digits: {n}' + ifExceptionsThrow( orig, 0 ); + } + + // Prevent later check for length on converted number. + isNum = !isNum; + } + n = convert( n, 10, b, x['s'] ); + + } else if ( n != 'Infinity' && n != 'NaN' ) { + + // 'new BigNumber() not a base {b} number: {n}' + ifExceptionsThrow( orig, 1, b ); + n = 'NaN'; + } + } else { + + // 'new BigNumber() base not an integer: {b}' + // 'new BigNumber() base out of range: {b}' + ifExceptionsThrow( b, 2 ); + + // Ignore base. + valid = isValid.test(n); + } + } else { + valid = isValid.test(n); + } + + if ( !valid ) { + + // Infinity/NaN + x['c'] = x['e'] = null; + + // NaN + if ( n != 'Infinity' ) { + + // No exception on NaN. + if ( n != 'NaN' ) { + + // 'new BigNumber() not a number: {n}' + ifExceptionsThrow( orig, 3 ); + } + x['s'] = null; + } + id = 0; + + return; + } + } + + // Decimal point? + if ( ( e = n.indexOf('.') ) > -1 ) { + n = n.replace( '.', '' ); + } + + // Exponential form? + if ( ( i = n.search( /e/i ) ) > 0 ) { + + // Determine exponent. + if ( e < 0 ) { + e = i; + } + e += +n.slice( i + 1 ); + n = n.substring( 0, i ); + + } else if ( e < 0 ) { + + // Integer. + e = n.length; + } + + // Determine leading zeros. + for ( i = 0; n.charAt(i) == '0'; i++ ) { + } + + b = n.length; + + // Disallow numbers with over 15 significant digits if number type. + if ( isNum && b > 15 && n.slice(i).length > 15 ) { + + // 'new BigNumber() number type has more than 15 significant digits: {n}' + ifExceptionsThrow( orig, 0 ); + } + id = 0; + + // Overflow? + if ( ( e -= i + 1 ) > MAX_EXP ) { + + // Infinity. + x['c'] = x['e'] = null; + + // Zero or underflow? + } else if ( i == b || e < MIN_EXP ) { + + // Zero. + x['c'] = [ x['e'] = 0 ]; + } else { + + // Determine trailing zeros. + for ( ; n.charAt(--b) == '0'; ) { + } + + x['e'] = e; + x['c'] = []; + + // Convert string to array of digits (without leading and trailing zeros). + for ( e = 0; i <= b; x['c'][e++] = +n.charAt(i++) ) { + } + } + } + + + // CONSTRUCTOR PROPERTIES/METHODS + + + BigNumber['ROUND_UP'] = 0; + BigNumber['ROUND_DOWN'] = 1; + BigNumber['ROUND_CEIL'] = 2; + BigNumber['ROUND_FLOOR'] = 3; + BigNumber['ROUND_HALF_UP'] = 4; + BigNumber['ROUND_HALF_DOWN'] = 5; + BigNumber['ROUND_HALF_EVEN'] = 6; + BigNumber['ROUND_HALF_CEIL'] = 7; + BigNumber['ROUND_HALF_FLOOR'] = 8; + + + /* + * Configure infrequently-changing library-wide settings. + * + * Accept an object or an argument list, with one or many of the following + * properties or parameters respectively: + * [ DECIMAL_PLACES [, ROUNDING_MODE [, EXPONENTIAL_AT [, RANGE [, ERRORS ]]]]] + * + * E.g. + * BigNumber.config(20, 4) is equivalent to + * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 }) + * Ignore properties/parameters set to null or undefined. + * + * Return an object with the properties current values. + */ + BigNumber['config'] = function () { + var v, p, + i = 0, + r = {}, + a = arguments, + o = a[0], + c = 'config', + inRange = function ( n, lo, hi ) { + return !( ( outOfRange = n < lo || n > hi ) || + parse(n) != n && n !== 0 ); + }, + has = o && typeof o == 'object' + ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null} + : function () {if ( a.length > i ) return ( v = a[i++] ) != null}; + + // [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive. + if ( has( p = 'DECIMAL_PLACES' ) ) { + + if ( inRange( v, 0, MAX ) ) { + DECIMAL_PLACES = v | 0; + } else { + + // 'config() DECIMAL_PLACES not an integer: {v}' + // 'config() DECIMAL_PLACES out of range: {v}' + ifExceptionsThrow( v, p, c ); + } + } + r[p] = DECIMAL_PLACES; + + // [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive. + if ( has( p = 'ROUNDING_MODE' ) ) { + + if ( inRange( v, 0, 8 ) ) { + ROUNDING_MODE = v | 0; + } else { + + // 'config() ROUNDING_MODE not an integer: {v}' + // 'config() ROUNDING_MODE out of range: {v}' + ifExceptionsThrow( v, p, c ); + } + } + r[p] = ROUNDING_MODE; + + /* + * [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or + * [ integer -MAX to 0 inclusive, 0 to MAX inclusive ]. + */ + if ( has( p = 'EXPONENTIAL_AT' ) ) { + + if ( inRange( v, -MAX, MAX ) ) { + TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) ); + } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) && + inRange( v[1], 0, MAX ) ) { + TO_EXP_NEG = ~~v[0]; + TO_EXP_POS = ~~v[1]; + } else { + + // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}' + // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}' + ifExceptionsThrow( v, p, c, 1 ); + } + } + r[p] = [ TO_EXP_NEG, TO_EXP_POS ]; + + /* + * [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or + * [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ]. + */ + if ( has( p = 'RANGE' ) ) { + + if ( inRange( v, -MAX, MAX ) && ~~v ) { + MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) ); + } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) && + inRange( v[1], 1, MAX ) ) { + MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]; + } else { + + // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}' + // 'config() RANGE out of range or not [negative, positive: {v}' + ifExceptionsThrow( v, p, c, 1, 1 ); + } + } + r[p] = [ MIN_EXP, MAX_EXP ]; + + // [ERRORS] {boolean|number} true, false, 1 or 0. + if ( has( p = 'ERRORS' ) ) { + + if ( v === !!v || v === 1 || v === 0 ) { + parse = ( outOfRange = id = 0, ERRORS = !!v ) + ? parseInt + : parseFloat; + } else { + + // 'config() ERRORS not a boolean or binary digit: {v}' + ifExceptionsThrow( v, p, c, 0, 0, 1 ); + } + } + r[p] = ERRORS; + + return r; + }; + + + // PRIVATE FUNCTIONS + + + // Assemble error messages. Throw BigNumber Errors. + function ifExceptionsThrow( arg, i, j, isArray, isRange, isErrors) { + + if ( ERRORS ) { + var error, + method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt', + 'lte', 'minus', 'mod', 'plus', 'times', 'toFr' + ][ id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0 ] + '()', + message = outOfRange ? ' out of range' : ' not a' + + ( isRange ? ' non-zero' : 'n' ) + ' integer'; + + message = ( [ + method + ' number type has more than 15 significant digits', + method + ' not a base ' + j + ' number', + method + ' base' + message, + method + ' not a number' ][i] || + j + '() ' + i + ( isErrors + ? ' not a boolean or binary digit' + : message + ( isArray + ? ' or not [' + ( outOfRange + ? ' negative, positive' + : ' integer, integer' ) + ' ]' + : '' ) ) ) + ': ' + arg; + + outOfRange = id = 0; + error = new Error(message); + error['name'] = 'BigNumber Error'; + + throw error; + } + } + + + /* + * Convert a numeric string of baseIn to a numeric string of baseOut. + */ + function convert( nStr, baseOut, baseIn, sign ) { + var e, dvs, dvd, nArr, fracArr, fracBN; + + // Convert string of base bIn to an array of numbers of baseOut. + // Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15]. + // Eg. strToArr('ff', 16) where baseOut is 10, returns [2, 5, 5]. + function strToArr( str, bIn ) { + var j, + i = 0, + strL = str.length, + arrL, + arr = [0]; + + for ( bIn = bIn || baseIn; i < strL; i++ ) { + + for ( arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++ ) { + } + + for ( arr[0] += DIGITS.indexOf( str.charAt(i) ), j = 0; + j < arr.length; + j++ ) { + + if ( arr[j] > baseOut - 1 ) { + + if ( arr[j + 1] == null ) { + arr[j + 1] = 0; + } + arr[j + 1] += arr[j] / baseOut ^ 0; + arr[j] %= baseOut; + } + } + } + + return arr.reverse(); + } + + // Convert array to string. + // E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11). + function arrToStr( arr ) { + var i = 0, + arrL = arr.length, + str = ''; + + for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) { + } + + return str; + } + + if ( baseIn < 37 ) { + nStr = nStr.toLowerCase(); + } + + /* + * If non-integer convert integer part and fraction part separately. + * Convert the fraction part as if it is an integer than use division to + * reduce it down again to a value less than one. + */ + if ( ( e = nStr.indexOf( '.' ) ) > -1 ) { + + /* + * Calculate the power to which to raise the base to get the number + * to divide the fraction part by after it has been converted as an + * integer to the required base. + */ + e = nStr.length - e - 1; + + // Use toFixed to avoid possible exponential notation. + dvs = strToArr( new BigNumber(baseIn)['pow'](e)['toF'](), 10 ); + + nArr = nStr.split('.'); + + // Convert the base of the fraction part (as integer). + dvd = strToArr( nArr[1] ); + + // Convert the base of the integer part. + nArr = strToArr( nArr[0] ); + + // Result will be a BigNumber with a value less than 1. + fracBN = divide( dvd, dvs, dvd.length - dvs.length, sign, baseOut, + // Is least significant digit of integer part an odd number? + nArr[nArr.length - 1] & 1 ); + + fracArr = fracBN['c']; + + // e can be <= 0 ( if e == 0, fracArr is [0] or [1] ). + if ( e = fracBN['e'] ) { + + // Append zeros according to the exponent of the result. + for ( ; ++e; fracArr.unshift(0) ) { + } + + // Append the fraction part to the converted integer part. + nStr = arrToStr(nArr) + '.' + arrToStr(fracArr); + + // fracArr is [1]. + // Fraction digits rounded up, so increment last digit of integer part. + } else if ( fracArr[0] ) { + + if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) { + ++nArr[e]; + nStr = arrToStr(nArr); + } else { + nStr = new BigNumber( arrToStr(nArr), + baseOut )['plus'](ONE)['toS'](baseOut); + } + + // fracArr is [0]. No fraction digits. + } else { + nStr = arrToStr(nArr); + } + } else { + + // Simple integer. Convert base. + nStr = arrToStr( strToArr(nStr) ); + } + + return nStr; + } + + + // Perform division in the specified base. Called by div and convert. + function divide( dvd, dvs, exp, s, base, isOdd ) { + var dvsL, dvsT, next, cmp, remI, + dvsZ = dvs.slice(), + dvdI = dvsL = dvs.length, + dvdL = dvd.length, + rem = dvd.slice( 0, dvsL ), + remL = rem.length, + quo = new BigNumber(ONE), + qc = quo['c'] = [], + qi = 0, + dig = DECIMAL_PLACES + ( quo['e'] = exp ) + 1; + + quo['s'] = s; + s = dig < 0 ? 0 : dig; + + // Add zeros to make remainder as long as divisor. + for ( ; remL++ < dvsL; rem.push(0) ) { + } + + // Create version of divisor with leading zero. + dvsZ.unshift(0); + + do { + + // 'next' is how many times the divisor goes into the current remainder. + for ( next = 0; next < base; next++ ) { + + // Compare divisor and remainder. + if ( dvsL != ( remL = rem.length ) ) { + cmp = dvsL > remL ? 1 : -1; + } else { + for ( remI = -1, cmp = 0; ++remI < dvsL; ) { + + if ( dvs[remI] != rem[remI] ) { + cmp = dvs[remI] > rem[remI] ? 1 : -1; + break; + } + } + } + + // Subtract divisor from remainder (if divisor < remainder). + if ( cmp < 0 ) { + + // Remainder cannot be more than one digit longer than divisor. + // Equalise lengths using divisor with extra leading zero? + for ( dvsT = remL == dvsL ? dvs : dvsZ; remL; ) { + + if ( rem[--remL] < dvsT[remL] ) { + + for ( remI = remL; + remI && !rem[--remI]; + rem[remI] = base - 1 ) { + } + --rem[remI]; + rem[remL] += base; + } + rem[remL] -= dvsT[remL]; + } + for ( ; !rem[0]; rem.shift() ) { + } + } else { + break; + } + } + + // Add the 'next' digit to the result array. + qc[qi++] = cmp ? next : ++next; + + // Update the remainder. + rem[0] && cmp + ? ( rem[remL] = dvd[dvdI] || 0 ) + : ( rem = [ dvd[dvdI] ] ); + + } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- ); + + // Leading zero? Do not remove if result is simply zero (qi == 1). + if ( !qc[0] && qi != 1 ) { + + // There can't be more than one zero. + --quo['e']; + qc.shift(); + } + + // Round? + if ( qi > dig ) { + rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null ); + } + + // Overflow? + if ( quo['e'] > MAX_EXP ) { + + // Infinity. + quo['c'] = quo['e'] = null; + + // Underflow? + } else if ( quo['e'] < MIN_EXP ) { + + // Zero. + quo['c'] = [quo['e'] = 0]; + } + + return quo; + } + + + /* + * Return a string representing the value of BigNumber n in normal or + * exponential notation rounded to the specified decimal places or + * significant digits. + * Called by toString, toExponential (exp 1), toFixed, and toPrecision (exp 2). + * d is the index (with the value in normal notation) of the digit that may be + * rounded up. + */ + function format( n, d, exp ) { + + // Initially, i is the number of decimal places required. + var i = d - (n = new BigNumber(n))['e'], + c = n['c']; + + // +-Infinity or NaN? + if ( !c ) { + return n['toS'](); + } + + // Round? + if ( c.length > ++d ) { + rnd( n, i, 10 ); + } + + // Recalculate d if toFixed as n['e'] may have changed if value rounded up. + i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1; + + // Append zeros? + for ( ; c.length < i; c.push(0) ) { + } + i = n['e']; + + /* + * toPrecision returns exponential notation if the number of significant + * digits specified is less than the number of digits necessary to + * represent the integer part of the value in normal notation. + */ + return exp == 1 || exp == 2 && ( --d < i || i <= TO_EXP_NEG ) + + // Exponential notation. + ? ( n['s'] < 0 && c[0] ? '-' : '' ) + ( c.length > 1 + ? ( c.splice( 1, 0, '.' ), c.join('') ) + : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i + + // Normal notation. + : n['toS'](); + } + + + // Round if necessary. + // Called by divide, format, setMode and sqrt. + function rnd( x, dp, base, isOdd, r ) { + var xc = x['c'], + isNeg = x['s'] < 0, + half = base / 2, + i = x['e'] + dp + 1, + + // 'next' is the digit after the digit that may be rounded up. + next = xc[i], + + /* + * 'more' is whether there are digits after 'next'. + * E.g. + * 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2 + * The 'next' digit is zero, and there ARE 'more' digits after it. + * 0.5 (e = -1) dp = 0 gives i = 0 + * The 'next' digit is 5 and there are no 'more' digits after it. + */ + more = r || i < 0 || xc[i + 1] != null; + + r = ROUNDING_MODE < 4 + ? ( next != null || more ) && + ( ROUNDING_MODE == 0 || + ROUNDING_MODE == 2 && !isNeg || + ROUNDING_MODE == 3 && isNeg ) + : next > half || next == half && + ( ROUNDING_MODE == 4 || more || + + /* + * isOdd is used in base conversion and refers to the least significant + * digit of the integer part of the value to be converted. The fraction + * part is rounded by this method separately from the integer part. + */ + ROUNDING_MODE == 6 && ( xc[i - 1] & 1 || !dp && isOdd ) || + ROUNDING_MODE == 7 && !isNeg || + ROUNDING_MODE == 8 && isNeg ); + + if ( i < 1 || !xc[0] ) { + xc.length = 0; + xc.push(0); + + if ( r ) { + + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xc[0] = 1; + x['e'] = -dp; + } else { + + // Zero. + x['e'] = 0; + } + + return x; + } + + // Remove any digits after the required decimal places. + xc.length = i--; + + // Round up? + if ( r ) { + + // Rounding up may mean the previous digit has to be rounded up and so on. + for ( --base; ++xc[i] > base; ) { + xc[i] = 0; + + if ( !i-- ) { + ++x['e']; + xc.unshift(1); + } + } + } + + // Remove trailing zeros. + for ( i = xc.length; !xc[--i]; xc.pop() ) { + } + + return x; + } + + + // Round after setting the appropriate rounding mode. + // Handles ceil, floor and round. + function setMode( x, dp, rm ) { + var r = ROUNDING_MODE; + + ROUNDING_MODE = rm; + x = new BigNumber(x); + x['c'] && rnd( x, dp, 10 ); + ROUNDING_MODE = r; + + return x; + } + + + // PROTOTYPE/INSTANCE METHODS + + + /* + * Return a new BigNumber whose value is the absolute value of this BigNumber. + */ + P['abs'] = P['absoluteValue'] = function () { + var x = new BigNumber(this); + + if ( x['s'] < 0 ) { + x['s'] = 1; + } + + return x; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber + * rounded to a whole number in the direction of Infinity. + */ + P['ceil'] = function () { + return setMode( this, 0, 2 ); + }; + + + /* + * Return + * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b), + * -1 if the value of this BigNumber is less than the value of BigNumber(y, b), + * 0 if they have the same value, + * or null if the value of either is NaN. + */ + P['comparedTo'] = P['cmp'] = function ( y, b ) { + var a, + x = this, + xc = x['c'], + yc = ( id = -id, y = new BigNumber( y, b ) )['c'], + i = x['s'], + j = y['s'], + k = x['e'], + l = y['e']; + + // Either NaN? + if ( !i || !j ) { + return null; + } + + a = xc && !xc[0], b = yc && !yc[0]; + + // Either zero? + if ( a || b ) { + return a ? b ? 0 : -j : i; + } + + // Signs differ? + if ( i != j ) { + return i; + } + + // Either Infinity? + if ( a = i < 0, b = k == l, !xc || !yc ) { + return b ? 0 : !xc ^ a ? 1 : -1; + } + + // Compare exponents. + if ( !b ) { + return k > l ^ a ? 1 : -1; + } + + // Compare digit by digit. + for ( i = -1, + j = ( k = xc.length ) < ( l = yc.length ) ? k : l; + ++i < j; ) { + + if ( xc[i] != yc[i] ) { + return xc[i] > yc[i] ^ a ? 1 : -1; + } + } + // Compare lengths. + return k == l ? 0 : k > l ^ a ? 1 : -1; + }; + + + /* + * n / 0 = I + * n / N = N + * n / I = 0 + * 0 / n = 0 + * 0 / 0 = N + * 0 / N = N + * 0 / I = 0 + * N / n = N + * N / 0 = N + * N / N = N + * N / I = N + * I / n = I + * I / 0 = I + * I / N = N + * I / I = N + * + * Return a new BigNumber whose value is the value of this BigNumber + * divided by the value of BigNumber(y, b), rounded according to + * DECIMAL_PLACES and ROUNDING_MODE. + */ + P['dividedBy'] = P['div'] = function ( y, b ) { + var xc = this['c'], + xe = this['e'], + xs = this['s'], + yc = ( id = 2, y = new BigNumber( y, b ) )['c'], + ye = y['e'], + ys = y['s'], + s = xs == ys ? 1 : -1; + + // Either NaN/Infinity/0? + return !xe && ( !xc || !xc[0] ) || !ye && ( !yc || !yc[0] ) + + // Either NaN? + ? new BigNumber( !xs || !ys || + + // Both 0 or both Infinity? + ( xc ? yc && xc[0] == yc[0] : !yc ) + + // Return NaN. + ? NaN + + // x is 0 or y is Infinity? + : xc && xc[0] == 0 || !yc + + // Return +-0. + ? s * 0 + + // y is 0. Return +-Infinity. + : s / 0 ) + + : divide( xc, yc, xe - ye, s, 10 ); + }; + + + /* + * Return true if the value of this BigNumber is equal to the value of + * BigNumber(n, b), otherwise returns false. + */ + P['equals'] = P['eq'] = function ( n, b ) { + id = 3; + return this['cmp']( n, b ) === 0; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber + * rounded to a whole number in the direction of -Infinity. + */ + P['floor'] = function () { + return setMode( this, 0, 3 ); + }; + + + /* + * Return true if the value of this BigNumber is greater than the value of + * BigNumber(n, b), otherwise returns false. + */ + P['greaterThan'] = P['gt'] = function ( n, b ) { + id = 4; + return this['cmp']( n, b ) > 0; + }; + + + /* + * Return true if the value of this BigNumber is greater than or equal to + * the value of BigNumber(n, b), otherwise returns false. + */ + P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) { + id = 5; + return ( b = this['cmp']( n, b ) ) == 1 || b === 0; + }; + + + /* + * Return true if the value of this BigNumber is a finite number, otherwise + * returns false. + */ + P['isFinite'] = P['isF'] = function () { + return !!this['c']; + }; + + + /* + * Return true if the value of this BigNumber is NaN, otherwise returns + * false. + */ + P['isNaN'] = function () { + return !this['s']; + }; + + + /* + * Return true if the value of this BigNumber is negative, otherwise + * returns false. + */ + P['isNegative'] = P['isNeg'] = function () { + return this['s'] < 0; + }; + + + /* + * Return true if the value of this BigNumber is 0 or -0, otherwise returns + * false. + */ + P['isZero'] = P['isZ'] = function () { + return !!this['c'] && this['c'][0] == 0; + }; + + + /* + * Return true if the value of this BigNumber is less than the value of + * BigNumber(n, b), otherwise returns false. + */ + P['lessThan'] = P['lt'] = function ( n, b ) { + id = 6; + return this['cmp']( n, b ) < 0; + }; + + + /* + * Return true if the value of this BigNumber is less than or equal to the + * value of BigNumber(n, b), otherwise returns false. + */ + P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) { + id = 7; + return ( b = this['cmp']( n, b ) ) == -1 || b === 0; + }; + + + /* + * n - 0 = n + * n - N = N + * n - I = -I + * 0 - n = -n + * 0 - 0 = 0 + * 0 - N = N + * 0 - I = -I + * N - n = N + * N - 0 = N + * N - N = N + * N - I = N + * I - n = I + * I - 0 = I + * I - N = N + * I - I = N + * + * Return a new BigNumber whose value is the value of this BigNumber minus + * the value of BigNumber(y, b). + */ + P['minus'] = function ( y, b ) { + var d, i, j, xLTy, + x = this, + a = x['s']; + + b = ( id = 8, y = new BigNumber( y, b ) )['s']; + + // Either NaN? + if ( !a || !b ) { + return new BigNumber(NaN); + } + + // Signs differ? + if ( a != b ) { + return y['s'] = -b, x['plus'](y); + } + + var xc = x['c'], + xe = x['e'], + yc = y['c'], + ye = y['e']; + + if ( !xe || !ye ) { + + // Either Infinity? + if ( !xc || !yc ) { + return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN ); + } + + // Either zero? + if ( !xc[0] || !yc[0] ) { + + // y is non-zero? + return yc[0] + ? ( y['s'] = -b, y ) + + // x is non-zero? + : new BigNumber( xc[0] + ? x + + // Both are zero. + // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity + : ROUNDING_MODE == 3 ? -0 : 0 ); + } + } + + // Determine which is the bigger number. + // Prepend zeros to equalise exponents. + if ( xc = xc.slice(), a = xe - ye ) { + d = ( xLTy = a < 0 ) ? ( a = -a, xc ) : ( ye = xe, yc ); + + for ( d.reverse(), b = a; b--; d.push(0) ) { + } + d.reverse(); + } else { + + // Exponents equal. Check digit by digit. + j = ( ( xLTy = xc.length < yc.length ) ? xc : yc ).length; + + for ( a = b = 0; b < j; b++ ) { + + if ( xc[b] != yc[b] ) { + xLTy = xc[b] < yc[b]; + break; + } + } + } + + // x < y? Point xc to the array of the bigger number. + if ( xLTy ) { + d = xc, xc = yc, yc = d; + y['s'] = -y['s']; + } + + /* + * Append zeros to xc if shorter. No need to add zeros to yc if shorter + * as subtraction only needs to start at yc.length. + */ + if ( ( b = -( ( j = xc.length ) - yc.length ) ) > 0 ) { + + for ( ; b--; xc[j++] = 0 ) { + } + } + + // Subtract yc from xc. + for ( b = yc.length; b > a; ){ + + if ( xc[--b] < yc[b] ) { + + for ( i = b; i && !xc[--i]; xc[i] = 9 ) { + } + --xc[i]; + xc[b] += 10; + } + xc[b] -= yc[b]; + } + + // Remove trailing zeros. + for ( ; xc[--j] == 0; xc.pop() ) { + } + + // Remove leading zeros and adjust exponent accordingly. + for ( ; xc[0] == 0; xc.shift(), --ye ) { + } + + /* + * No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity + * when neither x or y are Infinity. + */ + + // Underflow? + if ( ye < MIN_EXP || !xc[0] ) { + + /* + * Following IEEE 754 (2008) 6.3, + * n - n = +0 but n - n = -0 when rounding towards -Infinity. + */ + if ( !xc[0] ) { + y['s'] = ROUNDING_MODE == 3 ? -1 : 1; + } + + // Result is zero. + xc = [ye = 0]; + } + + return y['c'] = xc, y['e'] = ye, y; + }; + + + /* + * n % 0 = N + * n % N = N + * 0 % n = 0 + * -0 % n = -0 + * 0 % 0 = N + * 0 % N = N + * N % n = N + * N % 0 = N + * N % N = N + * + * Return a new BigNumber whose value is the value of this BigNumber modulo + * the value of BigNumber(y, b). + */ + P['modulo'] = P['mod'] = function ( y, b ) { + var x = this, + xc = x['c'], + yc = ( id = 9, y = new BigNumber( y, b ) )['c'], + i = x['s'], + j = y['s']; + + // Is x or y NaN, or y zero? + b = !i || !j || yc && !yc[0]; + + if ( b || xc && !xc[0] ) { + return new BigNumber( b ? NaN : x ); + } + + x['s'] = y['s'] = 1; + b = y['cmp'](x) == 1; + x['s'] = i, y['s'] = j; + + return b + ? new BigNumber(x) + : ( i = DECIMAL_PLACES, j = ROUNDING_MODE, + DECIMAL_PLACES = 0, ROUNDING_MODE = 1, + x = x['div'](y), + DECIMAL_PLACES = i, ROUNDING_MODE = j, + this['minus']( x['times'](y) ) ); + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber + * negated, i.e. multiplied by -1. + */ + P['negated'] = P['neg'] = function () { + var x = new BigNumber(this); + + return x['s'] = -x['s'] || null, x; + }; + + + /* + * n + 0 = n + * n + N = N + * n + I = I + * 0 + n = n + * 0 + 0 = 0 + * 0 + N = N + * 0 + I = I + * N + n = N + * N + 0 = N + * N + N = N + * N + I = N + * I + n = I + * I + 0 = I + * I + N = N + * I + I = I + * + * Return a new BigNumber whose value is the value of this BigNumber plus + * the value of BigNumber(y, b). + */ + P['plus'] = function ( y, b ) { + var d, + x = this, + a = x['s']; + + b = ( id = 10, y = new BigNumber( y, b ) )['s']; + + // Either NaN? + if ( !a || !b ) { + return new BigNumber(NaN); + } + + // Signs differ? + if ( a != b ) { + return y['s'] = -b, x['minus'](y); + } + + var xe = x['e'], + xc = x['c'], + ye = y['e'], + yc = y['c']; + + if ( !xe || !ye ) { + + // Either Infinity? + if ( !xc || !yc ) { + + // Return +-Infinity. + return new BigNumber( a / 0 ); + } + + // Either zero? + if ( !xc[0] || !yc[0] ) { + + // y is non-zero? + return yc[0] + ? y + + // x is non-zero? + : new BigNumber( xc[0] + ? x + + // Both are zero. Return zero. + : a * 0 ); + } + } + + // Prepend zeros to equalise exponents. + // Note: Faster to use reverse then do unshifts. + if ( xc = xc.slice(), a = xe - ye ) { + d = a > 0 ? ( ye = xe, yc ) : ( a = -a, xc ); + + for ( d.reverse(); a--; d.push(0) ) { + } + d.reverse(); + } + + // Point xc to the longer array. + if ( xc.length - yc.length < 0 ) { + d = yc, yc = xc, xc = d; + } + + /* + * Only start adding at yc.length - 1 as the + * further digits of xc can be left as they are. + */ + for ( a = yc.length, b = 0; a; + b = ( xc[--a] = xc[a] + yc[a] + b ) / 10 ^ 0, xc[a] %= 10 ) { + } + + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 + + if ( b ) { + xc.unshift(b); + + // Overflow? (MAX_EXP + 1 possible) + if ( ++ye > MAX_EXP ) { + + // Infinity. + xc = ye = null; + } + } + + // Remove trailing zeros. + for ( a = xc.length; xc[--a] == 0; xc.pop() ) { + } + + return y['c'] = xc, y['e'] = ye, y; + }; + + + /* + * Return a BigNumber whose value is the value of this BigNumber raised to + * the power e. If e is negative round according to DECIMAL_PLACES and + * ROUNDING_MODE. + * + * e {number} Integer, -MAX_POWER to MAX_POWER inclusive. + */ + P['toPower'] = P['pow'] = function ( e ) { + + // e to integer, avoiding NaN or Infinity becoming 0. + var i = e * 0 == 0 ? e | 0 : e, + x = new BigNumber(this), + y = new BigNumber(ONE); + + // Use Math.pow? + // Pass +-Infinity for out of range exponents. + if ( ( ( ( outOfRange = e < -MAX_POWER || e > MAX_POWER ) && + (i = e * 1 / 0) ) || + + /* + * Any exponent that fails the parse becomes NaN. + * + * Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false, + * despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true. + */ + parse(e) != e && e !== 0 && !(i = NaN) ) && + + // 'pow() exponent not an integer: {e}' + // 'pow() exponent out of range: {e}' + !ifExceptionsThrow( e, 'exponent', 'pow' ) || + + // Pass zero to Math.pow, as any value to the power zero is 1. + !i ) { + + // i is +-Infinity, NaN or 0. + return new BigNumber( Math.pow( x['toS'](), i ) ); + } + + for ( i = i < 0 ? -i : i; ; ) { + + if ( i & 1 ) { + y = y['times'](x); + } + i >>= 1; + + if ( !i ) { + break; + } + x = x['times'](x); + } + + return e < 0 ? ONE['div'](y) : y; + }; + + + /* + * Return a new BigNumber whose value is the value of this BigNumber + * rounded to a maximum of dp decimal places using rounding mode rm, or to + * 0 and ROUNDING_MODE respectively if omitted. + * + * [dp] {number} Integer, 0 to MAX inclusive. + * [rm] {number} Integer, 0 to 8 inclusive. + */ + P['round'] = function ( dp, rm ) { + + dp = dp == null || ( ( ( outOfRange = dp < 0 || dp > MAX ) || + parse(dp) != dp ) && + + // 'round() decimal places out of range: {dp}' + // 'round() decimal places not an integer: {dp}' + !ifExceptionsThrow( dp, 'decimal places', 'round' ) ) + ? 0 + : dp | 0; + + rm = rm == null || ( ( ( outOfRange = rm < 0 || rm > 8 ) || + + // Include '&& rm !== 0' because with Opera -0 == parseFloat(-0) is false. + parse(rm) != rm && rm !== 0 ) && + + // 'round() mode not an integer: {rm}' + // 'round() mode out of range: {rm}' + !ifExceptionsThrow( rm, 'mode', 'round' ) ) + ? ROUNDING_MODE + : rm | 0; + + return setMode( this, dp, rm ); + }; + + + /* + * sqrt(-n) = N + * sqrt( N) = N + * sqrt(-I) = N + * sqrt( I) = I + * sqrt( 0) = 0 + * sqrt(-0) = -0 + * + * Return a new BigNumber whose value is the square root of the value of + * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE. + */ + P['squareRoot'] = P['sqrt'] = function () { + var n, r, re, t, + x = this, + c = x['c'], + s = x['s'], + e = x['e'], + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE, + half = new BigNumber('0.5'); + + // Negative/NaN/Infinity/zero? + if ( s !== 1 || !c || !c[0] ) { + + return new BigNumber( !s || s < 0 && ( !c || c[0] ) + ? NaN + : c ? x : 1 / 0 ); + } + + // Initial estimate. + s = Math.sqrt( x['toS']() ); + ROUNDING_MODE = 1; + + /* + Math.sqrt underflow/overflow? + Pass x to Math.sqrt as integer, then adjust the exponent of the result. + */ + if ( s == 0 || s == 1 / 0 ) { + n = c.join(''); + + if ( !( n.length + e & 1 ) ) { + n += '0'; + } + r = new BigNumber( Math.sqrt(n) + '' ); + + // r may still not be finite. + if ( !r['c'] ) { + r['c'] = [1]; + } + r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 ); + } else { + r = new BigNumber( n = s.toString() ); + } + re = r['e']; + s = re + ( DECIMAL_PLACES += 4 ); + + if ( s < 3 ) { + s = 0; + } + e = s; + + // Newton-Raphson iteration. + for ( ; ; ) { + t = r; + r = half['times']( t['plus']( x['div'](t) ) ); + + if ( t['c'].slice( 0, s ).join('') === r['c'].slice( 0, s ).join('') ) { + c = r['c']; + + /* + The exponent of r may here be one less than the final result + exponent (re), e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust + s so the rounding digits are indexed correctly. + */ + s = s - ( n && r['e'] < re ); + + /* + The 4th rounding digit may be in error by -1 so if the 4 rounding + digits are 9999 or 4999 (i.e. approaching a rounding boundary) + continue the iteration. + */ + if ( c[s] == 9 && c[s - 1] == 9 && c[s - 2] == 9 && + ( c[s - 3] == 9 || n && c[s - 3] == 4 ) ) { + + /* + If 9999 on first run through, check to see if rounding up + gives the exact result as the nines may infinitely repeat. + */ + if ( n && c[s - 3] == 9 ) { + t = r['round']( dp, 0 ); + + if ( t['times'](t)['eq'](x) ) { + ROUNDING_MODE = rm; + DECIMAL_PLACES = dp; + + return t; + } + } + DECIMAL_PLACES += 4; + s += 4; + n = ''; + } else { + + /* + If the rounding digits are null, 0000 or 5000, check for an + exact result. If not, then there are further digits so + increment the 1st rounding digit to ensure correct rounding. + */ + if ( !c[e] && !c[e - 1] && !c[e - 2] && + ( !c[e - 3] || c[e - 3] == 5 ) ) { + + // Truncate to the first rounding digit. + if ( c.length > e - 2 ) { + c.length = e - 2; + } + + if ( !r['times'](r)['eq'](x) ) { + + while ( c.length < e - 3 ) { + c.push(0); + } + c[e - 3]++; + } + } + ROUNDING_MODE = rm; + rnd( r, DECIMAL_PLACES = dp, 10 ); + + return r; + } + } + } + }; + + + /* + * n * 0 = 0 + * n * N = N + * n * I = I + * 0 * n = 0 + * 0 * 0 = 0 + * 0 * N = N + * 0 * I = N + * N * n = N + * N * 0 = N + * N * N = N + * N * I = N + * I * n = I + * I * 0 = N + * I * N = N + * I * I = I + * + * Return a new BigNumber whose value is the value of this BigNumber times + * the value of BigNumber(y, b). + */ + P['times'] = function ( y, b ) { + var c, + x = this, + xc = x['c'], + yc = ( id = 11, y = new BigNumber( y, b ) )['c'], + i = x['e'], + j = y['e'], + a = x['s']; + + y['s'] = a == ( b = y['s'] ) ? 1 : -1; + + // Either NaN/Infinity/0? + if ( !i && ( !xc || !xc[0] ) || !j && ( !yc || !yc[0] ) ) { + + // Either NaN? + return new BigNumber( !a || !b || + + // x is 0 and y is Infinity or y is 0 and x is Infinity? + xc && !xc[0] && !yc || yc && !yc[0] && !xc + + // Return NaN. + ? NaN + + // Either Infinity? + : !xc || !yc + + // Return +-Infinity. + ? y['s'] / 0 + + // x or y is 0. Return +-0. + : y['s'] * 0 ); + } + y['e'] = i + j; + + if ( ( a = xc.length ) < ( b = yc.length ) ) { + c = xc, xc = yc, yc = c, j = a, a = b, b = j; + } + + for ( j = a + b, c = []; j--; c.push(0) ) { + } + + // Multiply! + for ( i = b - 1; i > -1; i-- ) { + + for ( b = 0, j = a + i; + j > i; + b = c[j] + yc[i] * xc[j - i - 1] + b, + c[j--] = b % 10 | 0, + b = b / 10 | 0 ) { + } + + if ( b ) { + c[j] = ( c[j] + b ) % 10; + } + } + + b && ++y['e']; + + // Remove any leading zero. + !c[0] && c.shift(); + + // Remove trailing zeros. + for ( j = c.length; !c[--j]; c.pop() ) { + } + + // No zero check needed as only x * 0 == 0 etc. + + // Overflow? + y['c'] = y['e'] > MAX_EXP + + // Infinity. + ? ( y['e'] = null ) + + // Underflow? + : y['e'] < MIN_EXP + + // Zero. + ? [ y['e'] = 0 ] + + // Neither. + : c; + + return y; + }; + + + /* + * Return a string representing the value of this BigNumber in exponential + * notation to dp fixed decimal places and rounded using ROUNDING_MODE if + * necessary. + * + * [dp] {number} Integer, 0 to MAX inclusive. + */ + P['toExponential'] = P['toE'] = function ( dp ) { + + return format( this, + ( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) || + + /* + * Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is + * false, despite -0 == parseFloat('-0') && 0 == -0 being true. + */ + parse(dp) != dp && dp !== 0 ) && + + // 'toE() decimal places not an integer: {dp}' + // 'toE() decimal places out of range: {dp}' + !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c'] + ? this['c'].length - 1 + : dp | 0, 1 ); + }; + + + /* + * Return a string representing the value of this BigNumber in normal + * notation to dp fixed decimal places and rounded using ROUNDING_MODE if + * necessary. + * + * Note: as with JavaScript's number type, (-0).toFixed(0) is '0', + * but e.g. (-0.00001).toFixed(0) is '-0'. + * + * [dp] {number} Integer, 0 to MAX inclusive. + */ + P['toFixed'] = P['toF'] = function ( dp ) { + var n, str, d, + x = this; + + if ( !( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) || + parse(dp) != dp && dp !== 0 ) && + + // 'toF() decimal places not an integer: {dp}' + // 'toF() decimal places out of range: {dp}' + !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) { + d = x['e'] + ( dp | 0 ); + } + + n = TO_EXP_NEG, dp = TO_EXP_POS; + TO_EXP_NEG = -( TO_EXP_POS = 1 / 0 ); + + // Note: str is initially undefined. + if ( d == str ) { + str = x['toS'](); + } else { + str = format( x, d ); + + // (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'. + // (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + if ( x['s'] < 0 && x['c'] ) { + + // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString. + if ( !x['c'][0] ) { + str = str.replace(/^-/, ''); + + // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign. + } else if ( str.indexOf('-') < 0 ) { + str = '-' + str; + } + } + } + TO_EXP_NEG = n, TO_EXP_POS = dp; + + return str; + }; + + + /* + * Return a string array representing the value of this BigNumber as a + * simple fraction with an integer numerator and an integer denominator. + * The denominator will be a positive non-zero value less than or equal to + * the specified maximum denominator. If a maximum denominator is not + * specified, the denominator will be the lowest value necessary to + * represent the number exactly. + * + * [maxD] {number|string|BigNumber} Integer >= 1 and < Infinity. + */ + P['toFraction'] = P['toFr'] = function ( maxD ) { + var q, frac, n0, d0, d2, n, e, + n1 = d0 = new BigNumber(ONE), + d1 = n0 = new BigNumber('0'), + x = this, + xc = x['c'], + exp = MAX_EXP, + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE, + d = new BigNumber(ONE); + + // NaN, Infinity. + if ( !xc ) { + return x['toS'](); + } + + e = d['e'] = xc.length - x['e'] - 1; + + // If max denominator is undefined or null... + if ( maxD == null || + + // or NaN... + ( !( id = 12, n = new BigNumber(maxD) )['s'] || + + // or less than 1, or Infinity... + ( outOfRange = n['cmp'](n1) < 0 || !n['c'] ) || + + // or not an integer... + ( ERRORS && n['e'] < n['c'].length - 1 ) ) && + + // 'toFr() max denominator not an integer: {maxD}' + // 'toFr() max denominator out of range: {maxD}' + !ifExceptionsThrow( maxD, 'max denominator', 'toFr' ) || + + // or greater than the maxD needed to specify the value exactly... + ( maxD = n )['cmp'](d) > 0 ) { + + // d is e.g. 10, 100, 1000, 10000... , n1 is 1. + maxD = e > 0 ? d : n1; + } + + MAX_EXP = 1 / 0; + n = new BigNumber( xc.join('') ); + + for ( DECIMAL_PLACES = 0, ROUNDING_MODE = 1; ; ) { + q = n['div'](d); + d2 = d0['plus']( q['times'](d1) ); + + if ( d2['cmp'](maxD) == 1 ) { + break; + } + + d0 = d1, d1 = d2; + + n1 = n0['plus']( q['times']( d2 = n1 ) ); + n0 = d2; + + d = n['minus']( q['times']( d2 = d ) ); + n = d2; + } + + d2 = maxD['minus'](d0)['div'](d1); + n0 = n0['plus']( d2['times'](n1) ); + d0 = d0['plus']( d2['times'](d1) ); + + n0['s'] = n1['s'] = x['s']; + + DECIMAL_PLACES = e * 2; + ROUNDING_MODE = rm; + + // Determine which fraction is closer to x, n0 / d0 or n1 / d1? + frac = n1['div'](d1)['minus'](x)['abs']()['cmp']( + n0['div'](d0)['minus'](x)['abs']() ) < 1 + ? [ n1['toS'](), d1['toS']() ] + : [ n0['toS'](), d0['toS']() ]; + + return MAX_EXP = exp, DECIMAL_PLACES = dp, frac; + }; + + + /* + * Return a string representing the value of this BigNumber to sd significant + * digits and rounded using ROUNDING_MODE if necessary. + * If sd is less than the number of digits necessary to represent the integer + * part of the value in normal notation, then use exponential notation. + * + * sd {number} Integer, 1 to MAX inclusive. + */ + P['toPrecision'] = P['toP'] = function ( sd ) { + + /* + * ERRORS true: Throw if sd not undefined, null or an integer in range. + * ERRORS false: Ignore sd if not a number or not in range. + * Truncate non-integers. + */ + return sd == null || ( ( ( outOfRange = sd < 1 || sd > MAX ) || + parse(sd) != sd ) && + + // 'toP() precision not an integer: {sd}' + // 'toP() precision out of range: {sd}' + !ifExceptionsThrow( sd, 'precision', 'toP' ) ) + ? this['toS']() + : format( this, --sd | 0, 2 ); + }; + + + /* + * Return a string representing the value of this BigNumber in base b, or + * base 10 if b is omitted. If a base is specified, including base 10, + * round according to DECIMAL_PLACES and ROUNDING_MODE. + * If a base is not specified, and this BigNumber has a positive exponent + * that is equal to or greater than TO_EXP_POS, or a negative exponent equal + * to or less than TO_EXP_NEG, return exponential notation. + * + * [b] {number} Integer, 2 to 64 inclusive. + */ + P['toString'] = P['toS'] = function ( b ) { + var u, str, strL, + x = this, + xe = x['e']; + + // Infinity or NaN? + if ( xe === null ) { + str = x['s'] ? 'Infinity' : 'NaN'; + + // Exponential format? + } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) { + return format( x, x['c'].length - 1, 1 ); + } else { + str = x['c'].join(''); + + // Negative exponent? + if ( xe < 0 ) { + + // Prepend zeros. + for ( ; ++xe; str = '0' + str ) { + } + str = '0.' + str; + + // Positive exponent? + } else if ( strL = str.length, xe > 0 ) { + + if ( ++xe > strL ) { + + // Append zeros. + for ( xe -= strL; xe-- ; str += '0' ) { + } + } else if ( xe < strL ) { + str = str.slice( 0, xe ) + '.' + str.slice(xe); + } + + // Exponent zero. + } else { + if ( u = str.charAt(0), strL > 1 ) { + str = u + '.' + str.slice(1); + + // Avoid '-0' + } else if ( u == '0' ) { + return u; + } + } + + if ( b != null ) { + + if ( !( outOfRange = !( b >= 2 && b < 65 ) ) && + ( b == (b | 0) || !ERRORS ) ) { + str = convert( str, b | 0, 10, x['s'] ); + + // Avoid '-0' + if ( str == '0' ) { + return str; + } + } else { + + // 'toS() base not an integer: {b}' + // 'toS() base out of range: {b}' + ifExceptionsThrow( b, 'base', 'toS' ); + } + } + + } + + return x['s'] < 0 ? '-' + str : str; + }; + + + /* + * Return the value of this BigNumber converted to a number primitive. + * + */ + P['toNumber'] = P['toN'] = function () { + var x = this; + + // Ensure zero has correct sign. + return +x || ( x['s'] ? 0 * x['s'] : NaN ); + }; + + + /* + * Return as toString, but do not accept a base argument. + */ + P['valueOf'] = function () { + return this['toS'](); + }; + + + // Add aliases for BigDecimal methods. + //P['add'] = P['plus']; + //P['subtract'] = P['minus']; + //P['multiply'] = P['times']; + //P['divide'] = P['div']; + //P['remainder'] = P['mod']; + //P['compareTo'] = P['cmp']; + //P['negate'] = P['neg']; + + + // EXPORT + + + // Node and other CommonJS-like environments that support module.exports. + if ( typeof module !== 'undefined' && module.exports ) { + module.exports = BigNumber; + + //AMD. + } else if ( typeof define == 'function' && define.amd ) { + define( function () { + return BigNumber; + }); + + //Browser. + } else { + global['BigNumber'] = BigNumber; + } + +})( this ); diff --git a/node_modules/mysql/node_modules/bignumber.js/bignumber.min.js b/node_modules/mysql/node_modules/bignumber.js/bignumber.min.js new file mode 100644 index 0000000..c6e985f --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/bignumber.min.js @@ -0,0 +1,2 @@ +/*! bignumber.js v1.4.1 https://github.com/MikeMcl/bignumber.js/LICENCE */ +(function(n){"use strict";function t(n,i){var c,l,a,b,w,p,s=this;if(!(s instanceof t))return new t(n,i);if(n instanceof t)if(u=0,i!==c)n+="";else{s.s=n.s;s.e=n.e;s.c=(n=n.c)?n.slice():n;return}if(typeof n!="string"&&(n=(a=typeof n=="number"||Object.prototype.toString.call(n)=="[object Number]")&&n===0&&1/n<0?"-0":n+""),p=n,i===c&&g.test(n))s.s=n.charAt(0)=="-"?(n=n.slice(1),-1):1;else{if(i==10)return k(n,e,r);if(n=rt.call(n).replace(/^\+(?!-)/,""),s.s=n.charAt(0)=="-"?(n=n.replace(/^-(?!-)/,""),-1):1,i!=null?i!=(i|0)&&y||(o=!(i>=2&&i<65))?(f(i,2),w=g.test(n)):(b="["+d.slice(0,i=i|0)+"]+",n=n.replace(/\.$/,"").replace(/^\./,"0."),(w=new RegExp("^"+b+"(?:\\."+b+")?$",i<37?"i":"").test(n))?(a&&(n.replace(/^0\.0*|\./,"").length>15&&f(p,0),a=!a),n=tt(n,10,i,s.s)):n!="Infinity"&&n!="NaN"&&(f(p,1,i),n="NaN")):w=g.test(n),!w){s.c=s.e=null;n!="Infinity"&&(n!="NaN"&&f(p,3),s.s=null);u=0;return}}for((c=n.indexOf("."))>-1&&(n=n.replace(".","")),(l=n.search(/e/i))>0?(c<0&&(c=l),c+=+n.slice(l+1),n=n.substring(0,l)):c<0&&(c=n.length),l=0;n.charAt(l)=="0";l++);if(i=n.length,a&&i>15&&n.slice(l).length>15&&f(p,0),u=0,(c-=l+1)>h)s.c=s.e=null;else if(l==i||ci-1&&(f[u+1]==null&&(f[u+1]=0),f[u+1]+=f[u]/i^0,f[u]%=i)}return f.reverse()}function o(n){for(var t=0,r=n.length,i="";t-1)if(e=n.length-e-1,c=h(new t(r).pow(e).toF(),10),f=n.split("."),l=h(f[1]),f=h(f[0]),a=it(l,c,l.length-c.length,u,i,f[f.length-1]&1),s=a.c,e=a.e){for(;++e;s.unshift(0));n=o(f)+"."+o(s)}else s[0]?f[e=f.length-1]c?1:-1;else for(a=-1,w=0;++as[a]?1:-1;break}if(w<0){for(d=c==y?i:rt;c;){if(s[--c]it&&b(l,e,f,o,s[0]!=null),l.e>h?l.c=l.e=null:l.e++i&&b(n,u,10),u=f[0]==0?u+1:r?i:n.e+u+1;f.length1?(f.splice(1,0,"."),f.join("")):f[0])+(u<0?"e":"e+")+u:n.toS()}function b(n,t,i,u,f){var e=n.c,s=n.s<0,c=i/2,o=n.e+t+1,h=e[o],l=f||o<0||e[o+1]!=null;if(f=r<4?(h!=null||l)&&(r==0||r==2&&!s||r==3&&s):h>c||h==c&&(r==4||l||r==6&&(e[o-1]&1||!t&&u)||r==7&&!s||r==8&&s),o<1||!e[0])return e.length=0,e.push(0),f?(e[0]=1,n.e=-t):n.e=0,n;if(e.length=o--,f)for(--i;++e[o]>i;)e[o]=0,o--||(++n.e,e.unshift(1));for(o=e.length;!e[--o];e.pop());return n}function k(n,i,u){var f=r;return r=u,n=new t(n),n.c&&b(n,i,10),r=f,n}var s=1e9,nt=1e6,e=20,r=4,c=-7,a=21,v=-s,h=s,y=!0,l=parseInt,i=t.prototype,d="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",o,u=0,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,rt=String.prototype.trim||function(){return this.replace(/^\s+|\s+$/g,"")},p=t(1);t.ROUND_UP=0;t.ROUND_DOWN=1;t.ROUND_CEIL=2;t.ROUND_FLOOR=3;t.ROUND_HALF_UP=4;t.ROUND_HALF_DOWN=5;t.ROUND_HALF_EVEN=6;t.ROUND_HALF_CEIL=7;t.ROUND_HALF_FLOOR=8;t.config=function(){var n,t,g=0,p={},d=arguments,k=d[0],w="config",i=function(n,t,i){return!((o=ni)||l(n)!=n&&n!==0)},b=k&&typeof k=="object"?function(){if(k.hasOwnProperty(t))return(n=k[t])!=null}:function(){if(d.length>g)return(n=d[g++])!=null};return b(t="DECIMAL_PLACES")&&(i(n,0,s)?e=n|0:f(n,t,w)),p[t]=e,b(t="ROUNDING_MODE")&&(i(n,0,8)?r=n|0:f(n,t,w)),p[t]=r,b(t="EXPONENTIAL_AT")&&(i(n,-s,s)?c=-(a=~~(n<0?-n:+n)):!o&&n&&i(n[0],-s,0)&&i(n[1],0,s)?(c=~~n[0],a=~~n[1]):f(n,t,w,1)),p[t]=[c,a],b(t="RANGE")&&(i(n,-s,s)&&~~n?v=-(h=~~(n<0?-n:+n)):!o&&n&&i(n[0],-s,-1)&&i(n[1],1,s)?(v=~~n[0],h=~~n[1]):f(n,t,w,1,1)),p[t]=[v,h],b(t="ERRORS")&&(n===!!n||n===1||n===0?l=(o=u=0,y=!!n)?parseInt:parseFloat:f(n,t,w,0,0,1)),p[t]=y,p};i.abs=i.absoluteValue=function(){var n=new t(this);return n.s<0&&(n.s=1),n};i.ceil=function(){return k(this,0,2)};i.comparedTo=i.cmp=function(n,i){var f,l=this,e=l.c,o=(u=-u,n=new t(n,i)).c,r=l.s,c=n.s,s=l.e,h=n.e;if(!r||!c)return null;if(f=e&&!e[0],i=o&&!o[0],f||i)return f?i?0:-c:r;if(r!=c)return r;if(f=r<0,i=s==h,!e||!o)return i?0:!e^f?1:-1;if(!i)return s>h^f?1:-1;for(r=-1,c=(s=e.length)<(h=o.length)?s:h;++ro[r]^f?1:-1;return s==h?0:s>h^f?1:-1};i.dividedBy=i.div=function(n,i){var r=this.c,o=this.e,s=this.s,f=(u=2,n=new t(n,i)).c,h=n.e,c=n.s,e=s==c?1:-1;return!o&&(!r||!r[0])||!h&&(!f||!f[0])?new t(!s||!c||(r?f&&r[0]==f[0]:!f)?NaN:r&&r[0]==0||!f?e*0:e/0):it(r,f,o-h,e,10)};i.equals=i.eq=function(n,t){return u=3,this.cmp(n,t)===0};i.floor=function(){return k(this,0,3)};i.greaterThan=i.gt=function(n,t){return u=4,this.cmp(n,t)>0};i.greaterThanOrEqualTo=i.gte=function(n,t){return u=5,(t=this.cmp(n,t))==1||t===0};i.isFinite=i.isF=function(){return!!this.c};i.isNaN=function(){return!this.s};i.isNegative=i.isNeg=function(){return this.s<0};i.isZero=i.isZ=function(){return!!this.c&&this.c[0]==0};i.lessThan=i.lt=function(n,t){return u=6,this.cmp(n,t)<0};i.lessThanOrEqualTo=i.lte=function(n,t){return u=7,(t=this.cmp(n,t))==-1||t===0};i.minus=function(n,i){var h,l,a,y,c=this,o=c.s;if(i=(u=8,n=new t(n,i)).s,!o||!i)return new t(NaN);if(o!=i)return n.s=-i,c.plus(n);var f=c.c,p=c.e,e=n.c,s=n.e;if(!p||!s){if(!f||!e)return f?(n.s=-i,n):new t(e?c:NaN);if(!f[0]||!e[0])return e[0]?(n.s=-i,n):new t(f[0]?c:r==3?-0:0)}if(f=f.slice(),o=p-s){for(h=(y=o<0)?(o=-o,f):(s=p,e),h.reverse(),i=o;i--;h.push(0));h.reverse()}else for(a=((y=f.length0)for(;i--;f[a++]=0);for(i=e.length;i>o;){if(f[--i]0?(s=l,e):(f=-f,r),o.reverse();f--;o.push(0));o.reverse()}for(r.length-e.length<0&&(o=e,e=r,r=o),f=e.length,i=0;f;i=(r[--f]=r[f]+e[f]+i)/10^0,r[f]%=10);for(i&&(r.unshift(i),++s>h&&(r=s=null)),f=r.length;r[--f]==0;r.pop());return n.c=r,n.e=s,n};i.toPower=i.pow=function(n){var i=n*0==0?n|0:n,r=new t(this),u=new t(p);if(((o=n<-nt||n>nt)&&(i=n/0)||l(n)!=n&&n!==0&&!(i=NaN))&&!f(n,"exponent","pow")||!i)return new t(Math.pow(r.toS(),i));for(i=i<0?-i:i;;){if(i&1&&(u=u.times(r)),i>>=1,!i)break;r=r.times(r)}return n<0?p.div(u):u};i.round=function(n,t){return n=n==null||((o=n<0||n>s)||l(n)!=n)&&!f(n,"decimal places","round")?0:n|0,t=t==null||((o=t<0||t>8)||l(t)!=t&&t!==0)&&!f(t,"mode","round")?r:t|0,k(this,n,t)};i.squareRoot=i.sqrt=function(){var o,u,c,s,h=this,n=h.c,i=h.s,f=h.e,l=e,a=r,v=new t("0.5");if(i!==1||!n||!n[0])return new t(!i||i<0&&(!n||n[0])?NaN:n?h:1/0);for(i=Math.sqrt(h.toS()),r=1,i==0||i==1/0?(o=n.join(""),o.length+f&1||(o+="0"),u=new t(Math.sqrt(o)+""),u.c||(u.c=[1]),u.e=((f+1)/2|0)-(f<0||f&1)):u=new t(o=i.toString()),c=u.e,i=c+(e+=4),i<3&&(i=0),f=i;;)if(s=u,u=v.times(s.plus(h.div(s))),s.c.slice(0,i).join("")===u.c.slice(0,i).join(""))if(n=u.c,i=i-(o&&u.ef-2&&(n.length=f-2),!u.times(u).eq(h))){while(n.length-1;s--){for(i=0,r=c+s;r>s;i=f[r]+o[s]*e[r-s-1]+i,f[r--]=i%10|0,i=i/10|0);i&&(f[r]=(f[r]+i)%10)}for(i&&++n.e,f[0]||f.shift(),r=f.length;!f[--r];f.pop());return n.c=n.e>h?n.e=null:n.es)||l(n)!=n&&n!==0)&&!f(n,"decimal places","toE"))&&this.c?this.c.length-1:n|0,1)};i.toFixed=i.toF=function(n){var u,t,r,i=this;return n==null||((o=n<0||n>s)||l(n)!=n&&n!==0)&&!f(n,"decimal places","toF")||(r=i.e+(n|0)),u=c,n=a,c=-(a=1/0),r==t?t=i.toS():(t=w(i,r),i.s<0&&i.c&&(i.c[0]?t.indexOf("-")<0&&(t="-"+t):t=t.replace(/^-/,""))),c=u,a=n,t};i.toFraction=i.toFr=function(n){var k,nt,c,l,i,s,d,a=l=new t(p),v=c=new t("0"),w=this,g=w.c,tt=h,it=e,rt=r,b=new t(p);if(!g)return w.toS();for(d=b.e=g.length-w.e-1,(n==null||(!(u=12,s=new t(n)).s||(o=s.cmp(a)<0||!s.c)||y&&s.e0)&&(n=d>0?b:a),h=1/0,s=new t(g.join("")),e=0,r=1;;){if(k=s.div(b),i=l.plus(k.times(v)),i.cmp(n)==1)break;l=v;v=i;a=c.plus(k.times(i=a));c=i;b=s.minus(k.times(i=b));s=i}return i=n.minus(l).div(v),c=c.plus(i.times(a)),l=l.plus(i.times(v)),c.s=a.s=w.s,e=d*2,r=rt,nt=a.div(v).minus(w).abs().cmp(c.div(l).minus(w).abs())<1?[a.toS(),v.toS()]:[c.toS(),l.toS()],h=tt,e=it,nt};i.toPrecision=i.toP=function(n){return n==null||((o=n<1||n>s)||l(n)!=n)&&!f(n,"precision","toP")?this.toS():w(this,--n|0,2)};i.toString=i.toS=function(n){var u,t,e,r=this,i=r.e;if(i===null)t=r.s?"Infinity":"NaN";else{if(n===u&&(i<=c||i>=a))return w(r,r.c.length-1,1);if(t=r.c.join(""),i<0){for(;++i;t="0"+t);t="0."+t}else if(e=t.length,i>0)if(++i>e)for(i-=e;i--;t+="0");else i1)t=u+"."+t.slice(1);else if(u=="0")return u;if(n!=null)if((o=!(n>=2&&n<65))||n!=(n|0)&&y)f(n,"base","toS");else if(t=tt(t,n|0,10,r.s),t=="0")return t}return r.s<0?"-"+t:t};i.toNumber=i.toN=function(){var n=this;return+n||(n.s?0*n.s:NaN)};i.valueOf=function(){return this.toS()};typeof module!="undefined"&&module.exports?module.exports=t:typeof define=="function"&&define.amd?define(function(){return t}):n.BigNumber=t})(this) \ No newline at end of file diff --git a/node_modules/mysql/node_modules/bignumber.js/doc/API.html b/node_modules/mysql/node_modules/bignumber.js/doc/API.html new file mode 100644 index 0000000..da221ac --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/doc/API.html @@ -0,0 +1,1731 @@ + + + + + + + bignumber.js API + + + + + + +
+ +

bignumber.js

+ +

A JavaScript library for arbitrary-precision arithmetic.

+ +

+ Hosted on GitHub. +

+ + +

API

+ +

+ In all examples below, var and semicolons are not shown, and + if a commented-out value is in quotes it means toString has + been called on the preceding expression. +

+ + + +

CONSTRUCTOR

+ +
+ BigNumberBigNumber(value [, base]) ⇒ + BigNumber + +
+
+
value
+
+ number|string|BigNumber : See RANGE for + range. +
+
+ A numeric value. +
+
+ Legitimate values include ±0, + ±Infinity and NaN. +
+
+ Values of type number with more than 15 significant digits are + considered invalid as calling toString or + valueOf on such numbers may not result in the intended + value. +
+
+ There is no limit to the number of digits of a value of type + string (other than that of JavaScript's maximum array size). +
+
+ Decimal string values may be in exponential, as well as normal + (non-exponential) notation. Non-decimal values must be in normal + notation. +
+
+ String values in hexadecimal literal form, e.g. '0xff', are + invalid, and string values in octal literal form will be interpreted as + decimals, e.g. '011' is interpreted as 11, not 9. +
+
Values in any base may have fraction digits.
+
+ For bases from 10 to 36, lower and/or upper case letters can be used to + represent values from 10 to 35. For bases above 36, a-z + represents values from 10 to 35, A-Z from 36 to 61, and + $ and _ represent 62 and 63 respectively + (this can be changed by ediiting the DIGITS variable near the top of the + source file). +
+
+
+
base
+
+ number : integer, 2 to 64 inclusive +
+
The base of value.
+
If base is omitted, or is null or undefined, + base 10 is assumed.
+
+

Returns a new instance of a BigNumber object.

+

+ If a base is specified, the value is rounded according to + the current DECIMAL_PLACES and + ROUNDING_MODE settings. + Usefully, this means the decimal places of a decimal value + passed to the constructor can be limited by explicitly specifying base 10. +

+

+ See Errors for the treatment of an invalid + value or base. +

+
+x = new BigNumber(9)                       // '9'
+y = new BigNumber(x)                       // '9'
+BigNumber(435.345)                         // 'new' is optional
+new BigNumber('5032485723458348569331745.33434346346912144534543')
+new BigNumber('4.321e+4')                  // '43210'
+new BigNumber('-735.0918e-430')            // '-7.350918e-428'
+new BigNumber(Infinity)                    // 'Infinity'
+new BigNumber(NaN)                         // 'NaN'
+new BigNumber('.5')                        // '0.5'
+new BigNumber('+2')                        // '2'
+new BigNumber(-10110100.1, 2)              // '-180.5'
+new BigNumber('123412421.234324', 5)       // '607236.557696'
+new BigNumber('ff.8', 16)                  // '255.5'
+
+new BigNumber(9, 2)
+// Throws 'not a base 2 number' if ERRORS is true, otherwise 'NaN'
+
+new BigNumber(96517860459076817.4395)
+// Throws 'number type has more than 15 significant digits'
+// if ERRORS is true, otherwise '96517860459076820'
+
+new BigNumber('blurgh')
+// Throws 'not a number' if ERRORS is true, otherwise 'NaN'
+
+BigNumber.config({DECIMAL_PLACES : 5})
+new BigNumber(1.23456789)                  // '1.23456789'
+new BigNumber(1.23456789, 10)              // '1.23457'
+ + +

Methods

+

+ The BigNumber constructor has one added method, + config, which configures the library-wide settings for + arithmetic, formatting and errors. +

+ +
+ configconfig([settings]) ⇒ object +
+ + Note: the settings can also be supplied as an argument list, + see below. + +
+
settings
+
object
+ +
+ An object that contains some or all of the following properties: +
+ + + +
DECIMAL_PLACES
+
+ number : integer, 0 to 1e+9 + inclusive
+ Default value: 20 +
+
+ The maximum number of decimal places of the results of + division, square root and base conversion operations, and power + operations with negative exponents.
+ I.e. aside from the base conversion which may be involved with any + method that accepts a base argument, the value is only relevant to + the dividedBy, squareRoot and + toPower methods. +
+
+
BigNumber.config({ DECIMAL_PLACES : 5 })
+BigNumber.config(5)    // equivalent
+
+ + + +
ROUNDING_MODE
+
+ number : integer, 0 to 8 + inclusive
+ Default value: 4 + (ROUND_HALF_UP) +
+
+ The rounding mode used in the above operations and by + round, + toExponential, + toFixed and + toPrecision. +
+
+ The modes are available as enumerated properties of the BigNumber + constructor. +
+
+
BigNumber.config({ ROUNDING_MODE : 0 })
+BigNumber.config(null, BigNumber.ROUND_UP)    // equivalent
+
+ + + +
EXPONENTIAL_AT
+
+ number : integer, magnitude 0 to + 1e+9 inclusive, or
+ number[] : [ integer -1e+9 to 0 inclusive, integer 0 to 1e+9 + inclusive ]
+ Default value: [-7, 20] +
+
+ The exponent value(s) at which toString returns + exponential notation. +
+
+ If a single number is assigned, the value is the exponent magnitude. +
+ If an array of two numbers is assigned then the first number is the + negative exponent value at and beneath which exponential notation is + used, and the second number is the positive exponent value at and + above which the same. +
+
+ For example, to emulate JavaScript numbers in terms of the exponent + values at which they begin to use exponential notation, use + [-7, 20]. +
+
+
BigNumber.config({ EXPONENTIAL_AT : 2 })
+new BigNumber(12.3)         // '12.3'        e is only 1
+new BigNumber(123)          // '1.23e+2'
+new BigNumber(0.123)        // '0.123'       e is only -1
+new BigNumber(0.0123)       // '1.23e-2'
+
+BigNumber.config({ EXPONENTIAL_AT : [-7, 20] })
+new BigNumber(123456789)    // '123456789'   e is only 8
+new BigNumber(0.000000123)  // '1.23e-7'
+
+// Almost never return exponential notation:
+BigNumber.config({ EXPONENTIAL_AT : 1e+9 })
+
+// Always return exponential notation:
+BigNumber.config({ EXPONENTIAL_AT : 0 })
+
+
+ Regardless of the value of EXPONENTIAL_AT, the + toFixed method will always return a value in + normal notation and the toExponential method will + always return a value in exponential form. +
+
+ Calling toString with a base argument, e.g. + toString(10), will also always return normal notation. +
+ + + +
RANGE
+
+ number : integer, magnitude 1 to + 1e+9 inclusive, or
+ number[] : [ integer -1e+9 to -1 inclusive, integer 1 to 1e+9 + inclusive ]
+ Default value: [-1e+9, 1e+9] +
+
+ The exponent value(s) beyond which overflow to Infinity and + underflow to zero occurs. +
+
+ If a single number is assigned, it is the maximum exponent + magnitude: values wth a positive exponent of greater magnitude + become Infinity and those with a negative exponent of + greater magnitude become zero. +
+ If an array of two numbers is assigned then the first number is the + negative exponent limit and the second number is the positive + exponent limit. +
+
+ For example, to emulate JavaScript numbers in terms of the exponent + values at which they become zero and Infinity, use + [-324, 308]. +
+
+
BigNumber.config({ RANGE : 500 })
+BigNumber.config().RANGE     // [ -500, 500 ]
+new BigNumber('9.999e499')   // '9.999e+499'
+new BigNumber('1e500')       // 'Infinity'
+new BigNumber('1e-499')      // '1e-499'
+new BigNumber('1e-500')      // '0'
+
+BigNumber.config({ RANGE : [-3, 4] })
+new BigNumber(99999)         // '99999'      e is only 4
+new BigNumber(100000)        // 'Infinity'   e is 5
+new BigNumber(0.001)         // '0.01'       e is only -3
+new BigNumber(0.0001)        // '0'          e is -4
+
+
+ The largest possible magnitude of a finite BigNumber is
+ 9.999...e+1000000000
+ The smallest possible magnitude of a non-zero BigNumber is
+ 1e-1000000000 +
+ + + +
ERRORS
+
+ boolean/number : true, false, 1 or 0
+ Default value: true +
+
+ The value that determines whether BigNumber Errors are thrown.
+ If ERRORS is false, this library will not throw errors. +
+
+ See Errors. +
+
+
BigNumber.config({ ERRORS : false })
+
+
+
+
+

+
Returns an object with the above properties and their current + values. +

+

+ If the value to be assigned to any of the above properties is + null or undefined it is ignored. See + Errors for the treatment of invalid values. +

+
+BigNumber.config({
+    DECIMAL_PLACES : 40,
+    ROUNDING_MODE : BigNumber.ROUND_HALF_CEIL,
+    EXPONENTIAL_AT : [-10, 20],
+    RANGE : [-500, 500],
+    ERRORS : true
+});
+
+// Alternatively but equivalently:
+BigNumber.config( 40, 7, [-10, 20], 500, 1 )
+
+obj = BigNumber.config();
+obj.ERRORS       // true
+obj.RANGE        // [-500, 500]
+ + + +

Properties

+

+ The library's enumerated rounding modes are stored as properties of the + constructor.
+ They are not referenced internally by the library itself. +

+

+ Rounding modes 0 to 6 (inclusive) are the same as those of Java's + BigDecimal class. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyValueDescription
ROUND_UP0Rounds away from zero
ROUND_DOWN1Rounds towards zero
ROUND_CEIL2Rounds towards Infinity
ROUND_FLOOR3Rounds towards -Infinity
ROUND_HALF_UP4 + Rounds towards nearest neighbour.
+ If equidistant, rounds away from zero +
ROUND_HALF_DOWN5 + Rounds towards nearest neighbour.
+ If equidistant, rounds towards zero +
ROUND_HALF_EVEN6 + Rounds towards nearest neighbour.
+ If equidistant, rounds towards even neighbour +
ROUND_HALF_CEIL7 + Rounds towards nearest neighbour.
+ If equidistant, rounds towards Infinity +
ROUND_HALF_FLOOR8 + Rounds towards nearest neighbour.
+ If equidistant, rounds towards -Infinity +
+
+BigNumber.config({ ROUNDING_MODE : BigNumber.ROUND_CEIL })
+BigNumber.config({ ROUNDING_MODE : 2 })     // equivalent
+ + +

INSTANCE

+ +

Methods

+

+ The methods inherited by a BigNumber instance from its constructor's + prototype object. +

+

+ A BigNumber is immutable in the sense that it is not changed by its + methods. +

+

+ The treatment of ±0, ±Infinity and + NaN is consistent with how JavaScript treats these values. +

+

+ Method names over 5 letters in length have a shorter alias (except + valueOf).
+ Internally, the library always uses the shorter method names. +

+ + + +
+ absoluteValue.abs() ⇒ BigNumber +
+

+ Returns a BigNumber whose value is the absolute value, i.e. the magnitude, + of this BigNumber. +

+
+x = new BigNumber(-0.8)
+y = x.absoluteValue()         // '0.8'
+z = y.abs()                   // '0.8'
+ + + +
+ ceil.ceil() ⇒ BigNumber +
+

+ Returns a BigNumber whose value is the value of this BigNumber rounded to + a whole number in the direction of Infinity. +

+
+x = new BigNumber(1.3)
+x.ceil()                      // '2'
+y = new BigNumber(-1.8)
+y.ceil()                      // '-1'
+ + + +
+ floor.floor() ⇒ + BigNumber +
+

+ Returns a BigNumber whose value is the value of this BigNumber rounded to + a whole number in the direction of -Infinity. +

+
+x = new BigNumber(1.8)
+x.floor()                     // '1'
+y = new BigNumber(-1.3)
+y.floor()                     // '-2'
+ + + +
+ negated.neg() ⇒ BigNumber +
+

+ Returns a BigNumber whose value is the value of this BigNumber negated, + i.e. multiplied by -1. +

+
+x = new BigNumber(1.8)
+x.negated()                   // '-1.8'
+y = new BigNumber(-1.3)
+y.neg()                       // '1.3'
+ + + +
+ squareRoot.sqrt() ⇒ BigNumber +
+

+ Returns a BigNumber whose value is the square root of this BigNumber, + correctly rounded according to the current + DECIMAL_PLACES and + ROUNDING_MODE settings. +

+
+x = new BigNumber(16)
+x.squareRoot()                // '4'
+y = new BigNumber(3)
+y.sqrt()                      // '1.73205080756887729353'
+ + + +
+ isFinite.isF() ⇒ boolean +
+

+ Returns true if the value of this BigNumber is a finite + number, otherwise returns false.
+ The only possible non-finite values of a BigNumber are NaN, Infinity and + -Infinity. +

+
+x = new BigNumber(1)
+x.isFinite()                  // true
+y = new BigNumber(Infinity)
+y.isF()                       // false
+

+ Note: The native method isFinite() can be used if + n <= Number.MAX_VALUE. +

+ + + +
+ isNaN.isNaN() ⇒ boolean +
+

+ Returns true if the value of this BigNumber is NaN, otherwise + returns false.
+

+
+x = new BigNumber(NaN)
+x.isNaN()                     // true
+y = new BigNumber('Infinity')
+y.isNaN()                     // false
+

+ Note: The native method isNaN() can also be used. +

+ + + +
+ isNegative.isNeg() ⇒ boolean +
+

+ Returns true if the value of this BigNumber is negative, + otherwise returns false.
+

+
+x = new BigNumber(-0)
+x.isNegative()                // true
+y = new BigNumber(2)
+y.isNeg                       // false
+

+ Note: n < 0 can be used if + n <= -Number.MIN_VALUE. +

+ + + +
+ isZero.isZ() ⇒ boolean +
+

+ Returns true if the value of this BigNumber is zero or minus + zero, otherwise returns false.
+

+
+x = new BigNumber(-0)
+x.isZero() && x.isNeg()        // true
+y = new BigNumber(Infinity)
+y.isZ()                        // false
+

+ Note: n == 0 can be used if + n >= Number.MIN_VALUE. +

+ + + +
+ comparedTo.cmp(n [, base]) ⇒ number +
+

+ n : number|string|BigNumber
+ base : number
+ + See constructor for further parameter details. + +

+ + + + + + + + + + + + + + + + + + + + + +
Returns 
1 + If the value of this BigNumber is greater than the value of n +
-1 + If the value of this BigNumber is less than the value of n +
0If this BigNumber and n have the same value
null + if the value of either this BigNumber or n is + NaN +
+
+x = new BigNumber(Infinity)
+y = new BigNumber(5)
+x.comparedTo(y)                // 1
+x.comparedTo(x.minus(1))       // 0
+y.cmp(NaN)                     // null
+y.cmp('110', 2)                // -1
+ + + +
+ dividedBy.div(n [, base]) ⇒ + BigNumber +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns a BigNumber whose value is the value of this BigNumber divided by + n, rounded according to the current + DECIMAL_PLACES and + ROUNDING_MODE settings. +

+
+x = new BigNumber(355)
+y = new BigNumber(113)
+x.dividedBy(y)             // '3.14159292035398230088'
+x.div(5)                   // '71'
+x.div(47, 16)              // '5'
+ + + +
+ minus.minus(n [, base]) ⇒ BigNumber +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns a BigNumber whose value is the value of this BigNumber minus + n. +

+
+0.3 - 0.1                  // 0.19999999999999998
+x = new BigNumber(0.3)
+x.minus(0.1)               // '0.2'
+x.minus(0.6, 20)           // '0'
+ + + +
+ modulo.mod(n [, base]) ⇒ BigNumber +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns a BigNumber whose value is the value of this BigNumber modulo + n, i.e. the integer remainder of dividing this BigNumber by + n. +

+

+ The result will have the same sign as this BigNumber, and it will match + that of JavaScript's % operator (within the limits of its precision) and + BigDecimal's remainder method. +

+
+1 % 0.9                    // 0.09999999999999998
+x = new BigNumber(1)
+x.modulo(0.9)              // '0.1'
+y = new BigNumber(33)
+y.mod('a', 33)             // '3'
+ + + +
+ plus.plus(n [, base]) ⇒ BigNumber +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns a BigNumber whose value is the value of this BigNumber plus + n. +

+
+0.1 + 0.2                       // 0.30000000000000004
+x = new BigNumber(0.1)
+y = x.plus(0.2)                 // '0.3'
+BigNumber(0.7).plus(x).plus(y)  // '1'
+x.plus('0.1', 8)                // '0.225'
+ + + +
+ times.times(n [, base]) ⇒ BigNumber +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns a BigNumber whose value is the value of this BigNumber times + n. +

+
+0.6 * 3                         // 1.7999999999999998
+x = new BigNumber(0.6)
+y = x.times(3)                  // '1.8'
+BigNumber('7e+500').times(y)    // '1.26e+501'
+x.times('-a', 16)               // '-6'
+ + + +
+ toPower.pow(exp) ⇒ BigNumber +
+

+ exp : number : integer, -1e+6 to 1e+6 inclusive +

+

+ Returns a BigNumber whose value is the value of this BigNumber raised to + the power exp. +

+

+ If exp is negative the result is rounded according to the + current DECIMAL_PLACES and + ROUNDING_MODE settings. +

+

+ If exp is not an integer or is out of range: +

+

+ If ERRORS is true a BigNumber + Error is thrown,
+ else if exp is greater than 1e+6, it is interpreted as + Infinity;
+ else if exp is less than -1e+6, it is interpreted as + -Infinity;
+ else if exp is otherwise a number, it is truncated to an + integer;
+ else it is interpreted as NaN. +

+

+ Note: High value exponents may cause this method to be slow to return. +

+
+Math.pow(0.7, 2)             // 0.48999999999999994
+x = new BigNumber(0.7)
+x.toPower(2)                 // '0.49'
+BigNumber(3).pow(-2)         // '0.11111111111111111111'
+
+new BigNumber(123.456).toPower(1000).toString().length     // 5099
+new BigNumber(2).pow(1e+6)   // Time taken (Node.js): 9 minutes 34 secs.
+ + + +
+ equals.eq(n [, base]) ⇒ boolean +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns true if the value of this BigNumber equals the value + of n, otherwise returns false.
+ As with JavaScript, NaN does not equal NaN. +
Note : This method uses the comparedTo method + internally. +

+
+0 === 1e-324                    // true
+x = new BigNumber(0)
+x.equals('1e-324')              // false
+BigNumber(-0).eq(x)             // true  ( -0 === 0 )
+BigNumber(255).eq('ff', 16)     // true
+
+y = new BigNumber(NaN)
+y.equals(NaN)                   // false
+ + + +
+ greaterThan.gt(n [, base]) ⇒ + boolean +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns true if the value of this BigNumber is greater than + the value of n, otherwise returns false.
+ Note : This method uses the comparedTo method internally. +

+
+0.1 > (0.3 - 0.2)                           // true
+x = new BigNumber(0.1)
+x.greaterThan(BigNumber(0.3).minus(0.2))    // false
+BigNumber(0).gt(x)                          // false
+BigNumber(11, 3).gt(11.1, 2)                // true
+ + + +
+ greaterThanOrEqualTo.gte(n [, base]) ⇒ + boolean +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns true if the value of this BigNumber is greater than + or equal to the value of n, otherwise returns + false.
+ Note : This method uses the comparedTo method internally. +

+
+(0.3 - 0.2) >= 0.1                   // false
+x = new BigNumber(0.3).minus(0.2)
+x.greaterThanOrEqualTo(0.1)          // true
+BigNumber(1).gte(x)                  // true
+BigNumber(10, 18).gte('i', 36)       // true
+ + + +
+ lessThan.lt(n [, base]) ⇒ boolean +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns true if the value of this BigNumber is less than the + value of n, otherwise returns false.
+ Note : This method uses the comparedTo method internally. +

+
+(0.3 - 0.2) < 0.1                    // true
+x = new BigNumber(0.3).minus(0.2)
+x.lessThan(0.1)                      // false
+BigNumber(0).lt(x)                   // true
+BigNumber(11.1, 2).lt(11, 3)         // true
+ + + +
+ lessThanOrEqualTo.lte(n [, base]) ⇒ + boolean +
+

+ n : number|string|BigNumber
+ base : number
+ See constructor for further parameter details. + +

+

+ Returns true if the value of this BigNumber is less than or + equal to the value of n, otherwise returns + false.
+ Note : This method uses the comparedTo method internally. +

+
+0.1 <= (0.3 - 0.2)                                // false
+x = new BigNumber(0.1)
+x.lessThanOrEqualTo(BigNumber(0.3).minus(0.2))    // true
+BigNumber(-1).lte(x)                              // true
+BigNumber(10, 18).lte('i', 36)                    // true
+ + + +
+ toExponential.toE([decimal_places]) ⇒ + string +
+

+ decimal_places : number : integer, 0 to 1e+9 inclusive +

+

+ Returns a string representing the value of this BigNumber in exponential + notation to the specified decimal places, i.e with one digit before the + decimal point and decimal_places digits after it. If rounding + is necessary, the current + ROUNDING_MODE is used. +

+

+ If the value of this BigNumber in exponential notation has fewer fraction + digits then is specified by decimal_places, the return value + will be appended with zeros accordingly. +

+

+ If decimal_places is omitted, or is null or + undefined, the number of digits after the decimal point defaults to the + minimum number of digits necessary to represent the value exactly. +

+

+ See Errors for the treatment of other + non-integer or out of range decimal_places values. +

+
+x = 45.6
+y = new BigNumber(x)
+x.toExponential()         // '4.56e+1'
+y.toExponential()         // '4.56e+1'
+x.toExponential(0)        // '5e+1'
+y.toE(0)                  // '5e+1'
+x.toExponential(1)        // '4.6e+1'
+y.toE(1)                  // '4.6e+1'
+x.toExponential(3)        // '4.560e+1'
+y.toE(3)                  // '4.560e+1'
+ + + +
+ toFixed.toF([decimal_places]) ⇒ + string +
+

+ decimal_places : number : integer, 0 to 1e+9 inclusive +

+

+ Returns a string representing the value of this BigNumber in normal + notation to the specified fixed number of decimal places, i.e. with + decimal_places digits after the decimal point. If rounding is + necessary, the current + ROUNDING_MODE setting is used. +

+

+ If the value of this BigNumber in normal notation has fewer fraction + digits then is specified by decimal_places, the return value + will be appended with zeros accordingly. +

+

+ Unlike Number.prototype.toFixed, which returns + exponential notation if a number is greater or equal to 1021, + this method will always return normal notation. +

+

+ If decimal_places is omitted, or is null or + undefined, then the return value is the same as n.toString(). + This is also unlike Number.prototype.toFixed, which returns + the value to zero decimal places. +

+

+ See Errors for the treatment of other + non-integer or out of range decimal_places values. +

+
+x = 45.6
+y = new BigNumber(x)
+x.toFixed()              // '46'
+y.toFixed()              // '45.6'
+y.toF(0)                 // '46'
+x.toFixed(3)             // '45.600'
+y.toF(3)                 // '45.600'
+ + + +
toNumber.toN() ⇒ number
+

Returns the value of this BigNumber as a number primitive.

+

+ Type coercion with, for example, JavaScript's unary plus operator can alternatively be used, + but then a BigNumber with the value minus zero will convert to positive zero. +

+
+x = new BigNumber(456.789)
+x.toNumber()                   // 456.789
++x                             // 456.789
+
+y = new BigNumber('45987349857634085409857349856430985')
+y.toNumber()                   // 4.598734985763409e+34
+
+z = new BigNumber(-0)
+1 / +z                         // Infinity
+1 / z.toNumber()               // -Infinity
+ + + +
+ toPrecision.toP([significant_figures]) ⇒ + string +
+

+ significant_figures : number : integer, 1 to 1e+9 + inclusive +

+

+ Returns a string representing the value of this BigNumber to the + specified number of significant digits. If rounding is necessary, the + current ROUNDING_MODE setting is + used. +

+

+ If significant_figures is less than the number of digits + necessary to represent the integer part of the value in normal notation, + then exponential notation is used. +

+

+ If significant_figures is omitted, or is null or + undefined, then the return value is the same as n.toString(). +

+

+ See Errors for the treatment of other + non-integer or out of range significant_figures values. +

+
+x = 45.6
+y = new BigNumber(x)
+x.toPrecision()           // '45.6'
+y.toPrecision()           // '45.6'
+x.toPrecision(1)          // '5e+1'
+y.toP(1)                  // '5e+1'
+x.toPrecision(5)          // '45.600'
+y.toP(5)                  // '45.600'
+ + + +
+ toString.toS([base]) ⇒ string +
+

+ base : number : integer, 2 to 64 inclusive +

+

+ Returns a string representing the value of this BigNumber in the specified + base, or base 10 if base is omitted. For bases above 10, + values from 10 to 35 are represented by a-z (as with + Number.toString), 36 to 61 by A-Z, and 62 and 63 + by $ and _ respectively. +

+

+ If a base is specified the value is rounded according to the current + DECIMAL_PLACES + and ROUNDING_MODE settings. +

+

+ If a base is not specified, and this BigNumber has a positive + exponent that is equal to or greater than the positive component of the + current EXPONENTIAL_AT setting, + or a negative exponent equal to or less than the negative component of the + setting, then exponential notation is returned. +

+

+ If base is null or undefined it is ignored. +
+ See Errors for the treatment of other non-integer or + out of range base values. +

+
+x = new BigNumber(750000)
+x.toString()                    // '750000'
+BigNumber.config({ EXPONENTIAL_AT : 5 })
+x.toString()                    // '7.5e+5'
+
+y = new BigNumber(362.875)
+y.toString(2)                   // '101101010.111'
+y.toString(9)                   // '442.77777777777777777778'
+y.toString(32)                  // 'ba.s'
+
+BigNumber.config({ DECIMAL_PLACES : 4 });
+z = new BigNumber('1.23456789')
+z.toString()                    // '1.23456789'
+z.toString(10)                  // '1.2346'
+ + + +
+ valueOf.valueOf() ⇒ string +
+

+ As toString, but does not accept a base argument. +

+
+x = new BigNumber('1.777e+457')
+x.valueOf()                      // '1.777e+457'
+ + + +
+ toFraction.toFr([max_denominator]) ⇒ + [string, string] +
+

+ max_denominator : number|string|BigNumber : + integer >= 1 and < Infinity +

+

+ Returns a string array representing the value of this BigNumber as a + simple fraction with an integer numerator and an integer denominator. The + denominator will be a positive non-zero value less than or equal to + max_denominator. +

+

+ If a maximum denominator is not specified, or is null or + undefined, the denominator will be the lowest value necessary to represent + the number exactly. +

+

+ See Errors for the treatment of other non-integer or + out of range max_denominator values. +

+
+x = new BigNumber(1.75)
+x.toFraction()            // '7, 4'
+
+pi = new BigNumber('3.14159265358')
+pi.toFr()                 // '157079632679,50000000000'
+pi.toFr(100000)           // '312689, 99532'
+pi.toFr(10000)            // '355, 113'
+pi.toFr(100)              // '311, 99'
+pi.toFr(10)               // '22, 7'
+pi.toFr(1)                // '3, 1'
+ + + +
+ round.round([decimal_places [, rounding_mode]]) + ⇒ BigNumber +
+

+ decimal_places : number : integer, 0 to 1e+9 inclusive +
+ rounding_mode : number : integer, 0 to 8 inclusive +

+

+ Returns a BigNumber whose value is the value of this BigNumber rounded by + the specified rounding_mode to a maximum of + decimal_places digits after the decimal point. +

+

+ if decimal_places is omitted, or is null or + undefined, the return value is n rounded to a whole number. +

+

+ if rounding_mode is omitted, or is null or + undefined, the current + ROUNDING_MODE setting is used. +

+

+ See Errors for the treatment of other + non-integer or out of range decimal_places or + rounding_mode values. +

+
+x = 1234.56
+Math.round(x)                             // 1235
+
+y = new BigNumber(x)
+y.round()                                 // '1235'
+y.round(1)                                // '1234.6'
+y.round(2)                                // '1234.56'
+y.round(10)                               // '1234.56'
+y.round(0, 1)                             // '1234'
+y.round(0, 6)                             // '1235'
+y.round(1, 1)                             // '1234.5'
+y.round(1, BigNumber.ROUND_HALF_EVEN)     // '1234.6'
+y                                         // '1234.56'
+ + + +

Properties

+

+ A BigNumber is an object with three properties: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionTypeValue
ccoefficient*number[] Array of single digits
eexponentnumberInteger, -1e+9 to 1e+9 inclusive
ssignnumber-1 or 1
+

*significand

+

+ The value of any of the three properties may also be null. +

+

+ The value of a BigNumber is stored in a normalised decimal floating point + format which corresponds to the value's toExponential form, + with the decimal point to be positioned after the most significant + (left-most) digit of the coefficient. +

+

+ Note that, as with JavaScript numbers, the original exponent and + fractional trailing zeros are not preserved. +

+
x = new BigNumber(0.123)              // '0.123'
+x.toExponential()                     // '1.23e-1'
+x.c                                   // '1,2,3'
+x.e                                   // -1
+x.s                                   // 1
+
+y = new Number(-123.4567000e+2)       // '-12345.67'
+y.toExponential()                     // '-1.234567e+4'
+z = new BigNumber('-123.4567000e+2')  // '-12345.67'
+z.toExponential()                     // '-1.234567e+4'
+z.c                                   // '1,2,3,4,5,6,7'
+z.e                                   // 4
+z.s                                   // -1
+ + +

+ A BigNumber is mutable in the sense that the value of its properties can + be changed.
+ For example, to rapidly shift a value by a power of 10: +

+
+x = new BigNumber('1234.000')      // '1234'
+x.toExponential()                  // '1.234e+3'
+x.c                                // '1,2,3,4'
+x.e                                // 3
+
+x.e = -5
+x                                  // '0.00001234'
+

+ If changing the coefficient array directly, which is not recommended, be + careful to avoid leading or trailing zeros (unless zero itself is being + represented). +

+ + + +

Zero, NaN and Infinity

+

+ The table below shows how ±0, NaN and ±Infinity are stored. +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ces
±0[0]0±1
NaNnullnullnull
±Infinitynullnull±1
+
+x = new Number(-0)      // 0
+1 / x == -Infinity     // true
+
+y = new BigNumber(-0)   // '0'
+y.c                     // '0' ( [0].toString() )
+y.e                     // 0
+y.s                     // -1
+ + + +

Errors

+

+ The errors that are thrown are generic Error objects with + name BigNumber Error. The table below shows the errors + that may be thrown if ERRORS is true, and the + action taken if ERRORS is false. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method(s)ERRORS : true
Throw BigNumber Error
ERRORS : false
Action on invalid argument
+ BigNumber
+ comparedTo
+ dividedBy
+ equals
+ greaterThan
+ greaterThanOrEqualTo
+ lessThan
+ lessThanOrEqualTo
+ minus
+ mod
+ plus
+ times
number type has more than
15 significant digits
Accept.
not a base... numberSubstitute NaN.
base not an integerTruncate to integer.
Ignore if not a number.
base out of rangeIgnore.
not a number*Substitute NaN.
configDECIMAL_PLACES not an integerTruncate to integer.
Ignore if not a number.
DECIMAL_PLACES out of rangeIgnore.
ROUNDING_MODE not an integerTruncate to integer.
Ignore if not a number.
ROUNDING_MODE out of rangeIgnore.
+ EXPONENTIAL_AT not an integer
+ or not [integer, integer] +
Truncate to integer(s).
Ignore if not number(s).
+ EXPONENTIAL_AT out of range
+ or not [negative, positive] +
Ignore.
+ RANGE not a non-zero integer
+ or not [integer, integer] +
Truncate to integer(s).
Ignore if zero or not number(s).
+ RANGE out of range
+ or not [negative, positive] +
Ignore.
+ ERRORS not a boolean
+ or binary digit +
Ignore.
toPowerexponent not an integerTruncate to integer.
Substitute NaN if not a number.
exponent out of rangeSubstitute ±Infinity. +
rounddecimal places not an integerTruncate to integer.
Ignore if not a number.
decimal places out of rangeIgnore.
mode not an integerTruncate to integer.
Ignore if not a number.
mode out of rangeIgnore.
toExponentialdecimal places not an integerTruncate to integer.
Ignore if not a number.
decimal places out of rangeIgnore.
toFixeddecimal places not an integerTruncate to integer.
Ignore if not a number.
decimal places out of rangeIgnore.
toFractionmax denominator not an integerTruncate to integer.
Ignore if not a number.
max denominator out of rangeIgnore.
toPrecisionprecision not an integerTruncate to integer.
Ignore if not a number.
precision out of rangeIgnore.
toStringbase not an integerTruncate to integer.
Ignore if not a number.
base out of rangeIgnore.
+

+ *No error is thrown if the value is NaN or 'NaN' +

+

+ The message of a BigNumber Error will also contain the name of the + method from which the error originated. +

+

+ To determine if an exception is a BigNumber Error: +

+
+try {
+    // ...
+} catch (e) {
+    if ( e instanceof Error && e.name == 'BigNumber Error' ) {
+        // ...
+    }
+}
+ +

FAQ

+
Why are trailing fractional zeros removed from BigNumbers?
+

+ Many arbitrary-precision libraries retain trailing fractional zeros as + they can indicate the precision of a value. This can be useful but the + results of arithmetic operations can be misleading. +

+
+x = new BigDecimal("1.0")
+y = new BigDecimal("1.1000")
+z = x.add(y)                      // 2.1000
+
+x = new BigDecimal("1.20")
+y = new BigDecimal("3.45000")
+z = x.multiply(y)                 // 4.1400000
+

+ To specify the precision of a value is to specify that the value lies + within a certain range. +

+

+ In the first example, x has a value of 1.0. The trailing zero + shows the precision of the value, implying that it is in the range 0.95 to + 1.05. Similarly, the precision indicated by the trailing zeros of + y indicates that the value is in the range 1.09995 to + 1.10005. If we add the two lowest values in the ranges we get 0.95 + + 1.09995 = 2.04995 and if we add the two highest values we get 1.05 + + 1.10005 = 2.15005, so the range of the result of the addition implied by + the precision of its operands is 2.04995 to 2.15005. The result given by + BigDecimal of 2.1000 however, indicates that the value is in the range + 2.09995 to 2.10005 and therefore the precision implied by its trailing + zeros is misleading. +

+

+ In the second example, the true range is 4.122744 to 4.157256 yet the + BigDecimal answer of 4.1400000 indicates a range of 4.13999995 to + 4.14000005. Again, the precision implied by the trailing zeros is + misleading. +

+

+ This library, like binary floating point and most calculators, does not + retain trailing fractional zeros. Instead, the toExponential, + toFixed and toPrecision methods enable trailing + zeros to be added if and when required. +

+
+ +
+ + + diff --git a/node_modules/mysql/node_modules/bignumber.js/package.json b/node_modules/mysql/node_modules/bignumber.js/package.json new file mode 100644 index 0000000..acae2a0 --- /dev/null +++ b/node_modules/mysql/node_modules/bignumber.js/package.json @@ -0,0 +1,61 @@ +{ + "name": "bignumber.js", + "description": "A library for arbitrary-precision decimal and non-decimal arithmetic", + "version": "1.4.1", + "keywords": [ + "arbitrary", + "precision", + "arithmetic", + "big", + "number", + "decimal", + "float", + "biginteger", + "bigdecimal", + "bignumber", + "bigint", + "bignum" + ], + "repository": { + "type": "git", + "url": "https://github.com/MikeMcl/bignumber.js.git" + }, + "main": "bignumber", + "author": { + "name": "Michael Mclaughlin", + "email": "M8ch88l@gmail.com" + }, + "engines": { + "node": "*" + }, + "license": "MIT", + "scripts": { + "test": "node ./test/every-test.js", + "build": "uglifyjs bignumber.js -c -m -o bignumber.min.js --preamble '/* bignumber.js v1.4.1 https://github.com/MikeMcl/bignumber.js/LICENCE */'" + }, + "bugs": { + "url": "https://github.com/MikeMcl/bignumber.js/issues" + }, + "homepage": "https://github.com/MikeMcl/bignumber.js", + "_id": "bignumber.js@1.4.1", + "dist": { + "shasum": "3d19ac321f8db4ba07aace23ebd4ac976fae6bfa", + "tarball": "http://registry.npmjs.org/bignumber.js/-/bignumber.js-1.4.1.tgz" + }, + "_from": "bignumber.js@1.4.1", + "_npmVersion": "1.4.6", + "_npmUser": { + "name": "mikemcl", + "email": "M8ch88l@gmail.com" + }, + "maintainers": [ + { + "name": "mikemcl", + "email": "M8ch88l@gmail.com" + } + ], + "directories": {}, + "_shasum": "3d19ac321f8db4ba07aace23ebd4ac976fae6bfa", + "_resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-1.4.1.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mysql/node_modules/readable-stream/.npmignore b/node_modules/mysql/node_modules/readable-stream/.npmignore new file mode 100644 index 0000000..38344f8 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/.npmignore @@ -0,0 +1,5 @@ +build/ +test/ +examples/ +fs.js +zlib.js \ No newline at end of file diff --git a/node_modules/mysql/node_modules/readable-stream/LICENSE b/node_modules/mysql/node_modules/readable-stream/LICENSE new file mode 100644 index 0000000..e3d4e69 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/LICENSE @@ -0,0 +1,18 @@ +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/node_modules/mysql/node_modules/readable-stream/README.md b/node_modules/mysql/node_modules/readable-stream/README.md new file mode 100644 index 0000000..e46b823 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/README.md @@ -0,0 +1,15 @@ +# readable-stream + +***Node-core streams for userland*** + +[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/) +[![NPM](https://nodei.co/npm-dl/readable-stream.png&months=6&height=3)](https://nodei.co/npm/readable-stream/) + +This package is a mirror of the Streams2 and Streams3 implementations in Node-core. + +If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core. + +**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12. + +**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` you’ll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when you’re ready to start using Streams3, pin to `"~1.1.0"` + diff --git a/node_modules/mysql/node_modules/readable-stream/duplex.js b/node_modules/mysql/node_modules/readable-stream/duplex.js new file mode 100644 index 0000000..ca807af --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/duplex.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_duplex.js") diff --git a/node_modules/mysql/node_modules/readable-stream/float.patch b/node_modules/mysql/node_modules/readable-stream/float.patch new file mode 100644 index 0000000..b984607 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/float.patch @@ -0,0 +1,923 @@ +diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js +index c5a741c..a2e0d8e 100644 +--- a/lib/_stream_duplex.js ++++ b/lib/_stream_duplex.js +@@ -26,8 +26,8 @@ + + module.exports = Duplex; + var util = require('util'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('./_stream_readable'); ++var Writable = require('./_stream_writable'); + + util.inherits(Duplex, Readable); + +diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js +index a5e9864..330c247 100644 +--- a/lib/_stream_passthrough.js ++++ b/lib/_stream_passthrough.js +@@ -25,7 +25,7 @@ + + module.exports = PassThrough; + +-var Transform = require('_stream_transform'); ++var Transform = require('./_stream_transform'); + var util = require('util'); + util.inherits(PassThrough, Transform); + +diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js +index 0c3fe3e..90a8298 100644 +--- a/lib/_stream_readable.js ++++ b/lib/_stream_readable.js +@@ -23,10 +23,34 @@ module.exports = Readable; + Readable.ReadableState = ReadableState; + + var EE = require('events').EventEmitter; ++if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { ++ return emitter.listeners(type).length; ++}; ++ ++if (!global.setImmediate) global.setImmediate = function setImmediate(fn) { ++ return setTimeout(fn, 0); ++}; ++if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) { ++ return clearTimeout(i); ++}; ++ + var Stream = require('stream'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var StringDecoder; +-var debug = util.debuglog('stream'); ++var debug; ++if (util.debuglog) ++ debug = util.debuglog('stream'); ++else try { ++ debug = require('debuglog')('stream'); ++} catch (er) { ++ debug = function() {}; ++} + + util.inherits(Readable, Stream); + +@@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) { + + + function onEofChunk(stream, state) { +- if (state.decoder && !state.ended) { ++ if (state.decoder && !state.ended && state.decoder.end) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); +diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js +index b1f9fcc..b0caf57 100644 +--- a/lib/_stream_transform.js ++++ b/lib/_stream_transform.js +@@ -64,8 +64,14 @@ + + module.exports = Transform; + +-var Duplex = require('_stream_duplex'); ++var Duplex = require('./_stream_duplex'); + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + util.inherits(Transform, Duplex); + + +diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js +index ba2e920..f49288b 100644 +--- a/lib/_stream_writable.js ++++ b/lib/_stream_writable.js +@@ -27,6 +27,12 @@ module.exports = Writable; + Writable.WritableState = WritableState; + + var util = require('util'); ++if (!util.isUndefined) { ++ var utilIs = require('core-util-is'); ++ for (var f in utilIs) { ++ util[f] = utilIs[f]; ++ } ++} + var Stream = require('stream'); + + util.inherits(Writable, Stream); +@@ -119,7 +125,7 @@ function WritableState(options, stream) { + function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. +- if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) ++ if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex'))) + return new Writable(options); + + this._writableState = new WritableState(options, this); +diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js +index e3787e4..8cd2127 100644 +--- a/test/simple/test-stream-big-push.js ++++ b/test/simple/test-stream-big-push.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var str = 'asdfasdfasdfasdfasdf'; + + var r = new stream.Readable({ +diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js +index bb73777..d40efc7 100644 +--- a/test/simple/test-stream-end-paused.js ++++ b/test/simple/test-stream-end-paused.js +@@ -25,7 +25,7 @@ var gotEnd = false; + + // Make sure we don't miss the end event for paused 0-length streams + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var stream = new Readable(); + var calledRead = false; + stream._read = function() { +diff --git a/test/simple/test-stream-pipe-after-end.js b/test/simple/test-stream-pipe-after-end.js +index b46ee90..0be8366 100644 +--- a/test/simple/test-stream-pipe-after-end.js ++++ b/test/simple/test-stream-pipe-after-end.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var util = require('util'); + + util.inherits(TestReadable, Readable); +diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js +deleted file mode 100644 +index f689358..0000000 +--- a/test/simple/test-stream-pipe-cleanup.js ++++ /dev/null +@@ -1,122 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// Permission is hereby granted, free of charge, to any person obtaining a +-// copy of this software and associated documentation files (the +-// "Software"), to deal in the Software without restriction, including +-// without limitation the rights to use, copy, modify, merge, publish, +-// distribute, sublicense, and/or sell copies of the Software, and to permit +-// persons to whom the Software is furnished to do so, subject to the +-// following conditions: +-// +-// The above copyright notice and this permission notice shall be included +-// in all copies or substantial portions of the Software. +-// +-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-// USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-// This test asserts that Stream.prototype.pipe does not leave listeners +-// hanging on the source or dest. +- +-var common = require('../common'); +-var stream = require('stream'); +-var assert = require('assert'); +-var util = require('util'); +- +-function Writable() { +- this.writable = true; +- this.endCalls = 0; +- stream.Stream.call(this); +-} +-util.inherits(Writable, stream.Stream); +-Writable.prototype.end = function() { +- this.endCalls++; +-}; +- +-Writable.prototype.destroy = function() { +- this.endCalls++; +-}; +- +-function Readable() { +- this.readable = true; +- stream.Stream.call(this); +-} +-util.inherits(Readable, stream.Stream); +- +-function Duplex() { +- this.readable = true; +- Writable.call(this); +-} +-util.inherits(Duplex, Writable); +- +-var i = 0; +-var limit = 100; +- +-var w = new Writable(); +- +-var r; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('end'); +-} +-assert.equal(0, r.listeners('end').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-for (i = 0; i < limit; i++) { +- r = new Readable(); +- r.pipe(w); +- r.emit('close'); +-} +-assert.equal(0, r.listeners('close').length); +-assert.equal(limit, w.endCalls); +- +-w.endCalls = 0; +- +-r = new Readable(); +- +-for (i = 0; i < limit; i++) { +- w = new Writable(); +- r.pipe(w); +- w.emit('close'); +-} +-assert.equal(0, w.listeners('close').length); +- +-r = new Readable(); +-w = new Writable(); +-var d = new Duplex(); +-r.pipe(d); // pipeline A +-d.pipe(w); // pipeline B +-assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup +-assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-r.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 0); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup +-assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 1); // B.cleanup +- +-d.emit('end'); +-assert.equal(d.endCalls, 1); +-assert.equal(w.endCalls, 1); +-assert.equal(r.listeners('end').length, 0); +-assert.equal(r.listeners('close').length, 0); +-assert.equal(d.listeners('end').length, 0); +-assert.equal(d.listeners('close').length, 0); +-assert.equal(w.listeners('end').length, 0); +-assert.equal(w.listeners('close').length, 0); +diff --git a/test/simple/test-stream-pipe-error-handling.js b/test/simple/test-stream-pipe-error-handling.js +index c5d724b..c7d6b7d 100644 +--- a/test/simple/test-stream-pipe-error-handling.js ++++ b/test/simple/test-stream-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Stream = require('stream').Stream; ++var Stream = require('../../').Stream; + + (function testErrorListenerCatches() { + var source = new Stream(); +diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js +index cb9d5fe..56f8d61 100644 +--- a/test/simple/test-stream-pipe-event.js ++++ b/test/simple/test-stream-pipe-event.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common'); +-var stream = require('stream'); ++var stream = require('../../'); + var assert = require('assert'); + var util = require('util'); + +diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js +index f2e6ec2..a5c9bf9 100644 +--- a/test/simple/test-stream-push-order.js ++++ b/test/simple/test-stream-push-order.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var assert = require('assert'); + + var s = new Readable({ +diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js +index 06f43dc..1701a9a 100644 +--- a/test/simple/test-stream-push-strings.js ++++ b/test/simple/test-stream-push-strings.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var util = require('util'); + + util.inherits(MyStream, Readable); +diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js +index ba6a577..a8e6f7b 100644 +--- a/test/simple/test-stream-readable-event.js ++++ b/test/simple/test-stream-readable-event.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + (function first() { + // First test, not reading when the readable is added. +diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js +index 2891ad6..11689ba 100644 +--- a/test/simple/test-stream-readable-flow-recursion.js ++++ b/test/simple/test-stream-readable-flow-recursion.js +@@ -27,7 +27,7 @@ var assert = require('assert'); + // more data continuously, but without triggering a nextTick + // warning or RangeError. + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + // throw an error if we trigger a nextTick warning. + process.throwDeprecation = true; +diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js +index 0c96476..7827538 100644 +--- a/test/simple/test-stream-unshift-empty-chunk.js ++++ b/test/simple/test-stream-unshift-empty-chunk.js +@@ -24,7 +24,7 @@ var assert = require('assert'); + + // This test verifies that stream.unshift(Buffer(0)) or + // stream.unshift('') does not set state.reading=false. +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + var r = new Readable(); + var nChunks = 10; +diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js +index 83fd9fa..17c18aa 100644 +--- a/test/simple/test-stream-unshift-read-race.js ++++ b/test/simple/test-stream-unshift-read-race.js +@@ -29,7 +29,7 @@ var assert = require('assert'); + // 3. push() after the EOF signaling null is an error. + // 4. _read() is not called after pushing the EOF null chunk. + +-var stream = require('stream'); ++var stream = require('../../'); + var hwm = 10; + var r = stream.Readable({ highWaterMark: hwm }); + var chunks = 10; +@@ -51,7 +51,14 @@ r._read = function(n) { + + function push(fast) { + assert(!pushedNull, 'push() after null push'); +- var c = pos >= data.length ? null : data.slice(pos, pos + n); ++ var c; ++ if (pos >= data.length) ++ c = null; ++ else { ++ if (n + pos > data.length) ++ n = data.length - pos; ++ c = data.slice(pos, pos + n); ++ } + pushedNull = c === null; + if (fast) { + pos += n; +diff --git a/test/simple/test-stream-writev.js b/test/simple/test-stream-writev.js +index 5b49e6e..b5321f3 100644 +--- a/test/simple/test-stream-writev.js ++++ b/test/simple/test-stream-writev.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + + var queue = []; + for (var decode = 0; decode < 2; decode++) { +diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js +index 3814bf0..248c1be 100644 +--- a/test/simple/test-stream2-basic.js ++++ b/test/simple/test-stream2-basic.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js +index 6cdd4e9..f0fa84b 100644 +--- a/test/simple/test-stream2-compatibility.js ++++ b/test/simple/test-stream2-compatibility.js +@@ -21,7 +21,7 @@ + + + var common = require('../common.js'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js +index 39b274f..006a19b 100644 +--- a/test/simple/test-stream2-finish-pipe.js ++++ b/test/simple/test-stream2-finish-pipe.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Buffer = require('buffer').Buffer; + + var r = new stream.Readable(); +diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js +deleted file mode 100644 +index e162406..0000000 +--- a/test/simple/test-stream2-fs.js ++++ /dev/null +@@ -1,72 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// Permission is hereby granted, free of charge, to any person obtaining a +-// copy of this software and associated documentation files (the +-// "Software"), to deal in the Software without restriction, including +-// without limitation the rights to use, copy, modify, merge, publish, +-// distribute, sublicense, and/or sell copies of the Software, and to permit +-// persons to whom the Software is furnished to do so, subject to the +-// following conditions: +-// +-// The above copyright notice and this permission notice shall be included +-// in all copies or substantial portions of the Software. +-// +-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-// USE OR OTHER DEALINGS IN THE SOFTWARE. +- +- +-var common = require('../common.js'); +-var R = require('_stream_readable'); +-var assert = require('assert'); +- +-var fs = require('fs'); +-var FSReadable = fs.ReadStream; +- +-var path = require('path'); +-var file = path.resolve(common.fixturesDir, 'x1024.txt'); +- +-var size = fs.statSync(file).size; +- +-var expectLengths = [1024]; +- +-var util = require('util'); +-var Stream = require('stream'); +- +-util.inherits(TestWriter, Stream); +- +-function TestWriter() { +- Stream.apply(this); +- this.buffer = []; +- this.length = 0; +-} +- +-TestWriter.prototype.write = function(c) { +- this.buffer.push(c.toString()); +- this.length += c.length; +- return true; +-}; +- +-TestWriter.prototype.end = function(c) { +- if (c) this.buffer.push(c.toString()); +- this.emit('results', this.buffer); +-} +- +-var r = new FSReadable(file); +-var w = new TestWriter(); +- +-w.on('results', function(res) { +- console.error(res, w.length); +- assert.equal(w.length, size); +- var l = 0; +- assert.deepEqual(res.map(function (c) { +- return c.length; +- }), expectLengths); +- console.log('ok'); +-}); +- +-r.pipe(w); +diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js +deleted file mode 100644 +index 15cffc2..0000000 +--- a/test/simple/test-stream2-httpclient-response-end.js ++++ /dev/null +@@ -1,52 +0,0 @@ +-// Copyright Joyent, Inc. and other Node contributors. +-// +-// Permission is hereby granted, free of charge, to any person obtaining a +-// copy of this software and associated documentation files (the +-// "Software"), to deal in the Software without restriction, including +-// without limitation the rights to use, copy, modify, merge, publish, +-// distribute, sublicense, and/or sell copies of the Software, and to permit +-// persons to whom the Software is furnished to do so, subject to the +-// following conditions: +-// +-// The above copyright notice and this permission notice shall be included +-// in all copies or substantial portions of the Software. +-// +-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +-// USE OR OTHER DEALINGS IN THE SOFTWARE. +- +-var common = require('../common.js'); +-var assert = require('assert'); +-var http = require('http'); +-var msg = 'Hello'; +-var readable_event = false; +-var end_event = false; +-var server = http.createServer(function(req, res) { +- res.writeHead(200, {'Content-Type': 'text/plain'}); +- res.end(msg); +-}).listen(common.PORT, function() { +- http.get({port: common.PORT}, function(res) { +- var data = ''; +- res.on('readable', function() { +- console.log('readable event'); +- readable_event = true; +- data += res.read(); +- }); +- res.on('end', function() { +- console.log('end event'); +- end_event = true; +- assert.strictEqual(msg, data); +- server.close(); +- }); +- }); +-}); +- +-process.on('exit', function() { +- assert(readable_event); +- assert(end_event); +-}); +- +diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js +index 2fbfbca..667985b 100644 +--- a/test/simple/test-stream2-large-read-stall.js ++++ b/test/simple/test-stream2-large-read-stall.js +@@ -30,7 +30,7 @@ var PUSHSIZE = 20; + var PUSHCOUNT = 1000; + var HWM = 50; + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable({ + highWaterMark: HWM + }); +@@ -39,23 +39,23 @@ var rs = r._readableState; + r._read = push; + + r.on('readable', function() { +- console.error('>> readable'); ++ //console.error('>> readable'); + do { +- console.error(' > read(%d)', READSIZE); ++ //console.error(' > read(%d)', READSIZE); + var ret = r.read(READSIZE); +- console.error(' < %j (%d remain)', ret && ret.length, rs.length); ++ //console.error(' < %j (%d remain)', ret && ret.length, rs.length); + } while (ret && ret.length === READSIZE); + +- console.error('<< after read()', +- ret && ret.length, +- rs.needReadable, +- rs.length); ++ //console.error('<< after read()', ++ // ret && ret.length, ++ // rs.needReadable, ++ // rs.length); + }); + + var endEmitted = false; + r.on('end', function() { + endEmitted = true; +- console.error('end'); ++ //console.error('end'); + }); + + var pushes = 0; +@@ -64,11 +64,11 @@ function push() { + return; + + if (pushes++ === PUSHCOUNT) { +- console.error(' push(EOF)'); ++ //console.error(' push(EOF)'); + return r.push(null); + } + +- console.error(' push #%d', pushes); ++ //console.error(' push #%d', pushes); + if (r.push(new Buffer(PUSHSIZE))) + setTimeout(push); + } +diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js +index 3e6931d..ff47d89 100644 +--- a/test/simple/test-stream2-objects.js ++++ b/test/simple/test-stream2-objects.js +@@ -21,8 +21,8 @@ + + + var common = require('../common.js'); +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var assert = require('assert'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js +index cf7531c..e3f3e4e 100644 +--- a/test/simple/test-stream2-pipe-error-handling.js ++++ b/test/simple/test-stream2-pipe-error-handling.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + (function testErrorListenerCatches() { + var count = 1000; +diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js +index 5e8e3cb..53b2616 100755 +--- a/test/simple/test-stream2-pipe-error-once-listener.js ++++ b/test/simple/test-stream2-pipe-error-once-listener.js +@@ -24,7 +24,7 @@ var common = require('../common.js'); + var assert = require('assert'); + + var util = require('util'); +-var stream = require('stream'); ++var stream = require('../../'); + + + var Read = function() { +diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js +index b63edc3..eb2b0e9 100644 +--- a/test/simple/test-stream2-push.js ++++ b/test/simple/test-stream2-push.js +@@ -20,7 +20,7 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + var assert = require('assert'); +diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js +index e8a7305..9740a47 100644 +--- a/test/simple/test-stream2-read-sync-stack.js ++++ b/test/simple/test-stream2-read-sync-stack.js +@@ -21,7 +21,7 @@ + + var common = require('../common'); + var assert = require('assert'); +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + var r = new Readable(); + var N = 256 * 1024; + +diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +index cd30178..4b1659d 100644 +--- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js ++++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js +@@ -22,10 +22,9 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('stream').Readable; ++var Readable = require('../../').Readable; + + test1(); +-test2(); + + function test1() { + var r = new Readable(); +@@ -88,31 +87,3 @@ function test1() { + console.log('ok'); + }); + } +- +-function test2() { +- var r = new Readable({ encoding: 'base64' }); +- var reads = 5; +- r._read = function(n) { +- if (!reads--) +- return r.push(null); // EOF +- else +- return r.push(new Buffer('x')); +- }; +- +- var results = []; +- function flow() { +- var chunk; +- while (null !== (chunk = r.read())) +- results.push(chunk + ''); +- } +- r.on('readable', flow); +- r.on('end', function() { +- results.push('EOF'); +- }); +- flow(); +- +- process.on('exit', function() { +- assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]); +- console.log('ok'); +- }); +-} +diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js +index 7c96ffe..04a96f5 100644 +--- a/test/simple/test-stream2-readable-from-list.js ++++ b/test/simple/test-stream2-readable-from-list.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var fromList = require('_stream_readable')._fromList; ++var fromList = require('../../lib/_stream_readable')._fromList; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js +index 675da8e..51fd3d5 100644 +--- a/test/simple/test-stream2-readable-legacy-drain.js ++++ b/test/simple/test-stream2-readable-legacy-drain.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Stream = require('stream'); ++var Stream = require('../../'); + var Readable = Stream.Readable; + + var r = new Readable(); +diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js +index 7314ae7..c971898 100644 +--- a/test/simple/test-stream2-readable-non-empty-end.js ++++ b/test/simple/test-stream2-readable-non-empty-end.js +@@ -21,7 +21,7 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + + var len = 0; + var chunks = new Array(10); +diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js +index 2e5cf25..fd8a3dc 100644 +--- a/test/simple/test-stream2-readable-wrap-empty.js ++++ b/test/simple/test-stream2-readable-wrap-empty.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); ++var Readable = require('../../lib/_stream_readable'); + var EE = require('events').EventEmitter; + + var oldStream = new EE(); +diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js +index 90eea01..6b177f7 100644 +--- a/test/simple/test-stream2-readable-wrap.js ++++ b/test/simple/test-stream2-readable-wrap.js +@@ -22,8 +22,8 @@ + var common = require('../common'); + var assert = require('assert'); + +-var Readable = require('_stream_readable'); +-var Writable = require('_stream_writable'); ++var Readable = require('../../lib/_stream_readable'); ++var Writable = require('../../lib/_stream_writable'); + var EE = require('events').EventEmitter; + + var testRuns = 0, completedRuns = 0; +diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js +index 5d2c32a..685531b 100644 +--- a/test/simple/test-stream2-set-encoding.js ++++ b/test/simple/test-stream2-set-encoding.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var R = require('_stream_readable'); ++var R = require('../../lib/_stream_readable'); + var util = require('util'); + + // tiny node-tap lookalike. +diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js +index 9c9ddd8..a0cacc6 100644 +--- a/test/simple/test-stream2-transform.js ++++ b/test/simple/test-stream2-transform.js +@@ -21,8 +21,8 @@ + + var assert = require('assert'); + var common = require('../common.js'); +-var PassThrough = require('_stream_passthrough'); +-var Transform = require('_stream_transform'); ++var PassThrough = require('../../').PassThrough; ++var Transform = require('../../').Transform; + + // tiny node-tap lookalike. + var tests = []; +diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js +index d66dc3c..365b327 100644 +--- a/test/simple/test-stream2-unpipe-drain.js ++++ b/test/simple/test-stream2-unpipe-drain.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + var crypto = require('crypto'); + + var util = require('util'); +diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js +index 99f8746..17c92ae 100644 +--- a/test/simple/test-stream2-unpipe-leak.js ++++ b/test/simple/test-stream2-unpipe-leak.js +@@ -22,7 +22,7 @@ + + var common = require('../common.js'); + var assert = require('assert'); +-var stream = require('stream'); ++var stream = require('../../'); + + var chunk = new Buffer('hallo'); + +diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js +index 704100c..209c3a6 100644 +--- a/test/simple/test-stream2-writable.js ++++ b/test/simple/test-stream2-writable.js +@@ -20,8 +20,8 @@ + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + var common = require('../common.js'); +-var W = require('_stream_writable'); +-var D = require('_stream_duplex'); ++var W = require('../../').Writable; ++var D = require('../../').Duplex; + var assert = require('assert'); + + var util = require('util'); +diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js +index b91bde3..2f72c15 100644 +--- a/test/simple/test-stream3-pause-then-read.js ++++ b/test/simple/test-stream3-pause-then-read.js +@@ -22,7 +22,7 @@ + var common = require('../common'); + var assert = require('assert'); + +-var stream = require('stream'); ++var stream = require('../../'); + var Readable = stream.Readable; + var Writable = stream.Writable; + diff --git a/node_modules/mysql/node_modules/readable-stream/lib/_stream_duplex.js b/node_modules/mysql/node_modules/readable-stream/lib/_stream_duplex.js new file mode 100644 index 0000000..b513d61 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/lib/_stream_duplex.js @@ -0,0 +1,89 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +module.exports = Duplex; + +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +forEach(objectKeys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); + +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; + + this.once('end', onend); +} + +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} diff --git a/node_modules/mysql/node_modules/readable-stream/lib/_stream_passthrough.js b/node_modules/mysql/node_modules/readable-stream/lib/_stream_passthrough.js new file mode 100644 index 0000000..895ca50 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/lib/_stream_passthrough.js @@ -0,0 +1,46 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; diff --git a/node_modules/mysql/node_modules/readable-stream/lib/_stream_readable.js b/node_modules/mysql/node_modules/readable-stream/lib/_stream_readable.js new file mode 100644 index 0000000..19ab358 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/lib/_stream_readable.js @@ -0,0 +1,951 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + + +/**/ +var debug = require('util'); +if (debug && debug.debuglog) { + debug = debug.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.readableObjectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + var Duplex = require('./_stream_duplex'); + + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + if (!addToFront) + state.reading = false; + + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); + + if (state.needReadable) + emitReadable(stream); + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } + + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); + + if (!util.isNull(ret)) + this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } + + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } +} + +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); +} + +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} diff --git a/node_modules/mysql/node_modules/readable-stream/lib/_stream_transform.js b/node_modules/mysql/node_modules/readable-stream/lib/_stream_transform.js new file mode 100644 index 0000000..905c5e4 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/lib/_stream_transform.js @@ -0,0 +1,209 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (!util.isNullOrUndefined(data)) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} diff --git a/node_modules/mysql/node_modules/readable-stream/lib/_stream_writable.js b/node_modules/mysql/node_modules/readable-stream/lib/_stream_writable.js new file mode 100644 index 0000000..db8539c --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/lib/_stream_writable.js @@ -0,0 +1,477 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.writableObjectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (!util.isFunction(cb)) + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function() { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function() { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); + + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } + + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); + +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/README.md b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/README.md new file mode 100644 index 0000000..5a76b41 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/float.patch b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/float.patch new file mode 100644 index 0000000..a06d5c0 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-var formatRegExp = /%[sdj%]/g; +-exports.format = function(f) { +- if (!isString(f)) { +- var objects = []; +- for (var i = 0; i < arguments.length; i++) { +- objects.push(inspect(arguments[i])); +- } +- return objects.join(' '); +- } +- +- var i = 1; +- var args = arguments; +- var len = args.length; +- var str = String(f).replace(formatRegExp, function(x) { +- if (x === '%%') return '%'; +- if (i >= len) return x; +- switch (x) { +- case '%s': return String(args[i++]); +- case '%d': return Number(args[i++]); +- case '%j': +- try { +- return JSON.stringify(args[i++]); +- } catch (_) { +- return '[Circular]'; +- } +- default: +- return x; +- } +- }); +- for (var x = args[i]; i < len; x = args[++i]) { +- if (isNull(x) || !isObject(x)) { +- str += ' ' + x; +- } else { +- str += ' ' + inspect(x); +- } +- } +- return str; +-}; +- +- +-// Mark that a method should not be used. +-// Returns a modified function which warns once by default. +-// If --no-deprecation is set, then it is a no-op. +-exports.deprecate = function(fn, msg) { +- // Allow for deprecating things in the process of starting up. +- if (isUndefined(global.process)) { +- return function() { +- return exports.deprecate(fn, msg).apply(this, arguments); +- }; +- } +- +- if (process.noDeprecation === true) { +- return fn; +- } +- +- var warned = false; +- function deprecated() { +- if (!warned) { +- if (process.throwDeprecation) { +- throw new Error(msg); +- } else if (process.traceDeprecation) { +- console.trace(msg); +- } else { +- console.error(msg); +- } +- warned = true; +- } +- return fn.apply(this, arguments); +- } +- +- return deprecated; +-}; +- +- +-var debugs = {}; +-var debugEnviron; +-exports.debuglog = function(set) { +- if (isUndefined(debugEnviron)) +- debugEnviron = process.env.NODE_DEBUG || ''; +- set = set.toUpperCase(); +- if (!debugs[set]) { +- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { +- var pid = process.pid; +- debugs[set] = function() { +- var msg = exports.format.apply(exports, arguments); +- console.error('%s %d: %s', set, pid, msg); +- }; +- } else { +- debugs[set] = function() {}; +- } +- } +- return debugs[set]; +-}; +- +- +-/** +- * Echos the value of a value. Trys to print the value out +- * in the best way possible given the different types. +- * +- * @param {Object} obj The object to print out. +- * @param {Object} opts Optional options object that alters the output. +- */ +-/* legacy: obj, showHidden, depth, colors*/ +-function inspect(obj, opts) { +- // default options +- var ctx = { +- seen: [], +- stylize: stylizeNoColor +- }; +- // legacy... +- if (arguments.length >= 3) ctx.depth = arguments[2]; +- if (arguments.length >= 4) ctx.colors = arguments[3]; +- if (isBoolean(opts)) { +- // legacy... +- ctx.showHidden = opts; +- } else if (opts) { +- // got an "options" object +- exports._extend(ctx, opts); +- } +- // set default options +- if (isUndefined(ctx.showHidden)) ctx.showHidden = false; +- if (isUndefined(ctx.depth)) ctx.depth = 2; +- if (isUndefined(ctx.colors)) ctx.colors = false; +- if (isUndefined(ctx.customInspect)) ctx.customInspect = true; +- if (ctx.colors) ctx.stylize = stylizeWithColor; +- return formatValue(ctx, obj, ctx.depth); +-} +-exports.inspect = inspect; +- +- +-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +-inspect.colors = { +- 'bold' : [1, 22], +- 'italic' : [3, 23], +- 'underline' : [4, 24], +- 'inverse' : [7, 27], +- 'white' : [37, 39], +- 'grey' : [90, 39], +- 'black' : [30, 39], +- 'blue' : [34, 39], +- 'cyan' : [36, 39], +- 'green' : [32, 39], +- 'magenta' : [35, 39], +- 'red' : [31, 39], +- 'yellow' : [33, 39] +-}; +- +-// Don't use 'blue' not visible on cmd.exe +-inspect.styles = { +- 'special': 'cyan', +- 'number': 'yellow', +- 'boolean': 'yellow', +- 'undefined': 'grey', +- 'null': 'bold', +- 'string': 'green', +- 'date': 'magenta', +- // "name": intentionally not styling +- 'regexp': 'red' +-}; +- +- +-function stylizeWithColor(str, styleType) { +- var style = inspect.styles[styleType]; +- +- if (style) { +- return '\u001b[' + inspect.colors[style][0] + 'm' + str + +- '\u001b[' + inspect.colors[style][1] + 'm'; +- } else { +- return str; +- } +-} +- +- +-function stylizeNoColor(str, styleType) { +- return str; +-} +- +- +-function arrayToHash(array) { +- var hash = {}; +- +- array.forEach(function(val, idx) { +- hash[val] = true; +- }); +- +- return hash; +-} +- +- +-function formatValue(ctx, value, recurseTimes) { +- // Provide a hook for user-specified inspect functions. +- // Check that value is an object with an inspect function on it +- if (ctx.customInspect && +- value && +- isFunction(value.inspect) && +- // Filter out the util module, it's inspect function is special +- value.inspect !== exports.inspect && +- // Also filter out any prototype objects using the circular check. +- !(value.constructor && value.constructor.prototype === value)) { +- var ret = value.inspect(recurseTimes, ctx); +- if (!isString(ret)) { +- ret = formatValue(ctx, ret, recurseTimes); +- } +- return ret; +- } +- +- // Primitive types cannot have properties +- var primitive = formatPrimitive(ctx, value); +- if (primitive) { +- return primitive; +- } +- +- // Look up the keys of the object. +- var keys = Object.keys(value); +- var visibleKeys = arrayToHash(keys); +- +- if (ctx.showHidden) { +- keys = Object.getOwnPropertyNames(value); +- } +- +- // Some type of object without properties can be shortcutted. +- if (keys.length === 0) { +- if (isFunction(value)) { +- var name = value.name ? ': ' + value.name : ''; +- return ctx.stylize('[Function' + name + ']', 'special'); +- } +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } +- if (isDate(value)) { +- return ctx.stylize(Date.prototype.toString.call(value), 'date'); +- } +- if (isError(value)) { +- return formatError(value); +- } +- } +- +- var base = '', array = false, braces = ['{', '}']; +- +- // Make Array say that they are Array +- if (isArray(value)) { +- array = true; +- braces = ['[', ']']; +- } +- +- // Make functions say that they are functions +- if (isFunction(value)) { +- var n = value.name ? ': ' + value.name : ''; +- base = ' [Function' + n + ']'; +- } +- +- // Make RegExps say that they are RegExps +- if (isRegExp(value)) { +- base = ' ' + RegExp.prototype.toString.call(value); +- } +- +- // Make dates with properties first say the date +- if (isDate(value)) { +- base = ' ' + Date.prototype.toUTCString.call(value); +- } +- +- // Make error with message first say the error +- if (isError(value)) { +- base = ' ' + formatError(value); +- } +- +- if (keys.length === 0 && (!array || value.length == 0)) { +- return braces[0] + base + braces[1]; +- } +- +- if (recurseTimes < 0) { +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } else { +- return ctx.stylize('[Object]', 'special'); +- } +- } +- +- ctx.seen.push(value); +- +- var output; +- if (array) { +- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +- } else { +- output = keys.map(function(key) { +- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); +- }); +- } +- +- ctx.seen.pop(); +- +- return reduceToSingleString(output, base, braces); +-} +- +- +-function formatPrimitive(ctx, value) { +- if (isUndefined(value)) +- return ctx.stylize('undefined', 'undefined'); +- if (isString(value)) { +- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') +- .replace(/'/g, "\\'") +- .replace(/\\"/g, '"') + '\''; +- return ctx.stylize(simple, 'string'); +- } +- if (isNumber(value)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- return ctx.stylize('' + value, 'number'); +- } +- if (isBoolean(value)) +- return ctx.stylize('' + value, 'boolean'); +- // For some reason typeof null is "object", so special case here. +- if (isNull(value)) +- return ctx.stylize('null', 'null'); +-} +- +- +-function formatError(value) { +- return '[' + Error.prototype.toString.call(value) + ']'; +-} +- +- +-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { +- var output = []; +- for (var i = 0, l = value.length; i < l; ++i) { +- if (hasOwnProperty(value, String(i))) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- String(i), true)); +- } else { +- output.push(''); +- } +- } +- keys.forEach(function(key) { +- if (!key.match(/^\d+$/)) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- key, true)); +- } +- }); +- return output; +-} +- +- +-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { +- var name, str, desc; +- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; +- if (desc.get) { +- if (desc.set) { +- str = ctx.stylize('[Getter/Setter]', 'special'); +- } else { +- str = ctx.stylize('[Getter]', 'special'); +- } +- } else { +- if (desc.set) { +- str = ctx.stylize('[Setter]', 'special'); +- } +- } +- if (!hasOwnProperty(visibleKeys, key)) { +- name = '[' + key + ']'; +- } +- if (!str) { +- if (ctx.seen.indexOf(desc.value) < 0) { +- if (isNull(recurseTimes)) { +- str = formatValue(ctx, desc.value, null); +- } else { +- str = formatValue(ctx, desc.value, recurseTimes - 1); +- } +- if (str.indexOf('\n') > -1) { +- if (array) { +- str = str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n').substr(2); +- } else { +- str = '\n' + str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n'); +- } +- } +- } else { +- str = ctx.stylize('[Circular]', 'special'); +- } +- } +- if (isUndefined(name)) { +- if (array && key.match(/^\d+$/)) { +- return str; +- } +- name = JSON.stringify('' + key); +- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { +- name = name.substr(1, name.length - 2); +- name = ctx.stylize(name, 'name'); +- } else { +- name = name.replace(/'/g, "\\'") +- .replace(/\\"/g, '"') +- .replace(/(^"|"$)/g, "'"); +- name = ctx.stylize(name, 'string'); +- } +- } +- +- return name + ': ' + str; +-} +- +- +-function reduceToSingleString(output, base, braces) { +- var numLinesEst = 0; +- var length = output.reduce(function(prev, cur) { +- numLinesEst++; +- if (cur.indexOf('\n') >= 0) numLinesEst++; +- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; +- }, 0); +- +- if (length > 60) { +- return braces[0] + +- (base === '' ? '' : base + '\n ') + +- ' ' + +- output.join(',\n ') + +- ' ' + +- braces[1]; +- } +- +- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +-} +- +- + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); +-} +- +- +-function pad(n) { +- return n < 10 ? '0' + n.toString(10) : n.toString(10); +-} +- +- +-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', +- 'Oct', 'Nov', 'Dec']; +- +-// 26 Feb 16:19:34 +-function timestamp() { +- var d = new Date(); +- var time = [pad(d.getHours()), +- pad(d.getMinutes()), +- pad(d.getSeconds())].join(':'); +- return [d.getDate(), months[d.getMonth()], time].join(' '); +-} +- +- +-// log is just a thin wrapper to console.log that prepends a timestamp +-exports.log = function() { +- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +-}; +- +- +-/** +- * Inherit the prototype methods from one constructor into another. +- * +- * The Function.prototype.inherits from lang.js rewritten as a standalone +- * function (not on Function.prototype). NOTE: If this file is to be loaded +- * during bootstrapping this function needs to be rewritten using some native +- * functions as prototype setup using normal JavaScript does not work as +- * expected during bootstrapping (see mirror.js in r114903). +- * +- * @param {function} ctor Constructor function which needs to inherit the +- * prototype. +- * @param {function} superCtor Constructor function to inherit prototype from. +- */ +-exports.inherits = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-exports._extend = function(origin, add) { +- // Don't do anything if add isn't an object +- if (!add || !isObject(add)) return origin; +- +- var keys = Object.keys(add); +- var i = keys.length; +- while (i--) { +- origin[keys[i]] = add[keys[i]]; +- } +- return origin; +-}; +- +-function hasOwnProperty(obj, prop) { +- return Object.prototype.hasOwnProperty.call(obj, prop); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/lib/util.js b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/lib/util.js new file mode 100644 index 0000000..9074e8e --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +function isBuffer(arg) { + return Buffer.isBuffer(arg); +} +exports.isBuffer = isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} \ No newline at end of file diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/package.json b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/package.json new file mode 100644 index 0000000..e4d8764 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/package.json @@ -0,0 +1,35 @@ +{ + "name": "core-util-is", + "version": "1.0.1", + "description": "The `util.is*` functions introduced in Node v0.12.", + "main": "lib/util.js", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is" + }, + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "readme": "# core-util-is\n\nThe `util.is*` functions introduced in Node v0.12.\n", + "readmeFilename": "README.md", + "homepage": "https://github.com/isaacs/core-util-is", + "_id": "core-util-is@1.0.1", + "_from": "core-util-is@>=1.0.0 <1.1.0" +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/util.js b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/util.js new file mode 100644 index 0000000..007fa10 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/core-util-is/util.js @@ -0,0 +1,106 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +function isBuffer(arg) { + return arg instanceof Buffer; +} +exports.isBuffer = isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/LICENSE b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/LICENSE new file mode 100644 index 0000000..dea3013 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/LICENSE @@ -0,0 +1,16 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/README.md b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/README.md new file mode 100644 index 0000000..b1c5665 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/README.md @@ -0,0 +1,42 @@ +Browser-friendly inheritance fully compatible with standard node.js +[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). + +This package exports standard `inherits` from node.js `util` module in +node environment, but also provides alternative browser-friendly +implementation through [browser +field](https://gist.github.com/shtylman/4339901). Alternative +implementation is a literal copy of standard one located in standalone +module to avoid requiring of `util`. It also has a shim for old +browsers with no `Object.create` support. + +While keeping you sure you are using standard `inherits` +implementation in node.js environment, it allows bundlers such as +[browserify](https://github.com/substack/node-browserify) to not +include full `util` package to your client code if all you need is +just `inherits` function. It worth, because browser shim for `util` +package is large and `inherits` is often the single function you need +from it. + +It's recommended to use this package instead of +`require('util').inherits` for any code that has chances to be used +not only in node.js but in browser too. + +## usage + +```js +var inherits = require('inherits'); +// then use exactly as the standard one +``` + +## note on version ~1.0 + +Version ~1.0 had completely different motivation and is not compatible +neither with 2.0 nor with standard node.js `inherits`. + +If you are using version ~1.0 and planning to switch to ~2.0, be +careful: + +* new version uses `super_` instead of `super` for referencing + superclass +* new version overwrites current prototype while old one preserves any + existing fields on it diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits.js b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits.js new file mode 100644 index 0000000..29f5e24 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits.js @@ -0,0 +1 @@ +module.exports = require('util').inherits diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits_browser.js b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits_browser.js new file mode 100644 index 0000000..c1e78a7 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/inherits_browser.js @@ -0,0 +1,23 @@ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/package.json b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/package.json new file mode 100644 index 0000000..9013262 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/package.json @@ -0,0 +1,33 @@ +{ + "name": "inherits", + "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", + "version": "2.0.1", + "keywords": [ + "inheritance", + "class", + "klass", + "oop", + "object-oriented", + "inherits", + "browser", + "browserify" + ], + "main": "./inherits.js", + "browser": "./inherits_browser.js", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/inherits" + }, + "license": "ISC", + "scripts": { + "test": "node test" + }, + "readme": "Browser-friendly inheritance fully compatible with standard node.js\n[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor).\n\nThis package exports standard `inherits` from node.js `util` module in\nnode environment, but also provides alternative browser-friendly\nimplementation through [browser\nfield](https://gist.github.com/shtylman/4339901). Alternative\nimplementation is a literal copy of standard one located in standalone\nmodule to avoid requiring of `util`. It also has a shim for old\nbrowsers with no `Object.create` support.\n\nWhile keeping you sure you are using standard `inherits`\nimplementation in node.js environment, it allows bundlers such as\n[browserify](https://github.com/substack/node-browserify) to not\ninclude full `util` package to your client code if all you need is\njust `inherits` function. It worth, because browser shim for `util`\npackage is large and `inherits` is often the single function you need\nfrom it.\n\nIt's recommended to use this package instead of\n`require('util').inherits` for any code that has chances to be used\nnot only in node.js but in browser too.\n\n## usage\n\n```js\nvar inherits = require('inherits');\n// then use exactly as the standard one\n```\n\n## note on version ~1.0\n\nVersion ~1.0 had completely different motivation and is not compatible\nneither with 2.0 nor with standard node.js `inherits`.\n\nIf you are using version ~1.0 and planning to switch to ~2.0, be\ncareful:\n\n* new version uses `super_` instead of `super` for referencing\n superclass\n* new version overwrites current prototype while old one preserves any\n existing fields on it\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/isaacs/inherits/issues" + }, + "homepage": "https://github.com/isaacs/inherits", + "_id": "inherits@2.0.1", + "_from": "inherits@>=2.0.1 <2.1.0" +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/test.js b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/test.js new file mode 100644 index 0000000..fc53012 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/inherits/test.js @@ -0,0 +1,25 @@ +var inherits = require('./inherits.js') +var assert = require('assert') + +function test(c) { + assert(c.constructor === Child) + assert(c.constructor.super_ === Parent) + assert(Object.getPrototypeOf(c) === Child.prototype) + assert(Object.getPrototypeOf(Object.getPrototypeOf(c)) === Parent.prototype) + assert(c instanceof Child) + assert(c instanceof Parent) +} + +function Child() { + Parent.call(this) + test(this) +} + +function Parent() {} + +inherits(Child, Parent) + +var c = new Child +test(c) + +console.log('ok') diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/README.md b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/README.md new file mode 100644 index 0000000..052a62b --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/README.md @@ -0,0 +1,54 @@ + +# isarray + +`Array#isArray` for older browsers. + +## Usage + +```js +var isArray = require('isarray'); + +console.log(isArray([])); // => true +console.log(isArray({})); // => false +``` + +## Installation + +With [npm](http://npmjs.org) do + +```bash +$ npm install isarray +``` + +Then bundle for the browser with +[browserify](https://github.com/substack/browserify). + +With [component](http://component.io) do + +```bash +$ component install juliangruber/isarray +``` + +## License + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/build/build.js b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/build/build.js new file mode 100644 index 0000000..ec58596 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/build/build.js @@ -0,0 +1,209 @@ + +/** + * Require the given path. + * + * @param {String} path + * @return {Object} exports + * @api public + */ + +function require(path, parent, orig) { + var resolved = require.resolve(path); + + // lookup failed + if (null == resolved) { + orig = orig || path; + parent = parent || 'root'; + var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); + err.path = orig; + err.parent = parent; + err.require = true; + throw err; + } + + var module = require.modules[resolved]; + + // perform real require() + // by invoking the module's + // registered function + if (!module.exports) { + module.exports = {}; + module.client = module.component = true; + module.call(this, module.exports, require.relative(resolved), module); + } + + return module.exports; +} + +/** + * Registered modules. + */ + +require.modules = {}; + +/** + * Registered aliases. + */ + +require.aliases = {}; + +/** + * Resolve `path`. + * + * Lookup: + * + * - PATH/index.js + * - PATH.js + * - PATH + * + * @param {String} path + * @return {String} path or null + * @api private + */ + +require.resolve = function(path) { + if (path.charAt(0) === '/') path = path.slice(1); + var index = path + '/index.js'; + + var paths = [ + path, + path + '.js', + path + '.json', + path + '/index.js', + path + '/index.json' + ]; + + for (var i = 0; i < paths.length; i++) { + var path = paths[i]; + if (require.modules.hasOwnProperty(path)) return path; + } + + if (require.aliases.hasOwnProperty(index)) { + return require.aliases[index]; + } +}; + +/** + * Normalize `path` relative to the current path. + * + * @param {String} curr + * @param {String} path + * @return {String} + * @api private + */ + +require.normalize = function(curr, path) { + var segs = []; + + if ('.' != path.charAt(0)) return path; + + curr = curr.split('/'); + path = path.split('/'); + + for (var i = 0; i < path.length; ++i) { + if ('..' == path[i]) { + curr.pop(); + } else if ('.' != path[i] && '' != path[i]) { + segs.push(path[i]); + } + } + + return curr.concat(segs).join('/'); +}; + +/** + * Register module at `path` with callback `definition`. + * + * @param {String} path + * @param {Function} definition + * @api private + */ + +require.register = function(path, definition) { + require.modules[path] = definition; +}; + +/** + * Alias a module definition. + * + * @param {String} from + * @param {String} to + * @api private + */ + +require.alias = function(from, to) { + if (!require.modules.hasOwnProperty(from)) { + throw new Error('Failed to alias "' + from + '", it does not exist'); + } + require.aliases[to] = from; +}; + +/** + * Return a require function relative to the `parent` path. + * + * @param {String} parent + * @return {Function} + * @api private + */ + +require.relative = function(parent) { + var p = require.normalize(parent, '..'); + + /** + * lastIndexOf helper. + */ + + function lastIndexOf(arr, obj) { + var i = arr.length; + while (i--) { + if (arr[i] === obj) return i; + } + return -1; + } + + /** + * The relative require() itself. + */ + + function localRequire(path) { + var resolved = localRequire.resolve(path); + return require(resolved, parent, path); + } + + /** + * Resolve relative to the parent. + */ + + localRequire.resolve = function(path) { + var c = path.charAt(0); + if ('/' == c) return path.slice(1); + if ('.' == c) return require.normalize(p, path); + + // resolve deps by returning + // the dep in the nearest "deps" + // directory + var segs = parent.split('/'); + var i = lastIndexOf(segs, 'deps') + 1; + if (!i) i = 0; + path = segs.slice(0, i + 1).join('/') + '/deps/' + path; + return path; + }; + + /** + * Check if module is defined at `path`. + */ + + localRequire.exists = function(path) { + return require.modules.hasOwnProperty(localRequire.resolve(path)); + }; + + return localRequire; +}; +require.register("isarray/index.js", function(exports, require, module){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; + +}); +require.alias("isarray/index.js", "isarray/index.js"); + diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/component.json b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/component.json new file mode 100644 index 0000000..9e31b68 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/component.json @@ -0,0 +1,19 @@ +{ + "name" : "isarray", + "description" : "Array#isArray for older browsers", + "version" : "0.0.1", + "repository" : "juliangruber/isarray", + "homepage": "https://github.com/juliangruber/isarray", + "main" : "index.js", + "scripts" : [ + "index.js" + ], + "dependencies" : {}, + "keywords": ["browser","isarray","array"], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT" +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/index.js b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/index.js new file mode 100644 index 0000000..5f5ad45 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/index.js @@ -0,0 +1,3 @@ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/package.json b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/package.json new file mode 100644 index 0000000..fc7904b --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/isarray/package.json @@ -0,0 +1,54 @@ +{ + "name": "isarray", + "description": "Array#isArray for older browsers", + "version": "0.0.1", + "repository": { + "type": "git", + "url": "git://github.com/juliangruber/isarray.git" + }, + "homepage": "https://github.com/juliangruber/isarray", + "main": "index.js", + "scripts": { + "test": "tap test/*.js" + }, + "dependencies": {}, + "devDependencies": { + "tap": "*" + }, + "keywords": [ + "browser", + "isarray", + "array" + ], + "author": { + "name": "Julian Gruber", + "email": "mail@juliangruber.com", + "url": "http://juliangruber.com" + }, + "license": "MIT", + "readme": "\n# isarray\n\n`Array#isArray` for older browsers.\n\n## Usage\n\n```js\nvar isArray = require('isarray');\n\nconsole.log(isArray([])); // => true\nconsole.log(isArray({})); // => false\n```\n\n## Installation\n\nWith [npm](http://npmjs.org) do\n\n```bash\n$ npm install isarray\n```\n\nThen bundle for the browser with\n[browserify](https://github.com/substack/browserify).\n\nWith [component](http://component.io) do\n\n```bash\n$ component install juliangruber/isarray\n```\n\n## License\n\n(MIT)\n\nCopyright (c) 2013 Julian Gruber <julian@juliangruber.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n", + "readmeFilename": "README.md", + "_id": "isarray@0.0.1", + "dist": { + "shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "tarball": "http://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "_from": "isarray@0.0.1", + "_npmVersion": "1.2.18", + "_npmUser": { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + "maintainers": [ + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + } + ], + "directories": {}, + "_shasum": "8a18acfca9a8f4177e09abfc6038939b05d1eedf", + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "bugs": { + "url": "https://github.com/juliangruber/isarray/issues" + } +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/.npmignore b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/.npmignore new file mode 100644 index 0000000..206320c --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/.npmignore @@ -0,0 +1,2 @@ +build +test diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/LICENSE b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/LICENSE new file mode 100644 index 0000000..6de584a --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/LICENSE @@ -0,0 +1,20 @@ +Copyright Joyent, Inc. and other Node contributors. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/README.md b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/README.md new file mode 100644 index 0000000..4d2aa00 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/README.md @@ -0,0 +1,7 @@ +**string_decoder.js** (`require('string_decoder')`) from Node.js core + +Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details. + +Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.** + +The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version. \ No newline at end of file diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/index.js b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/index.js new file mode 100644 index 0000000..b00e54f --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/index.js @@ -0,0 +1,221 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = require('buffer').Buffer; + +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; + + +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} diff --git a/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/package.json b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/package.json new file mode 100644 index 0000000..0364d54 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/node_modules/string_decoder/package.json @@ -0,0 +1,54 @@ +{ + "name": "string_decoder", + "version": "0.10.31", + "description": "The string_decoder module from Node core", + "main": "index.js", + "dependencies": {}, + "devDependencies": { + "tap": "~0.4.8" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/rvagg/string_decoder.git" + }, + "homepage": "https://github.com/rvagg/string_decoder", + "keywords": [ + "string", + "decoder", + "browser", + "browserify" + ], + "license": "MIT", + "gitHead": "d46d4fd87cf1d06e031c23f1ba170ca7d4ade9a0", + "bugs": { + "url": "https://github.com/rvagg/string_decoder/issues" + }, + "_id": "string_decoder@0.10.31", + "_shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94", + "_from": "string_decoder@>=0.10.0 <0.11.0", + "_npmVersion": "1.4.23", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "dist": { + "shasum": "62e203bc41766c6c28c9fc84301dab1c5310fa94", + "tarball": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mysql/node_modules/readable-stream/package.json b/node_modules/mysql/node_modules/readable-stream/package.json new file mode 100644 index 0000000..307cd42 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/package.json @@ -0,0 +1,70 @@ +{ + "name": "readable-stream", + "version": "1.1.13", + "description": "Streams3, a user-land copy of the stream library from Node.js v0.11.x", + "main": "readable.js", + "dependencies": { + "core-util-is": "~1.0.0", + "isarray": "0.0.1", + "string_decoder": "~0.10.x", + "inherits": "~2.0.1" + }, + "devDependencies": { + "tap": "~0.2.6" + }, + "scripts": { + "test": "tap test/simple/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/isaacs/readable-stream" + }, + "keywords": [ + "readable", + "stream", + "pipe" + ], + "browser": { + "util": false + }, + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "license": "MIT", + "gitHead": "3b672fd7ae92acf5b4ffdbabf74b372a0a56b051", + "bugs": { + "url": "https://github.com/isaacs/readable-stream/issues" + }, + "homepage": "https://github.com/isaacs/readable-stream", + "_id": "readable-stream@1.1.13", + "_shasum": "f6eef764f514c89e2b9e23146a75ba106756d23e", + "_from": "readable-stream@>=1.1.13 <1.2.0", + "_npmVersion": "1.4.23", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "maintainers": [ + { + "name": "isaacs", + "email": "i@izs.me" + }, + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "dist": { + "shasum": "f6eef764f514c89e2b9e23146a75ba106756d23e", + "tarball": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mysql/node_modules/readable-stream/passthrough.js b/node_modules/mysql/node_modules/readable-stream/passthrough.js new file mode 100644 index 0000000..27e8d8a --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/passthrough.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_passthrough.js") diff --git a/node_modules/mysql/node_modules/readable-stream/readable.js b/node_modules/mysql/node_modules/readable-stream/readable.js new file mode 100644 index 0000000..09b8bf5 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/readable.js @@ -0,0 +1,7 @@ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); diff --git a/node_modules/mysql/node_modules/readable-stream/transform.js b/node_modules/mysql/node_modules/readable-stream/transform.js new file mode 100644 index 0000000..5d482f0 --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/transform.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_transform.js") diff --git a/node_modules/mysql/node_modules/readable-stream/writable.js b/node_modules/mysql/node_modules/readable-stream/writable.js new file mode 100644 index 0000000..e1e9efd --- /dev/null +++ b/node_modules/mysql/node_modules/readable-stream/writable.js @@ -0,0 +1 @@ +module.exports = require("./lib/_stream_writable.js") diff --git a/node_modules/mysql/node_modules/require-all/.npmignore b/node_modules/mysql/node_modules/require-all/.npmignore new file mode 100644 index 0000000..b95d33c --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/.npmignore @@ -0,0 +1,2 @@ +*.un~ +node_modules/ \ No newline at end of file diff --git a/node_modules/mysql/node_modules/require-all/License b/node_modules/mysql/node_modules/require-all/License new file mode 100644 index 0000000..143bad2 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/License @@ -0,0 +1,19 @@ +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/mysql/node_modules/require-all/Readme.md b/node_modules/mysql/node_modules/require-all/Readme.md new file mode 100644 index 0000000..fce0a7b --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/Readme.md @@ -0,0 +1,25 @@ +# require-all + +An easy way to require all files within a directory. + +## Usage + +```js +var controllers = require('require-all')({ + dirname : __dirname + '/controllers', + filter : /(.+Controller)\.js$/, + excludeDirs : /^\.(git|svn)$/ +}); + +// controllers now is an object with references to all modules matching the filter +// for example: +// { HomeController: function HomeController() {...}, ...} +``` + +## Advanced usage + +If your objective is to simply require all .js and .json files in a directory you can just pass a string to require-all: + +``` js +var libs = require('require-all')(__dirname + '/lib'); +``` diff --git a/node_modules/mysql/node_modules/require-all/index.js b/node_modules/mysql/node_modules/require-all/index.js new file mode 100644 index 0000000..b7e1d04 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/index.js @@ -0,0 +1,40 @@ +var fs = require('fs'); + +module.exports = function requireAll(options) { + if (typeof options === 'string') { + options = { + dirname: options, + filter: /(.+)\.js(on)?$/, + excludeDirs: /^\.(git|svn)$/ + }; + } + + var files = fs.readdirSync(options.dirname); + var modules = {}; + + function excludeDirectory(dirname) { + return options.excludeDirs && dirname.match(options.excludeDirs); + } + + files.forEach(function (file) { + var filepath = options.dirname + '/' + file; + if (fs.statSync(filepath).isDirectory()) { + + if (excludeDirectory(file)) return; + + modules[file] = requireAll({ + dirname: filepath, + filter: options.filter, + excludeDirs: options.excludeDirs + }); + + } else { + var match = file.match(options.filter); + if (!match) return; + + modules[match[1]] = require(filepath); + } + }); + + return modules; +}; diff --git a/node_modules/mysql/node_modules/require-all/package.json b/node_modules/mysql/node_modules/require-all/package.json new file mode 100644 index 0000000..b4576b8 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/package.json @@ -0,0 +1,66 @@ +{ + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "name": "require-all", + "description": "An easy way to require all files within a directory.", + "version": "0.0.8", + "scripts": { + "test": "node test/test.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-require-all.git" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/felixge/node-require-all/blob/master/License" + } + ], + "main": "./index", + "engines": { + "node": "*" + }, + "dependencies": {}, + "devDependencies": { + "semver": "~2.1.0" + }, + "optionalDependencies": {}, + "readme": "# require-all\n\nAn easy way to require all files within a directory.\n\n## Usage\n\n```js\nvar controllers = require('require-all')({\n dirname : __dirname + '/controllers',\n filter : /(.+Controller)\\.js$/,\n excludeDirs : /^\\.(git|svn)$/\n});\n\n// controllers now is an object with references to all modules matching the filter\n// for example:\n// { HomeController: function HomeController() {...}, ...}\n```\n\n## Advanced usage\n\nIf your objective is to simply require all .js and .json files in a directory you can just pass a string to require-all:\n\n``` js\nvar libs = require('require-all')(__dirname + '/lib');\n```\n", + "readmeFilename": "Readme.md", + "bugs": { + "url": "https://github.com/felixge/node-require-all/issues" + }, + "_id": "require-all@0.0.8", + "dist": { + "shasum": "a7d4307d90e422fcb9f04af018c149920074e4b3", + "tarball": "http://registry.npmjs.org/require-all/-/require-all-0.0.8.tgz" + }, + "_from": "require-all@0.0.8", + "_npmVersion": "1.2.32", + "_npmUser": { + "name": "dscape", + "email": "nunojobpinto@gmail.com" + }, + "maintainers": [ + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "thlorenz", + "email": "thlorenz@gmx.de" + }, + { + "name": "dscape", + "email": "nunojobpinto@gmail.com" + } + ], + "directories": {}, + "_shasum": "a7d4307d90e422fcb9f04af018c149920074e4b3", + "_resolved": "https://registry.npmjs.org/require-all/-/require-all-0.0.8.tgz", + "homepage": "https://github.com/felixge/node-require-all" +} diff --git a/node_modules/mysql/node_modules/require-all/test/controllers/main-Controller.js b/node_modules/mysql/node_modules/require-all/test/controllers/main-Controller.js new file mode 100644 index 0000000..355ce40 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/controllers/main-Controller.js @@ -0,0 +1,4 @@ +exports.index = 1; +exports.show = 2; +exports.add = 3; +exports.edit = 4; diff --git a/node_modules/mysql/node_modules/require-all/test/controllers/notthis.js b/node_modules/mysql/node_modules/require-all/test/controllers/notthis.js new file mode 100644 index 0000000..8ac88c5 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/controllers/notthis.js @@ -0,0 +1 @@ +exports.yes = 'no'; diff --git a/node_modules/mysql/node_modules/require-all/test/controllers/other-Controller.js b/node_modules/mysql/node_modules/require-all/test/controllers/other-Controller.js new file mode 100644 index 0000000..aec8f24 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/controllers/other-Controller.js @@ -0,0 +1,2 @@ +exports.index = 1; +exports.show = 'nothing' diff --git a/node_modules/mysql/node_modules/require-all/test/filterdir/root.js b/node_modules/mysql/node_modules/require-all/test/filterdir/root.js new file mode 100644 index 0000000..c9fd536 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/filterdir/root.js @@ -0,0 +1 @@ +module.exports = { guten: 'tag' }; diff --git a/node_modules/mysql/node_modules/require-all/test/filterdir/sub/hello.js b/node_modules/mysql/node_modules/require-all/test/filterdir/sub/hello.js new file mode 100644 index 0000000..0174eea --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/filterdir/sub/hello.js @@ -0,0 +1 @@ +module.exports = { guten: 'abend' }; diff --git a/node_modules/mysql/node_modules/require-all/test/mydir/foo.js b/node_modules/mysql/node_modules/require-all/test/mydir/foo.js new file mode 100644 index 0000000..cb1c2c0 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/mydir/foo.js @@ -0,0 +1 @@ +module.exports = 'bar'; diff --git a/node_modules/mysql/node_modules/require-all/test/mydir/hello.js b/node_modules/mysql/node_modules/require-all/test/mydir/hello.js new file mode 100644 index 0000000..b1d17c1 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/mydir/hello.js @@ -0,0 +1,2 @@ +exports.world = true; +exports.universe = 42; diff --git a/node_modules/mysql/node_modules/require-all/test/mydir/sub/config.json b/node_modules/mysql/node_modules/require-all/test/mydir/sub/config.json new file mode 100644 index 0000000..d2b5939 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/mydir/sub/config.json @@ -0,0 +1,4 @@ +{ + "settingA": "A", + "settingB": "B" +} diff --git a/node_modules/mysql/node_modules/require-all/test/mydir/sub/no.2js b/node_modules/mysql/node_modules/require-all/test/mydir/sub/no.2js new file mode 100644 index 0000000..ec01c2c --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/mydir/sub/no.2js @@ -0,0 +1 @@ +module.exports = true; diff --git a/node_modules/mysql/node_modules/require-all/test/mydir/sub/yes.js b/node_modules/mysql/node_modules/require-all/test/mydir/sub/yes.js new file mode 100644 index 0000000..ec01c2c --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/mydir/sub/yes.js @@ -0,0 +1 @@ +module.exports = true; diff --git a/node_modules/mysql/node_modules/require-all/test/test.js b/node_modules/mysql/node_modules/require-all/test/test.js new file mode 100644 index 0000000..6c086c4 --- /dev/null +++ b/node_modules/mysql/node_modules/require-all/test/test.js @@ -0,0 +1,82 @@ +var assert = require('assert'); +var semver = require('semver'); +var requireAll = require('..'); + +var controllers = requireAll({ + dirname: __dirname + '/controllers', + filter: /(.+Controller)\.js$/ +}); + +assert.deepEqual(controllers, { + 'main-Controller': { + index: 1, + show: 2, + add: 3, + edit: 4 + }, + + 'other-Controller': { + index: 1, + show: 'nothing' + } +}); + +// +// requiring json only became an option in 0.6+ +// +if (semver.gt(process.version, 'v0.6.0')) { + var mydir = requireAll({ + dirname: __dirname + '/mydir', + filter: /(.+)\.(js|json)$/ + }); + + var mydir_contents = { + foo: 'bar', + hello: { + world: true, + universe: 42 + }, + sub: { + config: { + settingA: 'A', + settingB: 'B' + }, + yes: true + } + }; + + assert.deepEqual(mydir, mydir_contents); + + var defaults = requireAll(__dirname + '/mydir'); + + assert.deepEqual(defaults, mydir_contents); +} + +var unfiltered = requireAll({ + dirname: __dirname + '/filterdir', + filter: /(.+)\.js$/ +}); + +assert(unfiltered['.svn']); +assert(unfiltered.root); +assert(unfiltered.sub); + +var excludedSvn = requireAll({ + dirname: __dirname + '/filterdir', + filter: /(.+)\.js$/, + excludeDirs: /^\.svn$/ +}); + +assert.equal(excludedSvn['.svn'], undefined); +assert.ok(excludedSvn.root); +assert.ok(excludedSvn.sub); + +var excludedSvnAndSub = requireAll({ + dirname: __dirname + '/filterdir', + filter: /(.+)\.js$/, + excludeDirs: /^(\.svn|sub)$/ +}); + +assert.equal(excludedSvnAndSub['.svn'], undefined); +assert.ok(excludedSvnAndSub.root); +assert.equal(excludedSvnAndSub.sub, undefined); diff --git a/node_modules/mysql/package.json b/node_modules/mysql/package.json new file mode 100644 index 0000000..70b3de5 --- /dev/null +++ b/node_modules/mysql/package.json @@ -0,0 +1,106 @@ +{ + "name": "mysql", + "description": "A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 100% MIT licensed.", + "version": "2.5.2", + "license": "MIT", + "author": { + "name": "Felix Geisendörfer", + "email": "felix@debuggable.com", + "url": "http://debuggable.com/" + }, + "contributors": [ + { + "name": "Andrey Sidorov", + "email": "sidorares@yandex.ru" + }, + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "Diogo Resende", + "email": "dresende@thinkdigital.pt" + } + ], + "homepage": "https://github.com/felixge/node-mysql", + "repository": { + "type": "git", + "url": "https://github.com/felixge/node-mysql" + }, + "dependencies": { + "bignumber.js": "1.4.1", + "readable-stream": "~1.1.13", + "require-all": "0.0.8" + }, + "devDependencies": { + "istanbul": "0.3.2", + "rimraf": "2.2.8", + "mkdirp": "0.5.0", + "urun": "0.0.8", + "utest": "0.0.8" + }, + "engines": { + "node": ">= 0.6" + }, + "scripts": { + "test": "node test/run.js", + "test-cov": "node test/run-cov.js", + "test-travis": "node test/run-cov.js lcovonly" + }, + "gitHead": "c244a56a78003e7218d24bb4e5aa719e402b823d", + "bugs": { + "url": "https://github.com/felixge/node-mysql/issues" + }, + "_id": "mysql@2.5.2", + "_shasum": "8e7f12a940e8e958c417f9e80bf20ef8c36afd5a", + "_from": "mysql@*", + "_npmVersion": "1.4.21", + "_npmUser": { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + }, + "maintainers": [ + { + "name": "felixge", + "email": "felix@debuggable.com" + }, + { + "name": "egorfine", + "email": "me@egorfine.com" + }, + { + "name": "dresende", + "email": "dresende@thinkdigital.pt" + }, + { + "name": "femto113", + "email": "ken.woodruff@gmail.com" + }, + { + "name": "nate.lillich", + "email": "nate@lifewanted.com" + }, + { + "name": "tolgaek", + "email": "tolga.ekmen@gmail.com" + }, + { + "name": "sidorares", + "email": "sidorares@yandex.com" + }, + { + "name": "seanmonstar", + "email": "sean.monstar@gmail.com" + }, + { + "name": "dougwilson", + "email": "doug@somethingdoug.com" + } + ], + "dist": { + "shasum": "8e7f12a940e8e958c417f9e80bf20ef8c36afd5a", + "tarball": "http://registry.npmjs.org/mysql/-/mysql-2.5.2.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/mysql/-/mysql-2.5.2.tgz" +} diff --git a/node_modules/mysql2/.npmignore b/node_modules/mysql2/.npmignore new file mode 100644 index 0000000..59ee676 --- /dev/null +++ b/node_modules/mysql2/.npmignore @@ -0,0 +1,17 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz +.DS_Store + +tmp +pids +logs + +node_modules +npm-debug.log + diff --git a/node_modules/mysql2/.travis.yml b/node_modules/mysql2/.travis.yml new file mode 100644 index 0000000..10288b8 --- /dev/null +++ b/node_modules/mysql2/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +before_script: + - mysql -e 'create database if not exists test;' +node_js: + - "0.8" + - "0.10" + - "0.11" diff --git a/node_modules/mysql2/Changelog.md b/node_modules/mysql2/Changelog.md new file mode 100644 index 0000000..aa84625 --- /dev/null +++ b/node_modules/mysql2/Changelog.md @@ -0,0 +1,135 @@ +Backlog: + - Multiple results support in binary protocol #27 + - Apply timezone from config to DATETIME values with no tz #15 + - custom typeCast handlers in generated parser #39 + +HEAD + +0.12.5 - 30/07/2014 + - add 'execute' pool method similar to Pool##query #114 + - more debug output behind debug flag + +0.12.4 - 17/07/2014 + - 'debug' connection option now result in lots of + debug output #112 #77 + - send corectly compression flag if compression is on #102 + + +0.12.3 - 11/07/2014 + - fix node 0.8 - incompatible dependency version + +0.12.2 - 11/07/2014 + + - output milliseconds in date type #107 + - deserialise length coded int with > 24 bit numbers + to js int / float (and not throw "Bignts not supported") #108 + - support for Bigint numbers in insertId + +0.12.1 - 30/04/2014 + + - 'dateStrings' connection option support #99 + - use anonymous function for packet routing instead + of .bind() 3-5% speed improvement + - GEOMETRY type support in bimary protocol #97 + +0.12.0 - 29/04/2014 + + - route connection time errors from handshke command to + connection #96 + + - support for nestTables and rowsAsArray options in query() + and execute() #95, #94 + + - bugfix: date as parameter in prepared statement, + day of week was used incorrectly + instead of day of month #89 ab28dfca839728dfe40d941091902185d7c19b57 + + - GEOMETRY type support ported from node-mysql #93 ebd30fd12b3b7f53d97b9d09f947b12f61e0c2c5 + +0.11.8 + + - add DATE type support #84 1d49651d8e40bf43b79937d9de9b2909126b892c + - faster DATE parsing in text protocol cdfed2881462798bd85fbf906ea604875a3bd625 + + +0.11.7 + - initial implementaion of binlog protocol #83 #78 c8d45da6fc13a56d95ce6d57c3c8aa9524548770 + - interpret null DOUBLE values as null instead 0 #85 4c03b23f30949be0608d9543d69243944d79bb4a + - use srcEscape for null values (bunary parser) ef50bcafa452588eda4a40037b41f6b961085046 + +0.11.6 + - minor cleanups + +0.11.5 + - fix for non-utf strings serialisation (binary protocol only) cf9594aaab5b3d51a112bd1f43b39a55f508eef7 + +0.11.4 + - support YEAR type in prepared statements a0f33b5a4de4529130b3c4137f7a1dd3c02aed9e + +0.11.3 + - add transaction helpers #56, #76 cc0a9f9b721900d3a22c7fc84a5244c74cd33dd5 + +0.11.2 + + - wrap callbacks in nextTick for exception safety b73ac9868804b603a0ab6df6129cf3682476d118 + - domains support #73 36cba61359c83018a847ac4e7748d920b6f863c4 + +0.11.1 + + - buxfix: connection.connect callback was called more than once + #72 0352eefdafc0986f1ec79c0ce285f722ca12af16 + +0.11.0 + - Bundle Amazon RDS cert and allow to connect using e6af097b5facc089f1999c1fb076ada0ce2e7e99 + 'Amazon RDS' as ssl value + +0.10.7 + + - Amazon RDS+ssl example and public CA cert 709394a4afbbaf0500439e72caec5d37e949fe26 + - pool updated from node-mysql #71, #68, #61 db561dbe10a55bb0f9893eb0e2c4b429edd6ee3a + +0.10.6 + - handle TIMESTAMP type #59 6dd6fc82d95a16e18092c4db4e8da225b37e9314 + - rename pool's connection.end() to connection.release() #53 c63b2442e3c0fb5ea3953725ba9c1b3e08b2b831 + +0.10.5 + + - node-mysql compatibility: remove 'number of results in response' + callback argument (Brian White) #46 40af0530403a3892743d32974055c5ea23cbd3ec + - node 0.11 (use on('data') instead of ondata ) 39906c78b85a77e468694814a50f99714d7bbbd6 + - fix again ssl (#41) 713051bf997a186774b618cde583707320a1d551 + +0.10.4 + - node-mysql compatibility: remove 'number of results in response' + callback argument (Brian White) #45 c9cb926360da5e4028f7d2f83f4b4e94897cd8b8 + - 'resultIndex' parameter for non-multiple results query 8879bdde397b6cd730d234383fa322becd1134de + +0.10.3 + - various ssl fixes and refactoring (ssl was broken for some time) 213d375f7263cb6f5e724fdac3ea156ccee4bbd4 + - Server protocol: handle null values serialisation + (Michael Muturi Njonge) #36 831b2a100795f36649f0c3d79b7839a95f771a05 + +0.10.2 + - return DECIMAL and NEWDECIMAL as string in binary prot #40 969fba6ff1dbf14d53d3efc9f94083b8306cf0b5 + +0.10.1 + - Added ping command #38 cbca8648d1282fb57e55b3735c3b4d9a46d89d7b + +0.9.2 + - correctly parse NULL result for string and number #35 0a4ac65ec812f75861dc00c9243921d5d6602914 + - do not pollute global namespace from evaled parser #11 4b6ddaf0f70150945d0fea804db9106f343a0e51 + +0.9.1 + - PoolClaster ported from node-mysql #34 + +0.8.21 + - Fix in error message parsing (Noam Wasersprung) #31 6cc80a67eaa3baac7dd8eee7182c9eb00977e81a + - return insert/delete header for insert/delete commands #32 72aa8fe70981d7410a10edb9d7921e5d6ce1d3ca + +0.8.20 + - Make packet parser work with 0.11 ondata(buffer) with no start,end 9005fd1 + - Allow to use Date-like objects as date parameters (Amir Livneh) 6138dad0581fd5e2c45e1ce0b999e334db8979cf + +0.8.19 + - Multiple results support in text protocol #15 4812adaf1aa5b1dfa775a6cf0fa3bae54a7827d0 + - Use connection flags from createConnection parameters/url string 9218f055ceeb95ae7205348e06c07b89b799d031 diff --git a/node_modules/mysql2/License b/node_modules/mysql2/License new file mode 100644 index 0000000..51c1bf4 --- /dev/null +++ b/node_modules/mysql2/License @@ -0,0 +1,19 @@ +Copyright (c) 2013 Andrey Sidorov (sidorares@yandex.ru) and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/mysql2/README.md b/node_modules/mysql2/README.md new file mode 100644 index 0000000..6f606b3 --- /dev/null +++ b/node_modules/mysql2/README.md @@ -0,0 +1,244 @@ +#node-mysql2 + +[![Build Status](https://secure.travis-ci.org/sidorares/node-mysql2.png)](http://travis-ci.org/sidorares/node-mysql2) [![](https://gemnasium.com/sidorares/node-mysql2.png)](https://gemnasium.com/npms/mysql2) [TODO](https://github.com/cainus/node-coveralls): [![](https://coveralls.io/repos/sidorares/node-mysql2/badge.png)](https://coveralls.io/r/sidorares/node-mysql2) + + +Mysql client for node.js. Written in native JavaScript and aims to be mostly api compatible with [node-mysql](https://github.com/felixge/node-mysql) + +[![NPM](https://nodei.co/npm/mysql2.png?downloads=true&stars=true)](https://nodei.co/npm/mysql2/) +[![NPM](https://nodei.co/npm-dl/mysql2.png?months=6)](https://nodei.co/npm/mysql2/) + +## Features + + In addition to client-side query/escape and connection pooling + + - MySQL server API for proxies and mocks + - SSL and compression + - prepared statements + - binlog protocol client + +## Documentation + +See [node-mysql](https://github.com/felixge/node-mysql) documentation. If you see api incompatibilities, please report via github issue. + +## Known incompatibilities with node-mysql + +All numeric types converted to numbers. In contrast to node-mysql `zeroFill` flag is ignored in type conversion +You need to check corresponding field zeroFill flag and convert to string manually if this is of importance to you. + +DECIMAL and NEWDECIMAL types always returned as string + +## Known not yet supported features + +`LOAD DATA INFILE` and `SELECT INTO OUTFILE` +`client.changeUser()` + +## Examples + +Simple select: + +```js +var mysql = require('mysql2'); +var connection = mysql.createConnection({ user: 'test', database: 'test'}); + +connection.query('SELECT 1+1 as test1', function(err, rows) { + // +}); +``` + +Prepared statement and parameters: + +```js +var mysql = require('mysql2'); +var connection = mysql.createConnection({ user: 'test', database: 'test'}); + +connection.execute('SELECT 1+? as test1', [10], function(err, rows) { + // +}); +``` + +Connecting over encrypted connection: + +```js +var fs = require('fs'); +var mysql = require('mysql2'); +var connection = mysql.createConnection({ + user: 'test', + database: 'test', + ssl: { + key: fs.readFileSync('./certs/client-key.pem'), + cert: fs.readFileSync('./certs/client-cert.pem') + } +}); +connection.query('SELECT 1+1 as test1', console.log); +``` + +You can use 'Amazon RDS' string as value to ssl property to connect to Amazon RDS mysql over ssl (in that case http://s3.amazonaws.com/rds-downloads/mysql-ssl-ca-cert.pem CA cert is used) + +``` +var mysql = require('mysql2'); +var connection = mysql.createConnection({ + user: 'foo', + password: 'bar', + host: 'db.id.ap-southeast-2.rds.amazonaws.com', + ssl: 'Amazon RDS' +}); + +conn.query('show status like \'Ssl_cipher\'', function(err, res) { + console.log(err, res); + conn.end(); +}); +``` +Receiving rows as array of columns instead of hash with column name as key: + +```js +var options = {sql: 'select A,B,C,D from foo', rowsAsArray: true}; +connection.query(options, function(err, results) { + /* results will be an array of arrays like this now: + [[ + 'field A value', + 'field B value', + 'field C value', + 'field D value', + ], ...] + */ +}); + +``` + +Connecting using custom stream: + +```js +var net = require('net'); +var mysql = require('mysql2'); +var shape = require('shaper'); +var connection = mysql.createConnection({ + user: 'test', + database: 'test', + stream: net.connect('/tmp/mysql.sock').pipe(shape(10)) // emulate 10 bytes/sec link +}); +connection.query('SELECT 1+1 as test1', console.log); +``` + +Simple mysql proxy server: + +```js +var mysql = require('mysql2'); + +var server = mysql.createServer(); +server.listen(3307); +server.on('connection', function(conn) { + console.log('connection'); + + conn.serverHandshake({ + protocolVersion: 10, + serverVersion: 'node.js rocks', + connectionId: 1234, + statusFlags: 2, + characterSet: 8, + capabilityFlags: 0xffffff + }); + + conn.on('field_list', function(table, fields) { + console.log('field list:', table, fields); + conn.writeEof(); + }); + + var remote = mysql.createConnection({user: 'root', database: 'dbname', host:'server.example.com', password: 'secret'}); + + conn.on('query', function(sql) { + console.log('proxying query:' + sql); + remote.query(sql, function(err) { // overloaded args, either (err, result :object) + // or (err, rows :array, columns :array) + if (Array.isArray(arguments[1])) { + // response to a 'select', 'show' or similar + var rows = arguments[1], columns = arguments[2]; + console.log('rows', rows); + console.log('columns', columns); + conn.writeTextResult(rows, columns); + } else { + // response to an 'insert', 'update' or 'delete' + var result = arguments[1]; + console.log('result', result); + conn.writeOk(result); + } + }); + }); + + conn.on('end', remote.end.bind(remote)); +}); +``` +## MySQL Server API + +### Server + + * **createServer()** - creates server instance + * **Server.listen** - listen port / unix socket (same arguments as [net.Server.listen](http://nodejs.org/api/net.html#net_server_listen_port_host_backlog_callback)) + +events: + + * **connect** - new incoming connection. + +### Connection + + * **serverHandshake({serverVersion, protocolVersion, connectionId, statusFlags, characterSet, capabilityFlags})** - send server handshake initialisation packet, wait handshake response and start listening for commands + * **writeOk({affectedRows: num, insertId: num})** - send [OK packet](http://dev.mysql.com/doc/internals/en/overview.html#packet-OK_Packet) to client + * **writeEof(warnings, statusFlags)** - send EOF packet + * **writeTextResult(rows, fields)** - write query result to client. Rows and fields are in the same format as in `connection.query` callback. + * **writeColumns(fields)** - write fields + EOF packets. + * **writeTextRow(row)** - write array (not hash!) ov values as result row + * TODO: binary protocol + +events: + + * **query(sql)** - query from client + + +## License + + MIT + +## Acknowledgements + + - Internal protocol is written from scratch using my experience with [mysql-native](https://github.com/sidorares/nodejs-mysql-native) + - constants, sql parameters interpolation, pool, connection config class taken from [node-mysql](https://github.com/felixge/node-mysql) (I tried to preserve git history) + - SSL upgrade code based on @TooTallNate [code](https://gist.github.com/TooTallNate/848444) + - Secure connection / compressed connection api flags compatible to [mariasql](https://github.com/mscdex/node-mariasql/) client. + - [contributors](https://github.com/sidorares/node-mysql2/graphs/contributors) + +## Benchmarks + - see [node-mysql-benchmarks](https://github.com/mscdex/node-mysql-benchmarks) + - try to run example [benchmarks](https://github.com/sidorares/node-mysql2/tree/master/benchmarks) on your system + +## Examples using MySQL server API: + + - [Mysql-pg-proxy](https://github.com/sidorares/mysql-pg-proxy) - mysql to postgres proxy server. + - [Mysqlite.js](https://github.com/sidorares/mysqlite.js) - mysql server with JS-only (emscripten compiled) sqlite backend. + - [sql-engine](https://github.com/eugeneware/sql-engine) - mysql server with leveldb backend. + +## See also: + + - [wire protocol documentation](http://dev.mysql.com/doc/internals/en/client-server-protocol.html) + - [node-mysql](https://github.com/felixge/node-mysql) - most popular node.js mysql client library + - [node-mariasql](https://github.com/mscdex/node-mariasql/) - bindings to libmariasql. One of the fastest clients + - [node-libmysqlclident](https://github.com/Sannis/node-mysql-libmysqlclient) - bindings to libmysqlclient + - [mysql-co](https://github.com/sidorares/mysql-co) - wrappers to use mysql2 with generators and [co library](https://github.com/visionmedia/co) + - [mysql-utilities](https://github.com/tshemsedinov/node-mysql-utilities) - useful utilities on top of mysql connection + +## Contributing + +Feel free to create pull requests. +TODO in order of importance: + + - node-mysql api incompatibility fixes + - documentation + - tests + - benchmarks + - bug fixes + - TODOs in source code + - performance improvements + - features + +## Features TODO + - more server side commands support (binary protocol, etc) + - named parameters interpolarion into unnamed parameters translation for prepared statements diff --git a/node_modules/mysql2/benchmarks/FB/create.sql b/node_modules/mysql2/benchmarks/FB/create.sql new file mode 100644 index 0000000..258bfe6 --- /dev/null +++ b/node_modules/mysql2/benchmarks/FB/create.sql @@ -0,0 +1,58 @@ +# create benchmark user +GRANT ALL ON *.* TO 'benchmarkdbuser'@'%' IDENTIFIED BY 'benchmarkdbpass'; + +# modified from SO answer http://stackoverflow.com/questions/5125096/for-loop-in-mysql +DROP DATABASE IF EXISTS hello_world; +CREATE DATABASE hello_world; +USE hello_world; + +DROP TABLE IF EXISTS World; +CREATE TABLE World ( + id int(10) unsigned NOT NULL auto_increment, + randomNumber int NOT NULL default 0, + PRIMARY KEY (id) +) +ENGINE=INNODB; + +DROP PROCEDURE IF EXISTS load_data; + +DELIMITER # +CREATE PROCEDURE load_data() +BEGIN + +declare v_max int unsigned default 10000; +declare v_counter int unsigned default 0; + + TRUNCATE TABLE World; + START TRANSACTION; + while v_counter < v_max do + INSERT INTO World (randomNumber) VALUES ( floor(0 + (rand() * 10000)) ); + SET v_counter=v_counter+1; + end while; + commit; +END # + +DELIMITER ; + +CALL load_data(); + +DROP TABLE IF EXISTS Fortune; +CREATE TABLE Fortune ( + id int(10) unsigned NOT NULL auto_increment, + message varchar(2048) CHARACTER SET 'utf8' NOT NULL, + PRIMARY KEY (id) +) +ENGINE=INNODB; + +INSERT INTO Fortune (message) VALUES ('fortune: No such file or directory'); +INSERT INTO Fortune (message) VALUES ('A computer scientist is someone who fixes things that aren''t broken.'); +INSERT INTO Fortune (message) VALUES ('After enough decimal places, nobody gives a damn.'); +INSERT INTO Fortune (message) VALUES ('A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1'); +INSERT INTO Fortune (message) VALUES ('A computer program does what you tell it to do, not what you want it to do.'); +INSERT INTO Fortune (message) VALUES ('Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen'); +INSERT INTO Fortune (message) VALUES ('Any program that runs right is obsolete.'); +INSERT INTO Fortune (message) VALUES ('A list is only as strong as its weakest link. — Donald Knuth'); +INSERT INTO Fortune (message) VALUES ('Feature: A bug with seniority.'); +INSERT INTO Fortune (message) VALUES ('Computers make very fast, very accurate mistakes.'); +INSERT INTO Fortune (message) VALUES (''); +INSERT INTO Fortune (message) VALUES ('フレームワークのベンチマーク'); diff --git a/node_modules/mysql2/benchmarks/FB/fortunes.jade b/node_modules/mysql2/benchmarks/FB/fortunes.jade new file mode 100644 index 0000000..31e1864 --- /dev/null +++ b/node_modules/mysql2/benchmarks/FB/fortunes.jade @@ -0,0 +1,10 @@ +!!! 5 +html + head + title Fortunes + body + table + for fortune in fortunes + tr + td= fortune.id + td= fortune.message diff --git a/node_modules/mysql2/benchmarks/FB/hello.js b/node_modules/mysql2/benchmarks/FB/hello.js new file mode 100644 index 0000000..318e271 --- /dev/null +++ b/node_modules/mysql2/benchmarks/FB/hello.js @@ -0,0 +1,292 @@ +var cluster = require('cluster'); +var numCPUs = require('os').cpus().length; + +if(cluster.isMaster) { + // Fork workers. + for (var i = 0; i < numCPUs; i++) { + cluster.fork(); + } + + cluster.on('exit', function(worker, code, signal) { + console.log('worker ' + worker.pid + ' died'); + }); + + return; +} + +var http = require('http'); +var url = require('url'); +var libmysql = require('mysql-libmysqlclient').createConnectionSync(); +var mysql2 = require('../..'); +var mysql = require('mysql'); +var mariasql = require('mariasql'); +var async = require('async'); +var Mapper = require('mapper'); +var jade = require('jade'); +var fs = require('fs'); +var connMap = { user: 'root', password: '', database: 'hello_world', host: 'localhost' }; + +Mapper.connect(connMap, {verbose: false, strict: false}); +var World = Mapper.map("World", "id", "randomNumber"); + +var template = jade.compile(fs.readFileSync('./fortunes.jade')); + +libmysql.connectSync('localhost', 'root', '', 'hello_world'); +pool2 = mysql2.createPool(connMap); +pool1 = mysql.createPool(connMap); +mysql2conn = mysql2.createConnection(connMap); +mysql1conn = mysql.createConnection(connMap); +mariaconn = new mariasql(); +mariaconn.connect({ + host: connMap.host, + user: connMap.user, + password: connMap.password, + db: connMap.database +}); + +function getRandomNumber() { + return Math.floor(Math.random() * 10000) + 1; +} + +function sequelizeQuery(callback) { + World.findById(getRandomNumber(), function (err, world) { + callback(null, world); + }); +} + +function handlePrepared(req, res) { + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var results = []; + for (var i=0; i < queries; ++i) { + mysql2conn.execute("SELECT * FROM world WHERE id = ?", [getRandomNumber()], function (err, rows) { + results.push(rows[0]); + if (results.length == queries) + res.end(JSON.stringify(results)); + }); + } +} + +function handleMysqlIsh(conn, req, res) { + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + //pool.getConnection(function(err, conn) { + //console.log(conn, conn.query, '==============='); + var results = []; + for (var i=0; i < queries; ++i) { + mysql2conn.query("SELECT * FROM world WHERE id = ?", [getRandomNumber()], function (err, rows) { + results.push(rows[0]); + if (results.length == queries) + res.end(JSON.stringify(results)); + }); + } + //}); +} + +function handleMysqlIshPool(pool, req, res) { + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var results = []; + for (var i=0; i < queries; ++i) { + pool.getConnection(function(err, conn) { + mysql2conn.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, rows) { + results.push(rows[0]); + if (results.length == queries) + res.end(JSON.stringify(results)); + }); + }); + } +} + +function handleMaria(req, res) +{ + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var results = []; + for (var i=0; i < queries; ++i) { + mariaconn.query("SELECT * FROM world WHERE id = :id", { id: getRandomNumber() } ) + .on('result', function (dbres) { + dbres.on('row', function(row) { + results.push(row); + if (results.length == queries) + res.end(JSON.stringify(results)); + }); + }); + } +} + +function fortuneMysql(conn, res) { + var fortunes = []; + res.writeHead(200, {'Content-Type': 'text/html'}); + conn.query('select * from Fortune', function(err, fortunes) { + fortunes.push({id: 0, message: "Additional fortune added at request time."}); + fortunes.sort(sortFortunes); + res.end(template({fortunes: fortunes})); + }); +} + +function fortuneMaria(res) { + fortunes = []; + res.writeHead(200, {'Content-Type': 'text/html'}); + mariaconn.query("SELECT * from Fortune") + .on('result', function (dbres) { + dbres.on('row', function(row) { fortunes.push(row); }); + dbres.on('end', function() { + fortunes.push({id: 0, message: "Additional fortune added at request time."}); + fortunes.sort(sortFortunes); + res.end(template({fortunes: fortunes})); + }); + }); +} + +function sortFortunes(a, b) { + return (a.message < b.message) ? -1 : (a.message > b.message) ? 1 : 0; +} + +http.createServer(function (req, res) { + // JSON response object + var hello = {message: "Hello, world"}; + + var path = url.parse(req.url).pathname; + + switch (path) { + case '/json': + // JSON Response Test + res.writeHead(200, {'Content-Type': 'application/json; charset=UTF-8'}); + // Write JSON object to response + res.end(JSON.stringify(hello)); + break; + + case '/mysql-orm': + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var queryFunctions = new Array(queries); + + for (var i = 0; i < queries; i += 1) { + queryFunctions[i] = sequelizeQuery; + } + + res.writeHead(200, {'Content-Type': 'application/json'}); + + async.parallel(queryFunctions, function(err, results) { + res.end(JSON.stringify(results)); + }); + break; + + case '/mysql': + res.writeHead(200, {'Content-Type': 'application/json'}); + + function libmysqlQuery(callback) { + libmysql.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, res) { + if (err) { + throw err; + } + + res.fetchAll(function(err, rows) { + if (err) { + throw err; + } + + res.freeSync(); + callback(null, rows[0]); + }); + }); + } + + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var queryFunctions = new Array(queries); + + for (var i = 0; i < queries; i += 1) { + queryFunctions[i] = libmysqlQuery; + } + async.parallel(queryFunctions, function(err, results) { + if (err) { + res.writeHead(500); + return res.end('MYSQL CONNECTION ERROR.'); + } + res.end(JSON.stringify(results)); + }); + break; + + case '/mysql2': + handleMysqlIsh(mysql2conn, req, res); + break; + + case '/fortunes-mysql2': + fortuneMysql(mysql2conn, res); + break; + + case '/fortunes-mysql1': + fortuneMysql(mysql1conn, res); + break; + + case '/fortunes-maria': + fortuneMaria(res); + break; + + case '/mysql2pool': + handleMysqlIshPool(pool2, req, res); + break; + + case '/mysql2ps': + handlePrepared(req, res); + break; + + case '/mysql1': + handleMysqlIsh(mysql1conn, req, res); + break; + + case '/maria': + handleMaria(req, res); + break; + + case '/update': + res.writeHead(200, {'Content-Type': 'application/json'}); + + function libmysqlQuery(callback) { + libmysql.query("SELECT * FROM world WHERE id = " + getRandomNumber(), function (err, res) { + if (err) { + throw err; + } + + res.fetchAll(function(err, rows) { + if (err) { + throw err; + } + + res.freeSync(); + + rows[0].randomNumber = getRandomNumber(); + libmysql.query("UPDATE World SET randomNumber = " + rows[0].randomNumber + " WHERE id = " + rows[0]['id'], function (err, res) { + if (err) { + throw err; + } + }); + callback(null, rows[0]); + }); + }); + } + + var values = url.parse(req.url, true); + var queries = values.query.queries || 1; + var queryFunctions = new Array(queries); + + for (var i = 0; i < queries; i += 1) { + queryFunctions[i] = libmysqlQuery; + } + async.parallel(queryFunctions, function(err, results) { + if (err) { + res.writeHead(500); + return res.end('MYSQL CONNECTION ERROR.'); + } + res.end(JSON.stringify(results)); + }); + break; + + default: + // File not found handler + res.writeHead(404, {'Content-Type': 'text/html; charset=UTF-8'}); + res.end("NOT IMPLEMENTED"); + } +}).listen(8080); diff --git a/node_modules/mysql2/benchmarks/FB/package.json b/node_modules/mysql2/benchmarks/FB/package.json new file mode 100644 index 0000000..e501365 --- /dev/null +++ b/node_modules/mysql2/benchmarks/FB/package.json @@ -0,0 +1,14 @@ +{ + "name": "application-name", + "version": "0.0.1", + "private": true, + "dependencies": { + "async": "0.2.5", + "mysql-libmysqlclient": "1.5.2", + "mysql2": "0.7.0", + "mariasql": "0.1.18", + "mapper": "0.2.4-pre", + "jade": "~0.30.0" + }, + "main": "hello.js" +} diff --git a/node_modules/mysql2/benchmarks/bench-fake-server-maria.js b/node_modules/mysql2/benchmarks/bench-fake-server-maria.js new file mode 100644 index 0000000..d167cbe --- /dev/null +++ b/node_modules/mysql2/benchmarks/bench-fake-server-maria.js @@ -0,0 +1,63 @@ +var common = require('../test/common'); + + var Client = require('mariasql'); + var connection = new Client(); + connection.connect({ + host: '127.0.0.1', + port: 3333, + user: 'root', + password: '', + db: 'test' + }); + + +var assert = require('assert'); + +function benchmarkSelect(numLeft, callback) { + numRows = 0; + var q = connection.query('select 1+1 as qqq'); + q.on('result', function(res) { + //console.log("result!"); + //console.log(res); + + res.on('row', function(r) { + //console.log(r); + numRows++; + }); + + res.on('end', function() { + if (numLeft > 1) + benchmarkSelect(numLeft-1, callback); + else + callback(numRows); + }); + }); +} + +function benchmarkSelects(n, cb) { + var numSelects = 100; + var start = process.hrtime(); + benchmarkSelect(numSelects, function(rowsPerQuery) { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(' rows: ' + numSelects*1e9/diff + ' results/sec, ' + rowsPerQuery*numSelects*1e9/diff + ' rows/sec'); + if (n > 1) + benchmarkSelects(n - 1, cb); + else + cb(); + }); +} + +module.exports = function(done) { + console.log('connected'); + var testStart = process.hrtime(); + benchmarkSelects(5, function() { + var testEnd = process.hrtime(); + console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 ); + connection.end(); + if (done) + done(); + }); +}; + +connection.on('connect', module.exports); diff --git a/node_modules/mysql2/benchmarks/bench-fake-server.js b/node_modules/mysql2/benchmarks/bench-fake-server.js new file mode 100644 index 0000000..a4b5cb5 --- /dev/null +++ b/node_modules/mysql2/benchmarks/bench-fake-server.js @@ -0,0 +1,60 @@ +var common = require('../test/common'); +var connection = common.createConnection(); +var assert = require('assert'); + +// ==== simple pool === +var connections = new Array(10); +for (var i=0; i < connections.length; ++i) + connections[i] = common.createConnection(); +var currConn = 0; +function next() { + currConn++; + if (currConn == connections.length) + currConn = 0; + connection = connections[currConn]; +} +// ====================== + +function benchmarkSelect(numLeft, callback) { + //connection.query('query from fake server fixture', function(err, result) { + + // comment if no pool: + next(); + + var rows = 0; + var q = connection.query('query from fake server fixture'); + q.on('result', function() { rows++; }); + q.on('end', function() { + if (numLeft > 1) + benchmarkSelect(numLeft-1, callback); + else + callback(rows); + }); +} + +function benchmarkSelects(n, cb) { + var numSelects = 100000; + var start = process.hrtime(); + benchmarkSelect(numSelects, function(rowsPerQuery) { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(' rows: ' + numSelects*1e9/diff + ' results/sec, ' + rowsPerQuery*numSelects*1e9/diff + ' rows/sec'); + if (n > 1) + benchmarkSelects(n - 1, cb); + else + cb(); + }); +} + +module.exports = function(done) { + var testStart = process.hrtime(); + benchmarkSelects(5, function() { + var testEnd = process.hrtime(); + console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 ); + connection.end(); + if (done) + done(); + }); +}; + + module.exports(); diff --git a/node_modules/mysql2/benchmarks/bench-insert-select-parallel.js b/node_modules/mysql2/benchmarks/bench-insert-select-parallel.js new file mode 100644 index 0000000..e9a9d52 --- /dev/null +++ b/node_modules/mysql2/benchmarks/bench-insert-select-parallel.js @@ -0,0 +1,80 @@ +var common = require('../test/common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var table = 'insert_test'; +//var text = "本日は晴天なり"; +var text = "test abc xyz"; +connection.query('drop table ' + table).on('error', function() {}); +connection.query([ + 'CREATE TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255) NOT NULL,', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +function benchmarkInsert(numLeft, callback) { + connection.query('INSERT INTO ' + table + ' SET title="' + text + '"', function(err, result) { + if (err) throw err; + if (numLeft > 1) + benchmarkInsert(numLeft-1, callback); + else + callback(); + }); +} + +function benchmarkInserts(n, cb) { + var numInsert = 50000; + var start = process.hrtime(); + benchmarkInsert(numInsert, function() { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(numInsert*1e9/diff + ' inserts/sec'); + if (n > 1) + benchmarkInserts(n - 1, cb); + else + cb(); + }); +} + +function benchmarkParallelSelects(n, size, cb) { + var start = process.hrtime(); + var numRunning = 0; + + function commandDone() { + console.log(numRunning); + numRunning--; + if (numRunning > 0) + return; + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(size + ' rows: ' + n*1e9/diff + ' results/sec, ' + size*n*1e9/diff + ' rows/sec'); + cb(); + } + + var connections = new Array(n); + for (var i=0; i < n; ++i) + { + numRunning++; + connections[i] = common.createConnection(); + var cmd = connections[i].execute('select * from ' + table + ' limit ' + size, []); + cmd.on('end', commandDone); + } +} + +module.exports = function(done) { + var testStart = process.hrtime(); + benchmarkInserts(1, function() { + benchmarkParallelSelects(8, 50000, function() { + var testEnd = process.hrtime(); + console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 ); + if (done) + done(); + }); + }); +}; + +if (require.main === module) { + module.exports(); +} diff --git a/node_modules/mysql2/benchmarks/bench-insert-select-prepared.js b/node_modules/mysql2/benchmarks/bench-insert-select-prepared.js new file mode 100644 index 0000000..5715ec5 --- /dev/null +++ b/node_modules/mysql2/benchmarks/bench-insert-select-prepared.js @@ -0,0 +1,83 @@ +var common = require('../test/common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var table = 'insert_test'; +//var text = "本日は晴天なり"; +var text = "test abc xyz"; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +function benchmarkInsert(numLeft, callback) { + connection.execute('INSERT INTO ' + table + ' SET title="' + text + '"', [], function(err, result) { + if (err) throw err; + if (numLeft > 1) + benchmarkInsert(numLeft-1, callback); + else + callback(); + }); +} + +function benchmarkInserts(n, cb) { + var numInsert = 10000; + var start = process.hrtime(); + benchmarkInsert(numInsert, function() { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(numInsert*1e9/diff + ' inserts/sec'); + if (n > 1) + benchmarkInserts(n - 1, cb); + else + cb(); + }); +} + +function benchmarkSelect(numLeft, numSelect, callback) { + connection.execute('select * from ' + table + ' limit ' + numSelect, [], function(err, result) { + if (err) throw err; + if (numLeft > 1) + benchmarkSelect(numLeft-1, numSelect, callback); + else + callback(); + }); +} + +function benchmarkSelects(n, size, cb) { + var numSelects = 100; + var start = process.hrtime(); + benchmarkSelect(numSelects, size, function() { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(size + ' rows: ' + numSelects*1e9/diff + ' results/sec, ' + size*numSelects*1e9/diff + ' rows/sec'); + if (n > 1) + benchmarkSelects(n - 1, size, cb); + else + cb(); + }); +} + +module.exports = function(done) { + var testStart = process.hrtime(); + benchmarkInserts(1, function() { + benchmarkSelects(5, 100, function() { + benchmarkSelects(10, 1000, function() { + benchmarkSelects(2, 50000, function() { + var testEnd = process.hrtime(); + console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 ); + connection.end(); + if (done) + done(); + }); + }); + }); + }); +}; + +if (require.main === module) { + module.exports(); +} diff --git a/node_modules/mysql2/benchmarks/bench-insert-select.js b/node_modules/mysql2/benchmarks/bench-insert-select.js new file mode 100644 index 0000000..e1910e1 --- /dev/null +++ b/node_modules/mysql2/benchmarks/bench-insert-select.js @@ -0,0 +1,82 @@ +var common = require('../test/common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var table = 'insert_test'; +var text = "本日は晴天なり"; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +function benchmarkInsert(numLeft, callback) { + connection.query('INSERT INTO ' + table + ' SET title="' + text + '"', function(err, result) { + if (err) throw err; + if (numLeft > 1) + benchmarkInsert(numLeft-1, callback); + else + callback(); + }); +} + +function benchmarkInserts(n, cb) { + var numInsert = 10000; + var start = process.hrtime(); + benchmarkInsert(numInsert, function() { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(numInsert*1e9/diff + ' inserts/sec'); + if (n > 1) + benchmarkInserts(n - 1, cb); + else + cb(); + }); +} + +function benchmarkSelect(numLeft, numSelect, callback) { + connection.query('select * from ' + table + ' limit ' + numSelect, function(err, result) { + if (err) throw err; + if (numLeft > 1) + benchmarkSelect(numLeft-1, numSelect, callback); + else + callback(); + }); +} + +function benchmarkSelects(n, size, cb) { + var numSelects = 100; + var start = process.hrtime(); + benchmarkSelect(numSelects, size, function() { + var end = process.hrtime(); + var diff = common.hrdiff(start, end); + console.log(size + ' rows: ' + numSelects*1e9/diff + ' results/sec, ' + size*numSelects*1e9/diff + ' rows/sec'); + if (n > 1) + benchmarkSelects(n - 1, size, cb); + else + cb(); + }); +} + +module.exports = function(done) { + var testStart = process.hrtime(); + benchmarkInserts(5, function() { + benchmarkSelects(5, 10000, function() { + benchmarkSelects(10, 1000, function() { + benchmarkSelects(2, 50000, function() { + var testEnd = process.hrtime(); + console.log('total time: ', common.hrdiff(testStart, testEnd)/1e9 ); + connection.end(); + if (done) + done(); + }); + }); + }); + }); +}; + +if (require.main === module) { + module.exports(); +} diff --git a/node_modules/mysql2/benchmarks/benchmark-query.js b/node_modules/mysql2/benchmarks/benchmark-query.js new file mode 100644 index 0000000..7ce15f8 --- /dev/null +++ b/node_modules/mysql2/benchmarks/benchmark-query.js @@ -0,0 +1,34 @@ +var assert = require('assert'); +var createConnection = require('../test/common').createConnection; + +var sql = process.argv[2]; + +(function(cb) { + var db = createConnection(); + + var left = 10000; + var start = Date.now(); + var prev1000 = start; + function bench() + { + db.query(sql).on('end', function(err, res) { + left--; + if (left % 1000 === 0) + { + var curTime = Date.now(); + var last1000time = curTime - prev1000; + prev1000 = curTime; + console.error( (1000000/last1000time) + ' req/sec' ); + } + + if (left > 0) + bench(); + else { + console.error( 10000000/(Date.now() - start) + ' req/sec (average 10000 reqs)'); + db.end(); + if (cb) cb(); + } + }); + } + bench(); +})(); diff --git a/node_modules/mysql2/benchmarks/benchmark-server.js b/node_modules/mysql2/benchmarks/benchmark-server.js new file mode 100644 index 0000000..d05b3b1 --- /dev/null +++ b/node_modules/mysql2/benchmarks/benchmark-server.js @@ -0,0 +1,72 @@ +var mysql = require('../index.js'); +var flags = require('../lib/constants/client'); +var Packets = require('../lib/packets/index.js'); +var Packet = require('../lib/packets/packet'); + +function prepareReply(columns, row, n) { + var length = 0; + var rsHeader = Packets.ResultSetHeader.toPacket(columns.length); + length += rsHeader.length(); + var columnPackets = []; + columns.forEach(function(column) { + var packet = Packets.ColumnDefinition.toPacket(column); + length += packet.length(); + columnPackets.push(packet); + }); + var eof = Packets.EOF.toPacket(); + length += 2*eof.length(); + var rowPacket = Packets.TextRow.toPacket(row); + length += n*rowPacket.length(); + + var replyBuffer = new Buffer(length); + var offset = 0; + var id = 1; + function add(packet) { + packet.writeHeader(id); + id = id + 1; + packet.buffer.copy(replyBuffer, offset); + offset += packet.length(); + } + + var i; + add(rsHeader); + for (i=0; i < columns.length; ++i) + add(columnPackets[i]); + add(eof); + for (i=0; i < n; ++i) + add(rowPacket); + add(eof); + + return replyBuffer; +} + +var buff = prepareReply([{ + catalog: 'def', + schema: 'test', + table: 'test_table', + orgTable: 'test_table', + name: 'beta', + orgName: 'beta', + characterSet: 33, + columnLength: 384, + columnType: 3, //253, + flags: 0, + decimals: 0 + }], ['12345'], 1); + +var server = mysql.createServer(); +server.listen('/tmp/mybench3.sock'); +server.on('connection', function(conn) { + conn.serverHandshake({ + protocolVersion: 10, + serverVersion: 'node.js rocks', + connectionId: 1234, + statusFlags: 2, + characterSet: 8, + capabilityFlags: 0xffffff + }); + conn.on('query', function(query) { + //console.log(query); + conn.write(buff); + }); +}); diff --git a/node_modules/mysql2/benchmarks/http-select-and-render.js b/node_modules/mysql2/benchmarks/http-select-and-render.js new file mode 100644 index 0000000..bfb9252 --- /dev/null +++ b/node_modules/mysql2/benchmarks/http-select-and-render.js @@ -0,0 +1,39 @@ +var http = require('http'); +var fs = require('fs'); +var common = require('../test/common'); +var url = require('url'); + +var conn = common.createConnection(); +var render = common.createTemplate(); +var port = process.env.PORT; + +http.createServer(function(req, res) { + var q = url.parse(req.url, true); + if (q.pathname == '/render') { + + var sql = q.query.q; + var n = q.query.n; + var rowsTotal = []; + var doQueries = function(number) { + if (number === 0) { + var body = render({ records: rowsTotal}); + res.writeHead(200, { + 'Content-Length': body.length, + 'Content-Type': 'text/html' } + ); + res.end(body); + } else { + conn.query(sql, function(err, rows) { + // TODO: handle error + rowsTotal = rowsTotal.concat(rows); + doQueries(number-1); + }); + } + }; + doQueries(n); + + } else { + res.writeHead(404); + res.end(); + } +}).listen(port || 1234); diff --git a/node_modules/mysql2/benchmarks/httperf.sh b/node_modules/mysql2/benchmarks/httperf.sh new file mode 100644 index 0000000..85630ef --- /dev/null +++ b/node_modules/mysql2/benchmarks/httperf.sh @@ -0,0 +1 @@ +httperf --port=1234 --uri='/render?q=select%20*%20from%20foos%20limit%205,10000&n=2' --num-conns=10 --num-calls=2 rate=100 diff --git a/node_modules/mysql2/benchmarks/ping-pong-client.js b/node_modules/mysql2/benchmarks/ping-pong-client.js new file mode 100644 index 0000000..64a6717 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ping-pong-client.js @@ -0,0 +1,18 @@ +var net = require('net'); +var count = 0; +var byte = new Buffer([0x33]); +function pong() +{ + count++; + this.write(byte); +} + +var c = net.connect(3334); +c.setNoDelay(true); +c.ondata = pong; +pong.apply(c); + +setInterval(function() { + console.log(count); + count = 0; +}, 1000); diff --git a/node_modules/mysql2/benchmarks/ping-pong-server.js b/node_modules/mysql2/benchmarks/ping-pong-server.js new file mode 100644 index 0000000..7eb9071 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ping-pong-server.js @@ -0,0 +1,12 @@ +var net = require('net'); + +var byte = new Buffer([0x33]); +function pong() +{ + this.write(byte); +} + +net.createServer(function(s) { + s.setNoDelay(true); + s.ondata = pong; +}).listen(3334); diff --git a/node_modules/mysql2/benchmarks/ping-pong-uv.js b/node_modules/mysql2/benchmarks/ping-pong-uv.js new file mode 100644 index 0000000..973284c --- /dev/null +++ b/node_modules/mysql2/benchmarks/ping-pong-uv.js @@ -0,0 +1,30 @@ +var count = 0; +var byte = new Buffer([0x33]); + +function ping(buffer, offset, length) { + count++; + pong(this); +} + +function noop() {} +function pong(sock) +{ + var writeReq = sock.writeBuffer(byte); + writeReq.oncomplete = noop; +} + +var port = 3334; +var TCP = process.binding('tcp_wrap').TCP; +var client = new TCP(); +var req = client.connect('127.0.0.1', port); +req.oncomplete = function() { + console.log('connected'); + pong(client); +}; +client.onread = ping; +client.readStart(); + +setInterval(function() { + console.log(count); + count = 0; +}, 1000); diff --git a/node_modules/mysql2/benchmarks/ruby-mysql2/bench.rb b/node_modules/mysql2/benchmarks/ruby-mysql2/bench.rb new file mode 100644 index 0000000..beb0682 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ruby-mysql2/bench.rb @@ -0,0 +1,29 @@ +require 'rubygems' +require 'benchmark' +require 'mysql2' +require 'haml' + +number_of = 1 +database = 'test' +sql = "SELECT * FROM mysql2_test LIMIT 1" + +Benchmark.bmbm do |x| + mysql2 = Mysql2::Client.new(:host => "localhost", :username => "root") + mysql2.query "USE #{database}" + x.report "Mysql2 (cast: true)" do + number_of.times do + mysql2_result = mysql2.query sql, :symbolize_keys => true, :cast => true + puts haml :index, :locals => { :rows => mysqql2_result } + end + end + + x.report "Mysql2 (cast: false)" do + number_of.times do + mysql2_result = mysql2.query sql, :symbolize_keys => true, :cast => false + mysql2_result.each do |res| + # puts res.inspect + end + end + end + +end diff --git a/node_modules/mysql2/benchmarks/ruby-mysql2/benchmark-query.js b/node_modules/mysql2/benchmarks/ruby-mysql2/benchmark-query.js new file mode 100644 index 0000000..4e16cd5 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ruby-mysql2/benchmark-query.js @@ -0,0 +1,56 @@ +var assert = require('assert'); +var createConnection = require('../../test/common').createConnection; + +var sql = process.argv[2]; +var starthr = process.hrtime(); +var haml = require('hamljs'); +var fs = require('fs'); + +var render = haml.compile(fs.readFileSync('./views/index.haml')); + +l = 0; +var rowsReceived = 0; +var numRequests = 0; + +(function(cb) { + var db = createConnection(); + + var left = 1; + + var start = Date.now(); + var prev1000 = start; + function bench() + { + //db.query(sql).on('end', function(err, res) { + db.query(sql, function(err, res) { + //db.execute(sql, function(err, res) { + + rowsReceived += res.length; + numRequests++; + + l += render({results: res}).length; + console.log(render({results: res})); + + left--; + if (left % 1000 === 0) + { + var curTime = Date.now(); + var last1000time = curTime - prev1000; + prev1000 = curTime; + console.error( (1000000/last1000time) + ' req/sec' ); + } + + if (left > 0) + bench(); + else { + console.error( numRequests *1000/(Date.now() - start) + ' req/sec (average 10000 reqs)'); + console.error( rowsReceived*1000/(Date.now() - start) + ' row/sec (average 10000 reqs)'); + db.end(); + if (cb) cb(); + console.log(process.hrtime(starthr)); + console.log(l); + } + }); + } + bench(); +})(); diff --git a/node_modules/mysql2/benchmarks/ruby-mysql2/populate.js b/node_modules/mysql2/benchmarks/ruby-mysql2/populate.js new file mode 100644 index 0000000..64afb36 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ruby-mysql2/populate.js @@ -0,0 +1,82 @@ +var common = require('../../test/common'); +var connection = common.createConnection(); +var assert = require('assert'); +var Faker = require('charlatan'); +var fs = require('fs'); + +var createSql = fs.readFileSync('./schema.sql').toString(); + +// use seed to make it consistent between runs +// copy-paste from http://stackoverflow.com/questions/521295/javascript-random-seeds + +var m_w = 123456789; +var m_z = 987654321; +var mask = 0xffffffff; + +// Takes any integer +function seed(i) { + m_w = i; +} + +// Returns number between 0 (inclusive) and 1.0 (exclusive), +// just like Math.random(). +function rand() +{ + m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask; + m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask; + var result = ((m_z << 16) + m_w) & mask; + result /= 4294967296; + return result + 0.5; +} + +seed(123); + +connection.query(createSql); +connection.query("DELETE FROM mysql2_test"); + +function insertRow(r) { + connection.query("INSERT INTO mysql2_test SET ? ", r); +} + +var num_rows = 10000; + +var five_words, twenty5_paragraphs; +for (var i = 0; i < num_rows; ++i) +{ + five_words = Faker.Lorem.words(1 + rand(4)).join(' ').slice(0, 10); + twenty5_paragraphs = Faker.Lorem.paragraphs(1 + rand(24)).join(' '); + insertRow({ + bit_test: 1, + tiny_int_test: rand(128), + small_int_test: rand(32767), + medium_int_test: rand(8388607), + int_test: rand(2147483647), + big_int_test: rand(9223372036854775807), + float_test: rand(32767)/1.87, + float_zero_test: 0.0, + double_test: rand(8388607)/1.87, + decimal_test: rand(8388607)/1.87, + decimal_zero_test: 0, + date_test: '2010-4-4', + date_time_test: '2010-4-4 11:44:00', + timestamp_test: '2010-4-4 11:44:00', + time_test: '11:44:00', + year_test: 14, + char_test: five_words, + varchar_test: five_words, + binary_test: five_words, + varbinary_test: five_words, + tiny_blob_test: five_words, + tiny_text_test: Faker.Lorem.paragraph(rand(5)), + blob_test: twenty5_paragraphs, + text_test: twenty5_paragraphs, + medium_blob_test: twenty5_paragraphs, + medium_text_test: twenty5_paragraphs, + long_blob_test: twenty5_paragraphs, + long_text_test: twenty5_paragraphs, + enum_test: ['val1', 'val2'][rand(2)], + set_test: ['val1', 'val2', 'val1,val2'][rand(3)] + }); +} + +connection.end(); diff --git a/node_modules/mysql2/benchmarks/ruby-mysql2/schema.sql b/node_modules/mysql2/benchmarks/ruby-mysql2/schema.sql new file mode 100644 index 0000000..541a122 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ruby-mysql2/schema.sql @@ -0,0 +1,33 @@ + CREATE TABLE IF NOT EXISTS mysql2_test ( + null_test VARCHAR(10), + bit_test BIT, + tiny_int_test TINYINT, + small_int_test SMALLINT, + medium_int_test MEDIUMINT, + int_test INT, + big_int_test BIGINT, + float_test FLOAT(10,3), + float_zero_test FLOAT(10,3), + double_test DOUBLE(10,3), + decimal_test DECIMAL(10,3), + decimal_zero_test DECIMAL(10,3), + date_test DATE, + date_time_test DATETIME, + timestamp_test TIMESTAMP, + time_test TIME, + year_test YEAR(4), + char_test CHAR(10), + varchar_test VARCHAR(10), + binary_test BINARY(10), + varbinary_test VARBINARY(10), + tiny_blob_test TINYBLOB, + tiny_text_test TINYTEXT, + blob_test BLOB, + text_test TEXT, + medium_blob_test MEDIUMBLOB, + medium_text_test MEDIUMTEXT, + long_blob_test LONGBLOB, + long_text_test LONGTEXT, + enum_test ENUM('val1', 'val2'), + set_test SET('val1', 'val2') + ) DEFAULT CHARSET=utf8 diff --git a/node_modules/mysql2/benchmarks/ruby-mysql2/views/index.haml b/node_modules/mysql2/benchmarks/ruby-mysql2/views/index.haml new file mode 100644 index 0000000..d958d89 --- /dev/null +++ b/node_modules/mysql2/benchmarks/ruby-mysql2/views/index.haml @@ -0,0 +1,41 @@ +!!! +%html + %head + %title table dump goes here + %body + %h1 data data + %table + %tbody + - each row in results + %tr + %td= row.null_test + %td= row.bit_test + %td= row.tiny_int_test + %td= row.small_int_test + %td= row.medium_int_test + %td= row.int_test + %td= row.big_int_test + %td= row.float_test + %td= row.float_zero_test + %td= row.double_test + %td= row.decimal_test + %td= row.decimal_zero_test + %td= row.date_test + %td= row.date_time_test + %td= row.timestamp_test + %td= row.time_test + %td= row.year_test + %td= row.char_test + %td= row.varchar_test + %td= row.binary_test + %td= row.varbinary_test + %td= row.tiny_blob_test + %td= row.tiny_text_test + %td= row.blob_test + %td= row.text_test + %td= row.medium_blob_test + %td= row.medium_text_test + %td= row.long_blob_test + %td= row.long_text_test + %td= row.enum_test + %td= row.set_test diff --git a/node_modules/mysql2/benchmarks/test-benchmark-select-1.js b/node_modules/mysql2/benchmarks/test-benchmark-select-1.js new file mode 100644 index 0000000..842771c --- /dev/null +++ b/node_modules/mysql2/benchmarks/test-benchmark-select-1.js @@ -0,0 +1,32 @@ +var assert = require('assert'); +var createConnection = require('../common').createConnection; + +(function(cb) { + var db = createConnection(); + + var left = 10000; + var start = Date.now(); + var prev1000 = start; + function bench() + { + db.query('select 1').on('end', function(err, res) { + left--; + if (left % 1000 === 0) + { + var curTime = Date.now(); + var last1000time = curTime - prev1000; + prev1000 = curTime; + console.error( (1000000/last1000time) + ' req/sec' ); + } + + if (left > 0) + bench(); + else { + console.error( 10000000/(Date.now() - start) + ' req/sec (average 10000 reqs)'); + db.end(); + if (cb) cb(); + } + }); + } + bench(); +})(); diff --git a/node_modules/mysql2/debug.md b/node_modules/mysql2/debug.md new file mode 100644 index 0000000..e63acbf --- /dev/null +++ b/node_modules/mysql2/debug.md @@ -0,0 +1,39 @@ +# Debugging driver issues + +You can enable debug output using `debug` config option: + +```js +var conn = mysql.createConnection({ + port: 3306, + host: '1.2.3.4', + debug: true // <--- +} +``` +Also you can make additional information available during initialization if you +sert enfironment variable `NODE_DEBUG` + +## Interpreting debug log + +``` +Add command: Connection +Add command: query + ==> Connection#handshakeInit(0,,78) + <== Connection#handshakeInit(1,HandshakeResponse,67) + ==> Connection#handshakeResult(2,maybeOK,7) +Sending query command: select * from mil limit 10 + <== query#start(0,Query,31) + ==> query#resultsetHeader(1,,1) + ==> query#readField(2,,36) + ==> query#fieldsEOF(3,EOF,5) + ==> query#row(4,,2) + ==> query#row(5,,2) + ==> query#row(6,,2) + ==> query#row(7,,2) + ==> query#row(8,,2) + ==> query#row(9,,2) + ==> query#row(10,,2) + ==> query#row(11,,2) + ==> query#row(12,,2) + ==> query#row(13,,3) + ==> query#row(14,EOF,5) + ``` diff --git a/node_modules/mysql2/dump.rdb b/node_modules/mysql2/dump.rdb new file mode 100644 index 0000000..e17870c Binary files /dev/null and b/node_modules/mysql2/dump.rdb differ diff --git a/node_modules/mysql2/examples/binlog-watcher.js b/node_modules/mysql2/examples/binlog-watcher.js new file mode 100644 index 0000000..dcb4b08 --- /dev/null +++ b/node_modules/mysql2/examples/binlog-watcher.js @@ -0,0 +1,16 @@ +var mysql = require('../test/common').createConnection(); +var through2 = require('through2'); + +var binlogStream = mysql.createBinlogStream({ + serverId: 123, // slave ID, first field in "show slave hosts" sql response + // you can also specify slave host, username, password and port + masterId: 0, + filename: 'mysql-bin.000007', + binlogPos: 120, + flags: 1, // 1 = "non-blocking mode" +}); + +binlogStream.pipe(through2.obj(function(obj, enc, next) { + console.log(obj); + next(); +})); diff --git a/node_modules/mysql2/examples/execute.js b/node_modules/mysql2/examples/execute.js new file mode 100644 index 0000000..5590541 --- /dev/null +++ b/node_modules/mysql2/examples/execute.js @@ -0,0 +1,5 @@ +var mysql = require('../test/common').createConnection(); +mysql.execute("select ?+1 as qqq, ? as rrr, ? as yyy", [1, null, 3], function(err, rows, fields) { +//mysql.execute("select ?+?+? as qqq, ? as rrr", [1, 2, 5, "test"], function(err, rows, fields) { + console.log(err, rows, fields); +}); diff --git a/node_modules/mysql2/examples/mysqlproxy.js b/node_modules/mysql2/examples/mysqlproxy.js new file mode 100644 index 0000000..eeaa776 --- /dev/null +++ b/node_modules/mysql2/examples/mysqlproxy.js @@ -0,0 +1,45 @@ +var mysql = require('../index.js'); + +var server = mysql.createServer(); +server.listen(3307); +server.on('connection', function(conn) { + console.log('connection'); + + conn.serverHandshake({ + protocolVersion: 10, + serverVersion: 'node.js rocks', + connectionId: 1234, + statusFlags: 2, + characterSet: 8, + capabilityFlags: 0xffffff + }); + + conn.on('field_list', function(table, fields) { + console.log('field list:', table, fields); + conn.writeEof(); + }); + + var remote = mysql.createConnection({user: 'root', database: 'dbname', host:'server.example.com', password: 'secret'}); + + conn.on('query', function(sql) { + console.log('proxying query:' + sql); + remote.query(sql, function(err) { // overloaded args, either (err, result :object) + // or (err, rows :array, columns :array) + if (Array.isArray(arguments[1])) { + // response to a 'select', 'show' or similar + var rows = arguments[1], columns = arguments[2]; + console.log('rows', rows); + console.log('columns', columns); + conn.writeTextResult(rows, columns); + } else { + // response to an 'insert', 'update' or 'delete' + var result = arguments[1]; + console.log('result', result); + conn.writeOk(result); + } + }); + }); + + conn.on('end', remote.end.bind(remote)); +}); + diff --git a/node_modules/mysql2/examples/pool-test.js b/node_modules/mysql2/examples/pool-test.js new file mode 100644 index 0000000..aa13446 --- /dev/null +++ b/node_modules/mysql2/examples/pool-test.js @@ -0,0 +1,12 @@ +var pool = require('../test/common').createPool(); + +setInterval(function() { +for (var i=0; i < 5; ++i) { + pool.getConnection(function(err, db) { + db.query("select sleep(0.5) as qqq", function(err, rows, fields) { + console.log(rows, fields); + db.end(); + }); + }); +} +}, 1000); diff --git a/node_modules/mysql2/examples/server.js b/node_modules/mysql2/examples/server.js new file mode 100644 index 0000000..db95785 --- /dev/null +++ b/node_modules/mysql2/examples/server.js @@ -0,0 +1,41 @@ +var mysql = require('../index.js'); +var flags = require('../lib/constants/client'); + +var server = mysql.createServer(); +server.listen(3333); +server.on('connection', function(conn) { + // we can deny connection here: + // conn.writeError({ message: 'secret', errno: 123 }); + conn.serverHandshake({ + protocolVersion: 10, + serverVersion: '5.6.10', //'node.js rocks', + connectionId: 1234, + statusFlags: 2, + characterSet: 8, + capabilityFlags: 0xffffff + }); + + conn.on('field_list', function(table, fields) { + console.log('FIELD LIST:', table, fields); + conn.writeEof(); + }); + + conn.on('query', function(query) { + conn.writeColumns([{ + catalog: 'def', + schema: 'test', + table: 'test_table', + orgTable: 'test_table', + name: 'beta', + orgName: 'beta', + characterSet: 33, + columnLength: 384, + columnType: 253, + flags: 0, + decimals: 0 + }]); + conn.writeTextRow(['test тест テスト փորձարկում পরীক্ষা kiểm tra ']); + conn.writeTextRow(['ტესტი પરીક્ષણ מבחן פּרובירן اختبار परीक्षण']); + conn.writeEof(); + }); +}); diff --git a/node_modules/mysql2/examples/simple-select.js b/node_modules/mysql2/examples/simple-select.js new file mode 100644 index 0000000..df47d38 --- /dev/null +++ b/node_modules/mysql2/examples/simple-select.js @@ -0,0 +1,5 @@ +var mysql = require('../test/common').createConnection(); + +mysql.query("select * from foos limit 10", function(err, rows, fields) { + console.log(rows, fields); +}); diff --git a/node_modules/mysql2/examples/sprocedure.js b/node_modules/mysql2/examples/sprocedure.js new file mode 100644 index 0000000..73fd4bf --- /dev/null +++ b/node_modules/mysql2/examples/sprocedure.js @@ -0,0 +1,11 @@ +var mysql = require('../test/common').createConnection(); +//var create_proc = "mysql.query('DROP PROCEDURE IF EXISTS p; CREATE PROCEDURE p(IN i INT) BEGIN SELECT i as f; END;');"; +var create_proc = "CREATE PROCEDURE `get_user1`(IN supplied_user_id INT) BEGIN select * from mil1 ua where ua.id = supplied_user_id; END"; +mysql.query(create_proc, function(err, rows, fields) { + console.log('Error:', err, rows, fields); +}); + +mysql.execute('CALL get_user1(?)', [ 1 ], function (err, rows) { + console.log(JSON.stringify(err, rows, null, 2)); + mysql.end(); +}); diff --git a/node_modules/mysql2/examples/ssl/certs/ca-cert.pem b/node_modules/mysql2/examples/ssl/certs/ca-cert.pem new file mode 100644 index 0000000..6e0a83b --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/ca-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIJALO3/a+fdsicMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTMwNDMwMDEzNTUwWhcNMTYwMTI1MDEzNTUwWjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxFrsDfgxd5fb053eVqZ1a+iVVxoOkTl9f97BhIuUp3GE82UBMXQdL4Ec +gc3oQ56dEokvz9ghYn60cUBaH5sVjzm3qO3HYsHhA/nYoVa7U9TrSGhv3hWyqo48 +wWKHBYea325tcO2h9QanLFsnc1aauv8qGeWoa91lrfsT9G3nFdpiw587Nk+7NkKR +MhEbAf84qoTmcxo6hqOrqEZwhIozuiF0+oNNfj/Tmcd5517WJfWLAHjLPpBmc7Yw +vJqYqk7OK/BkX6NVx8OxcxcejvuosoZRbVK3Tuk+5N2AddncxU5Eq2kGVr890xTg +ZVwUFF4TRkenDKe3ez2DvlRDnuFzjQIDAQABo4GnMIGkMB0GA1UdDgQWBBQd7DqN +xTmSuT3f82DP13asHrqHIjB1BgNVHSMEbjBsgBQd7DqNxTmSuT3f82DP13asHrqH +IqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV +BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALO3/a+fdsicMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAA9+kUPZ7PfvD0SkgMnGXqnL2EPUPsgo +bRwciPx5E/SqoEczfYip+IcWAxRnifkFGXAzBq6w3GmGaJqG95vV5noj+md7KE2m +t8dxwGlOYP2H0oEubfrz6AHOcMDF68N2hmA4K0zj+Ag9XCJxN41vzaPgLuvNmDqB +O16Qh47CNoKtpEFZ4g6Yp3rErzhGVSLgLh2NmDzi6Vd78mmy454euLDTcbCnlKsA +kXvt8KCYacYNNV0m8mLYqPylJUZNvtFE4mAo35Uzbw6NawkWd+Aqx8UJCsQDhWWw +5T+24NcfiAs+Wqg3UvuzXlOZB721nmqgIYIcjyumMewGE/y1xLschIQ= +-----END CERTIFICATE----- diff --git a/node_modules/mysql2/examples/ssl/certs/ca-key.pem b/node_modules/mysql2/examples/ssl/certs/ca-key.pem new file mode 100644 index 0000000..76ba872 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/ca-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxFrsDfgxd5fb053eVqZ1a+iVVxoOkTl9f97BhIuUp3GE82UB +MXQdL4Ecgc3oQ56dEokvz9ghYn60cUBaH5sVjzm3qO3HYsHhA/nYoVa7U9TrSGhv +3hWyqo48wWKHBYea325tcO2h9QanLFsnc1aauv8qGeWoa91lrfsT9G3nFdpiw587 +Nk+7NkKRMhEbAf84qoTmcxo6hqOrqEZwhIozuiF0+oNNfj/Tmcd5517WJfWLAHjL +PpBmc7YwvJqYqk7OK/BkX6NVx8OxcxcejvuosoZRbVK3Tuk+5N2AddncxU5Eq2kG +Vr890xTgZVwUFF4TRkenDKe3ez2DvlRDnuFzjQIDAQABAoIBAQDDQW7PDWmTdU1C +CBCatfi6D5TCAsVNoI+t4kMpnOt7/qSorF4dYUvMe2VvpuQ6qbWkQwtqcY/xM/IX +VFjKaRttS4XY1GqbSBSMMZ08AtVRLb+yRzhG7ei3Na4w19tQomJdoJ/v1j5hO/Zt +Y0+9n/dJ0Id7LSbn7Ec6VRyoyckrrjmikw/y91UU/Xi3u2/64rJY+vbH2h090Ztg +MNt39v+VbengJ4vS/VbDk6qPv4CGUYWYfbz4ekRK0/xLWKW9vAu8KcN1iewmEyeH +W16686qKrhwDlCXYpZcTBnHB+QCxNfPRFJpfXzXSTCTY9aId79skCnEzBlUshKrV +6mYzlFcBAoGBAPIn62Gc7uRWCQkQaP05pjI4/v0I8ggvVfDwAyxY7QowLQXRT49O +zohCLtJFYN5Zd01hAgdrNl6QdtBF+rQEoKFKMRY8BI8G+lz6KHX5K37mAip/VjIl +a6sUUKu5lYOPqouDuAPoO1VRWulVPOx18/8s+vtk9OV3M+01vMBewXptAoGBAM+U +rx5Plg7qBPtLGTXCTbUHcvKKY2HdUHlzJjj8zcV8e6012GWcRblL4XmaxZTpS177 +JIDBPuhXDKjUwYemV1VBQlvh94f1ArDgh9+MEdYypYPvRDAzOg+Q3EGBW11zfYF9 +EqiWFud4vSZ4zFQgeg3cfCRIsXXfc3CDpzeV+CmhAoGBAJGeM8ulRXsFybUrqxbr +vedhouSipnkJjhKvIhle+FwyEED5V3CEIWqK8gD8O346KqXbeg7gB/fhw7EHA/WQ ++s9DADWwrcUcmx2iSQZ4ahGLWy4XGMxa+F4Of1xk42YT1KjE8rlWw6dQnuzFlzdS +zwFaGStn0GTUw+MXd4Pu90YZAoGAWlPS2Be9roO64zbMo44HjmzNYilCEcXiTNcE +nOu1BuiiUL8LiTu1Q2p3lRj6PVA/Ufdq7PQqUaP/iD/8bvC9NAYPwDfWJL1DDIDH +30juQg0L5Rtqyqaf70IT9hU6ErI8vOoWAnI9SUBK3sDV+Q2gzwNQqeFQB4DSlPVV +AGUr9cECgYARilqjaF8Ns3ilS3r3IEZ8I2wPAei/P9PCtkwkUsVpZ2+/SHxFAJkf +CaPVXdHMHkRXQUf1a+fAEYWiDnFnTaWXg/HyCt1V+Rr7g5eXsN+GwoeQ5Rywzi7m +K6atiYVINfvpNcN73dO7mB4jXgTNCh0K8ru9lf2nKgPzjd0muNDBww== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/mysql2/examples/ssl/certs/client-cert.pem b/node_modules/mysql2/examples/ssl/certs/client-cert.pem new file mode 100644 index 0000000..288be5c --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/client-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAeYCAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDAeFw0xMzA0MzAwMTM1NTVaFw0xNjAxMjUwMTM1NTVaMEUxCzAJBgNVBAYTAkFV +MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz +IFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCa+f+OWaOI +1W6HaBZ5Ch0fW9SKrv7Uz/mzAAGFer7+0KNF7JC0/WtK1lz0oBuYqt6wZQmIO0at +6RP55Uxyj5Zf8C2jyHPU2iAUYcV/QTBXw0JNXCV0v+NeNjmh7/Tngj5l7nfdebLz +4oooQ3OlN3wbbHSd4UNmMhCQKNVFGS3nOp1q7C3QXuJJuq5zOXE6T6DO43zLo3HG +JEGjtkXA8oFWW2wIKrhxJlNLxaW70UrLMxBCLJ2hI0MITYsYSA5aPw+EZ0rrkGc9 +qaagpWYR7Yu//i78XOK1p8wgtZTlHY4akWMCRMUEkcKpiMLxrTyBijG/4jrYuxdJ ++ZnIYWKkjYevAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAEl6Yw2X2tJhHV8Wut+1 +YWXYuuYV/JbPx1KJLWl78eFnnZfzdCkSzywv9ThW2xSehIH2anfb8HxrvypVa1/r +EUcgy8kMzoa9ZcPXs0Ol/hCEsYYQZ/rXgXtPjaIb92kznKXhLckAKpChx8LxeSYc +TZ6DVdhT+sWwSy/DetzavAq8QGFRyYL88bxibSgiBGRw7i5sWk5/T6dpx322MbtK +FMPv3K5Mt0b3eBsegcjTvFqJAPBADB/WVLUsp+ESruFTcWGf8H91aoiWhZspEHjt +j2XD/nlkC44t3RU8YNx2jAxj9HhG7QHfwsY9CDSwmnKtpUhvGUrGkp98Q/dUMbds +NP0= +-----END CERTIFICATE----- diff --git a/node_modules/mysql2/examples/ssl/certs/client-key.pem b/node_modules/mysql2/examples/ssl/certs/client-key.pem new file mode 100644 index 0000000..d6134fd --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/client-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAmvn/jlmjiNVuh2gWeQodH1vUiq7+1M/5swABhXq+/tCjReyQ +tP1rStZc9KAbmKresGUJiDtGrekT+eVMco+WX/Ato8hz1NogFGHFf0EwV8NCTVwl +dL/jXjY5oe/054I+Ze533Xmy8+KKKENzpTd8G2x0neFDZjIQkCjVRRkt5zqdauwt +0F7iSbquczlxOk+gzuN8y6NxxiRBo7ZFwPKBVltsCCq4cSZTS8Wlu9FKyzMQQiyd +oSNDCE2LGEgOWj8PhGdK65BnPammoKVmEe2Lv/4u/FzitafMILWU5R2OGpFjAkTF +BJHCqYjC8a08gYoxv+I62LsXSfmZyGFipI2HrwIDAQABAoIBAQCXqKrEHUiB8Yu2 +is/jJ1iUhYMbLGFI1TXgS9MxUotyRa5iET0TQSQsGlbhNYWMAzrlmBqZ7JggPIVF ++XS0b3uS6zFepB1mYQcfqwZgn+S1HenWVqR4+geA/MOti2s42yZBDfrTC/Np43mc +KVYUipWzKJF+pyET805uJOeANUHMkvP6So066akZgi+bAdIpNu0hvvq04KUbPNfE +c4XdT7CKZnNSHhgfXBLN+H10wfIKnL916qJtOaRERZmM/M/LQRJRrSZTTKZWwMHg +5eBdYLI3+/eYeNriLlWVAEMXuUN7TueJFzePuTe5TRdVHkHbBvQTliIvr+udu4MV +FGMTrfchAoGBAMjUuoF8X5dPtu3eHCrGsg787hPdSn9jDhOYoKKTAj8Ft7Rnl5X3 +twLfeTtBhrPpo0KYOYkO2bETb0xXp1hUAfOGTl/jy1LREqHUxKPnaEpO5CbJMzwq +rhAIR4ZgQcqxHkBbUJd+lLptnWbw9LxiysEVrHwRyKH39ZdbJTM4KZU3AoGBAMWM +mJRhYbPpiDLRiskFqEou9qU+zjq1RlbI6fWoz5+8K6A3zfBHE1J1ZvqF6tvOeoDx +HLY5vIwlIKy8XwmTwUQvd9TTuRD+ZnY9gUoPgDhEK8fSJeSb2OqZyKBwATM7Q9Cn +5pyTOsTkmlm4AKpczoAJ3WUmRmvYeT+uGfXU611JAoGAGEkJKKFWmeCM2WTTeSS/ +4WoajBJlcNQUnrAFNMOcMOzLEyi3vu3Olq1ZZp384QKuuF3aD0XZcz1LZyruVJMM +DVu/XH8aVjBsFV+6S6uvA9VYZ4xLAsqSc+PcalZ3fkA+zT99lmQ7LfQVZZ5bqfA0 +Xnb1fadU4KkwbJYcAH6ZIK8CgYAVVp14kZhDHbuXeajbE+BcuvvrV4BhOQlzAFq9 +LVHX+DRiJwT4qkS9CG9qKiL3QTNcUC8Aw/XI0Y3Y+rPtTed3XQU9mO0Jl+ErbnNT +s57u9PYhrGJpcigZFyljoxWOGh22IRy41vJnKCZAAK8Zt9KaY/ZlIaBDr+tQ5JZr +Rmdx+QKBgAI/n9g6Gf32skdVsM8ydyZbmUmU2EarGPLKtwv6rDljZekrX+ZQouJU +Wh0Wl7BZGoWScJGlcuNoeewalGY/GrAavaN0YvoyhCkIbeD/B53/bzsMTUvnDHk4 +sxT7ieigYTYabCbpr+g1687ydpEoU7GopE6u3xlmuhj3+HoR825c +-----END RSA PRIVATE KEY----- diff --git a/node_modules/mysql2/examples/ssl/certs/client-req.pem b/node_modules/mysql2/examples/ssl/certs/client-req.pem new file mode 100644 index 0000000..9229af3 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/client-req.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAJr5/45Zo4jVbodoFnkKHR9b1Iqu/tTP+bMAAYV6 +vv7Qo0XskLT9a0rWXPSgG5iq3rBlCYg7Rq3pE/nlTHKPll/wLaPIc9TaIBRhxX9B +MFfDQk1cJXS/4142OaHv9OeCPmXud915svPiiihDc6U3fBtsdJ3hQ2YyEJAo1UUZ +Lec6nWrsLdBe4km6rnM5cTpPoM7jfMujccYkQaO2RcDygVZbbAgquHEmU0vFpbvR +SsszEEIsnaEjQwhNixhIDlo/D4RnSuuQZz2ppqClZhHti7/+Lvxc4rWnzCC1lOUd +jhqRYwJExQSRwqmIwvGtPIGKMb/iOti7F0n5mchhYqSNh68CAwEAAaAAMA0GCSqG +SIb3DQEBBQUAA4IBAQATmAC1QQqi5DWnhtHhKCFORpclZLwNqQJR+wpMZ00Ajt3r ++jSJo/1j9Ecys1niia79y6iyiTqTJDVEmkP+9Wmgols1bMMYZIcbnb09m1G4kCuJ +Axg6ktJ/Dt5R5Gp3JiejBdimAwUJq1gZ7ywcXeV0LnZVpPBz1J1cfWkfP3vMcbqv +qufWq1JOQK0VxfhQqay0CZK4+LCoMaEgWPJCZoC7Eqw5KQKEBERhwETGYHF7wlgG +lqEgWL+aym5su+EW8nFRLJ8pdr9CW+pTaYZw28w34oIx8PYUNgwJ5uIawqZA7IuZ +dST/6A4nD04kJcs7KnPbLCRpRyvdqHiy+7xBd9SJ +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/mysql2/examples/ssl/certs/mkcerts.sh b/node_modules/mysql2/examples/ssl/certs/mkcerts.sh new file mode 100644 index 0000000..7e2d9fc --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/mkcerts.sh @@ -0,0 +1,6 @@ +openssl genrsa 2048 > ca-key.pem +openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem +openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem +openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem +openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem +openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem diff --git a/node_modules/mysql2/examples/ssl/certs/server-cert.pem b/node_modules/mysql2/examples/ssl/certs/server-cert.pem new file mode 100644 index 0000000..94b495b --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/server-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAeYCAQEwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV +BAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDAeFw0xMzA0MzAwMTM1NTJaFw0xNjAxMjUwMTM1NTJaMEUxCzAJBgNVBAYTAkFV +MRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRz +IFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqqHgScXj4 +koJQeURbPss1yAqiByb4Ub/ggNP4+ZQXdoXX+kBKoCXstPHvNwBQlg+m8a4g/x9g +Vj0gKL2nEo+CcIyNHjea728n1xTBHlpSesWqDsbdSMD6sgDl07hCVS4QAjt8a521 +pf4kKbv44Wa9ntpGPmLX7BFxLyN8LBsfTa+noYKxlQK9WJAbP7oL5bza4Uf84Iwg +BEXkku7RRyw48S9RFIEMjIIyUvhS1YIJW57F9rcqaMerdd5BQYcgzpfESbtayWkJ +Es89TgbvoD5njii7EFGgCB5DQfCbgOImJPRHNPHYj4iqGXitFKZO6uxUCyceodxV +KOM/LKZvJKFNAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBALSFOwPrNEyQg1Wp/WkW +BJACqNsnWJKnackSfjS6N4GwH8MOQgAgRwXx3RgpOHUgTnt6KiEQMI40tuHXU8A9 +JNC9XdX7x/EEqny+ZCpVd4P5CzXAJEiZ63WtmEUnjBRQiFxBsgh88cUnXFfIAGEa +jgudFMmVS/tz+UQgciu2FAWkfcCPH1z3fUmxBjrcX9iOCuJXohk2G7qmawfpCkaW +RFo6dBl3u8sEo5+/KeFtl0EmLRD9yMOx1XPoT9oVcpis/XxTkvPxS7hAHHc5ZIBq +w8f5NX/7jTiHJI4k1/mfyrDJMCwJPMzRlTppKSdwEylII5b8SmAaGjGvOiNi/7EX +v90= +-----END CERTIFICATE----- diff --git a/node_modules/mysql2/examples/ssl/certs/server-key.pem b/node_modules/mysql2/examples/ssl/certs/server-key.pem new file mode 100644 index 0000000..c24f872 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/server-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAqqh4EnF4+JKCUHlEWz7LNcgKogcm+FG/4IDT+PmUF3aF1/pA +SqAl7LTx7zcAUJYPpvGuIP8fYFY9ICi9pxKPgnCMjR43mu9vJ9cUwR5aUnrFqg7G +3UjA+rIA5dO4QlUuEAI7fGudtaX+JCm7+OFmvZ7aRj5i1+wRcS8jfCwbH02vp6GC +sZUCvViQGz+6C+W82uFH/OCMIARF5JLu0UcsOPEvURSBDIyCMlL4UtWCCVuexfa3 +KmjHq3XeQUGHIM6XxEm7WslpCRLPPU4G76A+Z44ouxBRoAgeQ0Hwm4DiJiT0RzTx +2I+Iqhl4rRSmTursVAsnHqHcVSjjPyymbyShTQIDAQABAoIBAHMqu9UedJezL3Ql +UicNik9iDyLnFrpvWMClz+bubq0i1BI7lJWH2/AQ8FAR2wmHK0rrQCqOYNs/d4Kz +W8Fa+jP5xjAZm0bYnDfTovLsi+Grbqdjz3pX9bt40rhGl8tT9oDhMMm3SjfirE41 +R+AeJJqEkCLlSQkUC3VJbXYHwcnuJhkVVxsRtNeIE9d5DSOoXuPjAnQjmS5zUBLz +JlA2a5bTLeENfcUL8Jr7WhxWIyIAFBY4ewpg7sbVmMnir3VD315OeowYMQpk/AaC +AiwDA1kJCYoKUCAuizSAS3I5WNFeqZfbhWskdct6MphcMrMsLWvqLtXvLImU+lgX +Z9rJHDUCgYEA1R3+p8WQ/YKppJb/klRMtWLnXHLlTan2YfDxmcLGC9zHro24uAL3 +SpuXivKzSKX8BGA+9lzSnWndX7PK5fi2UMnMAxNNE6Cxu0S+yjras92B+DMjiPRf +lk7trtyXhYjoxPQE8cCxfbKkl6uLYCKyi9JQwygyOPhEUDkZRcyNVusCgYEAzP9W +zqALi7ay0Dizu5ZXRsehQKw4ElMuvHHjt4r16aW7pe8ydqkmsm3Qk8VwfblqZFyU +ndSzWU+SguuD2pUz5re6wLKrZFIicirNS6m88AmCjTUQ5W+FBHpvkQCQWsN5ykfy +KAdfEJlZoInLYdU9Z1GueUk/4EBpToNFz7kzSqcCgYEAlrebvPLP0zlw1+Gh5M6R +YUYM8SigWgh1IlbPxjok7Ya6AQxhMmGGmdDnn3B8skgQrteSL5D9si2ITYJNX85A +wWm1SgeAXv0qNJIti7+Lo+BnZixkWRrZ7ubq2NtQnTNxyrf4NzBbVdXc6RZ8fwSK +2K9oRlxLCFcrmMCIywAahPkCgYEAwK0mTCNFdtYLj4Yb+K6/7Xjo6T51nVOt09U/ +8V2c8TSjAL2oMrud8YshxiKHLsQ9aYNS9F3dDI6r6H2wepxOIgaCc2f7i9lfIutz +9i/ds8dce5hq/xsobSMfBa0AAS9Fo4in5FO5WIKqKSgajyO8CQZO9RSSAxbHY9Ii +pbEusnUCgYBzVXEFSload51C82XgvwjwcayrKrGBq+5/K/N5xMGBxuObu2vWA3ks +MSTU2tXUiwpApY51v+88JGBHwI6+3EGRGEow09S0MlsHxjAG+MCz5Fj+nhoIJk78 +I/E+FGjJW+otrrz8rLi8bz+t3QTtB7rTiKMMpmIIIwG8OacUQPr82g== +-----END RSA PRIVATE KEY----- diff --git a/node_modules/mysql2/examples/ssl/certs/server-req.pem b/node_modules/mysql2/examples/ssl/certs/server-req.pem new file mode 100644 index 0000000..5d44838 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/certs/server-req.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx +ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKqoeBJxePiSglB5RFs+yzXICqIHJvhRv+CA0/j5 +lBd2hdf6QEqgJey08e83AFCWD6bxriD/H2BWPSAovacSj4JwjI0eN5rvbyfXFMEe +WlJ6xaoOxt1IwPqyAOXTuEJVLhACO3xrnbWl/iQpu/jhZr2e2kY+YtfsEXEvI3ws +Gx9Nr6ehgrGVAr1YkBs/ugvlvNrhR/zgjCAEReSS7tFHLDjxL1EUgQyMgjJS+FLV +gglbnsX2typox6t13kFBhyDOl8RJu1rJaQkSzz1OBu+gPmeOKLsQUaAIHkNB8JuA +4iYk9Ec08diPiKoZeK0Upk7q7FQLJx6h3FUo4z8spm8koU0CAwEAAaAAMA0GCSqG +SIb3DQEBBQUAA4IBAQCDtIfTr/LmuFYkuxt1bPj79AOmbONQrwOFP6szeBL44jJf +jaIH4gDWy70zhaZ4FmnskV4TbdEK5ENoW2Rif87JGex2yL+vzdKigRX0TzUYFA0x +IqzR/sx0iMV3EsW3qYPRq/QJErvD5rL1KA6J+nHMeZiRFRF34XaoVHk4zaFDM+J5 +rjMy8GnRS7lqBe31zuqLfU2I9Bwq2InpYMw1Pf+boarZiIwmfMtiHbb5Aap1lMh0 +u1WKfiuB6CqXtyXFJR5PJTwO581yuINByzKlZZyXUpP4MbargPc5f1thf3tKndgB +3GG1gmMsl/cUQ7XBdBH2WXCuipt0mflWj8qKylUA +-----END CERTIFICATE REQUEST----- diff --git a/node_modules/mysql2/examples/ssl/client-flags.sh b/node_modules/mysql2/examples/ssl/client-flags.sh new file mode 100644 index 0000000..04e1cf2 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/client-flags.sh @@ -0,0 +1 @@ +mysql --ssl-key=certs/client-key.pem --ssl-cert=certs/client-cert.pem -h 127.0.0.1 -P 3307 diff --git a/node_modules/mysql2/examples/ssl/rds-ssl.js b/node_modules/mysql2/examples/ssl/rds-ssl.js new file mode 100644 index 0000000..4454d3d --- /dev/null +++ b/node_modules/mysql2/examples/ssl/rds-ssl.js @@ -0,0 +1,16 @@ +var fs = require('fs'); +var mysql = require('../../index.js'); + +var conn = mysql.createConnection({ + user: process.env.USER, + password: process.env.PASSWORD, + database: process.env.DB, + host: process.env.HOST, + port: 3306, + ssl: 'Amazon RDS' +}); + +conn.query('show status like \'Ssl_cipher\'', function(err, res) { + console.log(err, res); + conn.end(); +}); diff --git a/node_modules/mysql2/examples/ssl/select-over-ssl.js b/node_modules/mysql2/examples/ssl/select-over-ssl.js new file mode 100644 index 0000000..d0a1e99 --- /dev/null +++ b/node_modules/mysql2/examples/ssl/select-over-ssl.js @@ -0,0 +1,21 @@ +var fs = require('fs'); +var mysql = require('../../index.js'); +var conn = mysql.createConnection({ + user: 'root', + password: '', + database: 'test', + host: '127.0.0.1', + port: '3306', + ssl: { + //key: fs.readFileSync('./certs/client-key.pem'), + //cert: fs.readFileSync('./certs/client-cert.pem') + ca: fs.readFileSync('./certs/ca-cert.pem') + } +}); + +conn.query('select 1+1 as test', function(err, res) { + console.log(res); + conn.query('select repeat("a", 100) as test', function(err, res) { + console.log(res); + }); +}); diff --git a/node_modules/mysql2/fixtures/mysql-ssl-ca-cert.pem b/node_modules/mysql2/fixtures/mysql-ssl-ca-cert.pem new file mode 100644 index 0000000..8b54fd2 --- /dev/null +++ b/node_modules/mysql2/fixtures/mysql-ssl-ca-cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQzCCAqygAwIBAgIJAOd1tlfiGoEoMA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0dGxlMRMw +EQYDVQQKEwpBbWF6b24uY29tMQwwCgYDVQQLEwNSRFMxHDAaBgNVBAMTE2F3cy5h +bWF6b24uY29tL3Jkcy8wHhcNMTAwNDA1MjI0NDMxWhcNMTUwNDA0MjI0NDMxWjB1 +MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHU2Vh +dHRsZTETMBEGA1UEChMKQW1hem9uLmNvbTEMMAoGA1UECxMDUkRTMRwwGgYDVQQD +ExNhd3MuYW1hem9uLmNvbS9yZHMvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB +gQDKhXGU7tizxUR5WaFoMTFcxNxa05PEjZaIOEN5ctkWrqYSRov0/nOMoZjqk8bC +med9vPFoQGD0OTakPs0jVe3wwmR735hyVwmKIPPsGlaBYj1O6llIpZeQVyupNx56 +UzqtiLaDzh1KcmfqP3qP2dInzBfJQKjiRudo1FWnpPt33QIDAQABo4HaMIHXMB0G +A1UdDgQWBBT/H3x+cqSkR/ePSIinPtc4yWKe3DCBpwYDVR0jBIGfMIGcgBT/H3x+ +cqSkR/ePSIinPtc4yWKe3KF5pHcwdTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh +c2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxEzARBgNVBAoTCkFtYXpvbi5jb20x +DDAKBgNVBAsTA1JEUzEcMBoGA1UEAxMTYXdzLmFtYXpvbi5jb20vcmRzL4IJAOd1 +tlfiGoEoMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAvguZy/BDT66x +GfgnJlyQwnFSeVLQm9u/FIvz4huGjbq9dqnD6h/Gm56QPFdyMEyDiZWaqY6V08lY +LTBNb4kcIc9/6pc0/ojKciP5QJRm6OiZ4vgG05nF4fYjhU7WClUx7cxq1fKjNc2J +UCmmYqgiVkAGWRETVo+byOSDZ4swb10= +-----END CERTIFICATE----- diff --git a/node_modules/mysql2/index.js b/node_modules/mysql2/index.js new file mode 100644 index 0000000..a3e80f9 --- /dev/null +++ b/node_modules/mysql2/index.js @@ -0,0 +1,33 @@ +var Connection = require('./lib/connection.js'); +var ConnectionConfig = require('./lib/connection_config.js'); +var SqlString = require('./lib/sql_string.js'); + +module.exports.createConnection = function(opts) { + return new Connection({config: new ConnectionConfig(opts)}); +}; + +module.exports.connect = module.exports.createConnection; + +module.exports.Connection = Connection; +module.exports.Types = require('./lib/constants/types.js'); + +module.exports.createPool = function(config) { + var PoolConfig = require('./lib/pool_config.js'); + var Pool = require('./lib/pool.js'); + return new Pool({config: new PoolConfig(config)}); +}; + +exports.createPoolCluster = function(config) { + var PoolConfig = require('./lib/pool_config.js'); + var PoolCluster = require('./lib/pool_cluster.js'); + return new PoolCluster(config); +}; + +module.exports.createServer = function() { + var Server = require('./lib/server.js'); + return new Server(); +}; + +exports.escape = SqlString.escape; +exports.escapeId = SqlString.escapeId; +exports.format = SqlString.format; diff --git a/node_modules/mysql2/inflate-test.js b/node_modules/mysql2/inflate-test.js new file mode 100644 index 0000000..e984fb6 --- /dev/null +++ b/node_modules/mysql2/inflate-test.js @@ -0,0 +1,3 @@ +var b = new Buffer('23 30 38 53 30 31 55 6e 6b 6e 6f 77 6e 20 63 6f 6d 6d 61 6e 64'.replace(/ /g, ''), 'hex'); +require('zlib').inflateRaw(b, console.log); +debugger diff --git a/node_modules/mysql2/lib/commands/binlog_dump.js b/node_modules/mysql2/lib/commands/binlog_dump.js new file mode 100644 index 0000000..6812c2b --- /dev/null +++ b/node_modules/mysql2/lib/commands/binlog_dump.js @@ -0,0 +1,104 @@ +var Command = require('./command'); +var util = require('util'); +var CommandCode = require('../constants/commands'); +var Packets = require('../packets'); + +function BinlogDump(opts) +{ + Command.call(this); + //this.onResult = callback; + this.opts = opts; +} +util.inherits(BinlogDump, Command); + +BinlogDump.prototype.start = function(packet, connection) { + var packet = new Packets.BinlogDump(this.opts); + connection.writePacket(packet.toPacket(1)); + return BinlogDump.prototype.binlogData; +}; + +function BinlogEventHeader(packet) { + this.timestamp = packet.readInt32(); + this.eventType = packet.readInt8(); + this.serverId = packet.readInt32(); + this.eventSize = packet.readInt32(); + this.logPos = packet.readInt32(); + this.flags = packet.readInt16(); +} + +function RotateEvent(packet) { + this.pposition = packet.readInt32(); + // TODO: read uint64 here + var positionDword2 = packet.readInt32(); + this.nextBinlog = packet.readString(); + this.name = 'RotateEvent'; +} + +function FormatDescriptionEvent(packet) { + this.binlogVersion = packet.readInt16(); + this.serverVersion = packet.readString(50).replace(/\u0000.*/, ''); + this.createTimestamp = packet.readInt32(); + this.eventHeaderLength = packet.readInt8(); // should be 19 + this.eventsLength = packet.readBuffer(); + this.name = 'FormatDescriptionEvent'; +} + +function QueryEvent(packet) { + + var parseStatusVars = require('../packets/binlog_query_statusvars.js'); + + this.slaveProxyId = packet.readInt32(); + this.executionTime = packet.readInt32(); + var schemaLength = packet.readInt8(); + this.errorCode = packet.readInt16(); + var statusVarsLength = packet.readInt16(); + var statusVars = packet.readBuffer(statusVarsLength); + + this.schema = packet.readString(schemaLength); + packet.readInt8(); // should be zero + this.statusVars = parseStatusVars(statusVars); + + this.query = packet.readString(); + this.name = 'QueryEvent'; +} + +function XidEvent(packet) { + this.binlogVersion = packet.readInt16(); + this.xid = packet.readInt64(); + this.name = 'XidEvent'; +} + +var eventParsers = []; + +eventParsers[2] = QueryEvent; +eventParsers[4] = RotateEvent; +eventParsers[15] = FormatDescriptionEvent; +eventParsers[16] = XidEvent; + +BinlogDump.prototype.binlogData = function(packet) { + // ok - continue consuming events + // error - error + // eof - end of binlog + if (packet.isEOF()) { + this.emit('eof'); + return null; + } + + // binlog event header + var ok = packet.readInt8(); + var header = new BinlogEventHeader(packet); + var EventParser = eventParsers[header.eventType]; + var event; + if (EventParser) + event = new EventParser(packet); + else { + event = { + name: 'UNKNOWN' + } + } + event.header = header; + this.emit('event', event); + return BinlogDump.prototype.binlogData; +}; + +module.exports = BinlogDump; diff --git a/node_modules/mysql2/lib/commands/client_handshake.js b/node_modules/mysql2/lib/commands/client_handshake.js new file mode 100644 index 0000000..9427612 --- /dev/null +++ b/node_modules/mysql2/lib/commands/client_handshake.js @@ -0,0 +1,98 @@ +var Command = require('./command'); +var Packets = require('../packets/index.js'); +var util = require('util'); +var ClientConstants = require('../constants/client'); + +function ClientHandshake(clientFlags) +{ + this.handshake = null; + this.clientFlags = clientFlags; + Command.call(this); +} +util.inherits(ClientHandshake, Command); + +ClientHandshake.prototype.start = function() { + return ClientHandshake.prototype.handshakeInit; +}; + +ClientHandshake.prototype.sendSSLRequest = function(connection) { + var sslRequest = new Packets.SSLRequest(this.clientFlags); + connection.writePacket(sslRequest.toPacket()); +}; + +function flagNames(flags) { + var res = []; + for (var c in ClientConstants) { + if (flags & ClientConstants[c]) + res.push(c.replace(/_/g, ' ').toLowerCase()); + } + return res; +} + +ClientHandshake.prototype.sendCredentials = function(connection, packetIndex) { + if (connection.config.debug) { + console.log('Sending handshake packet: flags:%d=(%s)', this.clientFlags, + flagNames(this.clientFlags).join(', ')); + } + var handshakeResponse = new Packets.HandshakeResponse({ + flags : this.clientFlags, + password: connection.config.password, + user : connection.config.user, + database: connection.config.database, + charsetNumber: connection.config.charsetNumber, + authPluginData1: this.handshake.authPluginData1, + authPluginData2: this.handshake.authPluginData2, + compress: connection.config.compress + }); + connection.writePacket(handshakeResponse.toPacket()); +}; + +ClientHandshake.prototype.handshakeInit = function(helloPacket, connection) { + var command = this; + + this.on('connect', function(connArgs) { + connection.emit('connect', connArgs); + }); + this.on('error', function(err) { + connection._protocolError = err; + connection.emit('error', err); + }); + this.handshake = Packets.Handshake.fromPacket(helloPacket); + if (connection.config.debug) { + console.log('Server hello packet: capability flags:%d=(%s)', this.handshake.capabilityFlags, + flagNames(this.handshake.capabilityFlags).join(', ')); + } + connection.serverCapabilityFlags = this.handshake.capabilityFlags; + connection.connectionId = this.handshake.connectionId; + var serverSSLSupport = this.handshake.capabilityFlags & ClientConstants.SSL; + + // use compression only if requested by client and supported by server + connection.config.compress = connection.config.compress && (this.handshake.capabilityFlags & ClientConstants.COMPRESS); + this.clientFlags = this.clientFlags | connection.config.compress; + + if (connection.config.ssl) { + if (!serverSSLSupport) + throw new Error('Server does not support secure connnection'); + // send ssl upgrade request and immediately upgrade connection to secure + this.clientFlags |= ClientConstants.SSL; + this.sendSSLRequest(connection); + connection.startTLS(function() { + // after connection is secure + command.sendCredentials(connection, 2); + }); + } else { + this.sendCredentials(connection, 1); + } + return ClientHandshake.prototype.handshakeResult; +}; + +ClientHandshake.prototype.handshakeResult = function(okPacket, connection) { + // error is already checked in base class. Done auth. + connection.authorized = true; + if (connection.config.compress) + connection.packetParser.onPacket = connection.handleCompressedPacket.bind(connection); + // TODO any useful information in ok packet to pass as argument? + connection.emit('connect', true); + return null; +}; +module.exports = ClientHandshake; diff --git a/node_modules/mysql2/lib/commands/command.js b/node_modules/mysql2/lib/commands/command.js new file mode 100644 index 0000000..62dd0bc --- /dev/null +++ b/node_modules/mysql2/lib/commands/command.js @@ -0,0 +1,43 @@ +var EventEmitter = require('events').EventEmitter; +var util = require('util'); + +function Command() { + EventEmitter.call(this); + this.next = null; +} +util.inherits(Command, EventEmitter); + +// slow. debug only +Command.prototype.stateName = function() { + var state = this.next; + for (i in this) + if (this[i] == state && i != 'next') + return i; +}; + +Command.prototype.execute = function(packet, connection) { + // TODO: hack + if (!this.next) { + this.next = this.start; + } + + if (packet && packet.isError()) { + var err = packet.asError(); + if (this.onResult) + this.onResult(err); + else + this.emit('error', err); + return true; + } + + // TODO: don't return anything from execute, it's ugly and error-prone. Listen for 'end' event in connection + this.next = this.next(packet, connection); + if (this.next) { + return false; + } else { + this.emit('end'); + return true; + } +}; + +module.exports = Command; diff --git a/node_modules/mysql2/lib/commands/execute.js b/node_modules/mysql2/lib/commands/execute.js new file mode 100644 index 0000000..ae1f14f --- /dev/null +++ b/node_modules/mysql2/lib/commands/execute.js @@ -0,0 +1,189 @@ +var Command = require('./command'); +var Packets = require('../packets/index.js'); +var util = require('util'); +var compileParser = require('../compile_binary_parser'); + +function Execute(options, callback) +{ + Command.call(this); + this.query = options.sql; + + this.onResult = callback; // TODO check felixge multi-result api + this.fieldCount = 0; + this.parameterCount = 0; + this.fields = []; + this.parameterDefinitions = []; + + this.resultFields = []; + this.resultFieldCount = 0; + this.insertId = 0; + + this.parameters = options.values; + this.rows = []; + this.statementInfo = null; + this.options = options; +} +util.inherits(Execute, Command); + +Execute.prototype.start = function(packet, connection) { + var cachedStatement = connection.statements[statementKey(this.query, this.options)]; + if (!cachedStatement) { // prepare first + connection.writePacket(new Packets.PrepareStatement(this.query).toPacket(1)); + } else { + this.statementInfo = cachedStatement; + return this.doExecute(connection); + } + return Execute.prototype.prepareHeader; +}; + +function PreparedStatementInfo(id) { + this.id = id; + this.parser = null; +} + +Execute.prototype.prepareHeader = function(packet, connection) { + var header = new Packets.PreparedStatementHeader(packet); + this.fieldCount = header.fieldCount; + this.parameterCount = header.parameterCount; + this.statementInfo = new PreparedStatementInfo(header.id); + + connection.statements[statementKey(this.query, this.options)] = this.statementInfo; + if (this.parameterCount > 0) + return Execute.prototype.readParameter; + else if (this.fieldCount > 0) + return Execute.prototype.readField; + else + return this.doExecute(connection); +}; + +Execute.prototype.readParameter = function(packet, connection) { + var def = new Packets.ColumnDefinition(packet); + this.parameterDefinitions.push(def); + if (this.parameterDefinitions.length == this.parameterCount) + return Execute.prototype.parametersEOF; + return this.readParameter; +}; + +function statementKey(query, options) { + return (typeof options.nestTables) + + '/' + options.nestTables + '/' + options.rowsAsHash + + query; +} + +// TODO: move to connection.js? +function getFieldsKey(fields, options) { + var res = (typeof options.nestTables) + '/' + options.nestTables + '/' + options.rowsAsHash; + for (var i=0; i < fields.length; ++i) + res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags; + return res; +} + +Execute.prototype.readField = function(packet, connection) { + var def = new Packets.ColumnDefinition(packet); + this.fields.push(def); + var parserKey = ''; + + // TODO: api to allow to flag "I'm not going to change schema for this statement" + // this way we can ignore column definitions in binary response and use + // definition from prepare phase. Note that it's what happens currently + // e.i if you do execute("select * from foo") and later add/remove/rename rows to foo + // (without reconnecting) you are in trouble + + if (this.fields.length == this.fieldCount) { + if (!this.statementInfo.parser) { + // compile row parser + parserKey = getFieldsKey(this.fields, this.options); + // try cached first + this.statementInfo.fields = this.fields; + this.statementInfo.parser = connection.binaryProtocolParsers[parserKey]; + if (!this.statementInfo.parser) { + this.statementInfo.parser = compileParser(this.fields, this.options, connection.config); + connection.binaryProtocolParsers[parserKey] = this.statementInfo.parser; + } + } + return Execute.prototype.fieldsEOF; + } + return Execute.prototype.readField; +}; + +Execute.prototype.parametersEOF = function(packet, connection) { + // check EOF + if (!packet.isEOF()) + throw "Expected EOF packet"; + if (this.fieldCount > 0) + return Execute.prototype.readField; + else + return this.doExecute(connection); +}; + +Execute.prototype.fieldsEOF = function(packet, connection) { + // check EOF + if (!packet.isEOF()) + throw "Expected EOF packet"; + return this.doExecute(connection); +}; + +Execute.prototype.doExecute = function(connection) +{ + connection.sequenceId = 0; + var executePacket = new Packets.Execute(this.statementInfo.id, this.parameters); + connection.writePacket(executePacket.toPacket(1)); + return Execute.prototype.resultsetHeader; +}; + +Execute.prototype.resultsetHeader = function(packet) { + var self = this; + var header = new Packets.ResultSetHeader(packet); + this.resultFieldCount = header.fieldCount; + this.insertId = header.insertId; + if (this.resultFieldCount === 0) { + if (this.onResult) + process.nextTick(function() { + self.onResult(null, header, []); + }); + return null; + } + return Execute.prototype.readResultField; +}; + +Execute.prototype.readResultField = function(packet) { + var def; + if (this.statementInfo.parser) // ignore result fields definition, we are reusing fields from prepare response + this.resultFields.push(null); + else { + def = new Packets.ColumnDefinition(packet); + this.resultFields.push(def); + } + if (this.resultFields.length == this.resultFieldCount) { + return Execute.prototype.resultFieldsEOF; + } + return Execute.prototype.readResultField; +}; + +Execute.prototype.resultFieldsEOF = function(packet) { + // check EOF + if (!packet.isEOF()) + throw "Expected EOF packet"; + return Execute.prototype.row; +}; + +Execute.prototype.row = function(packet) +{ + var self = this; + // TODO: refactor to share code with Query::row + if (packet.isEOF()) { + if (this.onResult) + process.nextTick(function() { + self.onResult(null, self.rows, self.statementInfo.fields); + }) + return null; + } + var r = new this.statementInfo.parser(packet); + if (this.onResult) + this.rows.push(r); + else + this.emit('result', r); + return Execute.prototype.row; +}; + +module.exports = Execute; diff --git a/node_modules/mysql2/lib/commands/index.js b/node_modules/mysql2/lib/commands/index.js new file mode 100644 index 0000000..dd984d4 --- /dev/null +++ b/node_modules/mysql2/lib/commands/index.js @@ -0,0 +1,4 @@ +"client_handshake server_handshake query execute ping register_slave binlog_dump".split(' ').forEach(function(name) { + var ctor = require('./' + name); + module.exports[ctor.name] = ctor; +}); diff --git a/node_modules/mysql2/lib/commands/ping.js b/node_modules/mysql2/lib/commands/ping.js new file mode 100644 index 0000000..531c227 --- /dev/null +++ b/node_modules/mysql2/lib/commands/ping.js @@ -0,0 +1,30 @@ +var Command = require('./command'); +var util = require('util'); +var CommandCode = require('../constants/commands'); +var Packet = require('../packets/packet'); + +// TODO: time statistics? +// usefull for queue size and network latency monitoring +// store created,sent,reply timestamps + +function Ping(callback) +{ + Command.call(this); + this.onResult = callback; +} +util.inherits(Ping, Command); + +Ping.prototype.start = function(packet, connection) { + var ping = new Packet(0, new Buffer([0, 0, 0, 0, CommandCode.PING])); + connection.writePacket(ping); + return Ping.prototype.pingResponse; +}; + +Ping.prototype.pingResponse = function(packet) { + // TODO: check it's OK packet. error check already done in caller + if (this.onResult) + process.nextTick(this.onResult.bind(this)); + return null; +}; + +module.exports = Ping; diff --git a/node_modules/mysql2/lib/commands/query.js b/node_modules/mysql2/lib/commands/query.js new file mode 100644 index 0000000..71fdf17 --- /dev/null +++ b/node_modules/mysql2/lib/commands/query.js @@ -0,0 +1,150 @@ +var Command = require('./command'); +var Packets = require('../packets/index.js'); +var util = require('util'); +var compileParser = require('../compile_text_parser.js'); +var ServerStatus = require('../constants/server_status.js'); + +function Query(sql, options, callback) +{ + Command.call(this); + this.query = sql; + this.options = options; + this.onResult = callback; + this._fieldCount = 0; + this._rowParser = null; + this._fields = []; + this._rows = []; + this._receivedFieldsCount = 0; + this._resultIndex = 0; +} +util.inherits(Query, Command); + +Query.prototype.start = function(packet, connection) { + if (connection.config.debug) { + console.log(' Sending query command: %s', this.query); + } + var cmdPacket = new Packets.Query(this.query); + connection.writePacket(cmdPacket.toPacket(1)); + return Query.prototype.resultsetHeader; +}; + +Query.prototype.done = function() { + var self = this; + if (this.onResult) { + var rows, fields; + if (this._resultIndex === 0) { + rows = this._rows[0]; + fields = this._fields[0]; + } else { + rows = this._rows; + fields = this._fields; + } + if (fields) { + process.nextTick(function() { + self.onResult(null, rows, fields); + }); + } else { + process.nextTick(function() { + self.onResult(null, rows); + }); + } + } + return null; +}; + +Query.prototype.resultsetHeader = function(packet, connection) { + var rs = new Packets.ResultSetHeader(packet, connection.config.bigNumberStrings); + this._fieldCount = rs.fieldCount; + if (connection.config.debug) { + console.log(' Resultset header received, expecting ' + rs.fieldCount + ' column definition packets'); + } + if (this._fieldCount === 0) { + this._rows.push(rs); + this._fields.push(void(0)); + this.emit('result', rs, this._resultIndex); + this.emit('fields', void(0), this._resultIndex); + if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) { + this._resultIndex++; + return Query.prototype.resultsetHeader; + } + return this.done(); + } + + this._receivedFieldsCount = 0; + this._rows.push([]); + this._fields.push([]); + return Query.prototype.readField; +}; + +// TODO: move to connection.js ? +function getFieldsKey(fields, options) { + var res = (typeof options.nestTables) + '/' + options.nestTables + '/' + options.rowsAsHash; + for (var i=0; i < fields.length; ++i) + res += '/' + fields[i].name + ':' + fields[i].columnType + ':' + fields[i].flags; + return res; +} + +Query.prototype.readField = function(packet, connection) { + + this._receivedFieldsCount++; + + // Often there is much more data in the column definition than in the row itself + // If you set manually _fields[0] to array of ColumnDefinition's (from previous call) + // you can 'cache' result of parsing. Field packets still received, but ignored in that case + // this is the reason _receivedFieldsCount exist (otherwise we could just use current length of fields array) + + if (this._fields[this._resultIndex].length != this._fieldCount) { + var field = new Packets.ColumnDefinition(packet); + this._fields[this._resultIndex].push(field); + if (connection.config.debug) { + console.log(' Column definition:'); + console.log(' name: ' + field.name); + console.log(' type: ' + field.columnType); + console.log(' flags: ' + field.flags); + } + } + + // last field received + if (this._receivedFieldsCount == this._fieldCount) { + var fields = this._fields[this._resultIndex]; + this.emit('fields', fields, this._resultIndex); + var parserKey = getFieldsKey(fields, this.options); + this.rowParser = connection.textProtocolParsers[parserKey]; + if (!this.rowParser) { + this.rowParser = compileParser(fields, this.options, connection.config); + connection.textProtocolParsers[parserKey] = this.rowParser; + } + return Query.prototype.fieldsEOF; + } + return Query.prototype.readField; +}; + +Query.prototype.fieldsEOF = function(packet) { + // check EOF + if (!packet.isEOF()) + throw "Expected EOF packet"; // !!!TODO don't crash if there is a protocol error + return Query.prototype.row; +}; + +Query.prototype.row = function(packet) +{ + if (packet.isEOF()) { + var status = packet.eofStatusFlags(); + var moreResults = packet.eofStatusFlags() & ServerStatus.SERVER_MORE_RESULTS_EXISTS; + if (moreResults) { + this._resultIndex++; + return Query.prototype.resultsetHeader; + } + return this.done(); + } + + var row = new this.rowParser(packet); + if (this.onResult) + this._rows[this._resultIndex].push(row); + else + this.emit('result', row, this._resultIndex); + + return Query.prototype.row; +}; + +module.exports = Query; diff --git a/node_modules/mysql2/lib/commands/register_slave.js b/node_modules/mysql2/lib/commands/register_slave.js new file mode 100644 index 0000000..19304f6 --- /dev/null +++ b/node_modules/mysql2/lib/commands/register_slave.js @@ -0,0 +1,26 @@ +var Command = require('./command'); +var util = require('util'); +var CommandCode = require('../constants/commands'); +var Packets = require('../packets'); + +function RegisterSlave(opts, callback) +{ + Command.call(this); + this.onResult = callback; + this.opts = opts; +} +util.inherits(RegisterSlave, Command); + +RegisterSlave.prototype.start = function(packet, connection) { + var packet = new Packets.RegisterSlave(this.opts); + connection.writePacket(packet.toPacket(1)); + return RegisterSlave.prototype.registerResponse; +}; + +RegisterSlave.prototype.registerResponse = function(packet) { + if (this.onResult) + process.nextTick(this.onResult.bind(this)); + return null; +}; + +module.exports = RegisterSlave; \ No newline at end of file diff --git a/node_modules/mysql2/lib/commands/server_handshake.js b/node_modules/mysql2/lib/commands/server_handshake.js new file mode 100644 index 0000000..46de993 --- /dev/null +++ b/node_modules/mysql2/lib/commands/server_handshake.js @@ -0,0 +1,98 @@ +var Command = require('./command'); +var Packets = require('../packets/index.js'); +var util = require('util'); +var ClientConstants = require('../constants/client'); +var CommandCode = require('../constants/commands'); + +function ServerHandshake(args) +{ + Command.call(this); + this.args = args; + /* + this.protocolVersion = args.protocolVersion || 10; + this.serverVersion = args.serverVersion; + this.connectionId = args.connectionId, + this.statusFlags = args.statusFlags, + this.characterSet = args.characterSet, + this.capabilityFlags = args.capabilityFlags || 512; + */ +} +util.inherits(ServerHandshake, Command); + +ServerHandshake.prototype.start = function(packet, connection) { + var serverHelloPacket = new Packets.Handshake(this.args); + serverHelloPacket.setScrambleData(function(err) { + connection.writePacket(serverHelloPacket.toPacket(0)); + }); + return ServerHandshake.prototype.readClientReply; +}; + +ServerHandshake.prototype.readClientReply = function(packet, connection) { + // TODO connection.writeOk(); + var ok = new Buffer([0x07, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00]); + connection.write(ok); + return ServerHandshake.prototype.dispatchCommands; +}; + +ServerHandshake.prototype.dispatchCommands = function(packet, connection) { + // command from client to server + var commandCode = packet.readInt8(); + switch (commandCode) { + case CommandCode.QUIT: + connection.stream.end(); + break; + case CommandCode.INIT_DB: + var schemaName = packet.readString(); + connection.emit('init_db', schemaName); + connection.writeOk(); + break; + case CommandCode.PING: + // allow custom ping response (delayed/incorrect/etc) + // if no listeners, respond with OK + if (connection.listeners('ping').length === 0) { + connection.writeOk(); + } else { + connection.emit('ping'); + } + break; + case CommandCode.QUERY: + var query = packet.readString(); + connection.emit('query', query); + break; + case CommandCode.FIELD_LIST: + var table = packet.readNullTerminatedString(); + var fields = packet.readString(); + connection.emit('field_list', table, fields); + break; + default: + console.log('Unknown command:', commandCode); + } + return ServerHandshake.prototype.dispatchCommands; +}; + +module.exports = ServerHandshake; + +// TODO: implement server-side 4.1 authentication +/* +4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c) + + SERVER: public_seed=create_random_string() + send(public_seed) + + CLIENT: recv(public_seed) + hash_stage1=sha1("password") + hash_stage2=sha1(hash_stage1) + reply=xor(hash_stage1, sha1(public_seed,hash_stage2) + + // this three steps are done in scramble() + + send(reply) + + + SERVER: recv(reply) + hash_stage1=xor(reply, sha1(public_seed,hash_stage2)) + candidate_hash2=sha1(hash_stage1) + check(candidate_hash2==hash_stage2) + +server stores sha1(sha1(password)) ( hash_stag2) +*/ diff --git a/node_modules/mysql2/lib/compile_binary_parser.js b/node_modules/mysql2/lib/compile_binary_parser.js new file mode 100644 index 0000000..725b49d --- /dev/null +++ b/node_modules/mysql2/lib/compile_binary_parser.js @@ -0,0 +1,132 @@ +var FieldFlags = require('./constants/field_flags'); +var Charsets = require('./constants/charsets'); +var Types = require('./constants/types'); +var vm = require('vm'); +var srcEscape = require('./helpers').srcEscape; + +var typeNames = []; +for (var t in Types) { + typeNames[Types[t]] = t; +} + +function compile(fields, options, config) { + var result = []; + var i=0; + var nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8); + result.push('(function(){ return function BinaryRow(packet) {'); + + if (options.rowsAsArray) + result.push(' var result = new Array(' + fields.length + ')'); + + var resultTables = {}; + var resultTablesArray = []; + + if (options.nestTables === true) { + for (i = 0; i < fields.length; i++) { + resultTables[fields[i].table] = 1; + } + resultTablesArray = Object.keys(resultTables); + for (i = 0; i < resultTablesArray.length; i++) { + result.push(' this[' + srcEscape(resultTablesArray[i]) + '] = {};'); + } + } + + result.push(' var statusByte = packet.readInt8();'); + for (i=0; i < nullBitmapLength; ++i) + result.push(' var nullBitmaskByte' + i + ' = packet.readInt8();'); + + var lvalue = ''; + var currentFieldNullBit = 4; + var nullByteIndex = 0; + var fieldName = ''; + var tableName = ''; + + for (i = 0; i < fields.length; i++) { + fieldName = srcEscape(fields[i].name); + result.push(' // ' + fieldName + ': '+ typeNames[fields[i].columnType]); + + if (typeof options.nestTables == 'string') { + tableName = srcEscape(fields[i].table); + lvalue = [' this[', srcEscape(fields[i].table + options.nestTables + fields[i].name), ']'].join(''); + } else if (options.nestTables === true) { + tableName = srcEscape(fields[i].table); + lvalue = [' this[', tableName, '][', fieldName, ']'].join(''); + } else if (options.rowsAsArray) { + lvalue = ' result[' + i.toString(10) + ']'; + } else + lvalue = ' this[' + srcEscape(fields[i].name) + ']'; + + if (fields[i].flags & FieldFlags.NOT_NULL) { // don't need to check null bitmap if field can't be null. + result.push(lvalue + ' = ' + readCodeFor(fields[i], config)); + } else if (fields[i].columnType == Types.NULL) { + result.push(lvalue + ' = null;'); + } else { + result.push(' if (nullBitmaskByte' + nullByteIndex + ' & ' + currentFieldNullBit + ')'); + result.push(' ' + lvalue + ' = null;'); + result.push(' else'); + result.push(' ' + lvalue + ' = ' + readCodeFor(fields[i], config)); + } + currentFieldNullBit *= 2; + if (currentFieldNullBit == 0x100) + { + currentFieldNullBit = 1; + nullByteIndex++; + } + } + + if (options.rowsAsArray) + result.push(' return result;'); + + result.push('}; })()'); + var src = result.join('\n'); + if (config.debug) { + console.log('Compiled text protocol row parser:'); + var cardinal = require('cardinal'); + console.log(cardinal.highlight(src)); + } + return vm.runInThisContext(src); +} + +function readCodeFor(field, config) { + var unsigned = field.flags & FieldFlags.UNSIGNED; + switch(field.columnType) { + case Types.TINY: + return unsigned ? "packet.readInt8();" : "packet.readSInt8();"; + case Types.SHORT: + return unsigned ? "packet.readInt16();" : "packet.readSInt16();"; + case Types.LONG: + case Types.INT24: // in binary protocol int24 is encoded in 4 bytes int32 + return unsigned ? "packet.readInt32();" : "packet.readSInt32();"; + case Types.YEAR: + return "packet.readInt16()"; + case Types.FLOAT: + return "packet.readFloat();"; + case Types.DOUBLE: + return "packet.readDouble();"; + case Types.NULL: + return "null;"; + case Types.DATE: + case Types.DATETIME: + case Types.TIMESTAMP: + case Types.NEWDATE: + if (config.dateStrings) + return "packet.readDateTimeString();"; + return "packet.readDateTime();"; + case Types.TIME: + return "packet.readTimeString()"; + case Types.DECIMAL: + case Types.NEWDECIMAL: + return "packet.readLengthCodedString();"; + case Types.GEOMETRY: + return "packet.parseGeometryValue();"; + case Types.LONGLONG: // TODO: 8 bytes. Implement as two 4 bytes read for now (it's out of JavaScript int precision!) + return unsigned ? "packet.readInt64();" : "packet.readSInt64();"; + default: + if (field.characterSet == Charsets.BINARY) + return "packet.readLengthCodedBuffer();"; + else + return "packet.readLengthCodedString();"; + } +} + +module.exports = compile; diff --git a/node_modules/mysql2/lib/compile_text_parser.js b/node_modules/mysql2/lib/compile_text_parser.js new file mode 100644 index 0000000..6ec1365 --- /dev/null +++ b/node_modules/mysql2/lib/compile_text_parser.js @@ -0,0 +1,104 @@ +var Types = require('./constants/types'); +var Charsets = require('./constants/charsets'); +var vm = require('vm'); +var srcEscape = require('./helpers').srcEscape; + +var typeNames = []; +for (var t in Types) { + typeNames[Types[t]] = t; +} + +function compile(fields, options, config) { + + var result = []; + var i=0; + var lvalue = ''; + + result.push('(function() { return function TextRow(packet) {'); + if (options.rowsAsArray) + result.push(' var result = new Array(' + fields.length + ')'); + + var resultTables = {}; + var resultTablesArray = []; + + if (options.nestTables === true) { + for (i = 0; i < fields.length; i++) { + resultTables[fields[i].table] = 1; + } + resultTablesArray = Object.keys(resultTables); + for (i = 0; i < resultTablesArray.length; i++) { + result.push(' this[' + srcEscape(resultTablesArray[i]) + '] = {};'); + } + } + + var fieldName = ''; + var tableName = ''; + for (i = 0; i < fields.length; i++) { + fieldName = srcEscape(fields[i].name); + result.push(' // ' + fieldName + ': '+ typeNames[fields[i].columnType]); + if (typeof options.nestTables == 'string') { + tableName = srcEscape(fields[i].table); + lvalue = [' this[', srcEscape(fields[i].table + options.nestTables + fields[i].name), ']'].join(''); + } else if (options.nestTables === true) { + tableName = srcEscape(fields[i].table); + lvalue = [' this[', tableName, '][', fieldName, ']'].join(''); + } else if (options.rowsAsArray) { + lvalue = ' result[' + i.toString(10) + ']'; + } else + lvalue = ' this[' + srcEscape(fields[i].name) + ']'; + result.push(lvalue + ' = ' + readCodeFor(fields[i].columnType, fields[i].characterSet, config)); + } + + if (options.rowsAsArray) + result.push(' return result;'); + + result.push('};})()'); + var src = result.join('\n'); + if (config.debug) { + console.log(' Compiled text protocol row parser:\n\n'); + var cardinal = require('cardinal'); + console.log(cardinal.highlight(src) + '\n\n'); + } + return vm.runInThisContext(src); +} + +function readCodeFor(type, charset, config) { + switch(type) { + case Types.TINY: + case Types.SHORT: + case Types.LONG: + case Types.INT24: + case Types.YEAR: + case Types.LONG: + case Types.LONGLONG: + return "packet.parseLengthCodedInt();"; + case Types.FLOAT: + case Types.DOUBLE: + return "packet.parseLengthCodedFloat();"; + case Types.NULL: + return "null; packet.skip(1);"; + case Types.DECIMAL: + case Types.NEWDECIMAL: + return "packet.readLengthCodedString(); //" + type + ' ' + charset; + case Types.DATE: + if (config.dateStrings) + return "packet.readLengthCodedString()"; + return "packet.parseDate();"; + case Types.DATETIME: + case Types.TIMESTAMP: + if (config.dateStrings) + return "packet.readLengthCodedString()"; + return "packet.parseDateTime();"; + case Types.TIME: + return "packet.readLengthCodedString()"; + case Types.GEOMETRY: + return "packet.parseGeometryValue();"; + default: + if (charset == Charsets.BINARY) + return "packet.readLengthCodedBuffer();"; + else + return "packet.readLengthCodedString(); //" + type + ' ' + charset; + } +} + +module.exports = compile; diff --git a/node_modules/mysql2/lib/connection.js b/node_modules/mysql2/lib/connection.js new file mode 100644 index 0000000..4926441 --- /dev/null +++ b/node_modules/mysql2/lib/connection.js @@ -0,0 +1,510 @@ +var net = require('net'); +var util = require('util'); +var EventEmitter = require('events').EventEmitter; +var Queue = require('fastqueue'); + +var PacketParser = require('./packet_parser'); +var Packet = require('./packets/packet'); +var Packets = require('./packets/index.js'); +var Commands = require('./commands/index.js'); +var SqlString = require('./sql_string'); + +var _connectionId = 0; + +function Connection(opts) +{ + EventEmitter.call(this); + this.config = opts.config; + + // TODO: fill defaults + // if no params, connect to /var/lib/mysql/mysql.sock ( /tmp/mysql.sock on OSX ) + // if host is given, connect to host:3306 + + // TODO: use `/usr/local/mysql/bin/mysql_config --socket` output? as default socketPath + // if there is no host/port and no socketPath parameters? + + if (!opts.config.stream) { + if (opts.config.socketPath) + this.stream = net.connect(opts.config.socketPath); + else + this.stream = net.connect(opts.config.port, opts.config.host); + } else { + this.stream = opts.config.stream; + } + this._internalId = _connectionId++; + + this._commands = new Queue(); + this._command = null; + + this.statements = {}; + + // TODO: make it lru cache + // https://github.com/mercadolibre/node-simple-lru-cache + // or https://github.com/rsms/js-lru + // or https://github.com/monsur/jscache + // or https://github.com/isaacs/node-lru-cache + // + // key is field.name + ':' + field.columnType + ':' field.flags + '/' + this.textProtocolParsers = {}; + + // TODO: not sure if cache should be separate (same key as with textProtocolParsers) + // or part of prepared statements cache (key is sql query) + this.binaryProtocolParsers = {}; + + this.serverCapabilityFlags = 0; + this.authorized = false; + + var connection = this; + this.sequenceId = 0; + + this.stream.on('error', function(err) { + connection.emit('error', err); + }); + + // big TODO: benchmark if it all worth using 'ondata' and onPacket callbacks directly + // compositing streams would be much more easier. + // also, look for existing length-prefixed streams to reuse instead of packet_parser + // https://github.com/squaremo/node-spb - currently only fixed 4 byte prefix + // ...? + + // see https://gist.github.com/khoomeister/4985691#use-that-instead-of-bind + this.packetParser = new PacketParser(function(p) { connection.handlePacket(p) }); + + // TODO: this code used to be an optimized version of handler + // DOES NOT WORK IN NODE 11 + // TODO: measure if we actually get something here + // if yes, re-enable for node 10 + //if (this.stream instanceof net.Stream) { + // this.stream.ondata = function(data, start, end) { + // connection.packetParser.execute(data, start, end); + // }; + //} else { + this.stream.on('data', function(data) { + connection.packetParser.execute(data, 0, data.length); + }); + //} + this._protocolError = null; + this.stream.on('end', function() { + // we need to set this flag everywhere where we want connaction to close + if (connection._closing) + return; + + if (!connection._protocolError) // no particular error message before disconnect + connection._protocolError = 'PROTOCOL_CONNECTION_LOST' + var err = new Error('Connection lost: The server closed the connection.'); + err.fatal = true; + err.code = connection._protocolError; + connection.emit('error', err); + + }); + var handshakeCommand; + if (!this.config.isServer) { + handshakeCommand = new Commands.ClientHandshake(this.config.clientFlags); + handshakeCommand.on('error', function(e) { connection.emit('error', e); }); + this.addCommand(handshakeCommand); + } +} +util.inherits(Connection, EventEmitter); + +Connection.prototype.write = function(buffer) { + this.stream.write(buffer); +}; + +// TODO: replace function in runtime instead of having if() here +// Needs benchmark. +Connection.prototype.writePacket = function(packet) { + packet.writeHeader(this.sequenceId); + if (this.config.debug) { + console.log(this._internalId + ' ' + this.connectionId + ' <== ' + this._command._commandName + '#' + this._command.stateName() + '(' + [this.sequenceId, packet._name, packet.length()].join(',') + ')'); + } + this.sequenceId++; + if (this.sequenceId == 256) + this.sequenceId = 0 + if (!this.config.compress || !this.authorized) { + this.write(packet.buffer); + } else { + var packetLen = packet.length(); + var compressHeader = new Buffer(7); + + // TODO: currently all outgoing packets are sent uncompressed (header + deflated length=0 as uncompressed flag) + // Need to implement deflation of outgoing packet. Also need to decide when not to compress small packets + // http://dev.mysql.com/doc/internals/en/compression.html#uncompressed-payload suggest not to compress packets less than 50 bytes + + // Write uncompressed packet + compressHeader.fill(0); + compressHeader.writeUInt8(packetLen & 0xff, 0); + compressHeader.writeUInt16LE(packetLen >> 8, 1); + this.write(compressHeader); + this.write(packet.buffer); + } +}; + +Connection.prototype.startTLS = function(onSecure) { + var connection = this; + var crypto = require('crypto'); + var tls = require('tls'); + var config = this.config; + var stream = this.stream; + + // special case for Amazon RDS: use http://s3.amazonaws.com/rds-downloads/mysql-ssl-ca-cert.pem CA cert if ssl option set to "Amazon RDS" + if (config.ssl === 'Amazon RDS') { + var fs = require('fs'); + var path = require('path'); + fs.readFile(path.resolve(__dirname, '../fixtures/mysql-ssl-ca-cert.pem'), function(err, ca) { + if (err) throw err; + config.ssl = { ca: ca }; + after(); + }); + } else + after(); + + function after() { + var credentials = crypto.createCredentials({ + key: config.ssl.key, + cert: config.ssl.cert, + passphrase: config.ssl.passphrase, + ca: config.ssl.ca + }); + var securePair = tls.createSecurePair(credentials, false); + if (stream.ondata) + stream.ondata = null; + stream.removeAllListeners('data'); + stream.pipe(securePair.encrypted); + securePair.encrypted.pipe(stream); + securePair.cleartext.on('data', function(data) { + connection.packetParser.execute(data.parent, data.offset, data.offset + data.length); + }); + connection.write = function(buffer) { + securePair.cleartext.write(buffer); + }; + securePair.on('secure', onSecure); + } +}; + +// TODO: this does not work if uncompressed packet is split by compressed +// packet boundary. +// My assumption about compressedPacket to contain one or more complete +// compressed packets was wrong. It can wrap any chunk of data. +// This will be rmoved in favor of connection.startInflate +// currently Handshake command overwrites connection.handlePacket with handleCompressedPacket +// before expecting first compressed packet +var zlib = require('zlib'); +Connection.prototype.handleCompressedPacket = function(packet) { + var connection = this; + var inflatedLength = packet.readInt24(); + if (inflatedLength !== 0) { + var compressedBody = packet.readBuffer(packet.length() - 3); + zlib.inflate(compressedBody, function(err, packets) { + if (err) + return connection.emit('error', err); + var offset = packets.offset; + var end = offset + packets.length; + var buffer = packets.parent; + var len = 0; + var id = 0; + // single compressed packet can contain multiple uncompressed + while (offset < end) { + len = buffer.readUInt16LE(offset) + (buffer[offset+2] << 16); + id = buffer[offset+3]; + connection.handlePacket(new Packet(id, buffer, offset + 4, offset + 4 + len)); + offset += 4 + len; + } + }); + } else { + inflatedLength = packet.readInt24(); + var sequenceId = packet.readInt8(); + connection.handlePacket(new Packet(sequenceId, packet.buffer, packet.offset, packet.offset + inflatedLength)); + } +}; + +// TODO: consider using @creationix simple-streams +// https://gist.github.com/creationix/5498108 +// https://github.com/creationix/min-stream-uv +// https://github.com/creationix/min-stream-helpers + + +// TODO: try with Stream2 streams +// +// changes stream -> packetParser to +// stream -> compressedPacketParser -> inflateStream -> packetParser +// note that in the caseof ssl this should become +// stream -> securePair.encrypted -> securePair.cleartext -> compressedPacketParser -> inflateStream -> packetParser +Connection.prototype.startInflate = function() { + var connection = this; + var zlib = require('zlib'); + var inflateStream = zlib.createInflate(); + var uncompressedPacketParser = connection.packetParser; + connection.packetParser = new PacketParser(function(compressedPacket) { + var inflatedLength = packet.readInt24(); + if (inflatedLength !== 0) { + inflateStream.write(packet.readBuffer(packet.length() - 3)); + } else { + uncompressedPacketParser.execute(packet.buffer, packet.offset, packet.end); + } + }); + inflateStream.on('data', function(buff) { + uncompressedPacketParser.execute(buff.parent, buff.offset, buff.offset + buff.length); + }); + if (this.stream.ondata) + this.stream.ondata = null; + this.stream.removeAllListeners('data'); + this.pipe(); +}; + +Connection.prototype.pipe = function() { + var connection = this; + if (this.stream instanceof net.Stream) { + this.stream.ondata = function(data, start, end) { + connection.packetParser.execute(data, start, end); + }; + } else { + this.stream.on('data', function(data) { + connection.packetParser.execute(data.parent, data.offset, data.offset + data.length); + }); + } +}; + +Connection.prototype.handlePacket = function(packet) { + // TODO: check packet sequenceId here + var packetType = ''; + if (packet) + this.sequenceId = packet.sequenceId + 1; + if (this.config.debug) { + if (packet) { + console.log(this._internalId + ' ' + this.connectionId + ' ==> ' + this._command._commandName + '#' + this._command.stateName() + '(' + [packet.sequenceId, packet.type(), packet.length()].join(',') + ')'); + } + } + var done = this._command.execute(packet, this); + if (done) { + this.sequenceId = 0; + this._command = this._commands.shift(); + if (this._command) + this.handlePacket(); + } +}; + +Connection.prototype.addCommand = function(cmd) { + if (this.config.debug) { + console.log('Add command: ' + arguments.callee.caller.name); + cmd._commandName = arguments.callee.caller.name; + } + if (!this._command) { + this._command = cmd; + this.handlePacket(); + } else { + this._commands.push(cmd); + } + return cmd; +}; + +Connection.prototype.format = function(sql, values) { + if (typeof this.config.queryFormat == "function") { + return this.config.queryFormat.call(this, sql, values, this.config.timezone); + } + return SqlString.format(sql, values, this.config.timezone); +}; + +Connection.prototype.escape = function(value) { + return SqlString.escape(value, false, this.config.timezone); +}; + +function _domainify(callback) { + var domain = process.domain; + if (domain && callback) + return process.domain.bind(callback); + else + return callback; +} + +Connection.prototype.query = function query(sql, values, cb) { + // copy-paste from node-mysql/lib/Connection.js:createQuery + var options = {}; + if (typeof sql === 'object') { + // query(options, cb) + options = sql; + if (typeof values === 'function') { + cb = values; + } else { + options.values = values; + } + } else if (typeof values === 'function') { + // query(sql, cb) + cb = values; + options.sql = sql; + options.values = undefined; + } else { + // query(sql, values, cb) + options.sql = sql; + options.values = values; + } + var rawSql = this.format(options.sql, options.values || []); + return this.addCommand(new Commands.Query(rawSql, options, _domainify(cb))); +}; + +Connection.prototype.execute = function execute(sql, values, cb) { + var options = {}; + if (typeof sql === 'object') { + // execute(options, cb) + options = sql; + if (typeof values === 'function') { + cb = values; + } else { + options.values = values; + } + } else if (typeof values === 'function') { + // execute(sql, cb) + cb = values; + options.sql = sql; + options.values = undefined; + } else { + // execute(sql, values, cb) + options.sql = sql; + options.values = values; + } + + return this.addCommand(new Commands.Execute(options, _domainify(cb))); +}; + +// transaction helpers +Connection.prototype.beginTransaction = function(cb) { + return this.query('START TRANSACTION', cb); +} + +Connection.prototype.commit = function(cb) { + return this.query('COMMIT', cb); +} + +Connection.prototype.rollback = function(cb) { + return this.query('ROLLBACK', cb); +} + +Connection.prototype.ping = function ping(cb) { + return this.addCommand(new Commands.Ping(_domainify(cb))); +}; + +Connection.prototype._registerSlave = function registerSlave(opts, cb) { + return this.addCommand(new Commands.RegisterSlave(opts, _domainify(cb))); +}; + +Connection.prototype._binlogDump = function binlogDump(opts, cb) { + return this.addCommand(new Commands.BinlogDump(opts, _domainify(cb))); +}; + +Connection.prototype.createBinlogStream = function(opts) { + // TODO: create proper stream class + // TODO: use through2 + var test = 1; + var Readable = require('stream').Readable; + var stream = new Readable({objectMode: true}); + stream._read = function() { + return { + data: test++ + } + }; + var connection = this; + connection._registerSlave(opts, function(err) { + var dumpCmd = connection._binlogDump(opts); + dumpCmd.on('event', function(ev) { + stream.push(ev); + }); + dumpCmd.on('eof', function() { + stream.push(null); + // if non-blocking, then close stream to prevent errors + if (opts.flags && (opts.flags & 0x01)) { + connection._closing = true; + connection.stream.end(); + } + }); + // TODO: pipe errors as well + }) + return stream; +} + +Connection.prototype.connect = function(cb) { + if (!cb) return; + var connectCalled = 0; + + // TODO domainify this callback as well. Note that domain has to be captured + // at the top of function due to nested callback + function callbackOnce(isErrorHandler) { + return function(param) { + if (!connectCalled) { + if (isErrorHandler) + cb(param); + else + cb(null, param); + } + connectCalled = 1; + }; + } + this.once('error', callbackOnce(true) ); + this.once('connect', callbackOnce(false)); +}; + +// =================================== +// outgoing server connection methods +// =================================== + +Connection.prototype.writeColumns = function(columns) { + var connection = this; + this.writePacket(Packets.ResultSetHeader.toPacket(columns.length)); + columns.forEach(function(column) { + connection.writePacket(Packets.ColumnDefinition.toPacket(column)); + }); + this.writeEof(); +}; + +// row is array of columns, not hash +Connection.prototype.writeTextRow = function(column) { + this.writePacket(Packets.TextRow.toPacket(column)); +}; + +Connection.prototype.writeTextResult = function(rows, columns) { + var connection = this; + connection.writeColumns(columns); + rows.forEach(function(row) { + var arrayRow = new Array(columns.length); + columns.forEach(function(column) { + arrayRow.push(row[column.name]); + }); + connection.writeTextRow(arrayRow); + }); + connection.writeEof(); +}; + +Connection.prototype.writeEof = function(warnings, statusFlags) { + this.writePacket(Packets.EOF.toPacket(warnings, statusFlags)); +}; + +Connection.prototype.writeOk = function(args) { + if (!args) + args = { affectedRows: 0 }; + this.writePacket(Packets.OK.toPacket(args)); +}; + +Connection.prototype.writeError = function(args) { + this.writePacket(Packets.Error.toPacket(args)); +}; + +Connection.prototype.serverHandshake = function serverHandshake(args) { + return this.addCommand(new Commands.ServerHandshake(args)); +}; + +// =============================================================== + +// TODO: domainify +Connection.prototype.end = function(callback) { + // TODO: implement COM_QUIT command + var self = this; + var endCmd = { connection: this }; + endCmd.execute = function() { + self._closing = true; + this.connection.stream.end(); + if (callback) + callback(); + }; + return this.addCommand(endCmd); + //return this.addCommand(new Commands.Quit(callback)); +}; + +module.exports = Connection; diff --git a/node_modules/mysql2/lib/connection_config.js b/node_modules/mysql2/lib/connection_config.js new file mode 100644 index 0000000..457055d --- /dev/null +++ b/node_modules/mysql2/lib/connection_config.js @@ -0,0 +1,120 @@ +var urlParse = require('url').parse; +var ClientConstants = require('./constants/client'); +var Charsets = require('./constants/charsets'); + +module.exports = ConnectionConfig; +function ConnectionConfig(options) { + if (typeof options === 'string') { + options = ConnectionConfig.parseUrl(options); + } + + this.isServer = options.isServer; + this.stream = options.stream; + + this.host = options.host || 'localhost'; + this.port = options.port || 3306; + this.socketPath = options.socketPath; + this.user = options.user || undefined; + this.password = options.password || undefined; + this.database = options.database; + this.insecureAuth = options.insecureAuth || false; + this.supportBigNumbers = options.supportBigNumbers || false; + this.bigNumberStrings = options.bigNumberStrings || false; + this.debug = options.debug; + this.timezone = options.timezone || 'local'; + this.flags = options.flags || ''; + this.queryFormat = options.queryFormat; + this.pool = options.pool || undefined; + this.multipleStatements = options.multipleStatements || false; + this.typeCast = (options.typeCast === undefined) ? true : options.typeCast; + this.ssl = options.ssl; + this.compress = options.compress || false; + this.dateStrings = options.dateStrings || false; + + + if (this.timezone[0] == " ") { + // "+" is a url encoded char for space so it + // gets translated to space when giving a + // connection string.. + this.timezone = "+" + this.timezone.substr(1); + } + + this.maxPacketSize = 0; + this.charsetNumber = (options.charset) + ? ConnectionConfig.getCharsetNumber(options.charset) + : options.charsetNumber||Charsets.UTF8_GENERAL_CI; + + this.clientFlags = ConnectionConfig.mergeFlags(ConnectionConfig.getDefaultFlags(options), + options.flags || ''); +} + +ConnectionConfig.mergeFlags = function(default_flags, user_flags) { + var flags = 0x0, i; + + user_flags = (user_flags || '').toUpperCase().split(/\s*,+\s*/); + + // add default flags unless "blacklisted" + for (i in default_flags) { + if (user_flags.indexOf("-" + default_flags[i]) >= 0) continue; + + flags |= ClientConstants[default_flags[i]] || 0x0; + } + // add user flags unless already already added + for (i in user_flags) { + if (user_flags[i][0] == "-") continue; + if (default_flags.indexOf(user_flags[i]) >= 0) continue; + + flags |= ClientConstants[user_flags[i]] || 0x0; + } + + return flags; +}; + +ConnectionConfig.getDefaultFlags = function(options) { + var defaultFlags = [ "LONG_PASSWORD", "FOUND_ROWS", "LONG_FLAG", + "CONNECT_WITH_DB", "ODBC", "LOCAL_FILES", + "IGNORE_SPACE", "PROTOCOL_41", "IGNORE_SIGPIPE", + "TRANSACTIONS", "RESERVED", "SECURE_CONNECTION", + "MULTI_RESULTS" ]; + if (options && options.multipleStatements) { + defaultFlags.push("MULTI_STATEMENTS"); + } + + return defaultFlags; +}; + +ConnectionConfig.getCharsetNumber = function(charset) { + return Charsets[charset]; +}; + +ConnectionConfig.parseUrl = function(url) { + url = urlParse(url, true); + + var options = { + host : url.hostname, + port : url.port, + database : url.pathname.substr(1), + }; + + if (url.auth) { + var auth = url.auth.split(':'); + options.user = auth[0]; + options.password = auth[1]; + } + + if (url.query) { + for (var key in url.query) { + var value = url.query[key]; + + try { + // Try to parse this as a JSON expression first + options[key] = JSON.parse(value); + } catch (err) { + // Otherwise assume it is a plain string + options[key] = value; + } + } + } + + return options; +}; diff --git a/node_modules/mysql2/lib/constants/charsets.js b/node_modules/mysql2/lib/constants/charsets.js new file mode 100644 index 0000000..5883964 --- /dev/null +++ b/node_modules/mysql2/lib/constants/charsets.js @@ -0,0 +1,195 @@ +exports.BIG5_CHINESE_CI = 1; +exports.LATIN2_CZECH_CS = 2; +exports.DEC8_SWEDISH_CI = 3; +exports.CP850_GENERAL_CI = 4; +exports.LATIN1_GERMAN1_CI = 5; +exports.HP8_ENGLISH_CI = 6; +exports.KOI8R_GENERAL_CI = 7; +exports.LATIN1_SWEDISH_CI = 8; +exports.LATIN2_GENERAL_CI = 9; +exports.SWE7_SWEDISH_CI = 10; +exports.ASCII_GENERAL_CI = 11; +exports.UJIS_JAPANESE_CI = 12; +exports.SJIS_JAPANESE_CI = 13; +exports.CP1251_BULGARIAN_CI = 14; +exports.LATIN1_DANISH_CI = 15; +exports.HEBREW_GENERAL_CI = 16; +exports.TIS620_THAI_CI = 18; +exports.EUCKR_KOREAN_CI = 19; +exports.LATIN7_ESTONIAN_CS = 20; +exports.LATIN2_HUNGARIAN_CI = 21; +exports.KOI8U_GENERAL_CI = 22; +exports.CP1251_UKRAINIAN_CI = 23; +exports.GB2312_CHINESE_CI = 24; +exports.GREEK_GENERAL_CI = 25; +exports.CP1250_GENERAL_CI = 26; +exports.LATIN2_CROATIAN_CI = 27; +exports.GBK_CHINESE_CI = 28; +exports.CP1257_LITHUANIAN_CI = 29; +exports.LATIN5_TURKISH_CI = 30; +exports.LATIN1_GERMAN2_CI = 31; +exports.ARMSCII8_GENERAL_CI = 32; +exports.UTF8_GENERAL_CI = 33; +exports.CP1250_CZECH_CS = 34; +exports.UCS2_GENERAL_CI = 35; +exports.CP866_GENERAL_CI = 36; +exports.KEYBCS2_GENERAL_CI = 37; +exports.MACCE_GENERAL_CI = 38; +exports.MACROMAN_GENERAL_CI = 39; +exports.CP852_GENERAL_CI = 40; +exports.LATIN7_GENERAL_CI = 41; +exports.LATIN7_GENERAL_CS = 42; +exports.MACCE_BIN = 43; +exports.CP1250_CROATIAN_CI = 44; +exports.UTF8MB4_GENERAL_CI = 45; +exports.UTF8MB4_BIN = 46; +exports.LATIN1_BIN = 47; +exports.LATIN1_GENERAL_CI = 48; +exports.LATIN1_GENERAL_CS = 49; +exports.CP1251_BIN = 50; +exports.CP1251_GENERAL_CI = 51; +exports.CP1251_GENERAL_CS = 52; +exports.MACROMAN_BIN = 53; +exports.UTF16_GENERAL_CI = 54; +exports.UTF16_BIN = 55; +exports.CP1256_GENERAL_CI = 57; +exports.CP1257_BIN = 58; +exports.CP1257_GENERAL_CI = 59; +exports.UTF32_GENERAL_CI = 60; +exports.UTF32_BIN = 61; +exports.BINARY = 63; +exports.ARMSCII8_BIN = 64; +exports.ASCII_BIN = 65; +exports.CP1250_BIN = 66; +exports.CP1256_BIN = 67; +exports.CP866_BIN = 68; +exports.DEC8_BIN = 69; +exports.GREEK_BIN = 70; +exports.HEBREW_BIN = 71; +exports.HP8_BIN = 72; +exports.KEYBCS2_BIN = 73; +exports.KOI8R_BIN = 74; +exports.KOI8U_BIN = 75; +exports.LATIN2_BIN = 77; +exports.LATIN5_BIN = 78; +exports.LATIN7_BIN = 79; +exports.CP850_BIN = 80; +exports.CP852_BIN = 81; +exports.SWE7_BIN = 82; +exports.UTF8_BIN = 83; +exports.BIG5_BIN = 84; +exports.EUCKR_BIN = 85; +exports.GB2312_BIN = 86; +exports.GBK_BIN = 87; +exports.SJIS_BIN = 88; +exports.TIS620_BIN = 89; +exports.UCS2_BIN = 90; +exports.UJIS_BIN = 91; +exports.GEOSTD8_GENERAL_CI = 92; +exports.GEOSTD8_BIN = 93; +exports.LATIN1_SPANISH_CI = 94; +exports.CP932_JAPANESE_CI = 95; +exports.CP932_BIN = 96; +exports.EUCJPMS_JAPANESE_CI = 97; +exports.EUCJPMS_BIN = 98; +exports.CP1250_POLISH_CI = 99; +exports.UTF16_UNICODE_CI = 101; +exports.UTF16_ICELANDIC_CI = 102; +exports.UTF16_LATVIAN_CI = 103; +exports.UTF16_ROMANIAN_CI = 104; +exports.UTF16_SLOVENIAN_CI = 105; +exports.UTF16_POLISH_CI = 106; +exports.UTF16_ESTONIAN_CI = 107; +exports.UTF16_SPANISH_CI = 108; +exports.UTF16_SWEDISH_CI = 109; +exports.UTF16_TURKISH_CI = 110; +exports.UTF16_CZECH_CI = 111; +exports.UTF16_DANISH_CI = 112; +exports.UTF16_LITHUANIAN_CI = 113; +exports.UTF16_SLOVAK_CI = 114; +exports.UTF16_SPANISH2_CI = 115; +exports.UTF16_ROMAN_CI = 116; +exports.UTF16_PERSIAN_CI = 117; +exports.UTF16_ESPERANTO_CI = 118; +exports.UTF16_HUNGARIAN_CI = 119; +exports.UTF16_SINHALA_CI = 120; +exports.UCS2_UNICODE_CI = 128; +exports.UCS2_ICELANDIC_CI = 129; +exports.UCS2_LATVIAN_CI = 130; +exports.UCS2_ROMANIAN_CI = 131; +exports.UCS2_SLOVENIAN_CI = 132; +exports.UCS2_POLISH_CI = 133; +exports.UCS2_ESTONIAN_CI = 134; +exports.UCS2_SPANISH_CI = 135; +exports.UCS2_SWEDISH_CI = 136; +exports.UCS2_TURKISH_CI = 137; +exports.UCS2_CZECH_CI = 138; +exports.UCS2_DANISH_CI = 139; +exports.UCS2_LITHUANIAN_CI = 140; +exports.UCS2_SLOVAK_CI = 141; +exports.UCS2_SPANISH2_CI = 142; +exports.UCS2_ROMAN_CI = 143; +exports.UCS2_PERSIAN_CI = 144; +exports.UCS2_ESPERANTO_CI = 145; +exports.UCS2_HUNGARIAN_CI = 146; +exports.UCS2_SINHALA_CI = 147; +exports.UTF32_UNICODE_CI = 160; +exports.UTF32_ICELANDIC_CI = 161; +exports.UTF32_LATVIAN_CI = 162; +exports.UTF32_ROMANIAN_CI = 163; +exports.UTF32_SLOVENIAN_CI = 164; +exports.UTF32_POLISH_CI = 165; +exports.UTF32_ESTONIAN_CI = 166; +exports.UTF32_SPANISH_CI = 167; +exports.UTF32_SWEDISH_CI = 168; +exports.UTF32_TURKISH_CI = 169; +exports.UTF32_CZECH_CI = 170; +exports.UTF32_DANISH_CI = 171; +exports.UTF32_LITHUANIAN_CI = 172; +exports.UTF32_SLOVAK_CI = 173; +exports.UTF32_SPANISH2_CI = 174; +exports.UTF32_ROMAN_CI = 175; +exports.UTF32_PERSIAN_CI = 176; +exports.UTF32_ESPERANTO_CI = 177; +exports.UTF32_HUNGARIAN_CI = 178; +exports.UTF32_SINHALA_CI = 179; +exports.UTF8_UNICODE_CI = 192; +exports.UTF8_ICELANDIC_CI = 193; +exports.UTF8_LATVIAN_CI = 194; +exports.UTF8_ROMANIAN_CI = 195; +exports.UTF8_SLOVENIAN_CI = 196; +exports.UTF8_POLISH_CI = 197; +exports.UTF8_ESTONIAN_CI = 198; +exports.UTF8_SPANISH_CI = 199; +exports.UTF8_SWEDISH_CI = 200; +exports.UTF8_TURKISH_CI = 201; +exports.UTF8_CZECH_CI = 202; +exports.UTF8_DANISH_CI = 203; +exports.UTF8_LITHUANIAN_CI = 204; +exports.UTF8_SLOVAK_CI = 205; +exports.UTF8_SPANISH2_CI = 206; +exports.UTF8_ROMAN_CI = 207; +exports.UTF8_PERSIAN_CI = 208; +exports.UTF8_ESPERANTO_CI = 209; +exports.UTF8_HUNGARIAN_CI = 210; +exports.UTF8_SINHALA_CI = 211; +exports.UTF8MB4_UNICODE_CI = 224; +exports.UTF8MB4_ICELANDIC_CI = 225; +exports.UTF8MB4_LATVIAN_CI = 226; +exports.UTF8MB4_ROMANIAN_CI = 227; +exports.UTF8MB4_SLOVENIAN_CI = 228; +exports.UTF8MB4_POLISH_CI = 229; +exports.UTF8MB4_ESTONIAN_CI = 230; +exports.UTF8MB4_SPANISH_CI = 231; +exports.UTF8MB4_SWEDISH_CI = 232; +exports.UTF8MB4_TURKISH_CI = 233; +exports.UTF8MB4_CZECH_CI = 234; +exports.UTF8MB4_DANISH_CI = 235; +exports.UTF8MB4_LITHUANIAN_CI = 236; +exports.UTF8MB4_SLOVAK_CI = 237; +exports.UTF8MB4_SPANISH2_CI = 238; +exports.UTF8MB4_ROMAN_CI = 239; +exports.UTF8MB4_PERSIAN_CI = 240; +exports.UTF8MB4_ESPERANTO_CI = 241; +exports.UTF8MB4_HUNGARIAN_CI = 242; +exports.UTF8MB4_SINHALA_CI = 243; \ No newline at end of file diff --git a/node_modules/mysql2/lib/constants/client.js b/node_modules/mysql2/lib/constants/client.js new file mode 100644 index 0000000..119488e --- /dev/null +++ b/node_modules/mysql2/lib/constants/client.js @@ -0,0 +1,26 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +exports.LONG_PASSWORD = 1; /* new more secure passwords */ +exports.FOUND_ROWS = 2; /* Found instead of affected rows */ +exports.LONG_FLAG = 4; /* Get all column flags */ +exports.CONNECT_WITH_DB = 8; /* One can specify db on connect */ +exports.NO_SCHEMA = 16; /* Don't allow database.table.column */ +exports.COMPRESS = 32; /* Can use compression protocol */ +exports.ODBC = 64; /* Odbc client */ +exports.LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */ +exports.IGNORE_SPACE = 256; /* Ignore spaces before '(' */ +exports.PROTOCOL_41 = 512; /* New 4.1 protocol */ +exports.INTERACTIVE = 1024; /* This is an interactive client */ +exports.SSL = 2048; /* Switch to SSL after handshake */ +exports.IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */ +exports.TRANSACTIONS = 8192; /* Client knows about transactions */ +exports.RESERVED = 16384; /* Old flag for 4.1 protocol */ +exports.SECURE_CONNECTION = 32768; /* New 4.1 authentication */ + +exports.MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */ +exports.MULTI_RESULTS = 131072; /* Enable/disable multi-results */ +exports.PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */ + +exports.PLUGIN_AUTH = 524288; /* Client supports plugin authentication */ + +exports.SSL_VERIFY_SERVER_CERT = 1073741824; +exports.REMEMBER_OPTIONS = 2147483648; diff --git a/node_modules/mysql2/lib/constants/commands.js b/node_modules/mysql2/lib/constants/commands.js new file mode 100644 index 0000000..adf0c1e --- /dev/null +++ b/node_modules/mysql2/lib/constants/commands.js @@ -0,0 +1,34 @@ +module.exports = { + SLEEP : 0x00, // deprecated + QUIT : 0x01, + INIT_DB : 0x02, + QUERY : 0x03, + FIELD_LIST : 0x04, + CREATE_DB : 0x05, + DROP_DB : 0x06, + REFRESH : 0x07, + SHUTDOWN : 0x08, + STATISTICS : 0x09, + PROCESS_INFO : 0x0a, // deprecated + CONNECT : 0x0b, // deprecated + PROCESS_KILL : 0x0c, + DEBUG : 0x0d, + PING : 0x0e, + TIME : 0x0f, // deprecated + DELAYED_INSERT : 0x10, // deprecated + CHANGE_USER : 0x11, + BINLOG_DUMP : 0x12, + TABLE_DUMP : 0x13, + CONNECT_OUT : 0x14, + REGISTER_SLAVE : 0x15, + STMT_PREPARE : 0x16, + STMT_EXECUTE : 0x17, + STMT_SEND_LONG_DATA: 0x18, + STMT_CLOSE : 0x19, + STMT_RESET : 0x1a, + SET_OPTION : 0x1b, + STMT_FETCH : 0x1c, + DAEMON : 0x1d, // deprecated + BINLOG_DUMP_GTID : 0x1e, + UNKNOWN : 0xff // bad! +}; \ No newline at end of file diff --git a/node_modules/mysql2/lib/constants/cursor.js b/node_modules/mysql2/lib/constants/cursor.js new file mode 100644 index 0000000..97e3d3e --- /dev/null +++ b/node_modules/mysql2/lib/constants/cursor.js @@ -0,0 +1,6 @@ +module.exports = { + NO_CURSOR: 0, + READ_ONLY: 1, + FOR_UPDATE: 2, + SCROLLABLE: 3 +}; diff --git a/node_modules/mysql2/lib/constants/errors.js b/node_modules/mysql2/lib/constants/errors.js new file mode 100644 index 0000000..5fcd72b --- /dev/null +++ b/node_modules/mysql2/lib/constants/errors.js @@ -0,0 +1,726 @@ +// Generated by generate-error-constants.js, do not modify by hand +module.exports.codeToName = []; +module.exports.codeToName[1000] = 'ER_HASHCHK'; +module.exports.codeToName[1001] = 'ER_NISAMCHK'; +module.exports.codeToName[1002] = 'ER_NO'; +module.exports.codeToName[1003] = 'ER_YES'; +module.exports.codeToName[1004] = 'ER_CANT_CREATE_FILE'; +module.exports.codeToName[1005] = 'ER_CANT_CREATE_TABLE'; +module.exports.codeToName[1006] = 'ER_CANT_CREATE_DB'; +module.exports.codeToName[1007] = 'ER_DB_CREATE_EXISTS'; +module.exports.codeToName[1008] = 'ER_DB_DROP_EXISTS'; +module.exports.codeToName[1009] = 'ER_DB_DROP_DELETE'; +module.exports.codeToName[1010] = 'ER_DB_DROP_RMDIR'; +module.exports.codeToName[1011] = 'ER_CANT_DELETE_FILE'; +module.exports.codeToName[1012] = 'ER_CANT_FIND_SYSTEM_REC'; +module.exports.codeToName[1013] = 'ER_CANT_GET_STAT'; +module.exports.codeToName[1014] = 'ER_CANT_GET_WD'; +module.exports.codeToName[1015] = 'ER_CANT_LOCK'; +module.exports.codeToName[1016] = 'ER_CANT_OPEN_FILE'; +module.exports.codeToName[1017] = 'ER_FILE_NOT_FOUND'; +module.exports.codeToName[1018] = 'ER_CANT_READ_DIR'; +module.exports.codeToName[1019] = 'ER_CANT_SET_WD'; +module.exports.codeToName[1020] = 'ER_CHECKREAD'; +module.exports.codeToName[1021] = 'ER_DISK_FULL'; +module.exports.codeToName[1022] = 'ER_DUP_KEY'; +module.exports.codeToName[1023] = 'ER_ERROR_ON_CLOSE'; +module.exports.codeToName[1024] = 'ER_ERROR_ON_READ'; +module.exports.codeToName[1025] = 'ER_ERROR_ON_RENAME'; +module.exports.codeToName[1026] = 'ER_ERROR_ON_WRITE'; +module.exports.codeToName[1027] = 'ER_FILE_USED'; +module.exports.codeToName[1028] = 'ER_FILSORT_ABORT'; +module.exports.codeToName[1029] = 'ER_FORM_NOT_FOUND'; +module.exports.codeToName[1030] = 'ER_GET_ERRNO'; +module.exports.codeToName[1031] = 'ER_ILLEGAL_HA'; +module.exports.codeToName[1032] = 'ER_KEY_NOT_FOUND'; +module.exports.codeToName[1033] = 'ER_NOT_FORM_FILE'; +module.exports.codeToName[1034] = 'ER_NOT_KEYFILE'; +module.exports.codeToName[1035] = 'ER_OLD_KEYFILE'; +module.exports.codeToName[1036] = 'ER_OPEN_AS_READONLY'; +module.exports.codeToName[1037] = 'ER_OUTOFMEMORY'; +module.exports.codeToName[1038] = 'ER_OUT_OF_SORTMEMORY'; +module.exports.codeToName[1039] = 'ER_UNEXPECTED_EOF'; +module.exports.codeToName[1040] = 'ER_CON_COUNT_ERROR'; +module.exports.codeToName[1041] = 'ER_OUT_OF_RESOURCES'; +module.exports.codeToName[1042] = 'ER_BAD_HOST_ERROR'; +module.exports.codeToName[1043] = 'ER_HANDSHAKE_ERROR'; +module.exports.codeToName[1044] = 'ER_DBACCESS_DENIED_ERROR'; +module.exports.codeToName[1045] = 'ER_ACCESS_DENIED_ERROR'; +module.exports.codeToName[1046] = 'ER_NO_DB_ERROR'; +module.exports.codeToName[1047] = 'ER_UNKNOWN_COM_ERROR'; +module.exports.codeToName[1048] = 'ER_BAD_NULL_ERROR'; +module.exports.codeToName[1049] = 'ER_BAD_DB_ERROR'; +module.exports.codeToName[1050] = 'ER_TABLE_EXISTS_ERROR'; +module.exports.codeToName[1051] = 'ER_BAD_TABLE_ERROR'; +module.exports.codeToName[1052] = 'ER_NON_UNIQ_ERROR'; +module.exports.codeToName[1053] = 'ER_SERVER_SHUTDOWN'; +module.exports.codeToName[1054] = 'ER_BAD_FIELD_ERROR'; +module.exports.codeToName[1055] = 'ER_WRONG_FIELD_WITH_GROUP'; +module.exports.codeToName[1056] = 'ER_WRONG_GROUP_FIELD'; +module.exports.codeToName[1057] = 'ER_WRONG_SUM_SELECT'; +module.exports.codeToName[1058] = 'ER_WRONG_VALUE_COUNT'; +module.exports.codeToName[1059] = 'ER_TOO_LONG_IDENT'; +module.exports.codeToName[1060] = 'ER_DUP_FIELDNAME'; +module.exports.codeToName[1061] = 'ER_DUP_KEYNAME'; +module.exports.codeToName[1062] = 'ER_DUP_ENTRY'; +module.exports.codeToName[1063] = 'ER_WRONG_FIELD_SPEC'; +module.exports.codeToName[1064] = 'ER_PARSE_ERROR'; +module.exports.codeToName[1065] = 'ER_EMPTY_QUERY'; +module.exports.codeToName[1066] = 'ER_NONUNIQ_TABLE'; +module.exports.codeToName[1067] = 'ER_INVALID_DEFAULT'; +module.exports.codeToName[1068] = 'ER_MULTIPLE_PRI_KEY'; +module.exports.codeToName[1069] = 'ER_TOO_MANY_KEYS'; +module.exports.codeToName[1070] = 'ER_TOO_MANY_KEY_PARTS'; +module.exports.codeToName[1071] = 'ER_TOO_LONG_KEY'; +module.exports.codeToName[1072] = 'ER_KEY_COLUMN_DOES_NOT_EXITS'; +module.exports.codeToName[1073] = 'ER_BLOB_USED_AS_KEY'; +module.exports.codeToName[1074] = 'ER_TOO_BIG_FIELDLENGTH'; +module.exports.codeToName[1075] = 'ER_WRONG_AUTO_KEY'; +module.exports.codeToName[1076] = 'ER_READY'; +module.exports.codeToName[1077] = 'ER_NORMAL_SHUTDOWN'; +module.exports.codeToName[1078] = 'ER_GOT_SIGNAL'; +module.exports.codeToName[1079] = 'ER_SHUTDOWN_COMPLETE'; +module.exports.codeToName[1080] = 'ER_FORCING_CLOSE'; +module.exports.codeToName[1081] = 'ER_IPSOCK_ERROR'; +module.exports.codeToName[1082] = 'ER_NO_SUCH_INDEX'; +module.exports.codeToName[1083] = 'ER_WRONG_FIELD_TERMINATORS'; +module.exports.codeToName[1084] = 'ER_BLOBS_AND_NO_TERMINATED'; +module.exports.codeToName[1085] = 'ER_TEXTFILE_NOT_READABLE'; +module.exports.codeToName[1086] = 'ER_FILE_EXISTS_ERROR'; +module.exports.codeToName[1087] = 'ER_LOAD_INFO'; +module.exports.codeToName[1088] = 'ER_ALTER_INFO'; +module.exports.codeToName[1089] = 'ER_WRONG_SUB_KEY'; +module.exports.codeToName[1090] = 'ER_CANT_REMOVE_ALL_FIELDS'; +module.exports.codeToName[1091] = 'ER_CANT_DROP_FIELD_OR_KEY'; +module.exports.codeToName[1092] = 'ER_INSERT_INFO'; +module.exports.codeToName[1093] = 'ER_UPDATE_TABLE_USED'; +module.exports.codeToName[1094] = 'ER_NO_SUCH_THREAD'; +module.exports.codeToName[1095] = 'ER_KILL_DENIED_ERROR'; +module.exports.codeToName[1096] = 'ER_NO_TABLES_USED'; +module.exports.codeToName[1097] = 'ER_TOO_BIG_SET'; +module.exports.codeToName[1098] = 'ER_NO_UNIQUE_LOGFILE'; +module.exports.codeToName[1099] = 'ER_TABLE_NOT_LOCKED_FOR_WRITE'; +module.exports.codeToName[1100] = 'ER_TABLE_NOT_LOCKED'; +module.exports.codeToName[1101] = 'ER_BLOB_CANT_HAVE_DEFAULT'; +module.exports.codeToName[1102] = 'ER_WRONG_DB_NAME'; +module.exports.codeToName[1103] = 'ER_WRONG_TABLE_NAME'; +module.exports.codeToName[1104] = 'ER_TOO_BIG_SELECT'; +module.exports.codeToName[1105] = 'ER_UNKNOWN_ERROR'; +module.exports.codeToName[1106] = 'ER_UNKNOWN_PROCEDURE'; +module.exports.codeToName[1107] = 'ER_WRONG_PARAMCOUNT_TO_PROCEDURE'; +module.exports.codeToName[1108] = 'ER_WRONG_PARAMETERS_TO_PROCEDURE'; +module.exports.codeToName[1109] = 'ER_UNKNOWN_TABLE'; +module.exports.codeToName[1110] = 'ER_FIELD_SPECIFIED_TWICE'; +module.exports.codeToName[1111] = 'ER_INVALID_GROUP_FUNC_USE'; +module.exports.codeToName[1112] = 'ER_UNSUPPORTED_EXTENSION'; +module.exports.codeToName[1113] = 'ER_TABLE_MUST_HAVE_COLUMNS'; +module.exports.codeToName[1114] = 'ER_RECORD_FILE_FULL'; +module.exports.codeToName[1115] = 'ER_UNKNOWN_CHARACTER_SET'; +module.exports.codeToName[1116] = 'ER_TOO_MANY_TABLES'; +module.exports.codeToName[1117] = 'ER_TOO_MANY_FIELDS'; +module.exports.codeToName[1118] = 'ER_TOO_BIG_ROWSIZE'; +module.exports.codeToName[1119] = 'ER_STACK_OVERRUN'; +module.exports.codeToName[1120] = 'ER_WRONG_OUTER_JOIN'; +module.exports.codeToName[1121] = 'ER_NULL_COLUMN_IN_INDEX'; +module.exports.codeToName[1122] = 'ER_CANT_FIND_UDF'; +module.exports.codeToName[1123] = 'ER_CANT_INITIALIZE_UDF'; +module.exports.codeToName[1124] = 'ER_UDF_NO_PATHS'; +module.exports.codeToName[1125] = 'ER_UDF_EXISTS'; +module.exports.codeToName[1126] = 'ER_CANT_OPEN_LIBRARY'; +module.exports.codeToName[1127] = 'ER_CANT_FIND_DL_ENTRY'; +module.exports.codeToName[1128] = 'ER_FUNCTION_NOT_DEFINED'; +module.exports.codeToName[1129] = 'ER_HOST_IS_BLOCKED'; +module.exports.codeToName[1130] = 'ER_HOST_NOT_PRIVILEGED'; +module.exports.codeToName[1131] = 'ER_PASSWORD_ANONYMOUS_USER'; +module.exports.codeToName[1132] = 'ER_PASSWORD_NOT_ALLOWED'; +module.exports.codeToName[1133] = 'ER_PASSWORD_NO_MATCH'; +module.exports.codeToName[1134] = 'ER_UPDATE_INFO'; +module.exports.codeToName[1135] = 'ER_CANT_CREATE_THREAD'; +module.exports.codeToName[1136] = 'ER_WRONG_VALUE_COUNT_ON_ROW'; +module.exports.codeToName[1137] = 'ER_CANT_REOPEN_TABLE'; +module.exports.codeToName[1138] = 'ER_INVALID_USE_OF_NULL'; +module.exports.codeToName[1139] = 'ER_REGEXP_ERROR'; +module.exports.codeToName[1140] = 'ER_MIX_OF_GROUP_FUNC_AND_FIELDS'; +module.exports.codeToName[1141] = 'ER_NONEXISTING_GRANT'; +module.exports.codeToName[1142] = 'ER_TABLEACCESS_DENIED_ERROR'; +module.exports.codeToName[1143] = 'ER_COLUMNACCESS_DENIED_ERROR'; +module.exports.codeToName[1144] = 'ER_ILLEGAL_GRANT_FOR_TABLE'; +module.exports.codeToName[1145] = 'ER_GRANT_WRONG_HOST_OR_USER'; +module.exports.codeToName[1146] = 'ER_NO_SUCH_TABLE'; +module.exports.codeToName[1147] = 'ER_NONEXISTING_TABLE_GRANT'; +module.exports.codeToName[1148] = 'ER_NOT_ALLOWED_COMMAND'; +module.exports.codeToName[1149] = 'ER_SYNTAX_ERROR'; +module.exports.codeToName[1150] = 'ER_DELAYED_CANT_CHANGE_LOCK'; +module.exports.codeToName[1151] = 'ER_TOO_MANY_DELAYED_THREADS'; +module.exports.codeToName[1152] = 'ER_ABORTING_CONNECTION'; +module.exports.codeToName[1153] = 'ER_NET_PACKET_TOO_LARGE'; +module.exports.codeToName[1154] = 'ER_NET_READ_ERROR_FROM_PIPE'; +module.exports.codeToName[1155] = 'ER_NET_FCNTL_ERROR'; +module.exports.codeToName[1156] = 'ER_NET_PACKETS_OUT_OF_ORDER'; +module.exports.codeToName[1157] = 'ER_NET_UNCOMPRESS_ERROR'; +module.exports.codeToName[1158] = 'ER_NET_READ_ERROR'; +module.exports.codeToName[1159] = 'ER_NET_READ_INTERRUPTED'; +module.exports.codeToName[1160] = 'ER_NET_ERROR_ON_WRITE'; +module.exports.codeToName[1161] = 'ER_NET_WRITE_INTERRUPTED'; +module.exports.codeToName[1162] = 'ER_TOO_LONG_STRING'; +module.exports.codeToName[1163] = 'ER_TABLE_CANT_HANDLE_BLOB'; +module.exports.codeToName[1164] = 'ER_TABLE_CANT_HANDLE_AUTO_INCREMENT'; +module.exports.codeToName[1165] = 'ER_DELAYED_INSERT_TABLE_LOCKED'; +module.exports.codeToName[1166] = 'ER_WRONG_COLUMN_NAME'; +module.exports.codeToName[1167] = 'ER_WRONG_KEY_COLUMN'; +module.exports.codeToName[1168] = 'ER_WRONG_MRG_TABLE'; +module.exports.codeToName[1169] = 'ER_DUP_UNIQUE'; +module.exports.codeToName[1170] = 'ER_BLOB_KEY_WITHOUT_LENGTH'; +module.exports.codeToName[1171] = 'ER_PRIMARY_CANT_HAVE_NULL'; +module.exports.codeToName[1172] = 'ER_TOO_MANY_ROWS'; +module.exports.codeToName[1173] = 'ER_REQUIRES_PRIMARY_KEY'; +module.exports.codeToName[1174] = 'ER_NO_RAID_COMPILED'; +module.exports.codeToName[1175] = 'ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE'; +module.exports.codeToName[1176] = 'ER_KEY_DOES_NOT_EXITS'; +module.exports.codeToName[1177] = 'ER_CHECK_NO_SUCH_TABLE'; +module.exports.codeToName[1178] = 'ER_CHECK_NOT_IMPLEMENTED'; +module.exports.codeToName[1179] = 'ER_CANT_DO_THIS_DURING_AN_TRANSACTION'; +module.exports.codeToName[1180] = 'ER_ERROR_DURING_COMMIT'; +module.exports.codeToName[1181] = 'ER_ERROR_DURING_ROLLBACK'; +module.exports.codeToName[1182] = 'ER_ERROR_DURING_FLUSH_LOGS'; +module.exports.codeToName[1183] = 'ER_ERROR_DURING_CHECKPOINT'; +module.exports.codeToName[1184] = 'ER_NEW_ABORTING_CONNECTION'; +module.exports.codeToName[1185] = 'ER_DUMP_NOT_IMPLEMENTED'; +module.exports.codeToName[1186] = 'ER_FLUSH_MASTER_BINLOG_CLOSED'; +module.exports.codeToName[1187] = 'ER_INDEX_REBUILD'; +module.exports.codeToName[1188] = 'ER_MASTER'; +module.exports.codeToName[1189] = 'ER_MASTER_NET_READ'; +module.exports.codeToName[1190] = 'ER_MASTER_NET_WRITE'; +module.exports.codeToName[1191] = 'ER_FT_MATCHING_KEY_NOT_FOUND'; +module.exports.codeToName[1192] = 'ER_LOCK_OR_ACTIVE_TRANSACTION'; +module.exports.codeToName[1193] = 'ER_UNKNOWN_SYSTEM_VARIABLE'; +module.exports.codeToName[1194] = 'ER_CRASHED_ON_USAGE'; +module.exports.codeToName[1195] = 'ER_CRASHED_ON_REPAIR'; +module.exports.codeToName[1196] = 'ER_WARNING_NOT_COMPLETE_ROLLBACK'; +module.exports.codeToName[1197] = 'ER_TRANS_CACHE_FULL'; +module.exports.codeToName[1198] = 'ER_SLAVE_MUST_STOP'; +module.exports.codeToName[1199] = 'ER_SLAVE_NOT_RUNNING'; +module.exports.codeToName[1200] = 'ER_BAD_SLAVE'; +module.exports.codeToName[1201] = 'ER_MASTER_INFO'; +module.exports.codeToName[1202] = 'ER_SLAVE_THREAD'; +module.exports.codeToName[1203] = 'ER_TOO_MANY_USER_CONNECTIONS'; +module.exports.codeToName[1204] = 'ER_SET_CONSTANTS_ONLY'; +module.exports.codeToName[1205] = 'ER_LOCK_WAIT_TIMEOUT'; +module.exports.codeToName[1206] = 'ER_LOCK_TABLE_FULL'; +module.exports.codeToName[1207] = 'ER_READ_ONLY_TRANSACTION'; +module.exports.codeToName[1208] = 'ER_DROP_DB_WITH_READ_LOCK'; +module.exports.codeToName[1209] = 'ER_CREATE_DB_WITH_READ_LOCK'; +module.exports.codeToName[1210] = 'ER_WRONG_ARGUMENTS'; +module.exports.codeToName[1211] = 'ER_NO_PERMISSION_TO_CREATE_USER'; +module.exports.codeToName[1212] = 'ER_UNION_TABLES_IN_DIFFERENT_DIR'; +module.exports.codeToName[1213] = 'ER_LOCK_DEADLOCK'; +module.exports.codeToName[1214] = 'ER_TABLE_CANT_HANDLE_FT'; +module.exports.codeToName[1215] = 'ER_CANNOT_ADD_FOREIGN'; +module.exports.codeToName[1216] = 'ER_NO_REFERENCED_ROW'; +module.exports.codeToName[1217] = 'ER_ROW_IS_REFERENCED'; +module.exports.codeToName[1218] = 'ER_CONNECT_TO_MASTER'; +module.exports.codeToName[1219] = 'ER_QUERY_ON_MASTER'; +module.exports.codeToName[1220] = 'ER_ERROR_WHEN_EXECUTING_COMMAND'; +module.exports.codeToName[1221] = 'ER_WRONG_USAGE'; +module.exports.codeToName[1222] = 'ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT'; +module.exports.codeToName[1223] = 'ER_CANT_UPDATE_WITH_READLOCK'; +module.exports.codeToName[1224] = 'ER_MIXING_NOT_ALLOWED'; +module.exports.codeToName[1225] = 'ER_DUP_ARGUMENT'; +module.exports.codeToName[1226] = 'ER_USER_LIMIT_REACHED'; +module.exports.codeToName[1227] = 'ER_SPECIFIC_ACCESS_DENIED_ERROR'; +module.exports.codeToName[1228] = 'ER_LOCAL_VARIABLE'; +module.exports.codeToName[1229] = 'ER_GLOBAL_VARIABLE'; +module.exports.codeToName[1230] = 'ER_NO_DEFAULT'; +module.exports.codeToName[1231] = 'ER_WRONG_VALUE_FOR_VAR'; +module.exports.codeToName[1232] = 'ER_WRONG_TYPE_FOR_VAR'; +module.exports.codeToName[1233] = 'ER_VAR_CANT_BE_READ'; +module.exports.codeToName[1234] = 'ER_CANT_USE_OPTION_HERE'; +module.exports.codeToName[1235] = 'ER_NOT_SUPPORTED_YET'; +module.exports.codeToName[1236] = 'ER_MASTER_FATAL_ERROR_READING_BINLOG'; +module.exports.codeToName[1237] = 'ER_SLAVE_IGNORED_TABLE'; +module.exports.codeToName[1238] = 'ER_INCORRECT_GLOBAL_LOCAL_VAR'; +module.exports.codeToName[1239] = 'ER_WRONG_FK_DEF'; +module.exports.codeToName[1240] = 'ER_KEY_REF_DO_NOT_MATCH_TABLE_REF'; +module.exports.codeToName[1241] = 'ER_OPERAND_COLUMNS'; +module.exports.codeToName[1242] = 'ER_SUBQUERY_NO_'; +module.exports.codeToName[1243] = 'ER_UNKNOWN_STMT_HANDLER'; +module.exports.codeToName[1244] = 'ER_CORRUPT_HELP_DB'; +module.exports.codeToName[1245] = 'ER_CYCLIC_REFERENCE'; +module.exports.codeToName[1246] = 'ER_AUTO_CONVERT'; +module.exports.codeToName[1247] = 'ER_ILLEGAL_REFERENCE'; +module.exports.codeToName[1248] = 'ER_DERIVED_MUST_HAVE_ALIAS'; +module.exports.codeToName[1249] = 'ER_SELECT_REDUCED'; +module.exports.codeToName[1250] = 'ER_TABLENAME_NOT_ALLOWED_HERE'; +module.exports.codeToName[1251] = 'ER_NOT_SUPPORTED_AUTH_MODE'; +module.exports.codeToName[1252] = 'ER_SPATIAL_CANT_HAVE_NULL'; +module.exports.codeToName[1253] = 'ER_COLLATION_CHARSET_MISMATCH'; +module.exports.codeToName[1254] = 'ER_SLAVE_WAS_RUNNING'; +module.exports.codeToName[1255] = 'ER_SLAVE_WAS_NOT_RUNNING'; +module.exports.codeToName[1256] = 'ER_TOO_BIG_FOR_UNCOMPRESS'; +module.exports.codeToName[1257] = 'ER_ZLIB_Z_MEM_ERROR'; +module.exports.codeToName[1258] = 'ER_ZLIB_Z_BUF_ERROR'; +module.exports.codeToName[1259] = 'ER_ZLIB_Z_DATA_ERROR'; +module.exports.codeToName[1260] = 'ER_CUT_VALUE_GROUP_CONCAT'; +module.exports.codeToName[1261] = 'ER_WARN_TOO_FEW_RECORDS'; +module.exports.codeToName[1262] = 'ER_WARN_TOO_MANY_RECORDS'; +module.exports.codeToName[1263] = 'ER_WARN_NULL_TO_NOTNULL'; +module.exports.codeToName[1264] = 'ER_WARN_DATA_OUT_OF_RANGE'; +module.exports.codeToName[1265] = 'WARN_DATA_TRUNCATED'; +module.exports.codeToName[1266] = 'ER_WARN_USING_OTHER_HANDLER'; +module.exports.codeToName[1267] = 'ER_CANT_AGGREGATE_'; +module.exports.codeToName[1268] = 'ER_DROP_USER'; +module.exports.codeToName[1269] = 'ER_REVOKE_GRANTS'; +module.exports.codeToName[1270] = 'ER_CANT_AGGREGATE_'; +module.exports.codeToName[1271] = 'ER_CANT_AGGREGATE_NCOLLATIONS'; +module.exports.codeToName[1272] = 'ER_VARIABLE_IS_NOT_STRUCT'; +module.exports.codeToName[1273] = 'ER_UNKNOWN_COLLATION'; +module.exports.codeToName[1274] = 'ER_SLAVE_IGNORED_SSL_PARAMS'; +module.exports.codeToName[1275] = 'ER_SERVER_IS_IN_SECURE_AUTH_MODE'; +module.exports.codeToName[1276] = 'ER_WARN_FIELD_RESOLVED'; +module.exports.codeToName[1277] = 'ER_BAD_SLAVE_UNTIL_COND'; +module.exports.codeToName[1278] = 'ER_MISSING_SKIP_SLAVE'; +module.exports.codeToName[1279] = 'ER_UNTIL_COND_IGNORED'; +module.exports.codeToName[1280] = 'ER_WRONG_NAME_FOR_INDEX'; +module.exports.codeToName[1281] = 'ER_WRONG_NAME_FOR_CATALOG'; +module.exports.codeToName[1282] = 'ER_WARN_QC_RESIZE'; +module.exports.codeToName[1283] = 'ER_BAD_FT_COLUMN'; +module.exports.codeToName[1284] = 'ER_UNKNOWN_KEY_CACHE'; +module.exports.codeToName[1285] = 'ER_WARN_HOSTNAME_WONT_WORK'; +module.exports.codeToName[1286] = 'ER_UNKNOWN_STORAGE_ENGINE'; +module.exports.codeToName[1287] = 'ER_WARN_DEPRECATED_SYNTAX'; +module.exports.codeToName[1288] = 'ER_NON_UPDATABLE_TABLE'; +module.exports.codeToName[1289] = 'ER_FEATURE_DISABLED'; +module.exports.codeToName[1290] = 'ER_OPTION_PREVENTS_STATEMENT'; +module.exports.codeToName[1291] = 'ER_DUPLICATED_VALUE_IN_TYPE'; +module.exports.codeToName[1292] = 'ER_TRUNCATED_WRONG_VALUE'; +module.exports.codeToName[1293] = 'ER_TOO_MUCH_AUTO_TIMESTAMP_COLS'; +module.exports.codeToName[1294] = 'ER_INVALID_ON_UPDATE'; +module.exports.codeToName[1295] = 'ER_UNSUPPORTED_PS'; +module.exports.codeToName[1296] = 'ER_GET_ERRMSG'; +module.exports.codeToName[1297] = 'ER_GET_TEMPORARY_ERRMSG'; +module.exports.codeToName[1298] = 'ER_UNKNOWN_TIME_ZONE'; +module.exports.codeToName[1299] = 'ER_WARN_INVALID_TIMESTAMP'; +module.exports.codeToName[1300] = 'ER_INVALID_CHARACTER_STRING'; +module.exports.codeToName[1301] = 'ER_WARN_ALLOWED_PACKET_OVERFLOWED'; +module.exports.codeToName[1302] = 'ER_CONFLICTING_DECLARATIONS'; +module.exports.codeToName[1303] = 'ER_SP_NO_RECURSIVE_CREATE'; +module.exports.codeToName[1304] = 'ER_SP_ALREADY_EXISTS'; +module.exports.codeToName[1305] = 'ER_SP_DOES_NOT_EXIST'; +module.exports.codeToName[1306] = 'ER_SP_DROP_FAILED'; +module.exports.codeToName[1307] = 'ER_SP_STORE_FAILED'; +module.exports.codeToName[1308] = 'ER_SP_LILABEL_MISMATCH'; +module.exports.codeToName[1309] = 'ER_SP_LABEL_REDEFINE'; +module.exports.codeToName[1310] = 'ER_SP_LABEL_MISMATCH'; +module.exports.codeToName[1311] = 'ER_SP_UNINIT_VAR'; +module.exports.codeToName[1312] = 'ER_SP_BADSELECT'; +module.exports.codeToName[1313] = 'ER_SP_BADRETURN'; +module.exports.codeToName[1314] = 'ER_SP_BADSTATEMENT'; +module.exports.codeToName[1315] = 'ER_UPDATE_LOG_DEPRECATED_IGNORED'; +module.exports.codeToName[1316] = 'ER_UPDATE_LOG_DEPRECATED_TRANSLATED'; +module.exports.codeToName[1317] = 'ER_QUERY_INTERRUPTED'; +module.exports.codeToName[1318] = 'ER_SP_WRONG_NO_OF_ARGS'; +module.exports.codeToName[1319] = 'ER_SP_COND_MISMATCH'; +module.exports.codeToName[1320] = 'ER_SP_NORETURN'; +module.exports.codeToName[1321] = 'ER_SP_NORETURNEND'; +module.exports.codeToName[1322] = 'ER_SP_BAD_CURSOR_QUERY'; +module.exports.codeToName[1323] = 'ER_SP_BAD_CURSOR_SELECT'; +module.exports.codeToName[1324] = 'ER_SP_CURSOR_MISMATCH'; +module.exports.codeToName[1325] = 'ER_SP_CURSOR_ALREADY_OPEN'; +module.exports.codeToName[1326] = 'ER_SP_CURSOR_NOT_OPEN'; +module.exports.codeToName[1327] = 'ER_SP_UNDECLARED_VAR'; +module.exports.codeToName[1328] = 'ER_SP_WRONG_NO_OF_FETCH_ARGS'; +module.exports.codeToName[1329] = 'ER_SP_FETCH_NO_DATA'; +module.exports.codeToName[1330] = 'ER_SP_DUP_PARAM'; +module.exports.codeToName[1331] = 'ER_SP_DUP_VAR'; +module.exports.codeToName[1332] = 'ER_SP_DUP_COND'; +module.exports.codeToName[1333] = 'ER_SP_DUP_CURS'; +module.exports.codeToName[1334] = 'ER_SP_CANT_ALTER'; +module.exports.codeToName[1335] = 'ER_SP_SUBSELECT_NYI'; +module.exports.codeToName[1336] = 'ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG'; +module.exports.codeToName[1337] = 'ER_SP_VARCOND_AFTER_CURSHNDLR'; +module.exports.codeToName[1338] = 'ER_SP_CURSOR_AFTER_HANDLER'; +module.exports.codeToName[1339] = 'ER_SP_CASE_NOT_FOUND'; +module.exports.codeToName[1340] = 'ER_FPARSER_TOO_BIG_FILE'; +module.exports.codeToName[1341] = 'ER_FPARSER_BAD_HEADER'; +module.exports.codeToName[1342] = 'ER_FPARSER_EOF_IN_COMMENT'; +module.exports.codeToName[1343] = 'ER_FPARSER_ERROR_IN_PARAMETER'; +module.exports.codeToName[1344] = 'ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER'; +module.exports.codeToName[1345] = 'ER_VIEW_NO_EXPLAIN'; +module.exports.codeToName[1346] = 'ER_FRM_UNKNOWN_TYPE'; +module.exports.codeToName[1347] = 'ER_WRONG_OBJECT'; +module.exports.codeToName[1348] = 'ER_NONUPDATEABLE_COLUMN'; +module.exports.codeToName[1349] = 'ER_VIEW_SELECT_DERIVED'; +module.exports.codeToName[1350] = 'ER_VIEW_SELECT_CLAUSE'; +module.exports.codeToName[1351] = 'ER_VIEW_SELECT_VARIABLE'; +module.exports.codeToName[1352] = 'ER_VIEW_SELECT_TMPTABLE'; +module.exports.codeToName[1353] = 'ER_VIEW_WRONG_LIST'; +module.exports.codeToName[1354] = 'ER_WARN_VIEW_MERGE'; +module.exports.codeToName[1355] = 'ER_WARN_VIEW_WITHOUT_KEY'; +module.exports.codeToName[1356] = 'ER_VIEW_INVALID'; +module.exports.codeToName[1357] = 'ER_SP_NO_DROP_SP'; +module.exports.codeToName[1358] = 'ER_SP_GOTO_IN_HNDLR'; +module.exports.codeToName[1359] = 'ER_TRG_ALREADY_EXISTS'; +module.exports.codeToName[1360] = 'ER_TRG_DOES_NOT_EXIST'; +module.exports.codeToName[1361] = 'ER_TRG_ON_VIEW_OR_TEMP_TABLE'; +module.exports.codeToName[1362] = 'ER_TRG_CANT_CHANGE_ROW'; +module.exports.codeToName[1363] = 'ER_TRG_NO_SUCH_ROW_IN_TRG'; +module.exports.codeToName[1364] = 'ER_NO_DEFAULT_FOR_FIELD'; +module.exports.codeToName[1365] = 'ER_DIVISION_BY_ZERO'; +module.exports.codeToName[1366] = 'ER_TRUNCATED_WRONG_VALUE_FOR_FIELD'; +module.exports.codeToName[1367] = 'ER_ILLEGAL_VALUE_FOR_TYPE'; +module.exports.codeToName[1368] = 'ER_VIEW_NONUPD_CHECK'; +module.exports.codeToName[1369] = 'ER_VIEW_CHECK_FAILED'; +module.exports.codeToName[1370] = 'ER_PROCACCESS_DENIED_ERROR'; +module.exports.codeToName[1371] = 'ER_RELAY_LOG_FAIL'; +module.exports.codeToName[1372] = 'ER_PASSWD_LENGTH'; +module.exports.codeToName[1373] = 'ER_UNKNOWN_TARGET_BINLOG'; +module.exports.codeToName[1374] = 'ER_IO_ERR_LOG_INDEX_READ'; +module.exports.codeToName[1375] = 'ER_BINLOG_PURGE_PROHIBITED'; +module.exports.codeToName[1376] = 'ER_FSEEK_FAIL'; +module.exports.codeToName[1377] = 'ER_BINLOG_PURGE_FATAL_ERR'; +module.exports.codeToName[1378] = 'ER_LOG_IN_USE'; +module.exports.codeToName[1379] = 'ER_LOG_PURGE_UNKNOWN_ERR'; +module.exports.codeToName[1380] = 'ER_RELAY_LOG_INIT'; +module.exports.codeToName[1381] = 'ER_NO_BINARY_LOGGING'; +module.exports.codeToName[1382] = 'ER_RESERVED_SYNTAX'; +module.exports.codeToName[1383] = 'ER_WSAS_FAILED'; +module.exports.codeToName[1384] = 'ER_DIFF_GROUPS_PROC'; +module.exports.codeToName[1385] = 'ER_NO_GROUP_FOR_PROC'; +module.exports.codeToName[1386] = 'ER_ORDER_WITH_PROC'; +module.exports.codeToName[1387] = 'ER_LOGGING_PROHIBIT_CHANGING_OF'; +module.exports.codeToName[1388] = 'ER_NO_FILE_MAPPING'; +module.exports.codeToName[1389] = 'ER_WRONG_MAGIC'; +module.exports.codeToName[1390] = 'ER_PS_MANY_PARAM'; +module.exports.codeToName[1391] = 'ER_KEY_PART_'; +module.exports.codeToName[1392] = 'ER_VIEW_CHECKSUM'; +module.exports.codeToName[1393] = 'ER_VIEW_MULTIUPDATE'; +module.exports.codeToName[1394] = 'ER_VIEW_NO_INSERT_FIELD_LIST'; +module.exports.codeToName[1395] = 'ER_VIEW_DELETE_MERGE_VIEW'; +module.exports.codeToName[1396] = 'ER_CANNOT_USER'; +module.exports.codeToName[1397] = 'ER_XAER_NOTA'; +module.exports.codeToName[1398] = 'ER_XAER_INVAL'; +module.exports.codeToName[1399] = 'ER_XAER_RMFAIL'; +module.exports.codeToName[1400] = 'ER_XAER_OUTSIDE'; +module.exports.codeToName[1401] = 'ER_XAER_RMERR'; +module.exports.codeToName[1402] = 'ER_XA_RBROLLBACK'; +module.exports.codeToName[1403] = 'ER_NONEXISTING_PROC_GRANT'; +module.exports.codeToName[1404] = 'ER_PROC_AUTO_GRANT_FAIL'; +module.exports.codeToName[1405] = 'ER_PROC_AUTO_REVOKE_FAIL'; +module.exports.codeToName[1406] = 'ER_DATA_TOO_LONG'; +module.exports.codeToName[1407] = 'ER_SP_BAD_SQLSTATE'; +module.exports.codeToName[1408] = 'ER_STARTUP'; +module.exports.codeToName[1409] = 'ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR'; +module.exports.codeToName[1410] = 'ER_CANT_CREATE_USER_WITH_GRANT'; +module.exports.codeToName[1411] = 'ER_WRONG_VALUE_FOR_TYPE'; +module.exports.codeToName[1412] = 'ER_TABLE_DEF_CHANGED'; +module.exports.codeToName[1413] = 'ER_SP_DUP_HANDLER'; +module.exports.codeToName[1414] = 'ER_SP_NOT_VAR_ARG'; +module.exports.codeToName[1415] = 'ER_SP_NO_RETSET'; +module.exports.codeToName[1416] = 'ER_CANT_CREATE_GEOMETRY_OBJECT'; +module.exports.codeToName[1417] = 'ER_FAILED_ROUTINE_BREAK_BINLOG'; +module.exports.codeToName[1418] = 'ER_BINLOG_UNSAFE_ROUTINE'; +module.exports.codeToName[1419] = 'ER_BINLOG_CREATE_ROUTINE_NEED_SUPER'; +module.exports.codeToName[1420] = 'ER_EXEC_STMT_WITH_OPEN_CURSOR'; +module.exports.codeToName[1421] = 'ER_STMT_HAS_NO_OPEN_CURSOR'; +module.exports.codeToName[1422] = 'ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG'; +module.exports.codeToName[1423] = 'ER_NO_DEFAULT_FOR_VIEW_FIELD'; +module.exports.codeToName[1424] = 'ER_SP_NO_RECURSION'; +module.exports.codeToName[1425] = 'ER_TOO_BIG_SCALE'; +module.exports.codeToName[1426] = 'ER_TOO_BIG_PRECISION'; +module.exports.codeToName[1427] = 'ER_M_BIGGER_THAN_D'; +module.exports.codeToName[1428] = 'ER_WRONG_LOCK_OF_SYSTEM_TABLE'; +module.exports.codeToName[1429] = 'ER_CONNECT_TO_FOREIGN_DATA_SOURCE'; +module.exports.codeToName[1430] = 'ER_QUERY_ON_FOREIGN_DATA_SOURCE'; +module.exports.codeToName[1431] = 'ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST'; +module.exports.codeToName[1432] = 'ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE'; +module.exports.codeToName[1433] = 'ER_FOREIGN_DATA_STRING_INVALID'; +module.exports.codeToName[1434] = 'ER_CANT_CREATE_FEDERATED_TABLE'; +module.exports.codeToName[1435] = 'ER_TRG_IN_WRONG_SCHEMA'; +module.exports.codeToName[1436] = 'ER_STACK_OVERRUN_NEED_MORE'; +module.exports.codeToName[1437] = 'ER_TOO_LONG_BODY'; +module.exports.codeToName[1438] = 'ER_WARN_CANT_DROP_DEFAULT_KEYCACHE'; +module.exports.codeToName[1439] = 'ER_TOO_BIG_DISPLAYWIDTH'; +module.exports.codeToName[1440] = 'ER_XAER_DUPID'; +module.exports.codeToName[1441] = 'ER_DATETIME_FUNCTION_OVERFLOW'; +module.exports.codeToName[1442] = 'ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG'; +module.exports.codeToName[1443] = 'ER_VIEW_PREVENT_UPDATE'; +module.exports.codeToName[1444] = 'ER_PS_NO_RECURSION'; +module.exports.codeToName[1445] = 'ER_SP_CANT_SET_AUTOCOMMIT'; +module.exports.codeToName[1446] = 'ER_MALFORMED_DEFINER'; +module.exports.codeToName[1447] = 'ER_VIEW_FRM_NO_USER'; +module.exports.codeToName[1448] = 'ER_VIEW_OTHER_USER'; +module.exports.codeToName[1449] = 'ER_NO_SUCH_USER'; +module.exports.codeToName[1450] = 'ER_FORBID_SCHEMA_CHANGE'; +module.exports.codeToName[1451] = 'ER_ROW_IS_REFERENCED_'; +module.exports.codeToName[1452] = 'ER_NO_REFERENCED_ROW_'; +module.exports.codeToName[1453] = 'ER_SP_BAD_VAR_SHADOW'; +module.exports.codeToName[1454] = 'ER_TRG_NO_DEFINER'; +module.exports.codeToName[1455] = 'ER_OLD_FILE_FORMAT'; +module.exports.codeToName[1456] = 'ER_SP_RECURSION_LIMIT'; +module.exports.codeToName[1457] = 'ER_SP_PROC_TABLE_CORRUPT'; +module.exports.codeToName[1458] = 'ER_SP_WRONG_NAME'; +module.exports.codeToName[1459] = 'ER_TABLE_NEEDS_UPGRADE'; +module.exports.codeToName[1460] = 'ER_SP_NO_AGGREGATE'; +module.exports.codeToName[1461] = 'ER_MAX_PREPARED_STMT_COUNT_REACHED'; +module.exports.codeToName[1462] = 'ER_VIEW_RECURSIVE'; +module.exports.codeToName[1463] = 'ER_NON_GROUPING_FIELD_USED'; +module.exports.codeToName[1464] = 'ER_TABLE_CANT_HANDLE_SPKEYS'; +module.exports.codeToName[1465] = 'ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA'; +module.exports.codeToName[1466] = 'ER_REMOVED_SPACES'; +module.exports.codeToName[1467] = 'ER_AUTOINC_READ_FAILED'; +module.exports.codeToName[1468] = 'ER_USERNAME'; +module.exports.codeToName[1469] = 'ER_HOSTNAME'; +module.exports.codeToName[1470] = 'ER_WRONG_STRING_LENGTH'; +module.exports.codeToName[1471] = 'ER_NON_INSERTABLE_TABLE'; +module.exports.codeToName[1472] = 'ER_ADMIN_WRONG_MRG_TABLE'; +module.exports.codeToName[1473] = 'ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT'; +module.exports.codeToName[1474] = 'ER_NAME_BECOMES_EMPTY'; +module.exports.codeToName[1475] = 'ER_AMBIGUOUS_FIELD_TERM'; +module.exports.codeToName[1476] = 'ER_FOREIGN_SERVER_EXISTS'; +module.exports.codeToName[1477] = 'ER_FOREIGN_SERVER_DOESNT_EXIST'; +module.exports.codeToName[1478] = 'ER_ILLEGAL_HA_CREATE_OPTION'; +module.exports.codeToName[1479] = 'ER_PARTITION_REQUIRES_VALUES_ERROR'; +module.exports.codeToName[1480] = 'ER_PARTITION_WRONG_VALUES_ERROR'; +module.exports.codeToName[1481] = 'ER_PARTITION_MAXVALUE_ERROR'; +module.exports.codeToName[1482] = 'ER_PARTITION_SUBPARTITION_ERROR'; +module.exports.codeToName[1483] = 'ER_PARTITION_SUBPART_MIX_ERROR'; +module.exports.codeToName[1484] = 'ER_PARTITION_WRONG_NO_PART_ERROR'; +module.exports.codeToName[1485] = 'ER_PARTITION_WRONG_NO_SUBPART_ERROR'; +module.exports.codeToName[1486] = 'ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR'; +module.exports.codeToName[1487] = 'ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR'; +module.exports.codeToName[1488] = 'ER_FIELD_NOT_FOUND_PART_ERROR'; +module.exports.codeToName[1489] = 'ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR'; +module.exports.codeToName[1490] = 'ER_INCONSISTENT_PARTITION_INFO_ERROR'; +module.exports.codeToName[1491] = 'ER_PARTITION_FUNC_NOT_ALLOWED_ERROR'; +module.exports.codeToName[1492] = 'ER_PARTITIONS_MUST_BE_DEFINED_ERROR'; +module.exports.codeToName[1493] = 'ER_RANGE_NOT_INCREASING_ERROR'; +module.exports.codeToName[1494] = 'ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR'; +module.exports.codeToName[1495] = 'ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR'; +module.exports.codeToName[1496] = 'ER_PARTITION_ENTRY_ERROR'; +module.exports.codeToName[1497] = 'ER_MIX_HANDLER_ERROR'; +module.exports.codeToName[1498] = 'ER_PARTITION_NOT_DEFINED_ERROR'; +module.exports.codeToName[1499] = 'ER_TOO_MANY_PARTITIONS_ERROR'; +module.exports.codeToName[1500] = 'ER_SUBPARTITION_ERROR'; +module.exports.codeToName[1501] = 'ER_CANT_CREATE_HANDLER_FILE'; +module.exports.codeToName[1502] = 'ER_BLOB_FIELD_IN_PART_FUNC_ERROR'; +module.exports.codeToName[1503] = 'ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF'; +module.exports.codeToName[1504] = 'ER_NO_PARTS_ERROR'; +module.exports.codeToName[1505] = 'ER_PARTITION_MGMT_ON_NONPARTITIONED'; +module.exports.codeToName[1506] = 'ER_FOREIGN_KEY_ON_PARTITIONED'; +module.exports.codeToName[1507] = 'ER_DROP_PARTITION_NON_EXISTENT'; +module.exports.codeToName[1508] = 'ER_DROP_LAST_PARTITION'; +module.exports.codeToName[1509] = 'ER_COALESCE_ONLY_ON_HASH_PARTITION'; +module.exports.codeToName[1510] = 'ER_REORG_HASH_ONLY_ON_SAME_NO'; +module.exports.codeToName[1511] = 'ER_REORG_NO_PARAM_ERROR'; +module.exports.codeToName[1512] = 'ER_ONLY_ON_RANGE_LIST_PARTITION'; +module.exports.codeToName[1513] = 'ER_ADD_PARTITION_SUBPART_ERROR'; +module.exports.codeToName[1514] = 'ER_ADD_PARTITION_NO_NEW_PARTITION'; +module.exports.codeToName[1515] = 'ER_COALESCE_PARTITION_NO_PARTITION'; +module.exports.codeToName[1516] = 'ER_REORG_PARTITION_NOT_EXIST'; +module.exports.codeToName[1517] = 'ER_SAME_NAME_PARTITION'; +module.exports.codeToName[1518] = 'ER_NO_BINLOG_ERROR'; +module.exports.codeToName[1519] = 'ER_CONSECUTIVE_REORG_PARTITIONS'; +module.exports.codeToName[1520] = 'ER_REORG_OUTSIDE_RANGE'; +module.exports.codeToName[1521] = 'ER_PARTITION_FUNCTION_FAILURE'; +module.exports.codeToName[1522] = 'ER_PART_STATE_ERROR'; +module.exports.codeToName[1523] = 'ER_LIMITED_PART_RANGE'; +module.exports.codeToName[1524] = 'ER_PLUGIN_IS_NOT_LOADED'; +module.exports.codeToName[1525] = 'ER_WRONG_VALUE'; +module.exports.codeToName[1526] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE'; +module.exports.codeToName[1527] = 'ER_FILEGROUP_OPTION_ONLY_ONCE'; +module.exports.codeToName[1528] = 'ER_CREATE_FILEGROUP_FAILED'; +module.exports.codeToName[1529] = 'ER_DROP_FILEGROUP_FAILED'; +module.exports.codeToName[1530] = 'ER_TABLESPACE_AUTO_EXTEND_ERROR'; +module.exports.codeToName[1531] = 'ER_WRONG_SIZE_NUMBER'; +module.exports.codeToName[1532] = 'ER_SIZE_OVERFLOW_ERROR'; +module.exports.codeToName[1533] = 'ER_ALTER_FILEGROUP_FAILED'; +module.exports.codeToName[1534] = 'ER_BINLOG_ROW_LOGGING_FAILED'; +module.exports.codeToName[1535] = 'ER_BINLOG_ROW_WRONG_TABLE_DEF'; +module.exports.codeToName[1536] = 'ER_BINLOG_ROW_RBR_TO_SBR'; +module.exports.codeToName[1537] = 'ER_EVENT_ALREADY_EXISTS'; +module.exports.codeToName[1538] = 'ER_EVENT_STORE_FAILED'; +module.exports.codeToName[1539] = 'ER_EVENT_DOES_NOT_EXIST'; +module.exports.codeToName[1540] = 'ER_EVENT_CANT_ALTER'; +module.exports.codeToName[1541] = 'ER_EVENT_DROP_FAILED'; +module.exports.codeToName[1542] = 'ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG'; +module.exports.codeToName[1543] = 'ER_EVENT_ENDS_BEFORE_STARTS'; +module.exports.codeToName[1544] = 'ER_EVENT_EXEC_TIME_IN_THE_PAST'; +module.exports.codeToName[1545] = 'ER_EVENT_OPEN_TABLE_FAILED'; +module.exports.codeToName[1546] = 'ER_EVENT_NEITHER_M_EXPR_NOR_M_AT'; +module.exports.codeToName[1547] = 'ER_COL_COUNT_DOESNT_MATCH_CORRUPTED'; +module.exports.codeToName[1548] = 'ER_CANNOT_LOAD_FROM_TABLE'; +module.exports.codeToName[1549] = 'ER_EVENT_CANNOT_DELETE'; +module.exports.codeToName[1550] = 'ER_EVENT_COMPILE_ERROR'; +module.exports.codeToName[1551] = 'ER_EVENT_SAME_NAME'; +module.exports.codeToName[1552] = 'ER_EVENT_DATA_TOO_LONG'; +module.exports.codeToName[1553] = 'ER_DROP_INDEX_FK'; +module.exports.codeToName[1554] = 'ER_WARN_DEPRECATED_SYNTAX_WITH_VER'; +module.exports.codeToName[1555] = 'ER_CANT_WRITE_LOCK_LOG_TABLE'; +module.exports.codeToName[1556] = 'ER_CANT_LOCK_LOG_TABLE'; +module.exports.codeToName[1557] = 'ER_FOREIGN_DUPLICATE_KEY'; +module.exports.codeToName[1558] = 'ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE'; +module.exports.codeToName[1559] = 'ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR'; +module.exports.codeToName[1560] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT'; +module.exports.codeToName[1561] = 'ER_NDB_CANT_SWITCH_BINLOG_FORMAT'; +module.exports.codeToName[1562] = 'ER_PARTITION_NO_TEMPORARY'; +module.exports.codeToName[1563] = 'ER_PARTITION_CONST_DOMAIN_ERROR'; +module.exports.codeToName[1564] = 'ER_PARTITION_FUNCTION_IS_NOT_ALLOWED'; +module.exports.codeToName[1565] = 'ER_DDL_LOG_ERROR'; +module.exports.codeToName[1566] = 'ER_NULL_IN_VALUES_LESS_THAN'; +module.exports.codeToName[1567] = 'ER_WRONG_PARTITION_NAME'; +module.exports.codeToName[1568] = 'ER_CANT_CHANGE_TX_ISOLATION'; +module.exports.codeToName[1569] = 'ER_DUP_ENTRY_AUTOINCREMENT_CASE'; +module.exports.codeToName[1570] = 'ER_EVENT_MODIFY_QUEUE_ERROR'; +module.exports.codeToName[1571] = 'ER_EVENT_SET_VAR_ERROR'; +module.exports.codeToName[1572] = 'ER_PARTITION_MERGE_ERROR'; +module.exports.codeToName[1573] = 'ER_CANT_ACTIVATE_LOG'; +module.exports.codeToName[1574] = 'ER_RBR_NOT_AVAILABLE'; +module.exports.codeToName[1575] = 'ER_BASE'; +module.exports.codeToName[1576] = 'ER_EVENT_RECURSION_FORBIDDEN'; +module.exports.codeToName[1577] = 'ER_EVENTS_DB_ERROR'; +module.exports.codeToName[1578] = 'ER_ONLY_INTEGERS_ALLOWED'; +module.exports.codeToName[1579] = 'ER_UNSUPORTED_LOG_ENGINE'; +module.exports.codeToName[1580] = 'ER_BAD_LOG_STATEMENT'; +module.exports.codeToName[1581] = 'ER_CANT_RENAME_LOG_TABLE'; +module.exports.codeToName[1582] = 'ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT'; +module.exports.codeToName[1583] = 'ER_WRONG_PARAMETERS_TO_NATIVE_FCT'; +module.exports.codeToName[1584] = 'ER_WRONG_PARAMETERS_TO_STORED_FCT'; +module.exports.codeToName[1585] = 'ER_NATIVE_FCT_NAME_COLLISION'; +module.exports.codeToName[1586] = 'ER_DUP_ENTRY_WITH_KEY_NAME'; +module.exports.codeToName[1587] = 'ER_BINLOG_PURGE_EMFILE'; +module.exports.codeToName[1588] = 'ER_EVENT_CANNOT_CREATE_IN_THE_PAST'; +module.exports.codeToName[1589] = 'ER_EVENT_CANNOT_ALTER_IN_THE_PAST'; +module.exports.codeToName[1590] = 'ER_SLAVE_INCIDENT'; +module.exports.codeToName[1591] = 'ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT'; +module.exports.codeToName[1592] = 'ER_BINLOG_UNSAFE_STATEMENT'; +module.exports.codeToName[1593] = 'ER_SLAVE_FATAL_ERROR'; +module.exports.codeToName[1594] = 'ER_SLAVE_RELAY_LOG_READ_FAILURE'; +module.exports.codeToName[1595] = 'ER_SLAVE_RELAY_LOG_WRITE_FAILURE'; +module.exports.codeToName[1596] = 'ER_SLAVE_CREATE_EVENT_FAILURE'; +module.exports.codeToName[1597] = 'ER_SLAVE_MASTER_COM_FAILURE'; +module.exports.codeToName[1598] = 'ER_BINLOG_LOGGING_IMPOSSIBLE'; +module.exports.codeToName[1599] = 'ER_VIEW_NO_CREATION_CTX'; +module.exports.codeToName[1600] = 'ER_VIEW_INVALID_CREATION_CTX'; +module.exports.codeToName[1601] = 'ER_SR_INVALID_CREATION_CTX'; +module.exports.codeToName[1602] = 'ER_TRG_CORRUPTED_FILE'; +module.exports.codeToName[1603] = 'ER_TRG_NO_CREATION_CTX'; +module.exports.codeToName[1604] = 'ER_TRG_INVALID_CREATION_CTX'; +module.exports.codeToName[1605] = 'ER_EVENT_INVALID_CREATION_CTX'; +module.exports.codeToName[1606] = 'ER_TRG_CANT_OPEN_TABLE'; +module.exports.codeToName[1607] = 'ER_CANT_CREATE_SROUTINE'; +module.exports.codeToName[1608] = 'ER_NEVER_USED'; +module.exports.codeToName[1609] = 'ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT'; +module.exports.codeToName[1610] = 'ER_SLAVE_CORRUPT_EVENT'; +module.exports.codeToName[1611] = 'ER_LOAD_DATA_INVALID_COLUMN'; +module.exports.codeToName[1612] = 'ER_LOG_PURGE_NO_FILE'; +module.exports.codeToName[1613] = 'ER_XA_RBTIMEOUT'; +module.exports.codeToName[1614] = 'ER_XA_RBDEADLOCK'; +module.exports.codeToName[1615] = 'ER_NEED_REPREPARE'; +module.exports.codeToName[1616] = 'ER_DELAYED_NOT_SUPPORTED'; +module.exports.codeToName[1617] = 'WARN_NO_MASTER_INFO'; +module.exports.codeToName[1618] = 'WARN_OPTION_IGNORED'; +module.exports.codeToName[1619] = 'WARN_PLUGIN_DELETE_BUILTIN'; +module.exports.codeToName[1620] = 'WARN_PLUGIN_BUSY'; +module.exports.codeToName[1621] = 'ER_VARIABLE_IS_READONLY'; +module.exports.codeToName[1622] = 'ER_WARN_ENGINE_TRANSACTION_ROLLBACK'; +module.exports.codeToName[1623] = 'ER_SLAVE_HEARTBEAT_FAILURE'; +module.exports.codeToName[1624] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE'; +module.exports.codeToName[1625] = 'ER_NDB_REPLICATION_SCHEMA_ERROR'; +module.exports.codeToName[1626] = 'ER_CONFLICT_FN_PARSE_ERROR'; +module.exports.codeToName[1627] = 'ER_EXCEPTIONS_WRITE_ERROR'; +module.exports.codeToName[1628] = 'ER_TOO_LONG_TABLE_COMMENT'; +module.exports.codeToName[1629] = 'ER_TOO_LONG_FIELD_COMMENT'; +module.exports.codeToName[1630] = 'ER_FUNC_INEXISTENT_NAME_COLLISION'; +module.exports.codeToName[1631] = 'ER_DATABASE_NAME'; +module.exports.codeToName[1632] = 'ER_TABLE_NAME'; +module.exports.codeToName[1633] = 'ER_PARTITION_NAME'; +module.exports.codeToName[1634] = 'ER_SUBPARTITION_NAME'; +module.exports.codeToName[1635] = 'ER_TEMPORARY_NAME'; +module.exports.codeToName[1636] = 'ER_RENAMED_NAME'; +module.exports.codeToName[1637] = 'ER_TOO_MANY_CONCURRENT_TRXS'; +module.exports.codeToName[1638] = 'WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED'; +module.exports.codeToName[1639] = 'ER_DEBUG_SYNC_TIMEOUT'; +module.exports.codeToName[1640] = 'ER_DEBUG_SYNC_HIT_LIMIT'; +module.exports.codeToName[1641] = 'ER_DUP_SIGNAL_SET'; +module.exports.codeToName[1642] = 'ER_SIGNAL_WARN'; +module.exports.codeToName[1643] = 'ER_SIGNAL_NOT_FOUND'; +module.exports.codeToName[1644] = 'ER_SIGNAL_EXCEPTION'; +module.exports.codeToName[1645] = 'ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER'; +module.exports.codeToName[1646] = 'ER_SIGNAL_BAD_CONDITION_TYPE'; +module.exports.codeToName[1647] = 'WARN_COND_ITEM_TRUNCATED'; +module.exports.codeToName[1648] = 'ER_COND_ITEM_TOO_LONG'; +module.exports.codeToName[1649] = 'ER_UNKNOWN_LOCALE'; +module.exports.codeToName[1650] = 'ER_SLAVE_IGNORE_SERVER_IDS'; +module.exports.codeToName[1651] = 'ER_QUERY_CACHE_DISABLED'; +module.exports.codeToName[1652] = 'ER_SAME_NAME_PARTITION_FIELD'; +module.exports.codeToName[1653] = 'ER_PARTITION_COLUMN_LIST_ERROR'; +module.exports.codeToName[1654] = 'ER_WRONG_TYPE_COLUMN_VALUE_ERROR'; +module.exports.codeToName[1655] = 'ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR'; +module.exports.codeToName[1656] = 'ER_MAXVALUE_IN_VALUES_IN'; +module.exports.codeToName[1657] = 'ER_TOO_MANY_VALUES_ERROR'; +module.exports.codeToName[1658] = 'ER_ROW_SINGLE_PARTITION_FIELD_ERROR'; +module.exports.codeToName[1659] = 'ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD'; +module.exports.codeToName[1660] = 'ER_PARTITION_FIELDS_TOO_LONG'; +module.exports.codeToName[1661] = 'ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE'; +module.exports.codeToName[1662] = 'ER_BINLOG_ROW_MODE_AND_STMT_ENGINE'; +module.exports.codeToName[1663] = 'ER_BINLOG_UNSAFE_AND_STMT_ENGINE'; +module.exports.codeToName[1664] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE'; +module.exports.codeToName[1665] = 'ER_BINLOG_STMT_MODE_AND_ROW_ENGINE'; +module.exports.codeToName[1666] = 'ER_BINLOG_ROW_INJECTION_AND_STMT_MODE'; +module.exports.codeToName[1667] = 'ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE'; +module.exports.codeToName[1668] = 'ER_BINLOG_UNSAFE_LIMIT'; +module.exports.codeToName[1669] = 'ER_BINLOG_UNSAFE_INSERT_DELAYED'; +module.exports.codeToName[1670] = 'ER_BINLOG_UNSAFE_SYSTEM_TABLE'; +module.exports.codeToName[1671] = 'ER_BINLOG_UNSAFE_AUTOINC_COLUMNS'; +module.exports.codeToName[1672] = 'ER_BINLOG_UNSAFE_UDF'; +module.exports.codeToName[1673] = 'ER_BINLOG_UNSAFE_SYSTEM_VARIABLE'; +module.exports.codeToName[1674] = 'ER_BINLOG_UNSAFE_SYSTEM_FUNCTION'; +module.exports.codeToName[1675] = 'ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS'; +module.exports.codeToName[1676] = 'ER_MESSAGE_AND_STATEMENT'; +module.exports.codeToName[1677] = 'ER_SLAVE_CONVERSION_FAILED'; +module.exports.codeToName[1678] = 'ER_SLAVE_CANT_CREATE_CONVERSION'; +module.exports.codeToName[1679] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT'; +module.exports.codeToName[1680] = 'ER_PATH_LENGTH'; +module.exports.codeToName[1681] = 'ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT'; +module.exports.codeToName[1682] = 'ER_WRONG_NATIVE_TABLE_STRUCTURE'; +module.exports.codeToName[1683] = 'ER_WRONG_PERFSCHEMA_USAGE'; +module.exports.codeToName[1684] = 'ER_WARN_I_S_SKIPPED_TABLE'; +module.exports.codeToName[1685] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT'; +module.exports.codeToName[1686] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT'; +module.exports.codeToName[1687] = 'ER_SPATIAL_MUST_HAVE_GEOM_COL'; +module.exports.codeToName[1688] = 'ER_TOO_LONG_INDEX_COMMENT'; +module.exports.codeToName[1689] = 'ER_LOCK_ABORTED'; +module.exports.codeToName[1690] = 'ER_DATA_OUT_OF_RANGE'; +module.exports.codeToName[1691] = 'ER_WRONG_SPVAR_TYPE_IN_LIMIT'; +module.exports.codeToName[1692] = 'ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE'; +module.exports.codeToName[1693] = 'ER_BINLOG_UNSAFE_MIXED_STATEMENT'; +module.exports.codeToName[1694] = 'ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN'; +module.exports.codeToName[1695] = 'ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN'; +module.exports.codeToName[1696] = 'ER_FAILED_READ_FROM_PAR_FILE'; +module.exports.codeToName[1697] = 'ER_VALUES_IS_NOT_INT_TYPE_ERROR'; +module.exports.codeToName[1698] = 'ER_ACCESS_DENIED_NO_PASSWORD_ERROR'; +module.exports.codeToName[1699] = 'ER_SET_PASSWORD_AUTH_PLUGIN'; +module.exports.codeToName[1700] = 'ER_GRANT_PLUGIN_USER_EXISTS'; +module.exports.codeToName[1701] = 'ER_TRUNCATE_ILLEGAL_FK'; +module.exports.codeToName[1702] = 'ER_PLUGIN_IS_PERMANENT'; +module.exports.codeToName[1703] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN'; +module.exports.codeToName[1704] = 'ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX'; +module.exports.codeToName[1705] = 'ER_STMT_CACHE_FULL'; +module.exports.codeToName[1706] = 'ER_MULTI_UPDATE_KEY_CONFLICT'; +module.exports.codeToName[1707] = 'ER_TABLE_NEEDS_REBUILD'; +module.exports.codeToName[1708] = 'WARN_OPTION_BELOW_LIMIT'; +module.exports.codeToName[1709] = 'ER_INDEX_COLUMN_TOO_LONG'; +module.exports.codeToName[1710] = 'ER_ERROR_IN_TRIGGER_BODY'; +module.exports.codeToName[1711] = 'ER_ERROR_IN_UNKNOWN_TRIGGER_BODY'; +module.exports.codeToName[1712] = 'ER_INDEX_CORRUPT'; +module.exports.codeToName[1713] = 'ER_UNDO_RECORD_TOO_BIG'; +module.exports.codeToName[1714] = 'ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT'; +module.exports.codeToName[1715] = 'ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE'; +module.exports.codeToName[1716] = 'ER_BINLOG_UNSAFE_REPLACE_SELECT'; +module.exports.codeToName[1717] = 'ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT'; +module.exports.codeToName[1718] = 'ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT'; +module.exports.codeToName[1719] = 'ER_BINLOG_UNSAFE_UPDATE_IGNORE'; +module.exports.codeToName[1720] = 'ER_PLUGIN_NO_UNINSTALL'; +module.exports.codeToName[1721] = 'ER_PLUGIN_NO_INSTALL'; +module.exports.codeToName[1722] = 'ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT'; +module.exports.codeToName[1723] = 'ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC'; diff --git a/node_modules/mysql2/lib/constants/field_flags.js b/node_modules/mysql2/lib/constants/field_flags.js new file mode 100644 index 0000000..3fe05c3 --- /dev/null +++ b/node_modules/mysql2/lib/constants/field_flags.js @@ -0,0 +1,18 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +exports.NOT_NULL = 1; /* Field can't be NULL */ +exports.PRI_KEY = 2; /* Field is part of a primary key */ +exports.UNIQUE_KEY = 4; /* Field is part of a unique key */ +exports.MULTIPLE_KEY = 8; /* Field is part of a key */ +exports.BLOB = 16; /* Field is a blob */ +exports.UNSIGNED = 32; /* Field is unsigned */ +exports.ZEROFILL = 64; /* Field is zerofill */ +exports.BINARY = 128; /* Field is binary */ + +/* The following are only sent to new clients */ +exports.ENUM = 256; /* field is an enum */ +exports.AUTO_INCREMENT = 512; /* field is a autoincrement field */ +exports.TIMESTAMP = 1024; /* Field is a timestamp */ +exports.SET = 2048; /* field is a set */ +exports.NO_DEFAULT_VALUE = 4096; /* Field doesn't have default value */ +exports.ON_UPDATE_NOW = 8192; /* Field is set to NOW on UPDATE */ +exports.NUM = 32768; /* Field is num (for clients) */ diff --git a/node_modules/mysql2/lib/constants/server_status.js b/node_modules/mysql2/lib/constants/server_status.js new file mode 100644 index 0000000..5537ee5 --- /dev/null +++ b/node_modules/mysql2/lib/constants/server_status.js @@ -0,0 +1,39 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h + +/** + Is raised when a multi-statement transaction + has been started, either explicitly, by means + of BEGIN or COMMIT AND CHAIN, or + implicitly, by the first transactional + statement, when autocommit=off. +*/ +exports.SERVER_STATUS_IN_TRANS = 1; +exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */ +exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */ +exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16; +exports.SERVER_QUERY_NO_INDEX_USED = 32; +/** + The server was able to fulfill the clients request and opened a + read-only non-scrollable cursor for a query. This flag comes + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. +*/ +exports.SERVER_STATUS_CURSOR_EXISTS = 64; +/** + This flag is sent when a read-only cursor is exhausted, in reply to + COM_STMT_FETCH command. +*/ +exports.SERVER_STATUS_LAST_ROW_SENT = 128; +exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */ +exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512; +/** + Sent to the client if after a prepared statement reprepare + we discovered that the new statement returns a different + number of result set columns. +*/ +exports.SERVER_STATUS_METADATA_CHANGED = 1024; +exports.SERVER_QUERY_WAS_SLOW = 2048; + +/** + To mark ResultSet containing output parameter values. +*/ +exports.SERVER_PS_OUT_PARAMS = 4096; diff --git a/node_modules/mysql2/lib/constants/types.js b/node_modules/mysql2/lib/constants/types.js new file mode 100644 index 0000000..21c4000 --- /dev/null +++ b/node_modules/mysql2/lib/constants/types.js @@ -0,0 +1,29 @@ +// Manually extracted from mysql-5.5.23/include/mysql_com.h +// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html +exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html) +exports.TINY = 0x01; // aka TINYINT, 1 byte +exports.SHORT = 0x02; // aka SMALLINT, 2 bytes +exports.LONG = 0x03; // aka INT, 4 bytes +exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes +exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes +exports.NULL = 0x06; // NULL (used for prepared statements, I think) +exports.TIMESTAMP = 0x07; // aka TIMESTAMP +exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes +exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes +exports.DATE = 0x0a; // aka DATE +exports.TIME = 0x0b; // aka TIME +exports.DATETIME = 0x0c; // aka DATETIME +exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask) +exports.NEWDATE = 0x0e; // aka ? +exports.VARCHAR = 0x0f; // aka VARCHAR (?) +exports.BIT = 0x10; // aka BIT, 1-8 byte +exports.NEWDECIMAL = 0xf6; // aka DECIMAL +exports.ENUM = 0xf7; // aka ENUM +exports.SET = 0xf8; // aka SET +exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT +exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT +exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT +exports.BLOB = 0xfc; // aka BLOB, TEXT +exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY +exports.STRING = 0xfe; // aka CHAR, BINARY +exports.GEOMETRY = 0xff; // aka GEOMETRY diff --git a/node_modules/mysql2/lib/helpers.js b/node_modules/mysql2/lib/helpers.js new file mode 100644 index 0000000..2554905 --- /dev/null +++ b/node_modules/mysql2/lib/helpers.js @@ -0,0 +1,21 @@ + /* + + this seems to be not only shorter, but faster than + string.replace(/\\/g, '\\\\'). + replace(/\u0008/g, '\\b'). + replace(/\t/g, '\\t'). + replace(/\n/g, '\\n'). + replace(/\f/g, '\\f'). + replace(/\r/g, '\\r'). + replace(/'/g, '\\\''). + replace(/"/g, '\\"'); + or string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") + see http://jsperf.com/string-escape-regexp-vs-json-stringify + */ + function srcEscape(str) { + var a = {}; + a[str] = 1; + return JSON.stringify(a).slice(1,-3); + } + +module.exports.srcEscape = srcEscape; diff --git a/node_modules/mysql2/lib/packet_parser.js b/node_modules/mysql2/lib/packet_parser.js new file mode 100644 index 0000000..0bd3283 --- /dev/null +++ b/node_modules/mysql2/lib/packet_parser.js @@ -0,0 +1,83 @@ +var Packet = require('./packets/packet'); + +// as this is very low level parser, EventEmitter is not used +// onPayload(sequenceId, payload) is called for each mysql packet +function PacketParser(onPacket) +{ + // array of last payload chunks + // only used when corrent payload is not complete + this.buffer = []; + // total length of chunks on buffer + this.bufferLength = 0; + this.headerLen = 0; + this.headerBuff = Buffer(4); + + this.state = 'head0'; + + // expected payload length + this.length = 0; + this.sequenceId = 0; + this.onPacket = onPacket; +} + +PacketParser.prototype.execute = function(chunk, start, end) { + + // node 0.11 has different ondata signature + if (!start && !end) { + start = 0; + end = chunk.length; + } + + while (start < chunk.length) { + if (this.state == 'head0' && (end - start) > 3) { + this.length = chunk[start] + (chunk[start+1] << 8) + (chunk[start+2] << 16); + this.sequenceId = chunk[start+3]; + var packetLength = this.length + 4; + if (end - start > packetLength) { // more than one packet in chunk + this.onPacket(new Packet(this.sequenceId, chunk, start + 4, start + packetLength)); + start += packetLength; + } else if (end - start == packetLength) { + return this.onPacket(new Packet(this.sequenceId, chunk, start + 4, start + packetLength)); + } else { // payload is incomplete + this.buffer = [chunk.slice(start + 4, end)]; + this.bufferLength = end - start - 4; + this.state = 'payload'; + return; + } + } else if (this.state == 'payload') { + var remainingPayload = this.length - this.bufferLength; + if (end - start >= remainingPayload) { // last chunk for payload + var payload = new Buffer(this.length); + var offset = 0; + for (var i=0; i < this.buffer.length; ++i) { + this.buffer[i].copy(payload, offset); + offset += this.buffer[i].length; + } + chunk.copy(payload, offset, start, start + remainingPayload); + this.onPacket(new Packet(this.sequenceId, payload, 0, this.length)); + this.buffer = []; + this.bufferLength = 0; + start += remainingPayload; + this.state = 'head0'; + } else { + this.buffer.push(chunk.slice(start, end)); + this.bufferLength += end - start; + return; + } + } else { // length < 4 or state != header0 + if (end - start + this.headerLen < 4) { + chunk.copy(this.headerBuff, this.headerLen, start, end); + this.headerLen += end - start; + this.state = 'head_'; + return; + } + chunk.copy(this.headerBuff, this.headerLen, start, start + 4 - this.headerLen); + start += 4 - this.headerLen; + this.length = this.headerBuff[0] + (this.headerBuff[1] << 8) + (this.headerBuff[2] << 16); + this.headerLen = 0; + this.state = 'payload'; + } + } +}; + +module.exports = PacketParser; diff --git a/node_modules/mysql2/lib/packets/binary_row.js b/node_modules/mysql2/lib/packets/binary_row.js new file mode 100644 index 0000000..695e7f2 --- /dev/null +++ b/node_modules/mysql2/lib/packets/binary_row.js @@ -0,0 +1,44 @@ +var Types = require('../constants/types'); +var Packet = require('../packets/packet'); + +function BinaryRow(columns) +{ + this.columns = columns || []; +} + + var binaryReader = new Array(256); + + // TODO: replace with constants.MYSQL_TYPE_* + binaryReader[Types.DECIMAL] = Packet.prototype.readLengthCodedString; + binaryReader[1] = Packet.prototype.readInt8; // tiny + binaryReader[2] = Packet.prototype.readInt16; // short + binaryReader[3] = Packet.prototype.readInt32; // long + binaryReader[4] = Packet.prototype.readFloat; // float + binaryReader[5] = Packet.prototype.readDouble; // double + binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap + binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP + binaryReader[8] = Packet.prototype.readInt64; // long long + binaryReader[9] = Packet.prototype.readInt32; // int24 + binaryReader[10] = Packet.prototype.readTimestamp; // date + binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME + binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME + binaryReader[13] = Packet.prototype.readInt16; // year + binaryReader[Types.VAR_STRING] = Packet.prototype.readLengthCodedString; // var string + // TODO: complete list of types... + +BinaryRow.fromPacket = function(fields, packet) { + var columns = new Array(fields.length); + var ok = packet.readInt8(); // TODO check it's 0 + var nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8); + // TODO: read and interpret null bitmap + packet.skip(nullBitmapLength); + for (var i = 0; i < columns.length; ++i) + columns[i] = binaryReader[fields[i].columnType].apply(packet); + return new BinaryRow(columns); +}; + +BinaryRow.prototype.toPacket = function(sequenceId) { + throw "Not implemented"; +}; + +module.exports = BinaryRow; diff --git a/node_modules/mysql2/lib/packets/binlog_dump.js b/node_modules/mysql2/lib/packets/binlog_dump.js new file mode 100644 index 0000000..b56baac --- /dev/null +++ b/node_modules/mysql2/lib/packets/binlog_dump.js @@ -0,0 +1,33 @@ +// http://dev.mysql.com/doc/internals/en/com-binlog-dump.html#packet-COM_BINLOG_DUMP + +var Packet = require('../packets/packet'); +var CommandCodes = require('../constants/commands'); + +// TODO: add flag to constants +// 0x01 - BINLOG_DUMP_NON_BLOCK +// send EOF instead of blocking + +function BinlogDump(opts) +{ + this.binlogPos = opts.binlogPos || 0; + this.serverId = opts.serverId || 0; + this.flags = opts.flags || 0; + this.filename = opts.filename || ''; +} + +BinlogDump.prototype.toPacket = function() +{ + var length = 15 + // TODO: should be ascii? + Buffer.byteLength(this.filename, 'utf8'); + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(CommandCodes.BINLOG_DUMP); + packet.writeInt32(this.binlogPos); + packet.writeInt16(this.flags); + packet.writeInt32(this.serverId); + packet.writeString(this.filename); + return packet; +}; + +module.exports = BinlogDump; \ No newline at end of file diff --git a/node_modules/mysql2/lib/packets/binlog_query_statusvars.js b/node_modules/mysql2/lib/packets/binlog_query_statusvars.js new file mode 100644 index 0000000..d880288 --- /dev/null +++ b/node_modules/mysql2/lib/packets/binlog_query_statusvars.js @@ -0,0 +1,99 @@ +// http://dev.mysql.com/doc/internals/en/query-event.html + +var keys = { + FLAGS2: 0, + SQL_MODE: 1, + CATALOG: 2, + AUTO_INCREMENT: 3, + CHARSET: 4, + TIME_ZONE: 5, + CATALOG_NZ: 6, + LC_TIME_NAMES: 7, + CHARSET_DATABASE: 8, + TABLE_MAP_FOR_UPDATE: 9, + MASTER_DATA_WRITTEN: 10, + INVOKERS: 11, + UPDATED_DB_NAMES: 12, + MICROSECONDS: 3 +}; + +module.exports = function parseStatusVars(buffer) { + var result = {}; + var offset = 0; + var key, length, username, hostname, prevOffset; + while(offset < buffer.length) { + key = buffer[offset++]; + val = [key]; + switch(key) { + case keys.FLAGS2: + result.flags = buffer.readUInt32LE(offset); + offset += 4; break; + case keys.SQL_MODE: + // value is 8 bytes, but all dcumented flags are in first 4 bytes + result.sqlMode = buffer.readUInt32LE(offset); + offset += 8; + break; + case keys.CATALOG: + length = buffer[offset++]; + result.catalog = buffer.toString('utf8', offset, offset + length); + offset += length + 1; // null byte after string + break; + case keys.CHARSET: + result.clientCharset = buffer.readUInt16LE(offset); + result.connectionCollation = buffer.readUInt16LE(offset + 2); + result.serverCharset = buffer.readUInt16LE(offset + 4); + offset += 6; + break; + case keys.TIME_ZONE: + length = buffer[offset++]; + result.timeZone = buffer.toString('utf8', offset, offset + length); + offset += length; // no null byte + break; + case keys.CATALOG_NZ: + length = buffer[offset++]; + result.catalogNz = buffer.toString('utf8', offset, offset + length); + offset += length ; // no null byte + break; + case keys.LC_TIME_NAMES: + result.lcTimeNames = buffer.readUInt16LE(offset); + offset += 2; + break; + case keys.CHARSET_DATABASE: + result.schemaCharset = buffer.readUInt16LE(offset); + offset += 2; + break; + case keys.TABLE_MAP_FOR_UPDATE: + result.mapForUpdate1 = buffer.readUInt32LE(offset); + result.mapForUpdate2 = buffer.readUInt32LE(offset + 4); + offset += 8; + break; + case keys.MASTER_DATA_WRITTEN: + result.masterDataWritten = buffer.readUInt32LE(offset); + offset += 4; + break; + case keys.INVOKERS: + length = buffer[offset++]; + result.invokerUsername = buffer.toString('utf8', offset, offset + length); + offset += length; + length = buffer[offset++]; + result.invokerHostname = buffer.toString('utf8', offset, offset + length); + offset += length; + break; + case keys.UPDATED_DB_NAMES: + length = buffer[offset++]; + // length - number of null-terminated strings + result.updatedDBs = []; // we'll store them as array here + for (; length; --length) { + prevOffset = offset; + // fast forward to null terminating byte + while(buffer[offset++] && offset < buffer.length) {} + result.updatedDBs.push(buffer.toString('utf8', prevOffset, offset-1)); + } + break; + case keys.MICROSECONDS: + result.microseconds = buffer.readInt16LE(offset) + (buffsre[offset+2] << 16); + offset += 3; + } + } + return result; +} \ No newline at end of file diff --git a/node_modules/mysql2/lib/packets/column_definition.js b/node_modules/mysql2/lib/packets/column_definition.js new file mode 100644 index 0000000..c27932c --- /dev/null +++ b/node_modules/mysql2/lib/packets/column_definition.js @@ -0,0 +1,46 @@ +var Packet = require('../packets/packet'); + +function ColumnDefinition(packet) +{ + this.catalog = packet.readLengthCodedString(); + this.schema = packet.readLengthCodedString(); + this.table = packet.readLengthCodedString(); + this.orgTable = packet.readLengthCodedString(); + this.name = packet.readLengthCodedString(); + this.orgName = packet.readLengthCodedString(); + packet.skip(1); // length of the following fields (always 0x0c) + this.characterSet = packet.readInt16(); + this.columnLength = packet.readInt32(); + this.columnType = packet.readInt8(); + this.flags = packet.readInt16(); + this.decimals = packet.readInt8(); +} + +ColumnDefinition.toPacket = function(column, sequenceId) +{ + var length = 0; + var fields = 'catalog schema table orgTable name orgName'.split(' '); + function addFieldLength(name) { + var str = column[name]; + length +=Packet.lengthCodedNumberLength(str); + length += str.length; + } + fields.forEach(addFieldLength); + length += 13; + var buffer = new Buffer(length); + function writeField(name) { + packet.writeLengthCodedString(column[name]); + } + var packet = new Packet(sequenceId, buffer); + packet.offset = 4; + fields.forEach(writeField); + packet.writeInt8 (0x0c); + packet.writeInt16(column.characterSet); + packet.writeInt32(column.columnLength); + packet.writeInt8 (column.columnType); + packet.writeInt16(column.flags); + packet.writeInt8 (column.decimals); + return packet; +}; + +module.exports = ColumnDefinition; diff --git a/node_modules/mysql2/lib/packets/execute.js b/node_modules/mysql2/lib/packets/execute.js new file mode 100644 index 0000000..68a9c4e --- /dev/null +++ b/node_modules/mysql2/lib/packets/execute.js @@ -0,0 +1,103 @@ +var CursorType = require('../constants/cursor'); +var CommandCodes = require('../constants/commands'); +var Types = require('../constants/types'); +var Packet = require('../packets/packet'); + +function Execute(id, parameters) +{ + this.id = id; + this.parameters = parameters; +} + +Execute.prototype.toPacket = function() +{ + + // TODO: don't try to calculate packet length in advance, allocate some big buffer in advance (header + 256 bytes?) + // and copy + reallocate if not enough + + var i; + // 0 + 4 - length, seqId + // 4 + 1 - COM_EXECUTE + // 5 + 4 - stmtId + // 9 + 1 - flags + // 10 + 4 - iteration-count (always 1) + var length = 14; + if (this.parameters && this.parameters.length > 0) + { + length += Math.floor((this.parameters.length + 7) / 8); + length += 1; // new-params-bound-flag + length += 2*this.parameters.length; // type byte for each parameter if new-params-bound-flag is set + for (i=0; i < this.parameters.length; i++) + { + if (this.parameters[i] !== null) { + if (Object.prototype.toString.call(this.parameters[i]) == '[object Date]') { + var d = this.parameters[i]; + // TODO: move to asMysqlDateTime() + this.parameters[i] = [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('-') + + ' ' + [d.getHours(), d.getMinutes(), d.getSeconds()].join(':'); + } + if (Buffer.isBuffer(this.parameters[i])) { + length += Packet.lengthCodedNumberLength(this.parameters[i].length); + length += this.parameters[i].length; + } + else { + var str = this.parameters[i].toString(); + var byteLen = Buffer.byteLength(str, 'utf8'); + length += Packet.lengthCodedNumberLength(byteLen); + length += byteLen; + } + } + } + } + + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(CommandCodes.STMT_EXECUTE); + packet.writeInt32(this.id); + packet.writeInt8(CursorType.NO_CURSOR); // flags + packet.writeInt32(1); // iteration-count, always 1 + if (this.parameters && this.parameters.length > 0) { + + var bitmap = 0; + var bitValue = 1; + for (i=0; i < this.parameters.length; i++) + { + if (this.parameters[i] === null) + bitmap += bitValue; + bitValue *= 2; + if (bitValue == 256) { + packet.writeInt8(bitmap); + bitmap = 0; + bitValue = 1; + } + } + if (bitValue != 1) + packet.writeInt8(bitmap); + + // TODO: explain meaning of the flag + // afaik, if set n*2 bytes with type of parameter are sent before parameters + // if not, previous execution types are used (TODO prooflink) + packet.writeInt8(1); // new-params-bound-flag + + // TODO: don't typecast always to sting, use parameters type + for (i=0; i < this.parameters.length; i++) + { + if (this.parameters[i] !== null) + packet.writeInt16(Types.VAR_STRING); + else + packet.writeInt16(Types.NULL); + } + for (i=0; i < this.parameters.length; i++) + { + if (this.parameters[i] !== null) + if (Buffer.isBuffer(this.parameters[i])) + packet.writeLengthCodedBuffer(this.parameters[i]); + else + packet.writeLengthCodedString(this.parameters[i].toString()); + } + } + return packet; +}; + +module.exports = Execute; diff --git a/node_modules/mysql2/lib/packets/handshake.js b/node_modules/mysql2/lib/packets/handshake.js new file mode 100644 index 0000000..0f8ee03 --- /dev/null +++ b/node_modules/mysql2/lib/packets/handshake.js @@ -0,0 +1,73 @@ +var Packet = require('../packets/packet'); + +function Handshake(args) { + this.protocolVersion = args.protocolVersion; + this.serverVersion = args.serverVersion; + this.capabilityFlags = args.capabilityFlags; + this.connectionId = args.connectionId; + this.authPluginData1 = args.authPluginData1; + this.authPluginData2 = args.authPluginData2; + this.characterSet = args.characterSet; + this.statusFlags = args.statusFlags; +} + +Handshake.fromPacket = function(packet) +{ + var args = {}; + args.protocolVersion = packet.readInt8(); + args.serverVersion = packet.readNullTerminatedString(); + args.connectionId = packet.readInt32(); + args.authPluginData1 = packet.readBuffer(8); + packet.skip(1); + args.capabilityFlags = packet.readInt16(); + if (packet.haveMoreData()) { + args.characterSet = packet.readInt8(); + args.statusFlags = packet.readInt16(); + // upper 2 bytes + args.capabilityFlags += packet.readInt16() << 16; + args.authPluginDataLength = packet.readInt8(); + packet.skip(10); + } + //var len = Math.max(12, args.authPluginDataLength - 8); + args.authPluginData2 = packet.readBuffer(12); + return new Handshake(args); +}; + +Handshake.prototype.setScrambleData = function(cb) { + var self = this; + require('crypto').randomBytes(20, function(err, data) { + if (err) return cb(err); + self.authPluginData1 = data.slice(0, 8); + self.authPluginData2 = data.slice(8,20); + cb(); + }); +}; + +Handshake.prototype.toPacket = function(sequenceId) { + var buffer, packet; + var length = 68 + Buffer.byteLength(this.serverVersion, 'utf8'); + buffer = new Buffer(length+4); + packet = new Packet(sequenceId, buffer); + packet.offset = 4; + packet.writeInt8(this.protocolVersion); + packet.writeString(this.serverVersion); + packet.writeInt8(0); + packet.writeInt32(this.connectionId); + packet.writeBuffer(this.authPluginData1); + packet.writeInt8(0); + packet.writeInt16(this.capabilityFlags & 0xffff); + packet.writeInt8(this.characterSet); + packet.writeInt16(this.statusFlags); + packet.writeInt16(this.capabilityFlags >> 16); + packet.writeInt8(21); // authPluginDataLength + var filler = new Buffer(10); + filler.fill(0); + packet.writeBuffer(filler); + packet.writeBuffer(this.authPluginData2); + packet.writeInt8(0); + packet.writeString('mysql_native_password'); + packet.writeInt8(0); + return packet; +}; + +module.exports = Handshake; diff --git a/node_modules/mysql2/lib/packets/handshake_response.js b/node_modules/mysql2/lib/packets/handshake_response.js new file mode 100644 index 0000000..ee7861b --- /dev/null +++ b/node_modules/mysql2/lib/packets/handshake_response.js @@ -0,0 +1,77 @@ +var ClientConstants = require('../constants/client'); +var Charsets = require('../constants/charsets'); +var crypto = require('crypto'); +var Packet = require('../packets/packet'); + +function sha1(msg, msg1, msg2) { + var hash = crypto.createHash('sha1'); + hash.update(msg); + if (msg1) + hash.update(msg1); + if (msg2) + hash.update(msg2); + return hash.digest('binary'); +} + +function xor(a, b) { + if (!Buffer.isBuffer(a)) + a = new Buffer(a, 'binary'); + if (!Buffer.isBuffer(b)) + b = new Buffer(b, 'binary'); + var result = new Buffer(a.length); + for (var i = 0; i < a.length; i++) { + result[i] = (a[i] ^ b[i]); + } + return result; +} + +function token(password, scramble1, scramble2) { + var scramble = Buffer(scramble1.toString('binary') + scramble2.toString('binary')); + if (!password) { + return new Buffer(0); + } + var stage1 = sha1(Buffer(password, "utf8").toString('binary')); + var stage2 = sha1(stage1); + var stage3 = sha1(scramble1, scramble2, stage2); + return xor(stage3, stage1); +} + +function HandshakeResponse(handshake) +{ + this.user = handshake.user || ''; + this.database = handshake.database || ''; + this.password = handshake.password || ''; + this.authPluginData1 = handshake.authPluginData1; + this.authPluginData2 = handshake.authPluginData2; + this.compress = handshake.compress; + this.clientFlags = handshake.flags; + this.authToken = token(this.password, this.authPluginData1, this.authPluginData2); + this.charsetNumber = handshake.charsetNumber; +} + +HandshakeResponse.prototype.toPacket = function() +{ + if (typeof this.user != 'string') + throw new Error('"user" connection config prperty must be a string'); + if (typeof this.database != 'string') + throw new Error('"database" connection config prperty must be a string'); + + var length = 36 + 23 + this.user.length + this.database.length; + + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + buffer.fill(0); + packet.offset = 4; + + packet.writeInt32(this.clientFlags); + packet.writeInt32(0); // max packet size. todo: move to config + packet.writeInt8(this.charsetNumber); + packet.skip(23); + packet.writeNullTerminatedString(this.user); + packet.writeInt8(this.authToken.length); + packet.writeBuffer(this.authToken); + packet.writeNullTerminatedString(this.database); + return packet; +}; + +module.exports = HandshakeResponse; diff --git a/node_modules/mysql2/lib/packets/index.js b/node_modules/mysql2/lib/packets/index.js new file mode 100644 index 0000000..0ccf978 --- /dev/null +++ b/node_modules/mysql2/lib/packets/index.js @@ -0,0 +1,68 @@ +"binlog_dump register_slave ssl_request handshake handshake_response query resultset_header column_definition text_row binary_row prepare_statement prepared_statement_header execute".split(' ').forEach(function(name) { + var ctor = require('./' + name); + module.exports[ctor.name] = ctor; + // monkey-patch it to include name if debug is on + if (process.env.NODE_DEBUG) { + if (ctor.prototype.toPacket) { + var old = ctor.prototype.toPacket; + ctor.prototype.toPacket = function() { + var p = old.call(this); + p._name = ctor.name; + return p; + } + } + } +}); + +// simple packets: +var Packet = require('./packet'); + +module.exports.OK = function OK() { +}; + +module.exports.OK.toPacket = function(args) { + var length = 5 + Packet.lengthCodedNumberLength(args.affectedRows); + if (args.insertId) + length += Packet.lengthCodedNumberLength(args.insertId); + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(0); + packet.writeLengthCodedNumber(args.affectedRows); + if (args.insertId) + packet.writeLengthCodedNumber(args.insertId); + packet._name = "OK"; + return packet; +}; + +// warnings, statusFlags +module.exports.EOF = function EOF() { +}; + +module.exports.EOF.toPacket = function(warnings, statusFlags) { + if (typeof warnings == 'undefined') + warnings = 0; + if (typeof statusFlags == 'undefined') + statusFlags = 0; + var packet = new Packet(0, new Buffer(9)); + packet.offset = 4; + packet.writeInt8(0xfe); + packet.writeInt16(warnings); + packet.writeInt16(statusFlags); + packet._name = "EOF"; + return packet; +}; + +module.exports.Error = function Error() { +}; + +module.exports.Error.toPacket = function(args) { + var packet = new Packet(0, new Buffer(13 + Buffer.byteLength(args.message, 'utf8'))); + packet.offset = 4; + packet.writeInt8(0xff); + packet.writeInt16(args.code); + packet.writeString('#_____'); + packet.writeString(args.message); + packet._name = "Error"; + return packet; +}; diff --git a/node_modules/mysql2/lib/packets/packet.js b/node_modules/mysql2/lib/packets/packet.js new file mode 100644 index 0000000..d53ea56 --- /dev/null +++ b/node_modules/mysql2/lib/packets/packet.js @@ -0,0 +1,606 @@ +//var BigNumber = require("bignumber.js"); +var ErrorCodeToName = require('../constants/errors').codeToName; + +var bn = require('bn.js'); + +function Packet(id, buffer, start, end) +{ + this.sequenceId = id; + this.buffer = buffer; + this.offset = start || 0; + this.start = start || 0; + this.end = end || this.buffer.length; +} + +// ============================== +// readers +// ============================== + +Packet.prototype.reset = function() { + this.offset = this.start; +}; + +Packet.prototype.length = function() { + return this.end - this.start; +}; + +Packet.prototype.slice = function() { + return this.buffer.slice(this.start, this.end); +}; + +Packet.prototype.dump = function() { + console.log([this.buffer.asciiSlice(this.start, this.end)], this.buffer.slice(this.start, this.end), this.length(), this.sequenceId); +}; + +Packet.prototype.haveMoreData = function() { + return this.end > this.offset; +}; + +Packet.prototype.skip = function(num) { + if (!num) + throw "Bad param in skip!"; // for some reason I keep doing skip(0) to indicate "skip one byte which should be 0" + this.offset += num; +}; + +Packet.prototype.readInt8 = function() +{ + return this.buffer[this.offset++]; +}; + +Packet.prototype.readInt16 = function() +{ + this.offset += 2; + return this.buffer.readUInt16LE(this.offset - 2, true); +}; + +Packet.prototype.readInt24 = function() { + return this.readInt16() + (this.readInt8() << 16); +}; + +Packet.prototype.readInt32 = function() +{ + this.offset += 4; + return this.buffer.readUInt32LE(this.offset - 4, true); +}; + +Packet.prototype.readSInt8 = function() +{ + return this.buffer.readInt8(this.offset++, true); +}; + +Packet.prototype.readSInt16 = function() +{ + this.offset += 2; + return this.buffer.readInt16LE(this.offset - 2, true); +}; + +Packet.prototype.readSInt32 = function() +{ + this.offset += 4; + return this.buffer.readInt32LE(this.offset - 4, true); +}; + +Packet.prototype.readInt64 = function() { + return this.readInt32() + 0x100000000*this.readInt32(); +}; + +Packet.prototype.readSInt64 = function() { + var word0 = this.readInt32(); + var word1 = this.readInt32(); + if (!(word1 & 0x80000000)) + return word0 + 0x100000000*word1; + return -((((~word1)>>>0) * 0x100000000) + ((~word0)>>>0) + 1); +}; + +Packet.prototype.isEOF = function() { + return this.buffer[this.offset] == 0xfe && this.length() < 9; +}; + +Packet.prototype.eofStatusFlags = function() { + return this.buffer.readInt16LE(this.offset + 3); +}; + +Packet.prototype.eofWarningCount = function() { + return this.buffer.readInt16LE(this.offset + 1); +}; + +Packet.prototype.readLengthCodedNumber = function(bigNumberStrings) { + var word0, word1; + var res; + var byte1 = this.readInt8(); + if (byte1 < 0xfb) + return byte1; + if (byte1 == 0xfc) { + return this.readInt8() + (this.readInt8() << 8); + } + if (byte1 == 0xfd) { + return this.readInt8() + (this.readInt8() << 8) + (this.readInt8() << 16); + } + if (byte1 == 0xfe) { + // TODO: check version + // Up to MySQL 3.22, 0xfe was followed by a 4-byte integer. + word0 = this.readInt32(); + word1 = this.readInt32(); + if (word1 === 0) + return word0; // don't convert to float if possible + if (word1 < 2097152) // max exact float point int, 2^52 / 2^32 + return word1*0x100000000 + word0; + + res = (new bn(word1)).ishln(32).iaddn(word0); + return bigNumberStrings ? res.toString() : res; + } + if (byte1 == 0xfb) + return null; + + console.trace(); + throw "Should not reach here: " + byte1; +}; + +Packet.prototype.readFloat = function() { + var res = this.buffer.readFloatLE(this.offset); + this.offset += 4; + return res; +}; + +Packet.prototype.readDouble = function() { + var res = this.buffer.readDoubleLE(this.offset); + this.offset += 8; + return res; +}; + +Packet.prototype.readBuffer = function(len) { + if (typeof len == 'undefined') + len = this.end - this.offset; + this.offset += len; + return this.buffer.slice(this.offset - len, this.offset); +}; + +var INVALID_DATE = new Date(NaN); +// DATE, DATETIME and TIMESTAMP +Packet.prototype.readDateTime = function() { + var length = this.readInt8(); + var y = 0; + var m = 0; + var d = 0; + var H = 0; + var M = 0; + var S = 0; + var ms = 0; + if (length > 3) { + y = this.readInt16(); + m = this.readInt8(); + d = this.readInt8(); + + } + if (length > 6) { + H = this.readInt8(); + M = this.readInt8(); + S = this.readInt8(); + } + if (length > 11) + ms = this.readInt32(); + if ((y + m + d + H + M + S + ms) === 0) { + return INVALID_DATE; + } + return new Date(y, m-1, d, H, M, S, ms); +}; + +// this is nearly duplicate of previous function so generated code is not slower +// due to "if (dateStrings)" branching +var pad = "000000000000"; +function leftPad(num, value) { + var s = value.toString(); + // if we don't need to pad + if (s.length >= num) + return s; + return (pad + s).slice(-num); +} + +Packet.prototype.readDateTimeString = function() { + var length = this.readInt8(); + var y = 0; + var m = 0; + var d = 0; + var H = 0; + var M = 0; + var S = 0; + var ms = 0; + var str; + if (length > 3) { + y = this.readInt16(); + m = this.readInt8(); + d = this.readInt8(); + str = [leftPad(4, y), leftPad(2, m), leftPad(2, d)].join('-'); + } + if (length > 6) { + H = this.readInt8(); + M = this.readInt8(); + S = this.readInt8(); + str += ' ' + [leftPad(2, H), leftPad(2, M), leftPad(2, S)].join(':'); + } + /* in text protocol you don't see microseconds as DATETIME/TIMESTAMP result. + instead you need to use MICROSECOND() function + if (length > 11) { + ms = this.readInt32(); + } + */ + return str; +}; + +// TIME - value as a string, Can be negative +Packet.prototype.readTimeString = function(convertTtoMs) { + var length = this.readInt8(); + if (length === 0) + return 0; + + var result = 0; + var sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte + var d = 0; + var H = 0; + var M = 0; + var S = 0; + var ms = 0; + if (length > 7) { + d = this.readInt32(); + H = this.readInt8(); + M = this.readInt8(); + S = this.readInt8(); + } + if (length > 11) + ms = this.readInt32(); + + if (convertTtoMs) { + H += d * 24; + M += H * 60; + S += M * 60; + ms += S * 1000; + ms *= sign; + return ms; + } + return ( sign === -1 ? '-' : '' ) + [( d ? (d*24) + H : H ), leftPad(2, M), leftPad(2, S)].join(':') + ( ms ? '.'+ ms : '' ); +}; + +Packet.prototype.readLengthCodedString = function() { + var len = this.readLengthCodedNumber(); + // TODO: check manually first byte here to avoid polymorphic return type? + if (len === null) + return null; + this.offset += len; + return this.buffer.utf8Slice(this.offset - len, this.offset); +}; + +Packet.prototype.readLengthCodedBuffer = function() { + var len = this.readLengthCodedNumber(); + return this.readBuffer(len); +}; + +Packet.prototype.readNullTerminatedString = function() { + var start = this.offset; + var end = this.offset; + while (this.buffer[end]) + end = end + 1; // TODO: handle OOB check + this.offset = end + 1; + return this.buffer.utf8Slice(start, end); +}; + +// TODO reuse? +Packet.prototype.readString = function(len) { + if (typeof len == 'undefined') + len = this.end - this.offset; + this.offset += len; + return this.buffer.utf8Slice(this.offset - len, this.offset); +}; + +var minus = '-'.charCodeAt(0); +var plus = '+'.charCodeAt(0); +// TODO: faster versions of parseInt for smaller types? +// discard overflow checks if we know from type definition it's safe so +Packet.prototype.parseInt = function(len) { + + if (len === null) + return null; + + var result = 0; + var end = this.offset + len; + var sign = 1; + if (len === 0) + return 0; // TODO: assert? exception? + if (this.buffer[this.offset] == minus) { + this.offset++; + sign = -1; + } + + // max precise int is 9007199254740992 + // note that we are here after handling optional +/- + // treat everything above 9000000000000000 as potential overflow + var str; + var numDigits = end - this.offset; + if (numDigits == 16 && (this.buffer[this.offset] - 48) > 8) { + str = this.readString(end - this.offset); + result = parseInt(str, 10); + if (result.toString() == str) + return sign*result; + else + return sign == -1 ? "-" + str : str; + } else if (numDigits > 16) { + str = this.readString(end - this.offset); + return sign == -1 ? "-" + str : str; + } + + if (this.buffer[this.offset] == plus) { + this.offset++; // just ignore + } + while(this.offset < end) { + result *= 10; + result += this.buffer[this.offset] - 48; + this.offset++; + } + return result*sign; +}; + +// copy-paste from https://github.com/felixge/node-mysql/blob/master/lib/protocol/Parser.js +Packet.prototype.parseGeometryValue = function() { + var buffer = this.readLengthCodedBuffer(); + var offset = 4; + + if (buffer === null || !buffer.length) { + return null; + } + + function parseGeometry() { + var x, y, i, j, numPoints, line; + var result = null; + var byteOrder = buffer.readUInt8(offset); offset += 1; + var wkbType = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + switch(wkbType) { + case 1: // WKBPoint + x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + result = {x: x, y: y}; + break; + case 2: // WKBLineString + numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + result = []; + for(i=numPoints;i>0;i--) { + x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + result.push({x: x, y: y}); + } + break; + case 3: // WKBPolygon + var numRings = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + result = []; + for(i=numRings;i>0;i--) { + numPoints = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + line = []; + for(j=numPoints;j>0;j--) { + x = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + y = byteOrder? buffer.readDoubleLE(offset) : buffer.readDoubleBE(offset); offset += 8; + line.push({x: x, y: y}); + } + result.push(line); + } + break; + case 4: // WKBMultiPoint + case 5: // WKBMultiLineString + case 6: // WKBMultiPolygon + case 7: // WKBGeometryCollection + var num = byteOrder? buffer.readUInt32LE(offset) : buffer.readUInt32BE(offset); offset += 4; + result = []; + for(i=num;i>0;i--) { + result.push(parseGeometry()); + } + break; + } + return result; + } + return parseGeometry(); +}; + +Packet.prototype.parseDate = function() { + var strLen = this.readLengthCodedNumber(); + if (strLen === null) + return null; + if (strLen != 10) { + // we expect only YYYY-MM-DD here. + // if for some reason it's not the case return invalid date + return new Date(NaN); + } + var y = this.parseInt(4); + this.offset++; // - + var m = this.parseInt(2); + this.offset++; // - + var d = this.parseInt(2); + return new Date(y, m-1, d); +}; + +Packet.prototype.parseDateTime = function() { + var str = this.readLengthCodedString(); + if (str === null) + return null; + return new Date(str); +}; + + +// TODO: handle E notation +var dot = '.'.charCodeAt(0); +var exponent = 'e'.charCodeAt(0); +var exponentCapital = 'E'.charCodeAt(0); +Packet.prototype.parseFloat = function(len) { + + if (len === null) + return null; + + var result = 0; + var end = this.offset + len; + var factor = 1; + var pastDot = false; + var charCode = 0; + if (len === 0) + return 0; // TODO: assert? exception? + + if (this.buffer[this.offset] == minus) { + this.offset++; + factor = -1; + } + if (this.buffer[this.offset] == plus) { + this.offset++; // just ignore + } + while(this.offset < end) { + charCode = this.buffer[this.offset]; + if (charCode == dot) + { + pastDot = true; + this.offset++; + } else if (charCode == exponent || charCode == exponentCapital) { + this.offset++; + var exponentValue = this.parseInt(end - this.offset); + return (result/factor)*Math.pow(10, exponentValue); + } else { + result *= 10; + result += this.buffer[this.offset] - 48; + this.offset++; + if (pastDot) + factor = factor*10; + } + } + return result/factor; +}; + +Packet.prototype.parseLengthCodedInt = function() { + return this.parseInt(this.readLengthCodedNumber()); +}; + +Packet.prototype.parseLengthCodedFloat = function() { + return this.parseFloat(this.readLengthCodedNumber()); +}; + +Packet.prototype.isError = function() { + return this.buffer[this.offset] == 0xff; +}; + +Packet.prototype.asError = function() { + this.reset(); + + var fieldCount = this.readInt8(); + var errorCode = this.readInt16(); + var sqlState = ''; + if (this.buffer[this.offset] == 0x23) + sqlState = this.readBuffer(6).toString(); + var message = this.readString(); + var err = new Error(message); + err.code = ErrorCodeToName[errorCode]; + err.sqlState = sqlState; + return err; +}; + + +Packet.lengthCodedNumberLength = function(n) { + if (n < 0xfb) + return 1; + if (n < 0xffff) + return 3; + if (n < 0xffffff) + return 5; + else + return 9; +}; + +Packet.prototype.writeInt32 = function(n) { + this.buffer.writeUInt32LE(n, this.offset); + this.offset += 4; +}; + +Packet.prototype.writeInt24 = function(n) { + this.writeInt8(n & 0xff); + this.writeInt16(n >> 8); +}; + +Packet.prototype.writeInt16 = function(n) { + this.buffer.writeUInt16LE(n, this.offset); + this.offset += 2; +}; + +Packet.prototype.writeInt8 = function(n) { + this.buffer.writeUInt8(n, this.offset); + this.offset++; +}; + +Packet.prototype.writeBuffer = function(b) { + b.copy(this.buffer, this.offset); + this.offset += b.length; +}; + +Packet.prototype.writeNull = function() { + this.buffer[this.offset] = 0xfb; + this.offset++; +}; + +// TODO: refactor following three? +Packet.prototype.writeNullTerminatedString = function(s) { + this.buffer.write(s, this.offset); + this.offset += s.length; + this.writeInt8(0); +}; + +Packet.prototype.writeString = function(s) { + var bytes = Buffer.byteLength(s, 'utf8'); + this.buffer.write(s, this.offset, bytes, 'utf8'); + this.offset += bytes; +}; + +Packet.prototype.writeLengthCodedString = function(s) { + var bytes = Buffer.byteLength(s, 'utf8'); + this.writeLengthCodedNumber(bytes); + this.buffer.write(s, this.offset, bytes, 'utf8'); + this.offset += bytes; +}; + +Packet.prototype.writeLengthCodedBuffer = function(b) { + this.writeLengthCodedNumber(b.length); + b.copy(this.buffer, this.offset); + this.offset += b.length; +}; + +Packet.prototype.writeLengthCodedNumber = function(n) { + // TODO: null - http://dev.mysql.com/doc/internals/en/overview.html#length-encoded-integer + if (n < 0xfb) + return this.writeInt8(n); + if (n < 0xffff) { + this.writeInt8(0xfc); + return this.writeInt16(n); + } + if (n < 0xffffff) { + this.writeInt8(0xfd); + return this.writeInt24(n); + } + console.log(n); + console.trace(); + throw "No bignumbers yet"; +}; + +Packet.prototype.writeHeader = function(sequenceId) +{ + var offset = this.offset; + this.offset = 0; + this.writeInt24(this.buffer.length - 4); + this.writeInt8(sequenceId); + this.offset = offset; +}; + +Packet.prototype.clone = function() { + var buffer = this.buffer.slice(this.start, this.end); + var other = new Packet(this.sequenceId, this.buffer); + return other; +}; + +Packet.prototype.type = function() { + if (this.isEOF()) + return 'EOF'; + if (this.isError()) + return 'Error'; + if (this.buffer[this.offset] == 0) + return 'maybeOK'; // could be other packet types as well + return ''; +}; +module.exports = Packet; diff --git a/node_modules/mysql2/lib/packets/prepare_statement.js b/node_modules/mysql2/lib/packets/prepare_statement.js new file mode 100644 index 0000000..c07aa79 --- /dev/null +++ b/node_modules/mysql2/lib/packets/prepare_statement.js @@ -0,0 +1,20 @@ +var Packet = require('../packets/packet'); +var CommandCodes = require('../constants/commands'); + +function PrepareStatement(sql) +{ + this.query = sql; +} + +PrepareStatement.prototype.toPacket = function() +{ + var length = 5 + Buffer.byteLength(this.query, 'utf8'); + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(CommandCodes.STMT_PREPARE); + packet.writeString(this.query); + return packet; +}; + +module.exports = PrepareStatement; diff --git a/node_modules/mysql2/lib/packets/prepared_statement_header.js b/node_modules/mysql2/lib/packets/prepared_statement_header.js new file mode 100644 index 0000000..de8f047 --- /dev/null +++ b/node_modules/mysql2/lib/packets/prepared_statement_header.js @@ -0,0 +1,15 @@ +var Packet = require('../packets/packet'); + +function PreparedStatementHeader(packet) +{ + packet.skip(1); // should be 0 + this.id = packet.readInt32(); + this.fieldCount = packet.readInt16(); + this.parameterCount = packet.readInt16(); + packet.skip(1); // should be 0 + this.warningCount = packet.readInt16(); +} + +// TODO: toPacket + +module.exports = PreparedStatementHeader; diff --git a/node_modules/mysql2/lib/packets/query.js b/node_modules/mysql2/lib/packets/query.js new file mode 100644 index 0000000..a42a881 --- /dev/null +++ b/node_modules/mysql2/lib/packets/query.js @@ -0,0 +1,20 @@ +var Packet = require('../packets/packet'); +var CommandCode = require('../constants/commands'); + +function Query(sql) +{ + this.query = sql; +} + +Query.prototype.toPacket = function() +{ + var length = 5 + Buffer.byteLength(this.query, 'utf8'); + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(CommandCode.QUERY); + packet.writeString(this.query); + return packet; +}; + +module.exports = Query; diff --git a/node_modules/mysql2/lib/packets/register_slave.js b/node_modules/mysql2/lib/packets/register_slave.js new file mode 100644 index 0000000..808c8a2 --- /dev/null +++ b/node_modules/mysql2/lib/packets/register_slave.js @@ -0,0 +1,41 @@ +// http://dev.mysql.com/doc/internals/en/com-register-slave.html +// note that documentation is incorrect, for example command code is actually 0x15 but documented as 0x14 + +var Packet = require('../packets/packet'); +var CommandCodes = require('../constants/commands'); + +function RegisterSlave(opts) +{ + this.serverId = opts.serverId || 0; + this.slaveHostname = opts.slaveHostname || ''; + this.slaveUser = opts.slaveUser || ''; + this.slavePassword = opts.slavePassword || ''; + this.slavePort = opts.slavePort || 0; + this.replicationRank = opts.replicationRank || 0; + this.masterId = opts.masterId || 0; +} + +RegisterSlave.prototype.toPacket = function() +{ + var length = 15 + // TODO: should be ascii? + Buffer.byteLength(this.slaveHostname, 'utf8') + + Buffer.byteLength(this.slaveUser, 'utf8') + + Buffer.byteLength(this.slavePassword, 'utf8') + 3 + 4; + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeInt8(CommandCodes.REGISTER_SLAVE); + packet.writeInt32(this.serverId); + packet.writeInt8(Buffer.byteLength(this.slaveHostname, 'utf8')); + packet.writeString(this.slaveHostname); + packet.writeInt8(Buffer.byteLength(this.slaveUser, 'utf8')); + packet.writeString(this.slaveUser); + packet.writeInt8(Buffer.byteLength(this.slavePassword, 'utf8')); + packet.writeString(this.slavePassword); + packet.writeInt16(this.slavePort); + packet.writeInt32(this.replicationRank); + packet.writeInt32(this.masterId); + return packet; +}; + +module.exports = RegisterSlave; diff --git a/node_modules/mysql2/lib/packets/resultset_header.js b/node_modules/mysql2/lib/packets/resultset_header.js new file mode 100644 index 0000000..c3b2c75 --- /dev/null +++ b/node_modules/mysql2/lib/packets/resultset_header.js @@ -0,0 +1,40 @@ +// TODO: rename to OK packet + +var Packet = require('../packets/packet'); + +function ResultSetHeader(packet, bigNumberStrings) +{ + if (packet.buffer[packet.offset] !== 0) { + this.fieldCount = packet.readLengthCodedNumber(); + } else { + this.fieldCount = packet.readInt8(); // skip OK byte + this.affectedRows = packet.readLengthCodedNumber(bigNumberStrings); + this.insertId = packet.readLengthCodedNumber(bigNumberStrings); + this.serverStatus = packet.readInt16(); + this.warningStatus = packet.readInt16(); + } + + // snippet from mysql-native: + // res.affected_rows = this.lcnum(); + // res.insert_id = this.lcnum(); + // res.server_status = this.num(2); + // res.warning_count = this.num(2); + + // TODO: extra +} + +// TODO: should be consistent instance member, but it's just easier here to have just function +ResultSetHeader.toPacket = function(fieldCount, insertId, sequenceId) { + var length = 4 + Packet.lengthCodedNumberLength(fieldCount); + if (typeof(insertId) != 'undefined') + length += Packet.lengthCodedNumberLength(insertId); + var buffer = new Buffer(length); + var packet = new Packet(0, buffer); + packet.offset = 4; + packet.writeLengthCodedNumber(fieldCount); + if (typeof(insertId) != 'undefined') + packet.writeLengthCodedNumber(insertId); + return packet; +}; + +module.exports = ResultSetHeader; diff --git a/node_modules/mysql2/lib/packets/ssl_request.js b/node_modules/mysql2/lib/packets/ssl_request.js new file mode 100644 index 0000000..761a0d3 --- /dev/null +++ b/node_modules/mysql2/lib/packets/ssl_request.js @@ -0,0 +1,24 @@ +var ClientConstants = require('../constants/client'); +var Packet = require('../packets/packet'); +var Charsets = require('../constants/charsets'); + +function SSLRequest(flags) +{ + this.clientFlags = flags | ClientConstants.SSL; +} + +SSLRequest.prototype.toPacket = function() +{ + var length = 36; + var buffer = new Buffer(36); + var packet = new Packet(0, buffer); + buffer.fill(0); + packet.offset = 4; + + packet.writeInt32(this.clientFlags); + packet.writeInt32(0); // max packet size. todo: move to config + packet.writeInt8(Charsets.UTF8_GENERAL_CI); + return packet; +}; + +module.exports = SSLRequest; diff --git a/node_modules/mysql2/lib/packets/text_row.js b/node_modules/mysql2/lib/packets/text_row.js new file mode 100644 index 0000000..44e2931 --- /dev/null +++ b/node_modules/mysql2/lib/packets/text_row.js @@ -0,0 +1,38 @@ +var Packet = require('../packets/packet'); + +function TextRow(columns) +{ + this.columns = columns || []; +} + +TextRow.fromPacket = function(packet) { + //packet.reset(); // set offset to starting point? + var columns = []; + while(packet.haveMoreData()) { + columns.push(packet.readLengthCodedString()); + } + return new TextRow(columns); +}; + +TextRow.toPacket = function(column) { + var sequenceId = 0; // TODO remove, this is calculated now in connecton + var buffer, packet; + var length = 0; + column.forEach(function(val) { + if (val === null || typeof(val) == 'undefined') return ++length; + var str = val.toString(10); + length += Packet.lengthCodedNumberLength(str); + length += str.length; + }); + buffer = new Buffer(length+4); + packet = new Packet(sequenceId, buffer); + packet.offset = 4; + column.forEach(function(val) { + if (val === null) return packet.writeNull(); + if (typeof val == 'undefined') return packet.writeInt8(0); + packet.writeLengthCodedString(val.toString(10)); + }); + return packet; +}; + +module.exports = TextRow; diff --git a/node_modules/mysql2/lib/pool.js b/node_modules/mysql2/lib/pool.js new file mode 100644 index 0000000..c99097c --- /dev/null +++ b/node_modules/mysql2/lib/pool.js @@ -0,0 +1,177 @@ +var mysql = require('../index.js'); +var Connection = mysql.Connection; + +var EventEmitter = require('events').EventEmitter; +var Util = require('util'); +var PoolConnection = require('./pool_connection.js'); + +module.exports = Pool; + +Util.inherits(Pool, EventEmitter); +function Pool(options) { + EventEmitter.call(this); + this.config = options.config; + this.config.connectionConfig.pool = this; + + this._allConnections = []; + this._freeConnections = []; + this._connectionQueue = []; + this._closed = false; +} + +Pool.prototype.getConnection = function (cb) { + if (this._closed) { + return process.nextTick(function(){ + return cb(new Error('Pool is closed.')); + }); + } + + var connection; + + if (this._freeConnections.length > 0) { + connection = this._freeConnections.shift(); + + return process.nextTick(function(){ + return cb(null, connection); + }); + } + + if (this.config.connectionLimit === 0 || this._allConnections.length < this.config.connectionLimit) { + connection = new PoolConnection(this, { config: this.config.connectionConfig }); + + this._allConnections.push(connection); + + return connection.connect(function(err) { + if (this._closed) { + return cb(new Error('Pool is closed.')); + } + if (err) { + return cb(err); + } + + this.emit('connection', connection); + return cb(null, connection); + }.bind(this)); + } + + if (!this.config.waitForConnections) { + return process.nextTick(function(){ + return cb(new Error('No connections available.')); + }); + } + + if (this.config.queueLimit && this._connectionQueue.length >= this.config.queueLimit) { + return cb(new Error('Queue limit reached.')); + } + + this._connectionQueue.push(cb); +}; + +Pool.prototype.releaseConnection = function (connection) { + var cb; + + if (!connection._pool) { + // The connection has been removed from the pool and is no longer good. + if (this._connectionQueue.length) { + cb = this._connectionQueue.shift(); + + process.nextTick(this.getConnection.bind(this, cb)); + } + } else if (this._connectionQueue.length) { + cb = this._connectionQueue.shift(); + + process.nextTick(cb.bind(null, null, connection)); + } else { + this._freeConnections.push(connection); + } +}; + +Pool.prototype.end = function (cb) { + this._closed = true; + + if (typeof cb != "function") { + cb = function (err) { + if (err) throw err; + }; + } + + var calledBack = false; + var closedConnections = 0; + var connection; + + var endCB = function(err) { + if (calledBack) { + return; + } + + if (err || ++closedConnections >= this._allConnections.length) { + calledBack = true; + return cb(err); + } + }.bind(this); + + if (this._allConnections.length === 0) { + return endCB(); + } + + for (var i = 0; i < this._allConnections.length; i++) { + connection = this._allConnections[i]; + connection._realEnd(endCB); + } +}; + +Pool.prototype.query = function (sql, values, cb) { + if (typeof values === 'function') { + cb = values; + values = null; + } + + this.getConnection(function (err, conn) { + if (err) return cb(err); + + conn.query(sql, values, function () { + conn.release(); + cb.apply(this, arguments); + }); + }); +}; + +Pool.prototype.execute = function (sql, values, cb) { + if (typeof values === 'function') { + cb = values; + values = null; + } + + this.getConnection(function (err, conn) { + if (err) return cb(err); + + conn.execute(sql, values, function () { + conn.release(); + cb.apply(this, arguments); + }); + }); +}; + +Pool.prototype._removeConnection = function(connection) { + var i; + + for (i = 0; i < this._allConnections.length; i++) { + if (this._allConnections[i] === connection) { + this._allConnections.splice(i, 1); + break; + } + } + + for (i = 0; i < this._freeConnections.length; i++) { + if (this._freeConnections[i] === connection) { + this._freeConnections.splice(i, 1); + break; + } + } + + this.releaseConnection(connection); +}; + +Pool.prototype.escape = function(value) { + return mysql.escape(value, this.config.connectionConfig.stringifyObjects, this.config.connectionConfig.timezone); +}; diff --git a/node_modules/mysql2/lib/pool_cluster.js b/node_modules/mysql2/lib/pool_cluster.js new file mode 100644 index 0000000..169bb7c --- /dev/null +++ b/node_modules/mysql2/lib/pool_cluster.js @@ -0,0 +1,242 @@ +var Pool = require('./pool.js'); +var PoolConfig = require('./pool_config.js'); +var Util = require('util'); +var EventEmitter = require('events').EventEmitter; + +module.exports = PoolCluster; + +/** + * PoolCluster + */ +function PoolCluster(config) { + EventEmitter.call(this); + + config = config || {}; + this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry; + this._removeNodeErrorCount = config.removeNodeErrorCount || 5; + this._defaultSelector = config.defaultSelector || 'RR'; + + this._closed = false; + this._lastId = 0; + this._nodes = {}; + this._serviceableNodeIds = []; + this._namespaces = {}; + this._findCaches = {}; +} + +Util.inherits(PoolCluster, EventEmitter); + +PoolCluster.prototype.of = function(pattern, selector) { + pattern = pattern || '*'; + + selector = selector || this._defaultSelector; + selector = selector.toUpperCase(); + if (typeof Selector[selector] === 'undefined') { + selector = this._defaultSelector; + } + + var key = pattern + selector; + + if (typeof this._namespaces[key] === 'undefined') { + this._namespaces[key] = new PoolNamespace(this, pattern, selector); + } + + return this._namespaces[key]; +}; + +PoolCluster.prototype.add = function(id, config) { + if (typeof id === 'object') { + config = id; + id = 'CLUSTER::' + (++this._lastId); + } + + if (typeof this._nodes[id] === 'undefined') { + this._nodes[id] = { + id: id, + errorCount: 0, + pool: new Pool({config: new PoolConfig(config)}) + }; + + this._serviceableNodeIds.push(id); + + this._clearFindCaches(); + } +}; + +PoolCluster.prototype.getConnection = function(pattern, selector, cb) { + var namespace; + if (typeof pattern === 'function') { + cb = pattern; + namespace = this.of(); + } else { + if (typeof selector === 'function') { + cb = selector; + selector = this._defaultSelector; + } + + namespace = this.of(pattern, selector); + } + + namespace.getConnection(cb); +}; + +PoolCluster.prototype.end = function() { + if (this._closed) { + return; + } + + this._closed = true; + + for (var id in this._nodes) { + this._nodes[id].pool.end(); + } +}; + +PoolCluster.prototype._findNodeIds = function(pattern) { + if (typeof this._findCaches[pattern] !== 'undefined') { + return this._findCaches[pattern]; + } + + var foundNodeIds; + + if (pattern === '*') { // all + foundNodeIds = this._serviceableNodeIds; + } else if (this._serviceableNodeIds.indexOf(pattern) != -1) { // one + foundNodeIds = [pattern]; + } else { // wild matching + var keyword = pattern.substring(pattern.length - 1, 0); + + foundNodeIds = this._serviceableNodeIds.filter(function (id) { + return id.indexOf(keyword) === 0; + }); + } + + this._findCaches[pattern] = foundNodeIds; + + return foundNodeIds; +}; + +PoolCluster.prototype._getNode = function(id) { + return this._nodes[id] || null; +}; + +PoolCluster.prototype._increaseErrorCount = function(node) { + if (++node.errorCount >= this._removeNodeErrorCount) { + var index = this._serviceableNodeIds.indexOf(node.id); + if (index !== -1) { + this._serviceableNodeIds.splice(index, 1); + delete this._nodes[node.id]; + + this._clearFindCaches(); + + node.pool.end(); + + this.emit('remove', node.id); + } + } +}; + +PoolCluster.prototype._decreaseErrorCount = function(node) { + if (node.errorCount > 0) { + --node.errorCount; + } +}; + +PoolCluster.prototype._getConnection = function(node, cb) { + var self = this; + + node.pool.getConnection(function (err, connection) { + if (err) { + self._increaseErrorCount(node); + + if (self._canRetry) { + console.warn('[Error] PoolCluster : ' + err); + return cb(null, 'retry'); + } else { + return cb(err); + } + } else { + self._decreaseErrorCount(node); + } + + connection._clusterId = node.id; + + cb(null, connection); + }); +}; + +PoolCluster.prototype._clearFindCaches = function() { + this._findCaches = {}; +}; + +/** + * PoolNamespace + */ +function PoolNamespace(cluster, pattern, selector) { + this._cluster = cluster; + this._pattern = pattern; + this._selector = new Selector[selector](); +} + +PoolNamespace.prototype.getConnection = function(cb) { + var clusterNode = this._getClusterNode(); + + if (clusterNode === null) { + return cb(new Error('Pool does Not exists.')); + } + + this._cluster._getConnection(clusterNode, function(err, connection) { + if (err) { + return cb(err); + } + + if (connection === 'retry') { + return this.getConnection(cb); + } + + cb(null, connection); + }.bind(this)); +}; + +PoolNamespace.prototype._getClusterNode = function() { + var foundNodeIds = this._cluster._findNodeIds(this._pattern); + + if (foundNodeIds.length === 0) { + return null; + } + + var nodeId = (foundNodeIds.length === 1) ? foundNodeIds[0] : this._selector(foundNodeIds); + + return this._cluster._getNode(nodeId); +}; + +/** + * Selector + */ +var Selector = {}; + +Selector.RR = function () { + var index = 0; + + return function(clusterIds) { + if (index >= clusterIds.length) { + index = 0; + } + + var clusterId = clusterIds[index++]; + + return clusterId; + }; +}; + +Selector.RANDOM = function () { + return function(clusterIds) { + return clusterIds[Math.floor(Math.random() * clusterIds.length)]; + }; +}; + +Selector.ORDER = function () { + return function(clusterIds) { + return clusterIds[0]; + }; +}; diff --git a/node_modules/mysql2/lib/pool_config.js b/node_modules/mysql2/lib/pool_config.js new file mode 100644 index 0000000..c75601e --- /dev/null +++ b/node_modules/mysql2/lib/pool_config.js @@ -0,0 +1,15 @@ +var ConnectionConfig = require('./connection_config.js'); + +module.exports = PoolConfig; +function PoolConfig(options) { + this.connectionConfig = new ConnectionConfig(options); + this.waitForConnections = (options.waitForConnections === undefined) + ? true + : Boolean(options.waitForConnections); + this.connectionLimit = (options.connectionLimit === undefined) + ? 10 + : Number(options.connectionLimit); + this.queueLimit = (options.queueLimit === undefined) + ? 0 + : Number(options.queueLimit); +} diff --git a/node_modules/mysql2/lib/pool_connection.js b/node_modules/mysql2/lib/pool_connection.js new file mode 100644 index 0000000..ccd2a4e --- /dev/null +++ b/node_modules/mysql2/lib/pool_connection.js @@ -0,0 +1,54 @@ +var mysql = require('../index.js'); +var Connection = mysql.Connection; + +var inherits = require('util').inherits; + +module.exports = PoolConnection; +inherits(PoolConnection, Connection); + +function PoolConnection(pool, options) { + Connection.call(this, options); + this._pool = pool; + + // When a fatal error occurs the connection's protocol ends, which will cause + // the connection to end as well, thus we only need to watch for the end event + // and we will be notified of disconnects. + this.on('end', this._removeFromPool); + this.on('error', this._removeFromPool); +} + +PoolConnection.prototype.release = function () { + if (!this._pool || this._pool._closed) { + return; + } + + return this._pool.releaseConnection(this); +}; + +// TODO: Remove this when we are removing PoolConnection#end +PoolConnection.prototype._realEnd = Connection.prototype.end; + +PoolConnection.prototype.end = function () { + console.warn( 'Calling conn.end() to release a pooled connection is ' + + 'deprecated. In next version calling conn.end() will be ' + + 'restored to default conn.end() behavior. Use ' + + 'conn.release() instead.' + ); + this.release(); +}; + +PoolConnection.prototype.destroy = function () { + this._removeFromPool(this); + return Connection.prototype.destroy.apply(this, arguments); +}; + +PoolConnection.prototype._removeFromPool = function(connection) { + if (!this._pool || this._pool._closed) { + return; + } + + var pool = this._pool; + this._pool = null; + + pool._removeConnection(this); +}; diff --git a/node_modules/mysql2/lib/results_stream.js b/node_modules/mysql2/lib/results_stream.js new file mode 100644 index 0000000..5405243 --- /dev/null +++ b/node_modules/mysql2/lib/results_stream.js @@ -0,0 +1,36 @@ +var Readable = require('stream').Readable; + +// copy-paste from https://github.com/felixge/node-mysql/blob/master/lib/protocol/sequences/Query.js +module.exports = function (command, connectionStream) { + command.stream = function(options) { + var self = this, + stream; + + options = options || {}; + options.objectMode = true; + stream = new Readable(options), + + stream._read = function() { + connectionStream.resume(); + }; + + this.on("result",function(row,i) { + if (!stream.push(row)) connectionStream.pause(); + stream.emit("result",row,i); // replicate old emitter + }); + + this.on("error",function(err) { + stream.emit('error',err); // Pass on any errors + }); + + this.on("end", function() { + stream.push(null); // pushing null, indicating EOF + }); + + this.on("fields",function(fields,i) { + stream.emit('fields",fields',i); // replicate old emitter + }); + + return stream; + }; +}; diff --git a/node_modules/mysql2/lib/server.js b/node_modules/mysql2/lib/server.js new file mode 100644 index 0000000..c632920 --- /dev/null +++ b/node_modules/mysql2/lib/server.js @@ -0,0 +1,31 @@ +var net = require('net'); +var util = require('util'); +var EventEmitter = require('events').EventEmitter; + +var PacketParser = require('./packet_parser'); +var Packet = require('./packets/packet'); +var Commands = require('./commands/index.js'); +var Connection = require('./connection'); +var ConnectionConfig = require('./connection_config'); + +// TODO: inherit Server from net.Server +function Server() +{ + EventEmitter.call(this); + this.connections = []; + this._server = net.createServer(this._handleConnection.bind(this)); +} +util.inherits(Server, EventEmitter); + +Server.prototype._handleConnection = function(socket) { + var connectionConfig = new ConnectionConfig({ stream: socket, isServer: true}); + var connection = new Connection({ config: connectionConfig}); + this.emit('connection', connection); + this.connections.push(connection); +}; + +Server.prototype.listen = function(port, host, backlog, callback) { + this._server.listen(port, host, backlog, callback); +}; + +module.exports = Server; diff --git a/node_modules/mysql2/lib/sql_string.js b/node_modules/mysql2/lib/sql_string.js new file mode 100644 index 0000000..b7eb304 --- /dev/null +++ b/node_modules/mysql2/lib/sql_string.js @@ -0,0 +1,145 @@ +var SqlString = exports; + +SqlString.escapeId = function (val, forbidQualified) { + if (forbidQualified) { + return '`' + val.replace(/`/g, '``') + '`'; + } + return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`'; +}; + +SqlString.escape = function(val, stringifyObjects, timeZone) { + if (val === undefined || val === null) { + return 'NULL'; + } + + switch (typeof val) { + case 'boolean': return (val) ? 'true' : 'false'; + case 'number': return val+''; + } + + if (val instanceof Date) { + val = SqlString.dateToString(val, timeZone || "Z"); + } + + if (Buffer.isBuffer(val)) { + return SqlString.bufferToString(val); + } + + if (Array.isArray(val)) { + return SqlString.arrayToList(val, timeZone); + } + + if (typeof val === 'object') { + if (stringifyObjects) { + val = val.toString(); + } else { + return SqlString.objectToValues(val, timeZone); + } + } + + val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) { + switch(s) { + case "\0": return "\\0"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\b": return "\\b"; + case "\t": return "\\t"; + case "\x1a": return "\\Z"; + default: return "\\"+s; + } + }); + return "'"+val+"'"; +}; + +SqlString.arrayToList = function(array, timeZone) { + return array.map(function(v) { + if (Array.isArray(v)) return '(' + SqlString.arrayToList(v) + ')'; + return SqlString.escape(v, true, timeZone); + }).join(', '); +}; + +SqlString.format = function(sql, values, timeZone) { + values = [].concat(values); + + return sql.replace(/\?\??/g, function(match) { + if (!values.length) { + return match; + } + + if (match == "??") { + return SqlString.escapeId(values.shift()); + } + return SqlString.escape(values.shift(), false, timeZone); + }); +}; + +SqlString.dateToString = function(date, timeZone) { + var dt = new Date(date); + + if (timeZone != 'local') { + var tz = convertTimezone(timeZone); + + dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000)); + if (tz !== false) { + dt.setTime(dt.getTime() + (tz * 60000)); + } + } + + var year = dt.getFullYear(); + var month = zeroPad(dt.getMonth() + 1, 2); + var day = zeroPad(dt.getDate(), 2); + var hour = zeroPad(dt.getHours(), 2); + var minute = zeroPad(dt.getMinutes(), 2); + var second = zeroPad(dt.getSeconds(), 2); + var millisecond = zeroPad(dt.getMilliseconds(), 3); + + return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second + '.' + millisecond; +}; + +SqlString.bufferToString = function(buffer) { + var hex = ''; + try { + hex = buffer.toString('hex'); + } catch (err) { + // node v0.4.x does not support hex / throws unknown encoding error + for (var i = 0; i < buffer.length; i++) { + var byte = buffer[i]; + hex += zeroPad(byte.toString(16)); + } + } + + return "X'" + hex+ "'"; +}; + +SqlString.objectToValues = function(object, timeZone) { + var values = []; + for (var key in object) { + var value = object[key]; + if(typeof value === 'function') { + continue; + } + + values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone)); + } + + return values.join(', '); +}; + +function zeroPad(number, length) { + number = number.toString(); + while (number.length < length) { + number = '0' + number; + } + + return number; +} + +function convertTimezone(tz) { + if (tz == "Z") return 0; + + var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/); + if (m) { + return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60; + } + return false; +} diff --git a/node_modules/mysql2/node_modules/.bin/cdl b/node_modules/mysql2/node_modules/.bin/cdl new file mode 120000 index 0000000..00a4369 --- /dev/null +++ b/node_modules/mysql2/node_modules/.bin/cdl @@ -0,0 +1 @@ +../cardinal/bin/cdl.js \ No newline at end of file diff --git a/node_modules/mysql2/node_modules/bn.js/.npmignore b/node_modules/mysql2/node_modules/bn.js/.npmignore new file mode 100644 index 0000000..bfd1047 --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/.npmignore @@ -0,0 +1,3 @@ +benchmarks/ +node_modules/ +npm-debug.log diff --git a/node_modules/mysql2/node_modules/bn.js/.travis.yml b/node_modules/mysql2/node_modules/bn.js/.travis.yml new file mode 100644 index 0000000..92a990f --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/.travis.yml @@ -0,0 +1,7 @@ +language: node_js +node_js: + - "0.10" + - "0.11" +branches: + only: + - master diff --git a/node_modules/mysql2/node_modules/bn.js/1.js b/node_modules/mysql2/node_modules/bn.js/1.js new file mode 100644 index 0000000..a9eac63 --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/1.js @@ -0,0 +1,17 @@ +var bn = require('./'); + +var p = new bn('ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', 16); +var a = new bn('79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798', 16); + +var c = a.sqr(); +var m = bn.red('p25519'); +var am = a.toRed(m); + +var t = 0; +console.log(a.sqr()); +console.time('montSqr'); +for (var i = 0; i < 1000000; i++) { + t += am.redSqr().length; +} +console.timeEnd('montSqr'); +console.log(t); diff --git a/node_modules/mysql2/node_modules/bn.js/README.md b/node_modules/mysql2/node_modules/bn.js/README.md new file mode 100644 index 0000000..ec953e7 --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/README.md @@ -0,0 +1,28 @@ +# bn.js [![Build Status](https://secure.travis-ci.org/indutny/bn.js.png)](http://travis-ci.org/indutny/bn.js) + +Just a bike-shed. + +#### LICENSE + +This software is licensed under the MIT License. + +Copyright Fedor Indutny, 2014. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mysql2/node_modules/bn.js/lib/bn.js b/node_modules/mysql2/node_modules/bn.js/lib/bn.js new file mode 100644 index 0000000..05d14f9 --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/lib/bn.js @@ -0,0 +1,1716 @@ +// Utils + +function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +} + +function assertEqual(l, r, msg) { + if (l != r) + throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); +} + +// Could use `inherits` module, but don't want to move from single file +// architecture yet. +function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor +} + +// BN + +function BN(number, base) { + // May be `new BN(bn)` ? + if (number !== null && + typeof number === 'object' && + Array.isArray(number.words)) { + return number; + } + + this.sign = false; + this.words = null; + this.length = 0; + + // Reduction context + this.red = null; + + if (number !== null) + this._init(number || 0, base || 10); +} +module.exports = BN; + +BN.BN = BN; +BN.wordSize = 26; + +BN.prototype._init = function init(number, base) { + if (typeof number === 'number') { + if (number < 0) { + this.sign = true; + number = -number; + } + this.words = [ number & 0x3ffffff ]; + this.length = 1; + return; + } else if (typeof number === 'object') { + // Perhaps a Uint8Array + assert(typeof number.length === 'number'); + this.length = Math.ceil(number.length / 3); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; + + // Assume big-endian + var off = 0; + for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { + var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + + return this.strip(); + } + if (base === 'hex') + base = 16; + assert(base <= 16); + + number = number.toString().replace(/\s+/g, ''); + var start = 0; + if (number[0] === '-') + start++; + + if (base === 16) + this._parseHex(number, start); + else + this._parseBase(number, base, start); + + if (number[0] === '-') + this.sign = true; + + this.strip(); +}; + +BN.prototype._parseHex = function parseHex(number, start) { + // Create possibly bigger array to ensure that it fits the number + this.length = Math.ceil((number.length - start) / 6); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; + + // Scan 24-bit chunks and add them to the number + var off = 0; + for (var i = number.length - 6, j = 0; i >= start; i -= 6) { + var w = parseInt(number.slice(i, i + 6), 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + if (i + 6 !== start) { + var w = parseInt(number.slice(start, i + 6), 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + } + this.strip(); +}; + +BN.prototype._parseBase = function parseBase(number, base, start) { + // Initialize as zero + this.words = [ 0 ]; + this.length = 1; + + var word = 0; + var q = 1; + var p = 0; + var bigQ = null; + for (var i = start; i < number.length; i++) { + var digit; + var ch = number[i]; + if (base === 10 || ch <= '9') + digit = ch | 0; + else if (ch >= 'a') + digit = ch.charCodeAt(0) - 97 + 10; + else + digit = ch.charCodeAt(0) - 65 + 10; + word *= base; + word += digit; + q *= base; + p++; + + if (q > 0xfffff) { + assert(q <= 0x3ffffff); + if (!bigQ) + bigQ = new BN(q); + this.mul(bigQ).copy(this); + this.iadd(new BN(word)); + word = 0; + q = 1; + p = 0; + } + } + if (p !== 0) { + this.mul(new BN(q)).copy(this); + this.iadd(new BN(word)); + } +}; + +BN.prototype.copy = function copy(dest) { + dest.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + dest.words[i] = this.words[i]; + dest.length = this.length; + dest.sign = this.sign; + dest.red = this.red; +}; + +BN.prototype.clone = function clone() { + var r = new BN(null); + this.copy(r); + return r; +}; + +// Remove leading `0` from `this` +BN.prototype.strip = function strip() { + while (this.length > 1 && this.words[this.length - 1] === 0) + this.length--; + return this._normSign(); +}; + +BN.prototype._normSign = function _normSign() { + // -0 = 0 + if (this.length === 1 && this.words[0] === 0) + this.sign = false; + return this; +}; + +BN.prototype.inspect = function inspect() { + return (this.red ? ''; +}; + +/* +function _zero(n) { + var code = ''; + for (var i = n - 1; i > 0; i--) { + var pad = ''; + for (var j = 0; j < n - i; j++) + pad += '0'; + code += 'if (w.length === ' + i + ') return \'' + pad + '\' + w;\n'; + } + code += 'return w'; + + return new Function('w', code); +} + +var zero6 = _zero(6); +var zero14 = _zero(14); +*/ + +// Sadly chrome apps could not contain `new Function()` calls +function zero6(w) { + if (w.length === 5) return '0' + w; + if (w.length === 4) return '00' + w; + if (w.length === 3) return '000' + w; + if (w.length === 2) return '0000' + w; + if (w.length === 1) return '00000' + w; + return w; +} + +function zero14(w) { + if (w.length === 13) return '0' + w; + if (w.length === 12) return '00' + w; + if (w.length === 11) return '000' + w; + if (w.length === 10) return '0000' + w; + if (w.length === 9) return '00000' + w; + if (w.length === 8) return '000000' + w; + if (w.length === 7) return '0000000' + w; + if (w.length === 6) return '00000000' + w; + if (w.length === 5) return '000000000' + w; + if (w.length === 4) return '0000000000' + w; + if (w.length === 3) return '00000000000' + w; + if (w.length === 2) return '000000000000' + w; + if (w.length === 1) return '0000000000000' + w; + return w; +} + +// Precomputed divisor for `.toString(10)` = 10 ^ 14 +var div10 = new BN(null); +div10.words = [ 0x7a4000, 0x16bcc4 ]; +div10.length = 2; + +BN.prototype.toString = function toString(base) { + base = base || 10; + if (base === 16 || base === 'hex') { + var out = ''; + var off = 0; + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i]; + var word = (((w << off) | carry) & 0xffffff).toString(16); + carry = (w >>> (24 - off)) & 0xffffff; + if (carry !== 0 || i !== this.length - 1) + out = zero6(word) + out; + else + out = word + out; + off += 2; + if (off >= 26) { + off -= 26; + i--; + } + } + if (carry !== 0) + out = carry.toString(16) + out; + if (this.sign) + out = '-' + out; + return out; + } else if (base === 10) { + var out = ''; + var c = this.clone(); + c.sign = false; + while (c.cmpn(0) !== 0) { + var r = c.modn(1000000); + c = c.idivn(1000000); + + if (c.cmpn(0) !== 0) + out = zero6(r + '') + out; + else + out = r + out; + } + if (this.cmpn(0) === 0) + out = '0' + out; + if (this.sign) + out = '-' + out; + return out; + } else { + assert(false, 'Only 16 and 10 base are supported'); + } +}; + +BN.prototype.toJSON = function toJSON() { + return this.toString(16); +}; + +BN.prototype.toArray = function toArray() { + this.strip(); + var res = new Array(this.byteLength()); + res[0] = 0; + + var q = this.clone(); + for (var i = 0; q.cmpn(0) !== 0; i++) { + var b = q.andln(0xff); + q.ishrn(8); + + // Assume big-endian + res[res.length - i - 1] = b; + } + + return res; +}; + +/* +function genCountBits(bits) { + var arr = []; + + for (var i = bits - 1; i >= 0; i--) { + var bit = '0x' + (1 << i).toString(16); + arr.push('w >= ' + bit + ' ? ' + (i + 1)); + } + + return new Function('w', 'return ' + arr.join(' :\n') + ' :\n0;'); +}; + +BN.prototype._countBits = genCountBits(26); +*/ + +// Sadly chrome apps could not contain `new Function()` calls +BN.prototype._countBits = function _countBits(w) { + return w >= 0x2000000 ? 26 : + w >= 0x1000000 ? 25 : + w >= 0x800000 ? 24 : + w >= 0x400000 ? 23 : + w >= 0x200000 ? 22 : + w >= 0x100000 ? 21 : + w >= 0x80000 ? 20 : + w >= 0x40000 ? 19 : + w >= 0x20000 ? 18 : + w >= 0x10000 ? 17 : + w >= 0x8000 ? 16 : + w >= 0x4000 ? 15 : + w >= 0x2000 ? 14 : + w >= 0x1000 ? 13 : + w >= 0x800 ? 12 : + w >= 0x400 ? 11 : + w >= 0x200 ? 10 : + w >= 0x100 ? 9 : + w >= 0x80 ? 8 : + w >= 0x40 ? 7 : + w >= 0x20 ? 6 : + w >= 0x10 ? 5 : + w >= 0x8 ? 4 : + w >= 0x4 ? 3 : + w >= 0x2 ? 2 : + w >= 0x1 ? 1 : + 0; +}; + +// Return number of used bits in a BN +BN.prototype.bitLength = function bitLength() { + var hi = 0; + var w = this.words[this.length - 1]; + var hi = this._countBits(w); + return (this.length - 1) * 26 + hi; +}; + +BN.prototype.byteLength = function byteLength() { + var hi = 0; + var w = this.words[this.length - 1]; + return Math.ceil(this.bitLength() / 8); +}; + +// Return negative clone of `this` +BN.prototype.neg = function neg() { + if (this.cmpn(0) === 0) + return this.clone(); + + var r = this.clone(); + r.sign = !this.sign; + return r; +}; + +// Add `num` to `this` in-place +BN.prototype.iadd = function iadd(num) { + // negative + positive + if (this.sign && !num.sign) { + this.sign = false; + var r = this.isub(num); + this.sign = !this.sign; + return this._normSign(); + + // positive + negative + } else if (!this.sign && num.sign) { + num.sign = false; + var r = this.isub(num); + num.sign = true; + return r._normSign(); + } + + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } + + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] + b.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + + this.length = a.length; + if (carry !== 0) { + this.words[this.length] = carry; + this.length++; + // Copy the rest of the words + } else if (a !== this) { + for (; i < a.length; i++) + this.words[i] = a.words[i]; + } + + return this; +}; + +// Add `num` to `this` +BN.prototype.add = function add(num) { + if (num.sign && !this.sign) { + num.sign = false; + var res = this.sub(num); + num.sign = true; + return res; + } else if (!num.sign && this.sign) { + this.sign = false; + var res = num.sub(this); + this.sign = true; + return res; + } + + if (this.length > num.length) + return this.clone().iadd(num); + else + return num.clone().iadd(this); +}; + +// Subtract `num` from `this` in-place +BN.prototype.isub = function isub(num) { + // this - (-num) = this + num + if (num.sign) { + num.sign = false; + var r = this.iadd(num); + num.sign = true; + return r._normSign(); + + // -this - num = -(this + num) + } else if (this.sign) { + this.sign = false; + this.iadd(num); + this.sign = true; + return this._normSign(); + } + + // At this point both numbers are positive + var cmp = this.cmp(num); + + // Optimization - zeroify + if (cmp === 0) { + this.sign = false; + this.length = 1; + this.words[0] = 0; + return this; + } + + // a > b + if (cmp > 0) { + var a = this; + var b = num; + } else { + var a = num; + var b = this; + } + + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] - b.words[i] - carry; + if (r < 0) { + r += 0x4000000; + carry = 1; + } else { + carry = 0; + } + this.words[i] = r; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] - carry; + if (r < 0) { + r += 0x4000000; + carry = 1; + } else { + carry = 0; + } + this.words[i] = r; + } + + // Copy rest of the words + if (carry === 0 && i < a.length && a !== this) + for (; i < a.length; i++) + this.words[i] = a.words[i]; + this.length = Math.max(this.length, i); + + if (a !== this) + this.sign = true; + + return this.strip(); +}; + +// Subtract `num` from `this` +BN.prototype.sub = function sub(num) { + return this.clone().isub(num); +}; + +/* +// NOTE: This could be potentionally used to generate loop-less multiplications +function _genCombMulTo(alen, blen) { + var len = alen + blen - 1; + var src = [ + 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + + 'mask = 0x3ffffff, shift = 0x4000000;', + 'out.length = ' + len + ';' + ]; + for (var k = 0; k < len; k++) { + var minJ = Math.max(0, k - alen + 1); + var maxJ = Math.min(k, blen - 1); + + for (var j = minJ; j <= maxJ; j++) { + var i = k - j; + var mul = 'a[' + i + '] * b[' + j + ']'; + + if (j === minJ) { + src.push('w = ' + mul + ' + c;'); + src.push('c = (w / shift) | 0;'); + } else { + src.push('w += ' + mul + ';'); + src.push('c += (w / shift) | 0;'); + } + src.push('w &= mask;'); + } + src.push('o[' + k + '] = w;'); + } + src.push('if (c !== 0) {', + ' o[' + k + '] = c;', + ' out.length++;', + '}', + 'return out;'); + + return src.join('\n'); +} +*/ + +// Multiply `this` by `num` and store data in out +BN.prototype.mulTo = function mulTo(num, out) { + out.sign = num.sign !== this.sign; + out.length = this.length + num.length; + + var carry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = carry >>> 26; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i]; + var b = num.words[j]; + var r = a * b; + + var lo = r & 0x3ffffff; + ncarry += (r / 0x4000000) | 0; + lo += rword; + rword = lo & 0x3ffffff; + ncarry += lo >>> 26; + } + out.words[k] = rword; + carry = ncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } + + return out.strip(); +}; + +// Multiply `this` by `num` +BN.prototype.mul = function mul(num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return this.mulTo(num, out); +}; + +// In-place Multiplication +BN.prototype.imul = function imul(num) { + if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { + this.words[0] = 0; + this.length = 1; + return this; + } + + var tlen = this.length; + var nlen = num.length; + + this.sign = num.sign !== this.sign; + this.length = this.length + num.length; + this.words[this.length - 1] = 0; + + var lastCarry = 0; + for (var k = this.length - 2; k >= 0; k--) { + // Sum all words with the same `i + j = k` and accumulate `carry`, + // note that carry could be >= 0x3ffffff + var carry = 0; + var rword = 0; + var maxJ = Math.min(k, nlen - 1); + for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i]; + var b = num.words[j]; + var r = a * b; + + var lo = r & 0x3ffffff; + carry += (r / 0x4000000) | 0; + lo += rword; + rword = lo & 0x3ffffff; + carry += lo >>> 26; + } + this.words[k] = rword; + this.words[k + 1] += carry; + carry = 0; + } + + // Propagate overflows + var carry = 0; + for (var i = 1; i < this.length; i++) { + var w = this.words[i] + carry; + this.words[i] = w & 0x3ffffff; + carry = w >>> 26; + } + + return this.strip(); +}; + +// `this` * `this` +BN.prototype.sqr = function sqr() { + return this.mul(this); +}; + +// `this` * `this` in-place +BN.prototype.isqr = function isqr() { + return this.mul(this); +}; + +// Shift-left in-place +BN.prototype.ishln = function ishln(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); + + var o = this.clone(); + if (r !== 0) { + var carry = 0; + for (var i = 0; i < this.length; i++) { + var newCarry = this.words[i] & carryMask; + var c = (this.words[i] - newCarry) << r; + this.words[i] = c | carry; + carry = newCarry >>> (26 - r); + } + if (carry) { + this.words[i] = carry; + this.length++; + } + } + + if (s !== 0) { + for (var i = this.length - 1; i >= 0; i--) + this.words[i + s] = this.words[i]; + for (var i = 0; i < s; i++) + this.words[i] = 0; + this.length += s; + } + + return this.strip(); +}; + +// Shift-right in-place +// NOTE: `hint` is a lowest bit before trailing zeroes +// NOTE: if `extended` is true - { lo: ..., hi: } object will be returned +BN.prototype.ishrn = function ishrn(bits, hint, extended) { + assert(typeof bits === 'number' && bits >= 0); + if (hint) + hint = (hint - (hint % 26)) / 26; + else + hint = 0; + + var r = bits % 26; + var s = Math.min((bits - r) / 26, this.length); + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + var maskedWords = extended; + + hint -= s; + hint = Math.max(0, hint); + + // Extended mode, copy masked part + if (maskedWords) { + for (var i = 0; i < s; i++) + maskedWords.words[i] = this.words[i]; + maskedWords.length = s; + } + + if (s === 0) { + // No-op, we should not move anything at all + } else if (this.length > s) { + this.length -= s; + for (var i = 0; i < this.length; i++) + this.words[i] = this.words[i + s]; + } else { + this.words[0] = 0; + this.length = 1; + } + + var carry = 0; + for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= hint); i--) { + var word = this.words[i]; + this.words[i] = (carry << (26 - r)) | (word >>> r); + carry = word & mask; + } + + // Push carried bits as a mask + if (maskedWords && carry !== 0) + maskedWords.words[maskedWords.length++] = carry; + + if (this.length === 0) { + this.words[0] = 0; + this.length = 1; + } + + this.strip(); + if (extended) + return { hi: this, lo: maskedWords }; + + return this; +}; + +// Shift-left +BN.prototype.shln = function shln(bits) { + return this.clone().ishln(bits); +}; + +// Shift-right +BN.prototype.shrn = function shrn(bits) { + return this.clone().ishrn(bits); +}; + +// Return only lowers bits of number (in-place) +BN.prototype.imaskn = function imaskn(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + + assert(!this.sign, 'imaskn works only with positive numbers'); + + if (r !== 0) + s++; + this.length = Math.min(s, this.length); + + if (r !== 0) { + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + this.words[this.length - 1] &= mask; + } + + return this.strip(); +}; + +// Return only lowers bits of number +BN.prototype.maskn = function maskn(bits) { + return this.clone().imaskn(bits); +}; + +// Add plain number `num` to `this` +BN.prototype.iaddn = function iaddn(num) { + assert(typeof num === 'number'); + if (num < 0) + return this.isubn(num); + this.words[0] += num; + + // Carry + for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { + this.words[i] -= 0x4000000; + if (i === this.length - 1) + this.words[i + 1] = 1; + else + this.words[i + 1]++; + } + this.length = Math.max(this.length, i + 1); + + return this; +}; + +// Subtract plain number `num` from `this` +BN.prototype.isubn = function isubn(num) { + assert(typeof num === 'number'); + assert(this.cmpn(num) >= 0, 'Sign change is not supported in isubn'); + if (num < 0) + return this.iaddn(-num); + this.words[0] -= num; + + // Carry + for (var i = 0; i < this.length && this.words[i] < 0; i++) { + this.words[i] += 0x4000000; + this.words[i + 1] -= 1; + } + + return this.strip(); +}; + +BN.prototype.addn = function addn(num) { + return this.clone().iaddn(num); +}; + +BN.prototype.subn = function subn(num) { + return this.clone().isubn(num); +}; + +BN.prototype._wordDiv = function _wordDiv(num, mode) { + var shift = this.length - num.length; + + var a = this.clone(); + var b = num; + + var q = mode !== 'mod' && new BN(0); + var sign = false; + + // Approximate quotient at each step + while (a.length > b.length) { + // NOTE: a.length is always >= 2, because of the condition .div() + var hi = a.words[a.length - 1] * 0x4000000 + a.words[a.length - 2]; + var sq = (hi / b.words[b.length - 1]); + var sqhi = (sq / 0x4000000) | 0; + var sqlo = sq & 0x3ffffff; + sq = new BN(null); + sq.words = [ sqlo, sqhi ]; + sq.length = 2; + + // Collect quotient + var shift = (a.length - b.length - 1) * 26; + if (q) { + var t = sq.shln(shift); + if (a.sign) + q.isub(t); + else + q.iadd(t); + } + + sq = sq.mul(b).ishln(shift); + if (a.sign) + a.iadd(sq) + else + a.isub(sq); + } + // At this point a.length <= b.length + while (a.ucmp(b) >= 0) { + // NOTE: a.length is always >= 2, because of the condition above + var hi = a.words[a.length - 1]; + var sq = new BN((hi / b.words[b.length - 1]) | 0); + var shift = (a.length - b.length) * 26; + + if (q) { + var t = sq.shln(shift); + if (a.sign) + q.isub(t); + else + q.iadd(t); + } + + sq = sq.mul(b).ishln(shift); + + if (a.sign) + a.iadd(sq); + else + a.isub(sq); + } + + if (a.sign) { + if (q) + q.isubn(1); + a.iadd(b); + } + return { div: q ? q : null, mod: a }; +}; + +BN.prototype.divmod = function divmod(num, mode) { + assert(num.cmpn(0) !== 0); + + if (this.sign && !num.sign) { + var res = this.neg().divmod(num, mode); + var div; + var mod; + if (mode !== 'mod') + div = res.div.neg(); + if (mode !== 'div') + mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); + return { + div: div, + mod: mod + }; + } else if (!this.sign && num.sign) { + var res = this.divmod(num.neg(), mode); + var div; + if (mode !== 'mod') + div = res.div.neg(); + return { div: div, mod: res.mod }; + } else if (this.sign && num.sign) { + return this.neg().divmod(num.neg(), mode); + } + + // Both numbers are positive at this point + + // Strip both numbers to approximate shift value + if (num.length > this.length || this.cmp(num) < 0) + return { div: new BN(0), mod: this }; + + // Very short reduction + if (num.length === 1) { + if (mode === 'div') + return { div: this.divn(num.words[0]), mod: null }; + else if (mode === 'mod') + return { div: null, mod: new BN(this.modn(num.words[0])) }; + return { + div: this.divn(num.words[0]), + mod: new BN(this.modn(num.words[0])) + }; + } + + return this._wordDiv(num, mode); +}; + +// Find `this` / `num` +BN.prototype.div = function div(num) { + return this.divmod(num, 'div').div; +}; + +// Find `this` % `num` +BN.prototype.mod = function mod(num) { + return this.divmod(num, 'mod').mod; +}; + +// Find Round(`this` / `num`) +BN.prototype.divRound = function divRound(num) { + var dm = this.divmod(num); + + // Fast case - exact division + if (dm.mod.cmpn(0) === 0) + return dm.div; + + var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; + + var half = num.shrn(1); + var r2 = num.andln(1); + var cmp = mod.cmp(half); + + // Round down + if (cmp < 0 || r2 === 1 && cmp === 0) + return dm.div; + + // Round up + return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1); +}; + +BN.prototype.modn = function modn(num) { + assert(num <= 0x3ffffff); + var p = (1 << 26) % num; + + var acc = 0; + for (var i = this.length - 1; i >= 0; i--) + acc = (p * acc + this.words[i]) % num; + + return acc; +}; + +// In-place division by number +BN.prototype.idivn = function idivn(num) { + assert(num <= 0x3ffffff); + + var carry = 0; + for (var i = this.length - 1; i >= 0; i--) { + var w = this.words[i] + carry * 0x4000000; + this.words[i] = (w / num) | 0; + carry = w % num; + } + + return this.strip(); +}; + +BN.prototype.divn = function divn(num) { + return this.clone().idivn(num); +}; + +BN.prototype._egcd = function _egcd(x1, p) { + assert(!p.sign); + assert(p.cmpn(0) !== 0); + + var a = this; + var b = p.clone(); + + if (a.sign) + a = a.mod(p); + else + a = a.clone(); + + var x2 = new BN(0); + while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { + while (a.isEven()) { + a.ishrn(1); + if (x1.isEven()) + x1.ishrn(1); + else + x1.iadd(p).ishrn(1); + } + while (b.isEven()) { + b.ishrn(1); + if (x2.isEven()) + x2.ishrn(1); + else + x2.iadd(p).ishrn(1); + } + if (a.cmp(b) >= 0) { + a.isub(b); + x1.isub(x2); + } else { + b.isub(a); + x2.isub(x1); + } + } + if (a.cmpn(1) === 0) + return x1; + else + return x2; +}; + +// Invert number in the field F(num) +BN.prototype.invm = function invm(num) { + return this._egcd(new BN(1), num).mod(num); +}; + +BN.prototype.isEven = function isEven(num) { + return (this.words[0] & 1) === 0; +}; + +BN.prototype.isOdd = function isOdd(num) { + return (this.words[0] & 1) === 1; +}; + +// And first word and num +BN.prototype.andln = function andln(num) { + return this.words[0] & num; +}; + +// Increment at the bit position in-line +BN.prototype.bincn = function bincn(bit) { + assert(typeof bit === 'number'); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; + + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + for (var i = this.length; i < s + 1; i++) + this.words[i] = 0; + this.words[s] |= q; + this.length = s + 1; + return this; + } + + // Add bit and propagate, if needed + var carry = q; + for (var i = s; carry !== 0 && i < this.length; i++) { + var w = this.words[i]; + w += carry; + carry = w >>> 26; + w &= 0x3ffffff; + this.words[i] = w; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + return this; +}; + +BN.prototype.cmpn = function cmpn(num) { + var sign = num < 0; + if (sign) + num = -num; + + if (this.sign && !sign) + return -1; + else if (!this.sign && sign) + return 1; + + num &= 0x3ffffff; + this.strip(); + + var res; + if (this.length > 1) { + res = 1; + } else { + var w = this.words[0]; + res = w === num ? 0 : w < num ? -1 : 1; + } + if (this.sign) + res = -res; + return res; +}; + +// Compare two numbers and return: +// 1 - if `this` > `num` +// 0 - if `this` == `num` +// -1 - if `this` < `num` +BN.prototype.cmp = function cmp(num) { + if (this.sign && !num.sign) + return -1; + else if (!this.sign && num.sign) + return 1; + + var res = this.ucmp(num); + if (this.sign) + return -res; + else + return res; +}; + +// Unsigned comparison +BN.prototype.ucmp = function ucmp(num) { + // At this point both numbers have the same sign + if (this.length > num.length) + return 1; + else if (this.length < num.length) + return -1; + + var res = 0; + for (var i = this.length - 1; i >= 0; i--) { + var a = this.words[i]; + var b = num.words[i]; + + if (a === b) + continue; + if (a < b) + res = -1; + else if (a > b) + res = 1; + break; + } + return res; +}; + +// +// A reduce context, could be using montgomery or something better, depending +// on the `m` itself. +// +BN.red = function red(num) { + return new Red(num); +}; + +BN.prototype.toRed = function toRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + assert(!this.sign, 'red works only with positives'); + return ctx.convertTo(this)._forceRed(ctx); +}; + +BN.prototype.fromRed = function fromRed() { + assert(this.red, 'fromRed works only with numbers in reduction context'); + return this.red.convertFrom(this); +}; + +BN.prototype._forceRed = function _forceRed(ctx) { + this.red = ctx; + return this; +}; + +BN.prototype.forceRed = function forceRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + return this._forceRed(ctx); +}; + +BN.prototype.redAdd = function redAdd(num) { + assert(this.red, 'redAdd works only with red numbers'); + return this.red.add(this, num); +}; + +BN.prototype.redIAdd = function redIAdd(num) { + assert(this.red, 'redIAdd works only with red numbers'); + return this.red.iadd(this, num); +}; + +BN.prototype.redSub = function redSub(num) { + assert(this.red, 'redSub works only with red numbers'); + return this.red.sub(this, num); +}; + +BN.prototype.redISub = function redISub(num) { + assert(this.red, 'redISub works only with red numbers'); + return this.red.isub(this, num); +}; + +BN.prototype.redShl = function redShl(num) { + assert(this.red, 'redShl works only with red numbers'); + return this.red.shl(this, num); +}; + +BN.prototype.redMul = function redMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.mul(this, num); +}; + +BN.prototype.redIMul = function redIMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.imul(this, num); +}; + +BN.prototype.redSqr = function redSqr() { + assert(this.red, 'redSqr works only with red numbers'); + this.red._verify1(this); + return this.red.sqr(this); +}; + +BN.prototype.redISqr = function redISqr() { + assert(this.red, 'redISqr works only with red numbers'); + this.red._verify1(this); + return this.red.isqr(this); +}; + +// Square root over p +BN.prototype.redSqrt = function redSqrt() { + assert(this.red, 'redSqrt works only with red numbers'); + this.red._verify1(this); + return this.red.sqrt(this); +}; + +BN.prototype.redInvm = function redInvm() { + assert(this.red, 'redInvm works only with red numbers'); + this.red._verify1(this); + return this.red.invm(this); +}; + +// Return negative clone of `this` % `red modulo` +BN.prototype.redNeg = function redNeg() { + assert(this.red, 'redNeg works only with red numbers'); + this.red._verify1(this); + return this.red.neg(this); +}; + +BN.prototype.redPow = function redPow(num) { + assert(this.red && !num.red, 'redPow(normalNum)'); + this.red._verify1(this); + return this.red.pow(this, num); +}; + +// Prime numbers with efficient reduction +var primes = { + k256: null, + p224: null, + p192: null, + p25519: null +}; + +// Pseudo-Mersenne prime +function MPrime(name, p) { + // P = 2 ^ N - K + this.name = name; + this.p = new BN(p, 16); + this.n = this.p.bitLength(); + this.k = new BN(1).ishln(this.n).isub(this.p); + + this.tmp = this._tmp(); +} + +MPrime.prototype._tmp = function _tmp() { + var tmp = new BN(null); + tmp.words = new Array(Math.ceil(this.n / 13)); + return tmp; +}; + +MPrime.prototype.ireduce = function ireduce(num) { + // Assumes that `num` is less than `P^2` + // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) + var r = num; + var rlen; + + do { + var pair = r.ishrn(this.n, 0, this.tmp); + r = this.imulK(pair.hi); + r = r.iadd(pair.lo); + rlen = r.bitLength(); + } while (rlen > this.n); + + var cmp = rlen < this.n ? -1 : r.cmp(this.p); + if (cmp === 0) { + r.words[0] = 0; + r.length = 1; + } else if (cmp > 0) { + r.isub(this.p); + } else { + r.strip(); + } + + return r; +}; + +MPrime.prototype.imulK = function imulK(num) { + return num.imul(this.k); +}; + +function K256() { + MPrime.call( + this, + 'k256', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); +} +inherits(K256, MPrime); + +K256.prototype.imulK = function imulK(num) { + // K = 0x1000003d1 = [ 0x40, 0x3d1 ] + num.words[num.length] = 0; + num.words[num.length + 1] = 0; + num.length += 2; + for (var i = num.length - 3; i >= 0; i--) { + var w = num.words[i]; + var hi = w * 0x40; + var lo = w * 0x3d1; + hi += (lo / 0x4000000) | 0; + var uhi = (hi / 0x4000000) | 0; + hi &= 0x3ffffff; + lo &= 0x3ffffff; + + num.words[i + 2] += uhi; + num.words[i + 1] += hi; + num.words[i] = lo; + } + var w = num.words[num.length - 2]; + if (w >= 0x4000000) { + num.words[num.length - 1] += w >>> 26; + num.words[num.length - 2] = w & 0x3ffffff; + } + if (num.words[num.length - 1] === 0) + num.length--; + if (num.words[num.length - 1] === 0) + num.length--; + return num; +}; + +function P224() { + MPrime.call( + this, + 'p224', + 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); +} +inherits(P224, MPrime); + +function P192() { + MPrime.call( + this, + 'p192', + 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); +} +inherits(P192, MPrime); + +function P25519() { + // 2 ^ 255 - 19 + MPrime.call( + this, + '25519', + '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); +} +inherits(P25519, MPrime); + +P25519.prototype.imulK = function imulK(num) { + // K = 0x13 + var carry = 0; + for (var i = 0; i < num.length; i++) { + var hi = num.words[i] * 0x13 + carry; + var lo = hi & 0x3ffffff; + hi >>>= 26; + + num.words[i] = lo; + carry = hi; + } + if (carry !== 0) + num.words[num.length++] = carry; + return num; +}; + +// Exported mostly for testing purposes, use plain name instead +BN._prime = function prime(name) { + // Cached version of prime + if (primes[name]) + return primes[name]; + + var prime; + if (name === 'k256') + prime = new K256(); + else if (name === 'p224') + prime = new P224(); + else if (name === 'p192') + prime = new P192(); + else if (name === 'p25519') + prime = new P25519(); + else + throw new Error('Unknown prime ' + name); + primes[name] = prime; + + return prime; +} + +// +// Base reduction engine +// +function Red(m) { + if (typeof m === 'string') { + var prime = BN._prime(m); + this.m = prime.p; + this.prime = prime; + } else { + this.m = m; + this.prime = null; + } +} + +Red.prototype._verify1 = function _verify1(a) { + assert(!a.sign, 'red works only with positives'); + assert(a.red, 'red works only with red numbers'); +}; + +Red.prototype._verify2 = function _verify2(a, b) { + assert(!a.sign && !b.sign, 'red works only with positives'); + assert(a.red && a.red === b.red, + 'red works only with red numbers'); +}; + +Red.prototype.imod = function imod(a) { + if (this.prime) + return this.prime.ireduce(a)._forceRed(this); + return a.mod(this.m)._forceRed(this); +}; + +Red.prototype.neg = function neg(a) { + var r = a.clone(); + r.sign = !r.sign; + return r.iadd(this.m)._forceRed(this); +}; + +Red.prototype.add = function add(a, b) { + this._verify2(a, b); + + var res = a.add(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res._forceRed(this); +}; + +Red.prototype.iadd = function iadd(a, b) { + this._verify2(a, b); + + var res = a.iadd(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res; +}; + +Red.prototype.sub = function sub(a, b) { + this._verify2(a, b); + + var res = a.sub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res._forceRed(this); +}; + +Red.prototype.isub = function isub(a, b) { + this._verify2(a, b); + + var res = a.isub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res; +}; + +Red.prototype.shl = function shl(a, num) { + this._verify1(a); + return this.imod(a.shln(num)); +}; + +Red.prototype.imul = function imul(a, b) { + this._verify2(a, b); + return this.imod(a.imul(b)); +}; + +Red.prototype.mul = function mul(a, b) { + this._verify2(a, b); + return this.imod(a.mul(b)); +}; + +Red.prototype.isqr = function isqr(a) { + return this.imul(a, a); +}; + +Red.prototype.sqr = function sqr(a) { + return this.mul(a, a); +}; + +Red.prototype.sqrt = function sqrt(a) { + if (a.cmpn(0) === 0) + return a.clone(); + + var mod3 = this.m.andln(3); + assert(mod3 % 2 === 1); + + // Fast case + if (mod3 === 3) { + var pow = this.m.add(new BN(1)).ishrn(2); + var r = this.pow(a, pow); + return r; + } + + // Tonelli-Shanks algorithm (Totally unoptimized and slow) + // + // Find Q and S, that Q * 2 ^ S = (P - 1) + var q = this.m.subn(1); + var s = 0; + while (q.cmpn(0) !== 0 && q.andln(1) === 0) { + s++; + q.ishrn(1); + } + assert(q.cmpn(0) !== 0); + + var one = new BN(1).toRed(this); + var nOne = one.redNeg(); + + // Find quadratic non-residue + // NOTE: Max is such because of generalized Riemann hypothesis. + var lpow = this.m.subn(1).ishrn(1); + var z = this.m.bitLength(); + z = new BN(2 * z * z).toRed(this); + while (this.pow(z, lpow).cmp(nOne) !== 0) + z.redIAdd(nOne); + + var c = this.pow(z, q); + var r = this.pow(a, q.addn(1).ishrn(1)); + var t = this.pow(a, q); + var m = s; + while (t.cmp(one) !== 0) { + var tmp = t; + for (var i = 0; tmp.cmp(one) !== 0; i++) + tmp = tmp.redSqr(); + assert(i < m); + var b = this.pow(c, new BN(1).ishln(m - i - 1)); + + r = r.redMul(b); + c = b.redSqr(); + t = t.redMul(c); + m = i; + } + + return r; +}; + +Red.prototype.invm = function invm(a) { + var inv = a._egcd(new BN(1), this.m); + if (inv.sign) { + inv.sign = false; + return this.imod(inv).redNeg(); + } else { + return this.imod(inv); + } +}; + +Red.prototype.pow = function pow(a, num) { + var w = []; + var q = num.clone(); + while (q.cmpn(0) !== 0) { + w.push(q.andln(1)); + q.ishrn(1); + } + + // Skip leading zeroes + var res = a; + for (var i = 0; i < w.length; i++, res = this.sqr(res)) + if (w[i] !== 0) + break; + + if (++i < w.length) { + for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { + if (w[i] === 0) + continue; + res = this.mul(res, q); + } + } + + return res; +}; + +Red.prototype.convertTo = function convertTo(num) { + return num.clone(); +}; + +Red.prototype.convertFrom = function convertFrom(num) { + var res = num.clone(); + res.red = null; + return res; +}; + +// +// Montgomery method engine +// + +BN.mont = function mont(num) { + return new Mont(num); +}; + +function Mont(m) { + Red.call(this, m); + + this.shift = this.m.bitLength(); + if (this.shift % 26 !== 0) + this.shift += 26 - (this.shift % 26); + this.r = new BN(1).ishln(this.shift); + this.r2 = this.imod(this.r.sqr()); + this.rinv = this.r.invm(this.m); + + // TODO(indutny): simplify it + this.minv = this.rinv.mul(this.r) + .sub(new BN(1)) + .div(this.m) + .neg() + .mod(this.r); +} +inherits(Mont, Red); + +Mont.prototype.convertTo = function convertTo(num) { + return this.imod(num.shln(this.shift)); +}; + +Mont.prototype.convertFrom = function convertFrom(num) { + var r = this.imod(num.mul(this.rinv)); + r.red = null; + return r; +}; + +Mont.prototype.imul = function imul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) { + a.words[0] = 0; + a.length = 1; + return a; + } + + var t = a.imul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); + + return res._forceRed(this); +}; + +Mont.prototype.mul = function mul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) + return new BN(0)._forceRed(this); + + var t = a.mul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); + + return res._forceRed(this); +}; + +Mont.prototype.invm = function invm(a) { + // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R + var res = this.imod(a.invm(this.m).mul(this.r2)); + return res._forceRed(this); +}; diff --git a/node_modules/mysql2/node_modules/bn.js/package.json b/node_modules/mysql2/node_modules/bn.js/package.json new file mode 100644 index 0000000..82514ee --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/package.json @@ -0,0 +1,52 @@ +{ + "name": "bn.js", + "version": "0.11.7", + "description": "Big number implementation in pure javascript", + "main": "lib/bn.js", + "scripts": { + "test": "mocha --reporter=spec test/*-test.js" + }, + "repository": { + "type": "git", + "url": "git@github.com:indutny/bn.js" + }, + "keywords": [ + "BN", + "BigNum", + "Big number", + "Modulo", + "Montgomery" + ], + "author": { + "name": "Fedor Indutny", + "email": "fedor@indutny.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/indutny/bn.js/issues" + }, + "homepage": "https://github.com/indutny/bn.js", + "devDependencies": { + "mocha": "^1.18.2" + }, + "_id": "bn.js@0.11.7", + "_shasum": "7c5be037ccd45afc3136c7af92466c93d4ce5a56", + "_from": "bn.js@0.11.7", + "_npmVersion": "1.4.9", + "_npmUser": { + "name": "indutny", + "email": "fedor@indutny.com" + }, + "maintainers": [ + { + "name": "indutny", + "email": "fedor@indutny.com" + } + ], + "dist": { + "shasum": "7c5be037ccd45afc3136c7af92466c93d4ce5a56", + "tarball": "http://registry.npmjs.org/bn.js/-/bn.js-0.11.7.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/bn.js/-/bn.js-0.11.7.tgz" +} diff --git a/node_modules/mysql2/node_modules/bn.js/test/bn-test.js b/node_modules/mysql2/node_modules/bn.js/test/bn-test.js new file mode 100644 index 0000000..9965f43 --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/test/bn-test.js @@ -0,0 +1,307 @@ +var assert = require('assert'); +var BN = require('../').BN; + +describe('BN', function() { + it('should work with Number input', function() { + assert.equal(new BN(12345).toString(16), '3039'); + }); + + it('should work with String input', function() { + assert.equal(new BN('29048849665247').toString(16), + '1a6b765d8cdf'); + assert.equal(new BN('-29048849665247').toString(16), + '-1a6b765d8cdf'); + assert.equal(new BN('1A6B765D8CDF', 16).toString(16), + '1a6b765d8cdf'); + assert.equal(new BN('FF', 16).toString(), '255'); + assert.equal(new BN('1A6B765D8CDF', 16).toString(), + '29048849665247'); + assert.equal(new BN('a89c e5af8724 c0a23e0e 0ff77500', 16).toString(16), + 'a89ce5af8724c0a23e0e0ff77500'); + assert.equal(new BN('123456789abcdef123456789abcdef123456789abcdef', + 16).toString(16), + '123456789abcdef123456789abcdef123456789abcdef'); + assert.equal(new BN('10654321').toString(), '10654321'); + assert.equal(new BN('10000000000000000').toString(10), + '10000000000000000'); + }); + + it('should import/export big endian', function() { + assert.equal(new BN([1,2,3]).toString(16), '10203'); + assert.equal(new BN([1,2,3,4]).toString(16), '1020304'); + assert.equal(new BN([1,2,3,4,5]).toString(16), '102030405'); + assert.equal(new BN([1,2,3,4,5,6,7,8]).toString(16), '102030405060708'); + assert.equal(new BN([1,2,3,4]).toArray().join(','), '1,2,3,4'); + assert.equal(new BN([1,2,3,4,5,6,7,8]).toArray().join(','), + '1,2,3,4,5,6,7,8'); + }); + + it('should return proper bitLength', function() { + assert.equal(new BN(0).bitLength(), 0); + assert.equal(new BN(0x1).bitLength(), 1); + assert.equal(new BN(0x2).bitLength(), 2); + assert.equal(new BN(0x3).bitLength(), 2); + assert.equal(new BN(0x4).bitLength(), 3); + assert.equal(new BN(0x8).bitLength(), 4); + assert.equal(new BN(0x10).bitLength(), 5); + assert.equal(new BN(0x100).bitLength(), 9); + assert.equal(new BN(0x123456).bitLength(), 21); + assert.equal(new BN('123456789', 16).bitLength(), 33); + assert.equal(new BN('8023456789', 16).bitLength(), 40); + }); + + it('should add numbers', function() { + assert.equal(new BN(14).add(new BN(26)).toString(16), '28'); + var k = new BN(0x1234); + var r = k; + for (var i = 0; i < 257; i++) + r = r.add(k); + assert.equal(r.toString(16), '125868'); + + var k = new BN('abcdefabcdefabcdef', 16); + var r = new BN('deadbeef', 16); + for (var i = 0; i < 257; i++) + r.iadd(k); + assert.equal(r.toString(16), 'ac79bd9b79be7a277bde'); + }); + + it('should subtract numbers', function() { + assert.equal(new BN(14).sub(new BN(26)).toString(16), '-c'); + assert.equal(new BN(26).sub(new BN(14)).toString(16), 'c'); + assert.equal(new BN(26).sub(new BN(26)).toString(16), '0'); + assert.equal(new BN(-26).sub(new BN(26)).toString(16), '-34'); + + var a = new BN( + '31ff3c61db2db84b9823d320907a573f6ad37c437abe458b1802cda041d6384' + + 'a7d8daef41395491e2', + 16); + var b = new BN( + '6f0e4d9f1d6071c183677f601af9305721c91d31b0bbbae8fb790000', + 16); + var r = new BN( + '31ff3c61db2db84b9823d3208989726578fd75276287cd9516533a9acfb9a67' + + '76281f34583ddb91e2', + 16); + assert.equal(a.sub(b).cmp(r), 0); + + // In-place + assert.equal(b.clone().isub(a).neg().cmp(r), 0); + + var r = b.sub(new BN(14)); + assert.equal(b.clone().isubn(14).cmp(r), 0); + + var r = new BN( + '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b', 16); + assert.equal(r.isubn(-1).toString(16), + '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681c'); + + // Carry and copy + var a = new BN('12345', 16); + var b = new BN('1000000000000', 16); + assert.equal(a.isub(b).toString(16), '-fffffffedcbb'); + + var a = new BN('12345', 16); + var b = new BN('1000000000000', 16); + assert.equal(b.isub(a).toString(16), 'fffffffedcbb'); + }); + + it('should mul numbers', function() { + assert.equal(new BN(0x1001).mul(new BN(0x1234)).toString(16), + '1235234'); + assert.equal(new BN(-0x1001).mul(new BN(0x1234)).toString(16), + '-1235234'); + assert.equal(new BN(-0x1001).mul(new BN(-0x1234)).toString(16), + '1235234'); + var n = new BN(0x1001); + var r = n; + for (var i = 0; i < 4; i++) + r = r.mul(n); + assert.equal(r.toString(16), + '100500a00a005001'); + + var n = new BN( + '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', + 16 + ); + assert.equal(n.mul(n).toString(16), + '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729ab9' + + 'b055c3a9458e4ce3289560a38e08ba8175a9446ce14e608245ab3a9' + + '978a8bd8acaa40'); + assert.equal(n.mul(n).mul(n).toString(16), + '1b888e01a06e974017a28a5b4da436169761c9730b7aeedf75fc60f687b' + + '46e0cf2cb11667f795d5569482640fe5f628939467a01a612b02350' + + '0d0161e9730279a7561043af6197798e41b7432458463e64fa81158' + + '907322dc330562697d0d600'); + + assert.equal( + new BN('-100000000000').mul(new BN('3').div(new BN('4'))).toString(16), + '0' + ); + }); + + it('should imul numbers', function() { + var a = new BN('abcdef01234567890abcd', 16); + var b = new BN('deadbeefa551edebabba8', 16); + var c = a.mul(b); + + assert.equal(a.imul(b).toString(16), c.toString(16)); + + var a = new BN('abcdef01234567890abcd214a25123f512361e6d236', 16); + var b = new BN('deadbeefa551edebabba8121234fd21bac0341324dd', 16); + var c = a.mul(b); + + assert.equal(a.imul(b).toString(16), c.toString(16)); + }); + + it('should div numbers', function() { + assert.equal(new BN('10').div(new BN(256)).toString(16), + '0'); + assert.equal(new BN('69527932928').div(new BN('16974594')).toString(16), + 'fff'); + assert.equal(new BN('-69527932928').div(new BN('16974594')).toString(16), + '-fff'); + + var b = new BN( + '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729ab9' + + 'b055c3a9458e4ce3289560a38e08ba8175a9446ce14e608245ab3a9' + + '978a8bd8acaa40', + 16); + var n = new BN( + '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', + 16 + ); + assert.equal(b.div(n).toString(16), n.toString(16)); + + assert.equal(new BN('1').div(new BN('-5')).toString(10), '0'); + + // Regression after moving to word div + var p = new BN( + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', + 16); + var a = new BN( + '79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798', + 16); + var as = a.sqr(); + assert.equal( + as.div(p).toString(16), + '39e58a8055b6fb264b75ec8c646509784204ac15a8c24e05babc9729e58090b9'); + + var p = new BN( + 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', + 16); + var a = new BN( + 'fffffffe00000003fffffffd0000000200000001fffffffe00000002ffffffff' + + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + 16); + assert.equal( + a.div(p).toString(16), + 'ffffffff00000002000000000000000000000001000000000000000000000001'); + }); + + it('should mod numbers', function() { + assert.equal(new BN('10').mod(new BN(256)).toString(16), + 'a'); + assert.equal(new BN('69527932928').mod(new BN('16974594')).toString(16), + '102f302'); + assert.equal(new BN('-69527932928').mod(new BN('16974594')).toString(16), + '1000'); + + var p = new BN( + 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', + 16); + var a = new BN( + 'fffffffe00000003fffffffd0000000200000001fffffffe00000002ffffffff' + + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + 16); + assert.equal( + a.mod(p).toString(16), + '0'); + }); + + it('should divRound numbers', function() { + assert.equal(new BN(9).divRound(new BN(20)).toString(10), + '0'); + assert.equal(new BN(10).divRound(new BN(20)).toString(10), + '1'); + assert.equal(new BN(150).divRound(new BN(20)).toString(10), + '8'); + assert.equal(new BN(149).divRound(new BN(20)).toString(10), + '7'); + assert.equal(new BN(149).divRound(new BN(17)).toString(10), + '9'); + assert.equal(new BN(144).divRound(new BN(17)).toString(10), + '8'); + assert.equal(new BN(-144).divRound(new BN(17)).toString(10), + '-8'); + }); + + it('should modn numbers', function() { + assert.equal(new BN('10', 16).modn(256).toString(16), '10'); + assert.equal(new BN('100', 16).modn(256).toString(16), '0'); + assert.equal(new BN('1001', 16).modn(256).toString(16), '1'); + assert.equal(new BN('100000000001', 16).modn(256).toString(16), '1'); + assert.equal(new BN('100000000001', 16).modn(257).toString(16), + new BN('100000000001', 16).mod(new BN(257)).toString(16)); + assert.equal(new BN('123456789012', 16).modn(3).toString(16), + new BN('123456789012', 16).mod(new BN(3)).toString(16)); + }); + + it('should idivn numbers', function() { + assert.equal(new BN('10', 16).idivn(3).toString(16), '5'); + assert.equal(new BN('12', 16).idivn(3).toString(16), '6'); + assert.equal(new BN('10000000000000000').idivn(3).toString(10), + '3333333333333333'); + assert.equal(new BN('100000000000000000000000000000').idivn(3).toString(10), + '33333333333333333333333333333'); + + var t = new BN(3); + assert.equal(new BN('12345678901234567890123456', 16).idivn(3).toString(16), + new BN('12345678901234567890123456', 16).div(t).toString(16)); + }); + + it('should shl numbers', function() { + assert.equal(new BN('69527932928').shln(13).toString(16), + '2060602000000'); + assert.equal(new BN('69527932928').shln(45).toString(16), + '206060200000000000000'); + }); + + it('should shr numbers', function() { + assert.equal(new BN('69527932928').shrn(13).toString(16), + '818180'); + assert.equal(new BN('69527932928').shrn(17).toString(16), + '81818'); + assert.equal(new BN('69527932928').shrn(256).toString(16), + '0'); + }); + + it('should invm numbers', function() { + var p = new BN(257); + var a = new BN(3); + var b = a.invm(p); + assert.equal(a.mul(b).mod(p).toString(16), '1'); + + var p192 = new BN( + 'fffffffffffffffffffffffffffffffeffffffffffffffff', + 16); + var a = new BN('deadbeef', 16); + var b = a.invm(p192); + assert.equal(a.mul(b).mod(p192).toString(16), '1'); + }); + + it('should support bincn', function() { + assert.equal(new BN(0).bincn(1).toString(16), '2'); + assert.equal(new BN(2).bincn(1).toString(16), '4'); + assert.equal(new BN(2).bincn(1).bincn(1).toString(16), + new BN(2).bincn(2).toString(16)); + assert.equal(new BN(0xffffff).bincn(1).toString(16), '1000001'); + }); + + it('should support imaskn', function() { + assert.equal(new BN(0).imaskn(1).toString(16), '0'); + assert.equal(new BN(3).imaskn(1).toString(16), '1'); + assert.equal(new BN('123456789', 16).imaskn(4).toString(16), '9'); + assert.equal(new BN('123456789', 16).imaskn(16).toString(16), '6789'); + assert.equal(new BN('123456789', 16).imaskn(28).toString(16), '3456789'); + }); +}); diff --git a/node_modules/mysql2/node_modules/bn.js/test/red-test.js b/node_modules/mysql2/node_modules/bn.js/test/red-test.js new file mode 100644 index 0000000..d57ba7c --- /dev/null +++ b/node_modules/mysql2/node_modules/bn.js/test/red-test.js @@ -0,0 +1,126 @@ +var assert = require('assert'); +var BN = require('../').BN; + +describe('BN.js/Reduction context', function() { + function testMethod(name, fn) { + describe(name + ' method', function() { + it('should support add, iadd, sub, isub operations', function() { + var p = new BN(257); + var m = fn(p); + var a = new BN(123).toRed(m); + var b = new BN(231).toRed(m); + + assert.equal(a.redAdd(b).fromRed().toString(10), '97'); + assert.equal(a.redSub(b).fromRed().toString(10), '149'); + assert.equal(b.redSub(a).fromRed().toString(10), '108'); + + assert.equal(a.clone().redIAdd(b).fromRed().toString(10), '97'); + assert.equal(a.clone().redISub(b).fromRed().toString(10), '149'); + assert.equal(b.clone().redISub(a).fromRed().toString(10), '108'); + }); + + it('should support pow and mul operations', function() { + var p192 = new BN( + 'fffffffffffffffffffffffffffffffeffffffffffffffff', + 16); + var m = fn(p192); + var a = new BN(123); + var b = new BN(231); + var c = a.toRed(m).redMul(b.toRed(m)).fromRed(); + assert(c.cmp(a.mul(b).mod(p192)) === 0); + + assert.equal(a.toRed(m).redPow(new BN(3)).fromRed() + .cmp(a.sqr().mul(a)), 0); + assert.equal(a.toRed(m).redPow(new BN(4)).fromRed() + .cmp(a.sqr().sqr()), 0); + assert.equal(a.toRed(m).redPow(new BN(8)).fromRed() + .cmp(a.sqr().sqr().sqr()), 0); + assert.equal(a.toRed(m).redPow(new BN(9)).fromRed() + .cmp(a.sqr().sqr().sqr().mul(a)), 0); + assert.equal(a.toRed(m).redPow(new BN(17)).fromRed() + .cmp(a.sqr().sqr().sqr().sqr().mul(a)), 0); + }); + + it('should sqrtm numbers', function() { + var p = new BN(263); + var m = fn(p); + var q = new BN(11).toRed(m); + var qr = q.redSqrt(true, p); + assert.equal(qr.redSqr().cmp(q), 0); + var qr = q.redSqrt(false, p); + assert.equal(qr.redSqr().cmp(q), 0); + + var p = new BN( + 'fffffffffffffffffffffffffffffffeffffffffffffffff', + 16); + var m = fn(p); + var q = new BN(13).toRed(m); + var qr = q.redSqrt(true, p); + assert.equal(qr.redSqr().cmp(q), 0); + var qr = q.redSqrt(false, p); + assert.equal(qr.redSqr().cmp(q), 0); + + // Tonelli-shanks + var p = new BN(13); + var m = fn(p); + var q = new BN(10).toRed(m); + assert.equal(q.redSqrt().fromRed().toString(10), '7'); + }); + + it('should invm numbers', function() { + var p = new BN(257); + var m = fn(p); + var a = new BN(3).toRed(m); + var b = a.redInvm(p); + assert.equal(a.redMul(b).fromRed().toString(16), '1'); + }); + + it('should imul numbers', function() { + var p = new BN( + 'fffffffffffffffffffffffffffffffeffffffffffffffff', + 16); + var m = fn(p); + + var a = new BN('deadbeefabbadead', 16); + var b = new BN('abbadeadbeefdead', 16); + var c = a.mul(b).mod(p); + + assert.equal(a.toRed(m).redIMul(b.toRed(m)).fromRed().toString(16), + c.toString(16)); + }); + }); + } + + testMethod('Plain', BN.red); + testMethod('Montgomery', BN.mont); + + describe('Pseudo-Mersenne Primes', function() { + it('should reduce numbers mod k256', function() { + var p = BN._prime('k256'); + + assert.equal(p.ireduce(new BN(0xdead)).toString(16), 'dead'); + assert.equal(p.ireduce(new BN('deadbeef', 16)).toString(16), 'deadbeef'); + + var num = new BN('fedcba9876543210fedcba9876543210dead' + + 'fedcba9876543210fedcba9876543210dead', + 16); + var exp = num.mod(p.p).toString(16); + assert.equal(p.ireduce(num).toString(16), exp); + + var regr = new BN('f7e46df64c1815962bf7bc9c56128798' + + '3f4fcef9cb1979573163b477eab93959' + + '335dfb29ef07a4d835d22aa3b6797760' + + '70a8b8f59ba73d56d01a79af9', + 16); + var exp = regr.mod(p.p).toString(16); + assert.equal(p.ireduce(regr).toString(16), exp); + }); + + it('should not fail to invm number mod k256', function() { + var regr2 = new BN( + '6c150c4aa9a8cf1934485d40674d4a7cd494675537bda36d49405c5d2c6f496f', 16); + regr2 = regr2.toRed(BN.red('k256')); + assert.equal(regr2.redInvm().redMul(regr2).fromRed().cmpn(1), 0); + }); + }); +}); diff --git a/node_modules/mysql2/node_modules/cardinal/.npmignore b/node_modules/mysql2/node_modules/cardinal/.npmignore new file mode 100644 index 0000000..7e2f179 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/.npmignore @@ -0,0 +1 @@ +assets diff --git a/node_modules/mysql2/node_modules/cardinal/.travis.yml b/node_modules/mysql2/node_modules/cardinal/.travis.yml new file mode 100644 index 0000000..65488b0 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.8 + - 0.10 diff --git a/node_modules/mysql2/node_modules/cardinal/LICENSE b/node_modules/mysql2/node_modules/cardinal/LICENSE new file mode 100644 index 0000000..19c037f --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/LICENSE @@ -0,0 +1,23 @@ +Copyright 2012 Thorsten Lorenz. +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mysql2/node_modules/cardinal/README.md b/node_modules/mysql2/node_modules/cardinal/README.md new file mode 100644 index 0000000..5c3d5ad --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/README.md @@ -0,0 +1,132 @@ +# cardinal [![Build Status](https://secure.travis-ci.org/thlorenz/cardinal.png)](http://travis-ci.org/thlorenz/cardinal) + +[![NPM](https://nodei.co/npm/cardinal.png?downloads=true&stars=true)](https://nodei.co/npm/cardinal/) + +**car·di·nal** *(kärdn-l, kärdnl)* - crested thick-billed North American finch having bright red plumage in the male. + +![screenshot](https://github.com/thlorenz/cardinal/raw/master/assets/screen-shot.png) + +## Features + +- highlights JavaScript code with ANSI colors to improve terminal output +- theming support, see [custom color themes](https://github.com/thlorenz/cardinal/tree/master/themes) +- optionally print line numbers +- API and command line interface (`cdl`) +- `.cardinalrc` config to customize settings +- supports UNIX pipes + +*** + +**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* + +- [Installation](#installation) + - [As library](#as-library) + - [As Commandline Tool](#as-commandline-tool) +- [Commandline](#commandline) + - [Highlight a file](#highlight-a-file) + - [As part of a UNIX pipe](#as-part-of-a-unix-pipe) + - [Theme](#theme) +- [API](#api) + - [*highlight(code[, opts])*](#highlightcode-opts) + - [*highlightFileSync(fullPath[, opts])*](#highlightfilesyncfullpath-opts) + - [*highlightFile(fullPath[, opts], callback)*](#highlightfilefullpath-opts-callback) + - [opts](#opts) +- [Examples ([*browse*](https://github.com/thlorenz/cardinal/tree/master/examples))](#examples-[browse]https://githubcom/thlorenz/cardinal/tree/master/examples) + + +## Installation + +### As library + + npm install cardinal + +### As Commandline Tool + + [sudo] npm install -g cardinal + +**Note:** + +When installed globally, cardinal exposes itself as the `cdl` command. + +## Commandline + +### Highlight a file + + cdl [options] + +**options**: + - `--nonum`: turns off line number printing (relevant if it is turned on inside `~/.cardinalrc` + +### As part of a UNIX pipe + + cat file.js | grep console | cdl + +**Note:** + +Not all code lines may be parsable JavaScript. In these cases the line is printed to the terminal without +highlighting it. + +### Theme + +The default theme will be used for highlighting. + +To use a different theme, include a `.cardinalrc` file in your `HOME` directory. + +This is a JSON file of the following form: + +```json +{ + "theme": "hide-semicolons", + "linenos": true|false +} +``` + +- `theme` can be the name of any of the [built-in themes](https://github.com/thlorenz/cardinal/tree/master/themes) or the +full path to a custom theme anywhere on your computer. +- linenos toggles line number printing + +## API + +### *highlight(code[, opts])* + +- returns the highlighted version of the passed code ({String}) or throws an error if it was not able to parse it +- opts (see below) + +### *highlightFileSync(fullPath[, opts])* + +- returns the highlighted version of the file whose fullPath ({String}) was passed or throws an error if it was not able + to parse it +- opts (see below) + +### *highlightFile(fullPath[, opts], callback)* + +- calls back with the highlighted version of the file whose fullPath ({String}) was passed or with an error if it was not able + to parse it +- opts (see below) +- `callback` ({Function}) has the following signature: `function (err, highlighted) { .. }` + +### opts + +opts is an {Object} with the following properties: + +- `theme` {Object} is used to optionally override the theme used to highlight +- `linenos` {Boolean} if `true` line numbers are included in the highlighted code +- `firstline` {Integer} sets line number of the first line when line numbers are printed +- `json` {Boolean} if `true` highlights JSON in addition to JavaScript (`true` by default if file extension is `.json`) + +## Examples ([*browse*](https://github.com/thlorenz/cardinal/tree/master/examples)) + +- [sample .cardinalrc](https://github.com/thlorenz/cardinal/blob/master/examples/.cardinalrc) +- [highlighting a code snippet](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-string.js) via + ***highlight()*** +- [file that highlights itself](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-self.js) via + ***highlightFile()*** including line numbers +- [file that highlights itself hiding all + semicolons](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-self-hide-semicolons.js) via + ***highlightFileSync()*** + + + + +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/thlorenz/cardinal/trend.png)](https://bitdeli.com/free "Bitdeli Badge") + diff --git a/node_modules/mysql2/node_modules/cardinal/bin/cdl.js b/node_modules/mysql2/node_modules/cardinal/bin/cdl.js new file mode 100755 index 0000000..c58eb08 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/bin/cdl.js @@ -0,0 +1,74 @@ +#!/usr/bin/env node +var cardinal = require('..') + , utl = require('../utl') + , settings = require('../settings') + , args = process.argv + , theme = settings.resolveTheme() + , opts = settings.getSettings() + , highlighted + ; + +opts = opts || {}; +opts.theme = theme; + +function usage() { + var msg = [ + 'Usage: cdl [options]' + , '' + , 'Options (~/.cardinalrc overrides):' + , ' --nonum: turn off line printing' + , '' + , 'Unix Pipe Example: cat filename.js | grep console | cdl' + , '' + ].join('\n'); + console.log(msg); +} + +function highlightFile () { + try { + highlighted = cardinal.highlightFileSync(args[2], opts); + console.log(highlighted); + } catch (e) { + console.trace(); + console.error(e); + } +} + +// E.g., "cardinal myfile.js" +if (args.length === 3) return highlightFile(); + +var opt = args[3]; + +// E.g., "cardinal myfile.js --nonum" +if (opt && opt.indexOf('--') === 0 ) { + if ((/^--(nonum|noline)/i).test(opt)) opts.linenos = false; + else { + usage(); + return console.error('Unknown option: ', opt); + } + + return highlightFile(); +} + + +// UNIX pipes e.g., "cat myfile.js | grep console | cardinal +var stdin = process.stdin + , stdout = process.stdout; + +// line numbers don't make sense when we are printing line by line +opts.linenos = false; + +stdin.setEncoding('utf-8'); +stdin.resume(); +stdin + .on('data', function (chunk) { + chunk.split('\n').forEach(function (line) { + try { + stdout.write(cardinal.highlight(line, opts) + '\n'); + } catch (e) { + // line doesn't represent a valid js snippet and therefore cannot be parsed -> just print as is + stdout.write(line + '\n'); + } + }); + }); + diff --git a/node_modules/mysql2/node_modules/cardinal/cardinal.js b/node_modules/mysql2/node_modules/cardinal/cardinal.js new file mode 100644 index 0000000..4df4bb4 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/cardinal.js @@ -0,0 +1,5 @@ +module.exports = { + highlight: require('./lib/highlight') + , highlightFile: require('./lib/highlightFile') + , highlightFileSync: require('./lib/highlightFileSync') +}; diff --git a/node_modules/mysql2/node_modules/cardinal/examples/.cardinalrc b/node_modules/mysql2/node_modules/cardinal/examples/.cardinalrc new file mode 100644 index 0000000..34be5cc --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/.cardinalrc @@ -0,0 +1,3 @@ +{ + "theme": "hide-semicolons" +} diff --git a/node_modules/mysql2/node_modules/cardinal/examples/README.md b/node_modules/mysql2/node_modules/cardinal/examples/README.md new file mode 100644 index 0000000..a6c2cd9 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/README.md @@ -0,0 +1,7 @@ +# Cardinal Examples + +You can run the examples individually or as a demo: + +- install cardinal: `npm install cardinal` +- explore cardinal: `npm explore cardinal` +- run the demo: `npm run demo` diff --git a/node_modules/mysql2/node_modules/cardinal/examples/highlight-json.js b/node_modules/mysql2/node_modules/cardinal/examples/highlight-json.js new file mode 100644 index 0000000..3c06e5d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/highlight-json.js @@ -0,0 +1,10 @@ +// This file will highlight the passed code using the custom theme when run via: "node highlight-json" + +var cardinal = require('..'); + +var json = JSON.stringify({ + foo: 'bar', + baz: 'quux' +}); + +console.log(cardinal.highlight(json, {json: true})); diff --git a/node_modules/mysql2/node_modules/cardinal/examples/highlight-self-hide-semicolons.js b/node_modules/mysql2/node_modules/cardinal/examples/highlight-self-hide-semicolons.js new file mode 100644 index 0000000..bf2c7d6 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/highlight-self-hide-semicolons.js @@ -0,0 +1,22 @@ + /* + * This file will highlight itself using a custom theme when run via: "node highlight-self-hide-semicolons" + * The custom theme highlights semicolons as 'black', thus hiding them. + */ + +var cardinal = require('..') + , hideSemicolonsTheme = require('../themes/hide-semicolons'); + +function highlight () { + + // Using the synchronous highlightFileSync() + // For asynchronous highlighting use: highlightFile() - see highlight-self.js + + try { + var highlighted = cardinal.highlightFileSync(__filename, hideSemicolonsTheme); + console.log(highlighted); + } catch (err) { + console.error(err); + } +} + +highlight(); diff --git a/node_modules/mysql2/node_modules/cardinal/examples/highlight-self.js b/node_modules/mysql2/node_modules/cardinal/examples/highlight-self.js new file mode 100644 index 0000000..ceeb599 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/highlight-self.js @@ -0,0 +1,16 @@ +// This file will highlight itself using the default theme when run via: "node highlight-self" + +var cardinal = require('..'); + +function highlight () { + + // Using the asynchronous highlightFile() + // For synchronous highlighting use: highlightFileSync() - see highlight-self-hide-semicolons.js + + cardinal.highlightFile(__filename, { linenos: true }, function (err, res) { + if (err) return console.error(err); + console.log(res); + }); +} + +highlight(); diff --git a/node_modules/mysql2/node_modules/cardinal/examples/highlight-string.js b/node_modules/mysql2/node_modules/cardinal/examples/highlight-string.js new file mode 100644 index 0000000..dcc7b4e --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/examples/highlight-string.js @@ -0,0 +1,14 @@ +// This file will highlight the passed code using the custom theme when run via: "node highlight-string" + +var cardinal = require('..'); + +var code = '' + + +function add (a, b) { + var sum = a + b; + return sum; +} + + +''; + +console.log(cardinal.highlight(code)); diff --git a/node_modules/mysql2/node_modules/cardinal/lib/highlight.js b/node_modules/mysql2/node_modules/cardinal/lib/highlight.js new file mode 100644 index 0000000..9c55e2c --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/lib/highlight.js @@ -0,0 +1,83 @@ +var redeyed = require('redeyed') + , theme = require('../themes/default') + , colors = require('ansicolors') + + , colorSurround = colors.brightBlack + , surroundClose = '\u001b[39m' + ; + +function trimEmptyLines(lines) { + + // remove lines from the end until we find a non-empy one + var line = lines.pop(); + while(!line || !line.length) + line = lines.pop(); + + // put the non-empty line back + if (line) lines.push(line); +} + +function addLinenos (highlightedCode, firstline) { + var highlightedLines = highlightedCode.split('\n'); + + trimEmptyLines(highlightedLines); + + var linesLen = highlightedLines.length + , lines = [] + , totalDigits + , lineno + ; + + function getDigits (n) { + if (n < 10) return 1; + if (n < 100) return 2; + if (n < 1000) return 3; + if (n < 10000) return 4; + // this works for up to 99,999 lines - any questions? + return 5; + } + + function pad (n, totalDigits) { + // not pretty, but simple and should perform quite well + var padDigits= totalDigits - getDigits(n); + switch(padDigits) { + case 0: return '' + n; + case 1: return ' ' + n; + case 2: return ' ' + n; + case 3: return ' ' + n; + case 4: return ' ' + n; + case 5: return ' ' + n; + } + } + + totalDigits = getDigits(linesLen + firstline - 1); + + for (var i = 0; i < linesLen; i++) { + // Don't close the escape sequence here in order to not break multi line code highlights like block comments + lineno = colorSurround(pad(i + firstline, totalDigits) + ': ').replace(surroundClose, ''); + lines.push(lineno + highlightedLines[i]); + } + + return lines.join('\n'); +} + +module.exports = function highlight (code, opts) { + opts = opts || { }; + if (opts.json) { + code = '!\n' + code; + } + try { + + var result = redeyed(code, opts.theme || theme) + , firstline = opts.firstline && !isNaN(opts.firstline) ? opts.firstline : 1; + + if (opts.json) { + result.code = result.code.split('\n').slice(1).join('\n'); + } + + return opts.linenos ? addLinenos(result.code, firstline) : result.code; + } catch (e) { + e.message = 'Unable to perform highlight. The code contained syntax errors: ' + e.message; + throw e; + } +}; diff --git a/node_modules/mysql2/node_modules/cardinal/lib/highlightFile.js b/node_modules/mysql2/node_modules/cardinal/lib/highlightFile.js new file mode 100644 index 0000000..bb3271d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/lib/highlightFile.js @@ -0,0 +1,26 @@ +var fs = require('fs') + , highlight = require('./highlight'); + +function isFunction (obj) { + return toString.call(obj) == '[object Function]'; +} + +module.exports = function highlightFile (fullPath, opts, cb) { + if (isFunction(opts)) { + cb = opts; + opts = { }; + } + opts = opts || { }; + if (opts.json !== false && fullPath.match(/\.json$/i)) { + opts.json = true; + } + + fs.readFile(fullPath, 'utf-8', function (err, code) { + if (err) return cb(err); + try { + cb(null, highlight(code, opts)); + } catch (e) { + cb(e); + } + }); +}; diff --git a/node_modules/mysql2/node_modules/cardinal/lib/highlightFileSync.js b/node_modules/mysql2/node_modules/cardinal/lib/highlightFileSync.js new file mode 100644 index 0000000..bc33dd4 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/lib/highlightFileSync.js @@ -0,0 +1,11 @@ +var fs = require('fs') + , highlight = require('./highlight'); + +module.exports = function highlightFileSync (fullPath, opts) { + var code = fs.readFileSync(fullPath, 'utf-8'); + opts = opts || { }; + if (opts.json !== false && fullPath.match(/\.json$/i)) { + opts.json = true; + } + return highlight(code, opts); +}; diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.npmignore b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.npmignore new file mode 100644 index 0000000..a72b52e --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.npmignore @@ -0,0 +1,15 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.travis.yml b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.travis.yml new file mode 100644 index 0000000..895dbd3 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/LICENSE b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/LICENSE new file mode 100644 index 0000000..41702c5 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/LICENSE @@ -0,0 +1,23 @@ +Copyright 2013 Thorsten Lorenz. +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/README.md b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/README.md new file mode 100644 index 0000000..30b6a52 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/README.md @@ -0,0 +1,42 @@ +# ansicolors [![build status](https://secure.travis-ci.org/thlorenz/ansicolors.png)](http://next.travis-ci.org/thlorenz/ansicolors) + +Functions that surround a string with ansicolor codes so it prints in color. + +## Installation + + npm install ansicolors + +## Usage + +```js +var colors = require('ansicolors'); + +// foreground colors +var redHerring = colors.red('herring'); +var blueMoon = colors.blue('moon'); +var brighBlueMoon = colors.brightBlue('moon'); + +console.log(redHerring); // this will print 'herring' in red +console.log(blueMoon); // this 'moon' in blue +console.log(brightBlueMoon); // I think you got the idea + +// background colors +console.log(colors.bgYellow('printed on yellow background')); +console.log(colors.bgBrightBlue('printed on bright blue background')); + +// mixing background and foreground colors +// below two lines have same result (order in which bg and fg are combined doesn't matter) +console.log(colors.bgYellow(colors.blue('printed on yellow background in blue'))); +console.log(colors.blue(colors.bgYellow('printed on yellow background in blue'))); +``` + +## Tests + +Look at the [tests](https://github.com/thlorenz/ansicolors/blob/master/test/ansicolors.js) to see more examples and/or run them via: + + npm explore ansicolors && npm test + +## Alternatives + +**ansicolors** tries to meet simple use cases with a very simple API. However, if you need a more powerful ansi formatting tool, +I'd suggest to look at the [features](https://github.com/TooTallNate/ansi.js#features) of the [ansi module](https://github.com/TooTallNate/ansi.js). diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/ansicolors.js b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/ansicolors.js new file mode 100644 index 0000000..b0e18f6 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/ansicolors.js @@ -0,0 +1,55 @@ +// ColorCodes explained: http://www.termsys.demon.co.uk/vtansi.htm +'use strict'; + +var colorNums = { + white : 37 + , black : 30 + , blue : 34 + , cyan : 36 + , green : 32 + , magenta : 35 + , red : 31 + , yellow : 33 + , brightBlack : 90 + , brightRed : 91 + , brightGreen : 92 + , brightYellow : 93 + , brightBlue : 94 + , brightMagenta : 95 + , brightCyan : 96 + , brightWhite : 97 + } + , backgroundColorNums = { + bgBlack : 40 + , bgRed : 41 + , bgGreen : 42 + , bgYellow : 43 + , bgBlue : 44 + , bgMagenta : 45 + , bgCyan : 46 + , bgWhite : 47 + , bgBrightBlack : 100 + , bgBrightRed : 101 + , bgBrightGreen : 102 + , bgBrightYellow : 103 + , bgBrightBlue : 104 + , bgBrightMagenta : 105 + , bgBrightCyan : 106 + , bgBrightWhite : 107 + } + , colors = {}; + + +Object.keys(colorNums).forEach(function (k) { + colors[k] = function (s) { + return '\u001b[' + colorNums[k] + 'm' + s + '\u001b[39m'; + }; +}); + +Object.keys(backgroundColorNums).forEach(function (k) { + colors[k] = function (s) { + return '\u001b[' + backgroundColorNums[k] + 'm' + s + '\u001b[49m'; + }; +}); + +module.exports = colors; diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/package.json b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/package.json new file mode 100644 index 0000000..4188c40 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/package.json @@ -0,0 +1,34 @@ +{ + "name": "ansicolors", + "version": "0.2.1", + "description": "Functions that surround a string with ansicolor codes so it prints in color.", + "main": "ansicolors.js", + "scripts": { + "test": "node test/*.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/thlorenz/ansicolors.git" + }, + "keywords": [ + "ansi", + "colors", + "highlight", + "string" + ], + "author": { + "name": "Thorsten Lorenz", + "email": "thlorenz@gmx.de", + "url": "thlorenz.com" + }, + "license": "MIT", + "readmeFilename": "README.md", + "gitHead": "858847ca28e8b360d9b70eee0592700fa2ab087d", + "readme": "# ansicolors [![build status](https://secure.travis-ci.org/thlorenz/ansicolors.png)](http://next.travis-ci.org/thlorenz/ansicolors)\n\nFunctions that surround a string with ansicolor codes so it prints in color.\n\n## Installation\n\n npm install ansicolors\n\n## Usage\n\n```js\nvar colors = require('ansicolors');\n\n// foreground colors\nvar redHerring = colors.red('herring');\nvar blueMoon = colors.blue('moon');\nvar brighBlueMoon = colors.brightBlue('moon');\n\nconsole.log(redHerring); // this will print 'herring' in red\nconsole.log(blueMoon); // this 'moon' in blue\nconsole.log(brightBlueMoon); // I think you got the idea\n\n// background colors\nconsole.log(colors.bgYellow('printed on yellow background'));\nconsole.log(colors.bgBrightBlue('printed on bright blue background'));\n\n// mixing background and foreground colors\n// below two lines have same result (order in which bg and fg are combined doesn't matter)\nconsole.log(colors.bgYellow(colors.blue('printed on yellow background in blue')));\nconsole.log(colors.blue(colors.bgYellow('printed on yellow background in blue')));\n```\n\n## Tests\n\nLook at the [tests](https://github.com/thlorenz/ansicolors/blob/master/test/ansicolors.js) to see more examples and/or run them via: \n\n npm explore ansicolors && npm test\n\n## Alternatives\n\n**ansicolors** tries to meet simple use cases with a very simple API. However, if you need a more powerful ansi formatting tool, \nI'd suggest to look at the [features](https://github.com/TooTallNate/ansi.js#features) of the [ansi module](https://github.com/TooTallNate/ansi.js).\n", + "bugs": { + "url": "https://github.com/thlorenz/ansicolors/issues" + }, + "homepage": "https://github.com/thlorenz/ansicolors", + "_id": "ansicolors@0.2.1", + "_from": "ansicolors@>=0.2.1 <0.3.0" +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/test/ansicolors.js b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/test/ansicolors.js new file mode 100644 index 0000000..46aec3e --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/ansicolors/test/ansicolors.js @@ -0,0 +1,55 @@ +'use strict'; + +var assert = require('assert') + , colors = require('..'); + +console.log('Foreground colors ..'); + +assert.equal(colors.white('printed in white'), '\u001b[37mprinted in white\u001b[39m'); + +assert.equal(colors.black('printed in black'), '\u001b[30mprinted in black\u001b[39m'); +assert.equal(colors.brightBlack('printed in bright black'), '\u001b[90mprinted in bright black\u001b[39m'); + +assert.equal(colors.green('printed in green'), '\u001b[32mprinted in green\u001b[39m'); +assert.equal(colors.brightGreen('printed in bright green'), '\u001b[92mprinted in bright green\u001b[39m'); + +assert.equal(colors.red('printed in red'), '\u001b[31mprinted in red\u001b[39m'); +assert.equal(colors.brightRed('printed in bright red'), '\u001b[91mprinted in bright red\u001b[39m'); + +console.log('OK'); + +console.log('Background colors ..'); + +assert.equal( + colors.bgBlack('printed with black background') + , '\u001b[40mprinted with black background\u001b[49m' +); + +assert.equal( + colors.bgYellow('printed with yellow background') + , '\u001b[43mprinted with yellow background\u001b[49m' +); +assert.equal( + colors.bgBrightYellow('printed with bright yellow background') + , '\u001b[103mprinted with bright yellow background\u001b[49m' +); + +assert.equal( + colors.bgWhite('printed with white background') + , '\u001b[47mprinted with white background\u001b[49m' +); + +console.log('OK'); + +console.log('Mixing background and foreground colors ..'); + +assert.equal( + colors.blue(colors.bgYellow('printed in blue with yellow background')) + , '\u001b[34m\u001b[43mprinted in blue with yellow background\u001b[49m\u001b[39m' +); +assert.equal( + colors.bgYellow(colors.blue('printed in blue with yellow background again')) + , '\u001b[43m\u001b[34mprinted in blue with yellow background again\u001b[39m\u001b[49m' +); + +console.log('OK'); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.npmignore b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.npmignore new file mode 100644 index 0000000..7dccd97 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.npmignore @@ -0,0 +1,15 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +node_modules +npm-debug.log \ No newline at end of file diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.travis.yml b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.travis.yml new file mode 100644 index 0000000..84fd7ca --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - 0.9 diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/Changelog.md b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/Changelog.md new file mode 100644 index 0000000..ab1f7bb --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/Changelog.md @@ -0,0 +1,15 @@ +# Changelog + +### 0.4 +- browser support + +### 0.3 +- passing more information into {Function} config +- API change: returning {Object} with code, ast, comments and tokens attached instead of just a code {String} +- comments support + +### 0.2 +- upgrade to Esprima 1.0.0 + +### 0.1 +- first working version diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/LICENSE b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/LICENSE new file mode 100644 index 0000000..19c037f --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/LICENSE @@ -0,0 +1,23 @@ +Copyright 2012 Thorsten Lorenz. +All rights reserved. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/README.md b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/README.md new file mode 100644 index 0000000..81b8a53 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/README.md @@ -0,0 +1,192 @@ +# redeyed [![build status](https://secure.travis-ci.org/thlorenz/redeyed.png?branch=master)](http://travis-ci.org/thlorenz/redeyed) + +*Add color to your JavaScript!* + +![frog](http://allaboutfrogs.org/gallery/photos/redeyes/red1.gif) + +[Red Eyed Tree Frog](http://allaboutfrogs.org/info/species/redeye.html) *(Agalychnis callidryas)* + +## What? + +Takes JavaScript code, along with a config and returns the original code with tokens wrapped and/or replaced as configured. + +## Where? + +- server side using nodejs +- in the [browser](#browser-support) + +## What for? + +One usecase is adding metadata to your code that can then be used to apply syntax highlighting. + +## How? + +- copy the [config.js](https://github.com/thlorenz/redeyed/blob/master/config.js) and edit it in order to specify how + certain tokens are to be surrounded/replaced +- replace the `undefined` of each token you want to configure with one of the following + +### {String} config + +`'before:after'` + +wraps the token inside before/after + +### {Object} config + +`{ _before: 'before', _after: 'after' }` + +wraps token inside before/after + +#### Missing before and after resolution for {String} and {Object} config + +For the `{String}` and `{Object}` configurations, 'before' or 'after' may be omitted: + +- `{String}`: + - `'before:'` (omitting 'after') + - `':after'` (omitting 'before') +- `{Object}`: + - `{ _before: 'before' }` (omitting '_after') + - `{ _after: 'after' }` (omitting '_before') + +In these cases the missing half is resolved as follows: + +- from the `parent._default` (i.e., `Keyword._default`) if found +- otherwise from the `config._default` if found +- otherwise `''` (empty string) + +### {Function} config + +`function (tokenString, info) { return {String}|{Object}; }` + +#### Inputs + +- tokenString: the content of the token that is currently being processed +- info: an object with the following structure + +```js +{ + // {Int} + // the index of the token being processed inside tokens + tokenIndex + + // {Array} + // all tokens that are being processed including comments + // (i.e. the result of merging esprima tokens and comments) + , tokens + + // {Object} + // the abstract syntax tree of the parsed code + , ast + + // {String} + // the code that was parsed (same string as the one passed to redeyed(code ..) + , code +} +``` + +In most cases the `tokenString` is all you need. The extra info object is passed in case you need to gather more +information about the `token`'s surroundings in order to decide how to transform it. +See: [replace-log-example](https://github.com/thlorenz/redeyed/blob/master/examples/replace-log.js) + +#### Output + +You can return a {String} or an {Object} from a {Function} config. + +- when returning a {String}, the token value will be replaced with it +- when returning an {Object}, it should be of the following form: + +```js +{ + // {String} + // the string that should be substituted for the value of the current and all skipped tokens + replacement + + // {Object} (Token) + // the token after which processing should continue + // all tokens in between the current one and this one inclusive will be ignored + , skipPastToken +} +``` + +### Transforming JavaScript code + +***redeyed(code, config[, opts])*** + +Invoke redeyed with your **config**uration, a **code** snippet and maybe **opts** as in the below example: + +```javascript +var redeyed = require('redeyed') + , config = require('./path/to/config') + , code = 'var a = 3;' + , result; + +// redeyed will throw an error (caused by the esprima parser) if the code has invalid javascript +try { + result = redeyed(code, config); + console.log(result.code); +} catch(err) { + console.error(err); +} +``` + +***opts***: +```js +{ // {Boolean} + // if true `result.code` is not assigned and therefore `undefined` + // if false (default) `result.code` property contains the result of `split.join` + nojoin: true|false +} +``` + +***return value***: + +```js +{ ast + , tokens + , comments + , splits + , code +} +``` + +- ast `{Array}`: [abstract syntax tree](http://en.wikipedia.org/wiki/Abstract_syntax_tree) as returned by [esprima + parse](http://en.wikipedia.org/wiki/Abstract_syntax_tree) +- tokens `{Array}`: [tokens](http://en.wikipedia.org/wiki/Token_(parser)) provided by esprima (excluding + comments) +- comments `{Array}`: block and line comments as provided by esprima +- splits `{Array}`: code pieces split up, some of which where transformed as configured +- code `{String}`: transformed code, same as `splits.join('')` unless this step has been skipped (see opts) + +## Browser Support + +### AMD + +Ensure to include [esprima](https://github.com/ariya/esprima) as one of your dependencies + +```js +define(['redeyed'], function (redeyed) { + [ .. ] +}); +``` + +### Attached to global window object + +The `redeyed {Function}` will be exposed globally as `window.redeyed` - big surprise! + +```html + + +``` + +## redeyed in the wild + +- [cardinal](https://github.com/thlorenz/cardinal): Syntax highlights JavaScript code with ANSI colors to be printed to + the terminal +- [peacock](http://thlorenz.github.com/peacock/): JavaScript syntax highlighter that generates html that is compatible + with pygments styles. + +## Examples + +- `npm explore redeyed; npm demo` will let you try the [browser example](https://github.com/thlorenz/redeyed/tree/master/examples/browser) +- `npm explore redeyed; npm demo-log` will let you try the [replace log example](https://github.com/thlorenz/redeyed/blob/master/examples/replace-log.js) + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/config.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/config.js new file mode 100644 index 0000000..ade0de8 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/config.js @@ -0,0 +1,137 @@ +/* + * Copy this file and use it as a starting point for your redeyed config. + * Just fill in the tokens you want to surround/replace. + * Keep in mind that more specific configurations override less specific ones. + */ + +module.exports = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : undefined + } + + , 'Identifier': { + _default: undefined + } + + , 'Null': { + _default: undefined + } + + , 'Numeric': { + _default: undefined + } + + , 'String': { + _default: undefined + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : undefined + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : undefined + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : undefined + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : undefined + , 'return' : undefined + , 'switch' : undefined + + , 'this' : undefined + , 'throw' : undefined + , 'try' : undefined + , 'typeof' : undefined + + , 'var' : undefined + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : undefined + } + , 'Punctuator': { + ';': undefined + , '.': undefined + , ',': undefined + + , '{': undefined + , '}': undefined + , '(': undefined + , ')': undefined + , '[': undefined + , ']': undefined + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: undefined + } + + // line comment + , Line: { + _default: undefined + } + + /* block comment */ + , Block: { + _default: undefined + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.css b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.css new file mode 100644 index 0000000..fc9206e --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.css @@ -0,0 +1,31 @@ +.code { + width: 500px; + height: 500px; + display: block; +} + +.config { + width: 500px; + height: 400px; + display: block; +} + +.go { + display: block; + float: right; + font-size: 18px; +} + +.result { + width: 500px; + height: 1000px; + display: block; +} + +.edit { + float: left; +} + +.results { + float: left; +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.html b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.html new file mode 100644 index 0000000..a20ea4c --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.html @@ -0,0 +1,35 @@ + + + + + + + + +
+ Change the config and/or the original code in order to affect the "redeyed" result +
+
+
+

Redeyed Config

+ + +
+
+

Original Code

+ +
+
+
+

Result

+ +
+ + + + + + + + + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.js new file mode 100644 index 0000000..82fd22f --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/index.js @@ -0,0 +1,33 @@ +var $code = $('.code') + , $config = $('.config') + , $result = $('.result') + ; + +function go () { + var config; + try { + config = JSON.parse($config.val()); + } catch (e) { + $result.val('In "Redeyed Config": ' + e.toString()); + return; + } + + try { + var code = $code.val() + , result = redeyed(code, config); + + $result.val(result.code); + } catch (e) { + $result.val('In "Original Code": ' + e.toString()); + } +} + +$code.val(window.redeyed.toString()); + +$config.val(JSON.stringify(window.sampleConfig, false, 2)); + +$('.go').click(go); + +go(); + + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/sample-config.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/sample-config.js new file mode 100644 index 0000000..47456ef --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/browser/sample-config.js @@ -0,0 +1,131 @@ +window.sampleConfig = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : '?:?' + } + + , 'Identifier': { + _default: '-> : <-' + } + + , 'Null': { + _default: '**:**' + } + + , 'Numeric': { + _default: 'n:N' + } + + , 'String': { + _default: 'string -> :' + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : undefined + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : undefined + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : undefined + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : undefined + , 'return' : undefined + , 'switch' : undefined + + , 'this' : undefined + , 'throw' : undefined + , 'try' : undefined + , 'typeof' : undefined + + , 'var' : undefined + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : ': <- keyword' + } + , 'Punctuator': { + ';': undefined + , '.': undefined + , ',': undefined + + , '{': undefined + , '}': undefined + , '(': undefined + , ')': undefined + , '[': undefined + , ']': undefined + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: undefined + } + + // line comment + , Line: { + _default: undefined + } + + /* block comment */ + , Block: { + _default: undefined + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/replace-log.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/replace-log.js new file mode 100644 index 0000000..4b12ccf --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/replace-log.js @@ -0,0 +1,61 @@ +var path = require('path') + , fs = require('fs') + , redeyed = require('..') + , vm = require('vm') + ; + +var samplePath = path.join(__dirname, 'sources', 'log.js') + , origCode = fs.readFileSync(samplePath, 'utf-8') + , kinds = ['silly', 'info', 'warn', 'error' ] + ; + +function replaceConsole(s, info) { + var code = info.code + , idx = info.tokenIndex + , tokens = info.tokens + , next = tokens[idx + 1].value + , kind = tokens[idx + 2].value + , openParen = tokens[idx + 3].value + , firstArgTkn = tokens[idx + 4] + , argIdx = idx + 3 + , open + , tkn + ; + + if (kind === 'log') kind = 'silly'; + + // not a console.xxx(...) statement? -> just return original + if (next !== '.' || !~kinds.indexOf(kind) || openParen !== '(') return s; + + // skip past arguments to console.xxx all args from ( to ) + open = 1; + while (open) { + tkn = tokens[++argIdx]; + + // count open parens vs. closed ones to handle things like console.log(new Error('..')); + if (tkn.value === '(') open++; + if (tkn.value === ')') open--; + } + + // tkn now is the last closing paren + var argsIncludingClosingParen = code.slice(firstArgTkn.range[0], tkn.range[1]) + , result = 'log.' + kind + '("main-logger", ' + argsIncludingClosingParen; + + // tell redeyed to skip the entire console.xxx(..) statement since we are replacing it all + return { replacement: result, skipPastToken: tkn }; +} + +function transformAndRun () { + var config = { + Identifier: { console: replaceConsole } + } + , code = redeyed(origCode, config).code + , context = vm.createContext({ require: require }); + + console.log('Original code:\n', origCode); + console.log('\nlog calls replaced:\n', code); + console.log('\nLets run it:'); + vm.runInContext(code, context, 'transformed-log.vm'); +} + +transformAndRun(); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/sources/log.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/sources/log.js new file mode 100644 index 0000000..7994d2f --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/examples/sources/log.js @@ -0,0 +1,8 @@ +// First two lines will be needed when we replaced all console.xxx statements with log.xxx +var log = require('npmlog'); +log.level = 'silly'; + +console.info('info ', 1); +console.log('log ', 2); +console.warn('warn ', 3); +console.error('error ', new Error('oh my!')); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esparse b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esparse new file mode 120000 index 0000000..7423b18 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esparse @@ -0,0 +1 @@ +../esprima/bin/esparse.js \ No newline at end of file diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esvalidate b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esvalidate new file mode 120000 index 0000000..16069ef --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/.bin/esvalidate @@ -0,0 +1 @@ +../esprima/bin/esvalidate.js \ No newline at end of file diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/README.md b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/README.md new file mode 100644 index 0000000..a74bd12 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/README.md @@ -0,0 +1,73 @@ +**Esprima** ([esprima.org](http://esprima.org)) is a high performance, +standard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm) +parser written in ECMAScript (also popularly known as +[JavaScript](http://en.wikipedia.org/wiki/JavaScript>JavaScript)). +Esprima is created and maintained by [Ariya Hidayat](http://twitter.com/ariyahidayat), +with the help of [many contributors](https://github.com/ariya/esprima/contributors). + +Esprima runs on web browsers (IE 6+, Firefox 1+, Safari 3+, Chrome 1+, Konqueror 4.6+, Opera 8+) as well as +[Node.js](http://nodejs.org). + +### Features + +- Full support for [ECMAScript 5.1](http://www.ecma-international.org/publications/standards/Ecma-262.htm)(ECMA-262) +- Sensible [syntax tree format](http://esprima.org/doc/index.html#ast) compatible with Mozilla +[Parser AST](https://developer.mozilla.org/en/SpiderMonkey/Parser_API) +- Heavily tested (> 550 [unit tests](http://esprima.org/test/) with solid 100% statement coverage) +- Optional tracking of syntax node location (index-based and line-column) +- Experimental support for ES6/Harmony (module, class, destructuring, ...) + +Esprima is blazing fast (see the [benchmark suite](http://esprima.org/test/benchmarks.html)). +It is up to 3x faster than UglifyJS v1 and it is still [competitive](http://esprima.org/test/compare.html) +with the new generation of fast parsers. + +### Applications + +Esprima serves as the basis for many popular JavaScript development tools: + +- Code coverage analysis: [node-cover](https://github.com/itay/node-cover), [Istanbul](https://github.com/yahoo/Istanbul) +- Documentation tool: [JFDoc](https://github.com/thejohnfreeman/jfdoc), [JSDuck](https://github.com/senchalabs/jsduck) +- Language extension: [LLJS](http://mbebenita.github.com/LLJS/) (low-level JS), +[Sweet.js](http://sweetjs.org/) (macro) +- ES6/Harmony transpiler: [Six](https://github.com/matthewrobb/six), [Harmonizr](https://github.com/jdiamond/harmonizr) +- Eclipse Orion smart editing ([outline view](https://github.com/aclement/esprima-outline), [content assist](http://contraptionsforprogramming.blogspot.com/2012/02/better-javascript-content-assist-in.html)) +- Source code modification: [Esmorph](https://github.com/ariya/esmorph), [Code Painter](https://github.com/fawek/codepainter), +- Source transformation: [node-falafel](https://github.com/substack/node-falafel), [Esmangle](https://github.com/Constellation/esmangle), [escodegen](https://github.com/Constellation/escodegen) + +### Questions? +- [Documentation](http://esprima.org/doc) +- [Issue tracker](http://issues.esprima.org): [known problems](http://code.google.com/p/esprima/issues/list?q=Defect) +and [future plans](http://code.google.com/p/esprima/issues/list?q=Enhancement) +- [Mailing list](http://groups.google.com/group/esprima) +- [Contribution guide](http://esprima.org/doc/index.html#contribution) + +Follow [@Esprima](http://twitter.com/Esprima) on Twitter to get the +development updates. +Feedback and contribution are welcomed! + +### License + +Copyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about) + and other contributors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esparse.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esparse.js new file mode 100755 index 0000000..3e7bb81 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esparse.js @@ -0,0 +1,117 @@ +#!/usr/bin/env node +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint sloppy:true node:true rhino:true */ + +var fs, esprima, fname, content, options, syntax; + +if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); +} else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esparse.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esparse [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --comment Gather all line and block comments in an array'); + console.log(' --loc Include line-column location info for each syntax node'); + console.log(' --range Include index-based range for each syntax node'); + console.log(' --raw Display the raw value of literals'); + console.log(' --tokens List all tokens in an array'); + console.log(' --tolerant Tolerate errors on a best-effort basis (experimental)'); + console.log(' -v, --version Shows program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = {}; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Parser (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry === '--comment') { + options.comment = true; + } else if (entry === '--loc') { + options.loc = true; + } else if (entry === '--range') { + options.range = true; + } else if (entry === '--raw') { + options.raw = true; + } else if (entry === '--tokens') { + options.tokens = true; + } else if (entry === '--tolerant') { + options.tolerant = true; + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else if (typeof fname === 'string') { + console.log('Error: more than one input file.'); + process.exit(1); + } else { + fname = entry; + } +}); + +if (typeof fname !== 'string') { + console.log('Error: no input file.'); + process.exit(1); +} + +try { + content = fs.readFileSync(fname, 'utf-8'); + syntax = esprima.parse(content, options); + console.log(JSON.stringify(syntax, null, 4)); +} catch (e) { + console.log('Error: ' + e.message); + process.exit(1); +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esvalidate.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esvalidate.js new file mode 100755 index 0000000..e0af3f7 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/bin/esvalidate.js @@ -0,0 +1,177 @@ +#!/usr/bin/env node +/* + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint sloppy:true plusplus:true node:true rhino:true */ + +var fs, esprima, options, fnames, count; + +if (typeof require === 'function') { + fs = require('fs'); + esprima = require('esprima'); +} else if (typeof load === 'function') { + try { + load('esprima.js'); + } catch (e) { + load('../esprima.js'); + } +} + +// Shims to Node.js objects when running under Rhino. +if (typeof console === 'undefined' && typeof process === 'undefined') { + console = { log: print }; + fs = { readFileSync: readFile }; + process = { argv: arguments, exit: quit }; + process.argv.unshift('esvalidate.js'); + process.argv.unshift('rhino'); +} + +function showUsage() { + console.log('Usage:'); + console.log(' esvalidate [options] file.js'); + console.log(); + console.log('Available options:'); + console.log(); + console.log(' --format=type Set the report format, plain (default) or junit'); + console.log(' -v, --version Print program version'); + console.log(); + process.exit(1); +} + +if (process.argv.length <= 2) { + showUsage(); +} + +options = { + format: 'plain' +}; + +fnames = []; + +process.argv.splice(2).forEach(function (entry) { + + if (entry === '-h' || entry === '--help') { + showUsage(); + } else if (entry === '-v' || entry === '--version') { + console.log('ECMAScript Validator (using Esprima version', esprima.version, ')'); + console.log(); + process.exit(0); + } else if (entry.slice(0, 9) === '--format=') { + options.format = entry.slice(9); + if (options.format !== 'plain' && options.format !== 'junit') { + console.log('Error: unknown report format ' + options.format + '.'); + process.exit(1); + } + } else if (entry.slice(0, 2) === '--') { + console.log('Error: unknown option ' + entry + '.'); + process.exit(1); + } else { + fnames.push(entry); + } +}); + +if (fnames.length === 0) { + console.log('Error: no input file.'); + process.exit(1); +} + +if (options.format === 'junit') { + console.log(''); + console.log(''); +} + +count = 0; +fnames.forEach(function (fname) { + var content, timestamp, syntax, name; + try { + content = fs.readFileSync(fname, 'utf-8'); + + if (content[0] === '#' && content[1] === '!') { + content = '//' + content.substr(2, content.length); + } + + timestamp = Date.now(); + syntax = esprima.parse(content, { tolerant: true }); + + if (options.format === 'junit') { + + name = fname; + if (name.lastIndexOf('/') >= 0) { + name = name.slice(name.lastIndexOf('/') + 1); + } + + console.log(''); + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + console.log(' '); + console.log(' ' + + error.message + '(' + name + ':' + error.lineNumber + ')' + + ''); + console.log(' '); + }); + + console.log(''); + + } else if (options.format === 'plain') { + + syntax.errors.forEach(function (error) { + var msg = error.message; + msg = msg.replace(/^Line\ [0-9]*\:\ /, ''); + msg = fname + ':' + error.lineNumber + ': ' + msg; + console.log(msg); + ++count; + }); + + } + } catch (e) { + ++count; + if (options.format === 'junit') { + console.log(''); + console.log(' '); + console.log(' ' + + e.message + '(' + fname + ((e.lineNumber) ? ':' + e.lineNumber : '') + + ')'); + console.log(' '); + console.log(''); + } else { + console.log('Error: ' + e.message); + } + } +}); + +if (options.format === 'junit') { + console.log(''); +} + +if (count > 0) { + process.exit(1); +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/esprima.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/esprima.js new file mode 100644 index 0000000..f1320da --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/esprima.js @@ -0,0 +1,3908 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint bitwise:true plusplus:true */ +/*global esprima:true, define:true, exports:true, window: true, +throwError: true, createLiteral: true, generateStatement: true, +parseAssignmentExpression: true, parseBlock: true, parseExpression: true, +parseFunctionDeclaration: true, parseFunctionExpression: true, +parseFunctionSourceElements: true, parseVariableIdentifier: true, +parseLeftHandSideExpression: true, +parseStatement: true, parseSourceElement: true */ + +(function (root, factory) { + 'use strict'; + + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, + // Rhino, and plain browser loading. + if (typeof define === 'function' && define.amd) { + define(['exports'], factory); + } else if (typeof exports !== 'undefined') { + factory(exports); + } else { + factory((root.esprima = {})); + } +}(this, function (exports) { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + buffer, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'), + NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function sliceSource(from, to) { + return source.slice(from, to); + } + + if (typeof 'esprima'[0] === 'undefined') { + sliceSource = function sliceArraySource(from, to) { + return source.slice(from, to).join(''); + }; + } + + function isDecimalDigit(ch) { + return '0123456789'.indexOf(ch) >= 0; + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') || + (ch === '\u000C') || (ch === '\u00A0') || + (ch.charCodeAt(0) >= 0x1680 && + '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029'); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === '$') || (ch === '_') || (ch === '\\') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch)); + } + + function isIdentifierPart(ch) { + return (ch === '$') || (ch === '_') || (ch === '\\') || + (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || + ((ch >= '0') && (ch <= '9')) || + ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch)); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + + // Future reserved words. + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + } + + return false; + } + + function isStrictModeReservedWord(id) { + switch (id) { + + // Strict Mode reserved words. + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + } + + return false; + } + + function isRestrictedWord(id) { + return id === 'eval' || id === 'arguments'; + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + var keyword = false; + switch (id.length) { + case 2: + keyword = (id === 'if') || (id === 'in') || (id === 'do'); + break; + case 3: + keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try'); + break; + case 4: + keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with'); + break; + case 5: + keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw'); + break; + case 6: + keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch'); + break; + case 7: + keyword = (id === 'default') || (id === 'finally'); + break; + case 8: + keyword = (id === 'function') || (id === 'continue') || (id === 'debugger'); + break; + case 10: + keyword = (id === 'instanceof'); + break; + } + + if (keyword) { + return true; + } + + switch (id) { + // Future reserved words. + // 'const' is specialized as Keyword in V8. + case 'const': + return true; + + // For compatiblity to SpiderMonkey and ES.next + case 'yield': + case 'let': + return true; + } + + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + return isFutureReservedWord(id); + } + + // 7.4 Comments + + function skipComment() { + var ch, blockComment, lineComment; + + blockComment = false; + lineComment = false; + + while (index < length) { + ch = source[index]; + + if (lineComment) { + ch = source[index++]; + if (isLineTerminator(ch)) { + lineComment = false; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } + } else if (blockComment) { + if (isLineTerminator(ch)) { + if (ch === '\r' && source[index + 1] === '\n') { + ++index; + } + ++lineNumber; + ++index; + lineStart = index; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + ch = source[index++]; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + if (ch === '*') { + ch = source[index]; + if (ch === '/') { + ++index; + blockComment = false; + } + } + } + } else if (ch === '/') { + ch = source[index + 1]; + if (ch === '/') { + index += 2; + lineComment = true; + } else if (ch === '*') { + index += 2; + blockComment = true; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + break; + } + } else if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanIdentifier() { + var ch, start, id, restore; + + ch = source[index]; + if (!isIdentifierStart(ch)) { + return; + } + + start = index; + if (ch === '\\') { + ++index; + if (source[index] !== 'u') { + return; + } + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + if (ch === '\\' || !isIdentifierStart(ch)) { + return; + } + id = ch; + } else { + index = restore; + id = 'u'; + } + } else { + id = source[index++]; + } + + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch)) { + break; + } + if (ch === '\\') { + ++index; + if (source[index] !== 'u') { + return; + } + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + if (ch === '\\' || !isIdentifierPart(ch)) { + return; + } + id += ch; + } else { + index = restore; + id += 'u'; + } + } else { + id += source[index++]; + } + } + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + return { + type: Token.Identifier, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (isKeyword(id)) { + return { + type: Token.Keyword, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.1 Null Literals + + if (id === 'null') { + return { + type: Token.NullLiteral, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.2 Boolean Literals + + if (id === 'true' || id === 'false') { + return { + type: Token.BooleanLiteral, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + return { + type: Token.Identifier, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + ch1 = source[index], + ch2, + ch3, + ch4; + + // Check for most common single-character punctuators. + + if (ch1 === ';' || ch1 === '{' || ch1 === '}') { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === ',' || ch1 === '(' || ch1 === ')') { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // Dot (.) can also start a floating-point number, hence the need + // to check the next character. + + ch2 = source[index + 1]; + if (ch1 === '.' && !isDecimalDigit(ch2)) { + return { + type: Token.Punctuator, + value: source[index++], + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // Peek more characters. + + ch3 = source[index + 2]; + ch4 = source[index + 3]; + + // 4-character punctuator: >>>= + + if (ch1 === '>' && ch2 === '>' && ch3 === '>') { + if (ch4 === '=') { + index += 4; + return { + type: Token.Punctuator, + value: '>>>=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // 3-character punctuators: === !== >>> <<= >>= + + if (ch1 === '=' && ch2 === '=' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '===', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '!' && ch2 === '=' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '!==', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '>' && ch2 === '>' && ch3 === '>') { + index += 3; + return { + type: Token.Punctuator, + value: '>>>', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '<' && ch2 === '<' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '<<=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + if (ch1 === '>' && ch2 === '>' && ch3 === '=') { + index += 3; + return { + type: Token.Punctuator, + value: '>>=', + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 2-character punctuators: <= >= == != ++ -- << >> && || + // += -= *= %= &= |= ^= /= + + if (ch2 === '=') { + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + index += 2; + return { + type: Token.Punctuator, + value: ch1 + ch2, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { + if ('+-<>&|'.indexOf(ch2) >= 0) { + index += 2; + return { + type: Token.Punctuator, + value: ch1 + ch2, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // The remaining 1-character punctuators. + + if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) { + return { + type: Token.Punctuator, + value: source[index++], + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + } + + // 7.8.3 Numeric Literals + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isHexDigit(ch)) { + break; + } + number += source[index++]; + } + + if (number.length <= 2) { + // only 0x + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + return { + type: Token.NumericLiteral, + value: parseInt(number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } else if (isOctalDigit(ch)) { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isOctalDigit(ch)) { + break; + } + number += source[index++]; + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch) || isDecimalDigit(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // decimal number starts with '0' such as '09' is illegal. + if (isDecimalDigit(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } + + if (ch === '.') { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + + ch = source[index]; + if (isDecimalDigit(ch)) { + number += source[index++]; + while (index < length) { + ch = source[index]; + if (!isDecimalDigit(ch)) { + break; + } + number += source[index++]; + } + } else { + ch = 'character ' + ch; + if (index >= length) { + ch = ''; + } + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (index < length) { + ch = source[index]; + if (isIdentifierStart(ch)) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!isLineTerminator(ch)) { + switch (ch) { + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'u': + case 'x': + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + } + } else if (isLineTerminator(ch)) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + lineNumber: lineNumber, + lineStart: lineStart, + range: [start, index] + }; + } + + function scanRegExp() { + var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false; + + buffer = null; + skipComment(); + + start = index; + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch)) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } else if (isLineTerminator(ch)) { + throwError({}, Messages.UnterminatedRegExp); + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + pattern = str.substr(1, str.length - 2); + + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch)) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + str += '\\u'; + for (; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + } else { + str += '\\'; + } + } else { + flags += ch; + str += ch; + } + } + + try { + value = new RegExp(pattern, flags); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + return { + literal: str, + value: value, + range: [start, index] + }; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advance() { + var ch, token; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + range: [index, index] + }; + } + + token = scanPunctuator(); + if (typeof token !== 'undefined') { + return token; + } + + ch = source[index]; + + if (ch === '\'' || ch === '"') { + return scanStringLiteral(); + } + + if (ch === '.' || isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + token = scanIdentifier(); + if (typeof token !== 'undefined') { + return token; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + function lex() { + var token; + + if (buffer) { + index = buffer.range[1]; + lineNumber = buffer.lineNumber; + lineStart = buffer.lineStart; + token = buffer; + buffer = null; + return token; + } + + buffer = null; + return advance(); + } + + function lookahead() { + var pos, line, start; + + if (buffer !== null) { + return buffer; + } + + pos = index; + line = lineNumber; + start = lineStart; + buffer = advance(); + index = pos; + lineNumber = line; + lineStart = start; + + return buffer; + } + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + return args[index] || ''; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.range[0]; + error.lineNumber = token.lineNumber; + error.column = token.range[0] - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + + function expectKeyword(keyword) { + var token = lex(); + if (token.type !== Token.Keyword || token.value !== keyword) { + throwUnexpected(token); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + var token = lookahead(); + return token.type === Token.Punctuator && token.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + var token = lookahead(); + return token.type === Token.Keyword && token.value === keyword; + } + + // Return true if the next token is an assignment operator + + function matchAssign() { + var token = lookahead(), + op = token.value; + + if (token.type !== Token.Punctuator) { + return false; + } + return op === '=' || + op === '*=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + } + + function consumeSemicolon() { + var token, line; + + // Catch the very common case first. + if (source[index] === ';') { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (match(';')) { + lex(); + return; + } + + token = lookahead(); + if (token.type !== Token.EOF && !match('}')) { + throwUnexpected(token); + } + } + + // Return true if provided expression is LeftHandSideExpression + + function isLeftHandSide(expr) { + return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = []; + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + expect(']'); + + return { + type: Syntax.ArrayExpression, + elements: elements + }; + } + + // 11.1.5 Object Initialiser + + function parsePropertyFunction(param, first) { + var previousStrict, body; + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (first && strict && isRestrictedWord(param[0].name)) { + throwErrorTolerant(first, Messages.StrictParamName); + } + strict = previousStrict; + + return { + type: Syntax.FunctionExpression, + id: null, + params: param, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + function parseObjectPropertyKey() { + var token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return createLiteral(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseObjectProperty() { + var token, key, id, param; + + token = lookahead(); + + if (token.type === Token.Identifier) { + + id = parseObjectPropertyKey(); + + // Property Assignment: Getter and Setter. + + if (token.value === 'get' && !match(':')) { + key = parseObjectPropertyKey(); + expect('('); + expect(')'); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction([]), + kind: 'get' + }; + } else if (token.value === 'set' && !match(':')) { + key = parseObjectPropertyKey(); + expect('('); + token = lookahead(); + if (token.type !== Token.Identifier) { + expect(')'); + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction([]), + kind: 'set' + }; + } else { + param = [ parseVariableIdentifier() ]; + expect(')'); + return { + type: Syntax.Property, + key: key, + value: parsePropertyFunction(param, token), + kind: 'set' + }; + } + } else { + expect(':'); + return { + type: Syntax.Property, + key: id, + value: parseAssignmentExpression(), + kind: 'init' + }; + } + } else if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + return { + type: Syntax.Property, + key: key, + value: parseAssignmentExpression(), + kind: 'init' + }; + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, kind, map = {}, toString = String; + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + if (Object.prototype.hasOwnProperty.call(map, name)) { + if (map[name] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[name] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[name] |= kind; + } else { + map[name] = kind; + } + + properties.push(property); + + if (!match('}')) { + expect(','); + } + } + + expect('}'); + + return { + type: Syntax.ObjectExpression, + properties: properties + }; + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + function parsePrimaryExpression() { + var token = lookahead(), + type = token.type; + + if (type === Token.Identifier) { + return { + type: Syntax.Identifier, + name: lex().value + }; + } + + if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return createLiteral(lex()); + } + + if (type === Token.Keyword) { + if (matchKeyword('this')) { + lex(); + return { + type: Syntax.ThisExpression + }; + } + + if (matchKeyword('function')) { + return parseFunctionExpression(); + } + } + + if (type === Token.BooleanLiteral) { + lex(); + token.value = (token.value === 'true'); + return createLiteral(token); + } + + if (type === Token.NullLiteral) { + lex(); + token.value = null; + return createLiteral(token); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('/') || match('/=')) { + return createLiteral(scanRegExp()); + } + + return throwUnexpected(lex()); + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseNewExpression() { + var expr; + + expectKeyword('new'); + + expr = { + type: Syntax.NewExpression, + callee: parseLeftHandSideExpression(), + 'arguments': [] + }; + + if (match('(')) { + expr['arguments'] = parseArguments(); + } + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr; + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[') || match('(')) { + if (match('(')) { + expr = { + type: Syntax.CallExpression, + callee: expr, + 'arguments': parseArguments() + }; + } else if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + } + } + + return expr; + } + + + function parseLeftHandSideExpression() { + var expr; + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[')) { + if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + } + } + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(), token; + + token = lookahead(); + if (token.type !== Token.Punctuator) { + return expr; + } + + if ((match('++') || match('--')) && !peekLineTerminator()) { + // 11.3.1, 11.3.2 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant({}, Messages.StrictLHSPostfix); + } + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + expr = { + type: Syntax.UpdateExpression, + operator: lex().value, + argument: expr, + prefix: false + }; + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr; + + token = lookahead(); + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return parsePostfixExpression(); + } + + if (match('++') || match('--')) { + token = lex(); + expr = parseUnaryExpression(); + // 11.4.4, 11.4.5 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant({}, Messages.StrictLHSPrefix); + } + + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + expr = { + type: Syntax.UpdateExpression, + operator: token.value, + argument: expr, + prefix: true + }; + return expr; + } + + if (match('+') || match('-') || match('~') || match('!')) { + expr = { + type: Syntax.UnaryExpression, + operator: lex().value, + argument: parseUnaryExpression(), + prefix: true + }; + return expr; + } + + if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + expr = { + type: Syntax.UnaryExpression, + operator: lex().value, + argument: parseUnaryExpression(), + prefix: true + }; + if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { + throwErrorTolerant({}, Messages.StrictDelete); + } + return expr; + } + + return parsePostfixExpression(); + } + + // 11.5 Multiplicative Operators + + function parseMultiplicativeExpression() { + var expr = parseUnaryExpression(); + + while (match('*') || match('/') || match('%')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseUnaryExpression() + }; + } + + return expr; + } + + // 11.6 Additive Operators + + function parseAdditiveExpression() { + var expr = parseMultiplicativeExpression(); + + while (match('+') || match('-')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseMultiplicativeExpression() + }; + } + + return expr; + } + + // 11.7 Bitwise Shift Operators + + function parseShiftExpression() { + var expr = parseAdditiveExpression(); + + while (match('<<') || match('>>') || match('>>>')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseAdditiveExpression() + }; + } + + return expr; + } + // 11.8 Relational Operators + + function parseRelationalExpression() { + var expr, previousAllowIn; + + previousAllowIn = state.allowIn; + state.allowIn = true; + + expr = parseShiftExpression(); + + while (match('<') || match('>') || match('<=') || match('>=') || (previousAllowIn && matchKeyword('in')) || matchKeyword('instanceof')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseShiftExpression() + }; + } + + state.allowIn = previousAllowIn; + return expr; + } + + // 11.9 Equality Operators + + function parseEqualityExpression() { + var expr = parseRelationalExpression(); + + while (match('==') || match('!=') || match('===') || match('!==')) { + expr = { + type: Syntax.BinaryExpression, + operator: lex().value, + left: expr, + right: parseRelationalExpression() + }; + } + + return expr; + } + + // 11.10 Binary Bitwise Operators + + function parseBitwiseANDExpression() { + var expr = parseEqualityExpression(); + + while (match('&')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '&', + left: expr, + right: parseEqualityExpression() + }; + } + + return expr; + } + + function parseBitwiseXORExpression() { + var expr = parseBitwiseANDExpression(); + + while (match('^')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '^', + left: expr, + right: parseBitwiseANDExpression() + }; + } + + return expr; + } + + function parseBitwiseORExpression() { + var expr = parseBitwiseXORExpression(); + + while (match('|')) { + lex(); + expr = { + type: Syntax.BinaryExpression, + operator: '|', + left: expr, + right: parseBitwiseXORExpression() + }; + } + + return expr; + } + + // 11.11 Binary Logical Operators + + function parseLogicalANDExpression() { + var expr = parseBitwiseORExpression(); + + while (match('&&')) { + lex(); + expr = { + type: Syntax.LogicalExpression, + operator: '&&', + left: expr, + right: parseBitwiseORExpression() + }; + } + + return expr; + } + + function parseLogicalORExpression() { + var expr = parseLogicalANDExpression(); + + while (match('||')) { + lex(); + expr = { + type: Syntax.LogicalExpression, + operator: '||', + left: expr, + right: parseLogicalANDExpression() + }; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent; + + expr = parseLogicalORExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + + expr = { + type: Syntax.ConditionalExpression, + test: expr, + consequent: consequent, + alternate: parseAssignmentExpression() + }; + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var token, expr; + + token = lookahead(); + expr = parseConditionalExpression(); + + if (matchAssign()) { + // LeftHandSideExpression + if (!isLeftHandSide(expr)) { + throwErrorTolerant({}, Messages.InvalidLHSInAssignment); + } + + // 11.13.1 + if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { + throwErrorTolerant(token, Messages.StrictLHSAssignment); + } + + expr = { + type: Syntax.AssignmentExpression, + operator: lex().value, + left: expr, + right: parseAssignmentExpression() + }; + } + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + expr = { + type: Syntax.SequenceExpression, + expressions: [ expr ] + }; + + while (index < length) { + if (!match(',')) { + break; + } + lex(); + expr.expressions.push(parseAssignmentExpression()); + } + + } + return expr; + } + + // 12.1 Block + + function parseStatementList() { + var list = [], + statement; + + while (index < length) { + if (match('}')) { + break; + } + statement = parseSourceElement(); + if (typeof statement === 'undefined') { + break; + } + list.push(statement); + } + + return list; + } + + function parseBlock() { + var block; + + expect('{'); + + block = parseStatementList(); + + expect('}'); + + return { + type: Syntax.BlockStatement, + body: block + }; + } + + // 12.2 Variable Statement + + function parseVariableIdentifier() { + var token = lex(); + + if (token.type !== Token.Identifier) { + throwUnexpected(token); + } + + return { + type: Syntax.Identifier, + name: token.value + }; + } + + function parseVariableDeclaration(kind) { + var id = parseVariableIdentifier(), + init = null; + + // 12.2.1 + if (strict && isRestrictedWord(id.name)) { + throwErrorTolerant({}, Messages.StrictVarName); + } + + if (kind === 'const') { + expect('='); + init = parseAssignmentExpression(); + } else if (match('=')) { + lex(); + init = parseAssignmentExpression(); + } + + return { + type: Syntax.VariableDeclarator, + id: id, + init: init + }; + } + + function parseVariableDeclarationList(kind) { + var list = []; + + do { + list.push(parseVariableDeclaration(kind)); + if (!match(',')) { + break; + } + lex(); + } while (index < length); + + return list; + } + + function parseVariableStatement() { + var declarations; + + expectKeyword('var'); + + declarations = parseVariableDeclarationList(); + + consumeSemicolon(); + + return { + type: Syntax.VariableDeclaration, + declarations: declarations, + kind: 'var' + }; + } + + // kind may be `const` or `let` + // Both are experimental and not in the specification yet. + // see http://wiki.ecmascript.org/doku.php?id=harmony:const + // and http://wiki.ecmascript.org/doku.php?id=harmony:let + function parseConstLetDeclaration(kind) { + var declarations; + + expectKeyword(kind); + + declarations = parseVariableDeclarationList(kind); + + consumeSemicolon(); + + return { + type: Syntax.VariableDeclaration, + declarations: declarations, + kind: kind + }; + } + + // 12.3 Empty Statement + + function parseEmptyStatement() { + expect(';'); + + return { + type: Syntax.EmptyStatement + }; + } + + // 12.4 Expression Statement + + function parseExpressionStatement() { + var expr = parseExpression(); + + consumeSemicolon(); + + return { + type: Syntax.ExpressionStatement, + expression: expr + }; + } + + // 12.5 If statement + + function parseIfStatement() { + var test, consequent, alternate; + + expectKeyword('if'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + consequent = parseStatement(); + + if (matchKeyword('else')) { + lex(); + alternate = parseStatement(); + } else { + alternate = null; + } + + return { + type: Syntax.IfStatement, + test: test, + consequent: consequent, + alternate: alternate + }; + } + + // 12.6 Iteration Statements + + function parseDoWhileStatement() { + var body, test, oldInIteration; + + expectKeyword('do'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + if (match(';')) { + lex(); + } + + return { + type: Syntax.DoWhileStatement, + body: body, + test: test + }; + } + + function parseWhileStatement() { + var test, body, oldInIteration; + + expectKeyword('while'); + + expect('('); + + test = parseExpression(); + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + return { + type: Syntax.WhileStatement, + test: test, + body: body + }; + } + + function parseForVariableDeclaration() { + var token = lex(); + + return { + type: Syntax.VariableDeclaration, + declarations: parseVariableDeclarationList(), + kind: token.value + }; + } + + function parseForStatement() { + var init, test, update, left, right, body, oldInIteration; + + init = test = update = null; + + expectKeyword('for'); + + expect('('); + + if (match(';')) { + lex(); + } else { + if (matchKeyword('var') || matchKeyword('let')) { + state.allowIn = false; + init = parseForVariableDeclaration(); + state.allowIn = true; + + if (init.declarations.length === 1 && matchKeyword('in')) { + lex(); + left = init; + right = parseExpression(); + init = null; + } + } else { + state.allowIn = false; + init = parseExpression(); + state.allowIn = true; + + if (matchKeyword('in')) { + // LeftHandSideExpression + if (!isLeftHandSide(init)) { + throwErrorTolerant({}, Messages.InvalidLHSInForIn); + } + + lex(); + left = init; + right = parseExpression(); + init = null; + } + } + + if (typeof left === 'undefined') { + expect(';'); + } + } + + if (typeof left === 'undefined') { + + if (!match(';')) { + test = parseExpression(); + } + expect(';'); + + if (!match(')')) { + update = parseExpression(); + } + } + + expect(')'); + + oldInIteration = state.inIteration; + state.inIteration = true; + + body = parseStatement(); + + state.inIteration = oldInIteration; + + if (typeof left === 'undefined') { + return { + type: Syntax.ForStatement, + init: init, + test: test, + update: update, + body: body + }; + } + + return { + type: Syntax.ForInStatement, + left: left, + right: right, + body: body, + each: false + }; + } + + // 12.7 The continue statement + + function parseContinueStatement() { + var token, label = null; + + expectKeyword('continue'); + + // Optimize the most common form: 'continue;'. + if (source[index] === ';') { + lex(); + + if (!state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: null + }; + } + + if (peekLineTerminator()) { + if (!state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: null + }; + } + + token = lookahead(); + if (token.type === Token.Identifier) { + label = parseVariableIdentifier(); + + if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { + throwError({}, Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !state.inIteration) { + throwError({}, Messages.IllegalContinue); + } + + return { + type: Syntax.ContinueStatement, + label: label + }; + } + + // 12.8 The break statement + + function parseBreakStatement() { + var token, label = null; + + expectKeyword('break'); + + // Optimize the most common form: 'break;'. + if (source[index] === ';') { + lex(); + + if (!(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: null + }; + } + + if (peekLineTerminator()) { + if (!(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: null + }; + } + + token = lookahead(); + if (token.type === Token.Identifier) { + label = parseVariableIdentifier(); + + if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) { + throwError({}, Messages.UnknownLabel, label.name); + } + } + + consumeSemicolon(); + + if (label === null && !(state.inIteration || state.inSwitch)) { + throwError({}, Messages.IllegalBreak); + } + + return { + type: Syntax.BreakStatement, + label: label + }; + } + + // 12.9 The return statement + + function parseReturnStatement() { + var token, argument = null; + + expectKeyword('return'); + + if (!state.inFunctionBody) { + throwErrorTolerant({}, Messages.IllegalReturn); + } + + // 'return' followed by a space and an identifier is very common. + if (source[index] === ' ') { + if (isIdentifierStart(source[index + 1])) { + argument = parseExpression(); + consumeSemicolon(); + return { + type: Syntax.ReturnStatement, + argument: argument + }; + } + } + + if (peekLineTerminator()) { + return { + type: Syntax.ReturnStatement, + argument: null + }; + } + + if (!match(';')) { + token = lookahead(); + if (!match('}') && token.type !== Token.EOF) { + argument = parseExpression(); + } + } + + consumeSemicolon(); + + return { + type: Syntax.ReturnStatement, + argument: argument + }; + } + + // 12.10 The with statement + + function parseWithStatement() { + var object, body; + + if (strict) { + throwErrorTolerant({}, Messages.StrictModeWith); + } + + expectKeyword('with'); + + expect('('); + + object = parseExpression(); + + expect(')'); + + body = parseStatement(); + + return { + type: Syntax.WithStatement, + object: object, + body: body + }; + } + + // 12.10 The swith statement + + function parseSwitchCase() { + var test, + consequent = [], + statement; + + if (matchKeyword('default')) { + lex(); + test = null; + } else { + expectKeyword('case'); + test = parseExpression(); + } + expect(':'); + + while (index < length) { + if (match('}') || matchKeyword('default') || matchKeyword('case')) { + break; + } + statement = parseStatement(); + if (typeof statement === 'undefined') { + break; + } + consequent.push(statement); + } + + return { + type: Syntax.SwitchCase, + test: test, + consequent: consequent + }; + } + + function parseSwitchStatement() { + var discriminant, cases, clause, oldInSwitch, defaultFound; + + expectKeyword('switch'); + + expect('('); + + discriminant = parseExpression(); + + expect(')'); + + expect('{'); + + cases = []; + + if (match('}')) { + lex(); + return { + type: Syntax.SwitchStatement, + discriminant: discriminant, + cases: cases + }; + } + + oldInSwitch = state.inSwitch; + state.inSwitch = true; + defaultFound = false; + + while (index < length) { + if (match('}')) { + break; + } + clause = parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + throwError({}, Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + + state.inSwitch = oldInSwitch; + + expect('}'); + + return { + type: Syntax.SwitchStatement, + discriminant: discriminant, + cases: cases + }; + } + + // 12.13 The throw statement + + function parseThrowStatement() { + var argument; + + expectKeyword('throw'); + + if (peekLineTerminator()) { + throwError({}, Messages.NewlineAfterThrow); + } + + argument = parseExpression(); + + consumeSemicolon(); + + return { + type: Syntax.ThrowStatement, + argument: argument + }; + } + + // 12.14 The try statement + + function parseCatchClause() { + var param; + + expectKeyword('catch'); + + expect('('); + if (match(')')) { + throwUnexpected(lookahead()); + } + + param = parseVariableIdentifier(); + // 12.14.1 + if (strict && isRestrictedWord(param.name)) { + throwErrorTolerant({}, Messages.StrictCatchVariable); + } + + expect(')'); + + return { + type: Syntax.CatchClause, + param: param, + body: parseBlock() + }; + } + + function parseTryStatement() { + var block, handlers = [], finalizer = null; + + expectKeyword('try'); + + block = parseBlock(); + + if (matchKeyword('catch')) { + handlers.push(parseCatchClause()); + } + + if (matchKeyword('finally')) { + lex(); + finalizer = parseBlock(); + } + + if (handlers.length === 0 && !finalizer) { + throwError({}, Messages.NoCatchOrFinally); + } + + return { + type: Syntax.TryStatement, + block: block, + guardedHandlers: [], + handlers: handlers, + finalizer: finalizer + }; + } + + // 12.15 The debugger statement + + function parseDebuggerStatement() { + expectKeyword('debugger'); + + consumeSemicolon(); + + return { + type: Syntax.DebuggerStatement + }; + } + + // 12 Statements + + function parseStatement() { + var token = lookahead(), + expr, + labeledBody; + + if (token.type === Token.EOF) { + throwUnexpected(token); + } + + if (token.type === Token.Punctuator) { + switch (token.value) { + case ';': + return parseEmptyStatement(); + case '{': + return parseBlock(); + case '(': + return parseExpressionStatement(); + default: + break; + } + } + + if (token.type === Token.Keyword) { + switch (token.value) { + case 'break': + return parseBreakStatement(); + case 'continue': + return parseContinueStatement(); + case 'debugger': + return parseDebuggerStatement(); + case 'do': + return parseDoWhileStatement(); + case 'for': + return parseForStatement(); + case 'function': + return parseFunctionDeclaration(); + case 'if': + return parseIfStatement(); + case 'return': + return parseReturnStatement(); + case 'switch': + return parseSwitchStatement(); + case 'throw': + return parseThrowStatement(); + case 'try': + return parseTryStatement(); + case 'var': + return parseVariableStatement(); + case 'while': + return parseWhileStatement(); + case 'with': + return parseWithStatement(); + default: + break; + } + } + + expr = parseExpression(); + + // 12.12 Labelled Statements + if ((expr.type === Syntax.Identifier) && match(':')) { + lex(); + + if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) { + throwError({}, Messages.Redeclaration, 'Label', expr.name); + } + + state.labelSet[expr.name] = true; + labeledBody = parseStatement(); + delete state.labelSet[expr.name]; + + return { + type: Syntax.LabeledStatement, + label: expr, + body: labeledBody + }; + } + + consumeSemicolon(); + + return { + type: Syntax.ExpressionStatement, + expression: expr + }; + } + + // 13 Function Definition + + function parseFunctionSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted, + oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody; + + expect('{'); + + while (index < length) { + token = lookahead(); + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = sliceSource(token.range[0] + 1, token.range[1] - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + oldLabelSet = state.labelSet; + oldInIteration = state.inIteration; + oldInSwitch = state.inSwitch; + oldInFunctionBody = state.inFunctionBody; + + state.labelSet = {}; + state.inIteration = false; + state.inSwitch = false; + state.inFunctionBody = true; + + while (index < length) { + if (match('}')) { + break; + } + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + + expect('}'); + + state.labelSet = oldLabelSet; + state.inIteration = oldInIteration; + state.inSwitch = oldInSwitch; + state.inFunctionBody = oldInFunctionBody; + + return { + type: Syntax.BlockStatement, + body: sourceElements + }; + } + + function parseFunctionDeclaration() { + var id, param, params = [], body, token, stricted, firstRestricted, message, previousStrict, paramSet; + + expectKeyword('function'); + token = lookahead(); + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + + expect('('); + + if (!match(')')) { + paramSet = {}; + while (index < length) { + token = lookahead(); + param = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + stricted = token; + message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + stricted = token; + message = Messages.StrictParamDupe; + } + } else if (!firstRestricted) { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + firstRestricted = token; + message = Messages.StrictParamDupe; + } + } + params.push(param); + paramSet[param.name] = true; + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwError(firstRestricted, message); + } + if (strict && stricted) { + throwErrorTolerant(stricted, message); + } + strict = previousStrict; + + return { + type: Syntax.FunctionDeclaration, + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + function parseFunctionExpression() { + var token, id = null, stricted, firstRestricted, message, param, params = [], body, previousStrict, paramSet; + + expectKeyword('function'); + + if (!match('(')) { + token = lookahead(); + id = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictFunctionName); + } + } else { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictFunctionName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } + } + } + + expect('('); + + if (!match(')')) { + paramSet = {}; + while (index < length) { + token = lookahead(); + param = parseVariableIdentifier(); + if (strict) { + if (isRestrictedWord(token.value)) { + stricted = token; + message = Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + stricted = token; + message = Messages.StrictParamDupe; + } + } else if (!firstRestricted) { + if (isRestrictedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictParamName; + } else if (isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = Messages.StrictReservedWord; + } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) { + firstRestricted = token; + message = Messages.StrictParamDupe; + } + } + params.push(param); + paramSet[param.name] = true; + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + previousStrict = strict; + body = parseFunctionSourceElements(); + if (strict && firstRestricted) { + throwError(firstRestricted, message); + } + if (strict && stricted) { + throwErrorTolerant(stricted, message); + } + strict = previousStrict; + + return { + type: Syntax.FunctionExpression, + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }; + } + + // 14 Program + + function parseSourceElement() { + var token = lookahead(); + + if (token.type === Token.Keyword) { + switch (token.value) { + case 'const': + case 'let': + return parseConstLetDeclaration(token.value); + case 'function': + return parseFunctionDeclaration(); + default: + return parseStatement(); + } + } + + if (token.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead(); + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = sliceSource(token.range[0] + 1, token.range[1] - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var program; + strict = false; + program = { + type: Syntax.Program, + body: parseSourceElements() + }; + return program; + } + + // The following functions are needed only when the option to preserve + // the comments is active. + + function addComment(type, value, start, end, loc) { + assert(typeof start === 'number', 'Comment must have valid position'); + + // Because the way the actual token is scanned, often the comments + // (if any) are skipped twice during the lexical analysis. + // Thus, we need to skip adding a comment if the comment array already + // handled it. + if (extra.comments.length > 0) { + if (extra.comments[extra.comments.length - 1].range[1] > start) { + return; + } + } + + extra.comments.push({ + type: type, + value: value, + range: [start, end], + loc: loc + }); + } + + function scanComment() { + var comment, ch, loc, start, blockComment, lineComment; + + comment = ''; + blockComment = false; + lineComment = false; + + while (index < length) { + ch = source[index]; + + if (lineComment) { + ch = source[index++]; + if (isLineTerminator(ch)) { + loc.end = { + line: lineNumber, + column: index - lineStart - 1 + }; + lineComment = false; + addComment('Line', comment, start, index - 1, loc); + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + comment = ''; + } else if (index >= length) { + lineComment = false; + comment += ch; + loc.end = { + line: lineNumber, + column: length - lineStart + }; + addComment('Line', comment, start, length, loc); + } else { + comment += ch; + } + } else if (blockComment) { + if (isLineTerminator(ch)) { + if (ch === '\r' && source[index + 1] === '\n') { + ++index; + comment += '\r\n'; + } else { + comment += ch; + } + ++lineNumber; + ++index; + lineStart = index; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + ch = source[index++]; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + comment += ch; + if (ch === '*') { + ch = source[index]; + if (ch === '/') { + comment = comment.substr(0, comment.length - 1); + blockComment = false; + ++index; + loc.end = { + line: lineNumber, + column: index - lineStart + }; + addComment('Block', comment, start, index, loc); + comment = ''; + } + } + } + } else if (ch === '/') { + ch = source[index + 1]; + if (ch === '/') { + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + start = index; + index += 2; + lineComment = true; + if (index >= length) { + loc.end = { + line: lineNumber, + column: index - lineStart + }; + lineComment = false; + addComment('Line', comment, start, index, loc); + } + } else if (ch === '*') { + start = index; + index += 2; + blockComment = true; + loc = { + start: { + line: lineNumber, + column: index - lineStart - 2 + } + }; + if (index >= length) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + break; + } + } else if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + ++lineNumber; + lineStart = index; + } else { + break; + } + } + } + + function filterCommentLocation() { + var i, entry, comment, comments = []; + + for (i = 0; i < extra.comments.length; ++i) { + entry = extra.comments[i]; + comment = { + type: entry.type, + value: entry.value + }; + if (extra.range) { + comment.range = entry.range; + } + if (extra.loc) { + comment.loc = entry.loc; + } + comments.push(comment); + } + + extra.comments = comments; + } + + function collectToken() { + var start, loc, token, range, value; + + skipComment(); + start = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = extra.advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + range = [token.range[0], token.range[1]]; + value = sliceSource(token.range[0], token.range[1]); + extra.tokens.push({ + type: TokenName[token.type], + value: value, + range: range, + loc: loc + }); + } + + return token; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = extra.scanRegExp(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + range: [pos, index], + loc: loc + }); + + return regex; + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function createLiteral(token) { + return { + type: Syntax.Literal, + value: token.value + }; + } + + function createRawLiteral(token) { + return { + type: Syntax.Literal, + value: token.value, + raw: sliceSource(token.range[0], token.range[1]) + }; + } + + function createLocationMarker() { + var marker = {}; + + marker.range = [index, index]; + marker.loc = { + start: { + line: lineNumber, + column: index - lineStart + }, + end: { + line: lineNumber, + column: index - lineStart + } + }; + + marker.end = function () { + this.range[1] = index; + this.loc.end.line = lineNumber; + this.loc.end.column = index - lineStart; + }; + + marker.applyGroup = function (node) { + if (extra.range) { + node.groupRange = [this.range[0], this.range[1]]; + } + if (extra.loc) { + node.groupLoc = { + start: { + line: this.loc.start.line, + column: this.loc.start.column + }, + end: { + line: this.loc.end.line, + column: this.loc.end.column + } + }; + } + }; + + marker.apply = function (node) { + if (extra.range) { + node.range = [this.range[0], this.range[1]]; + } + if (extra.loc) { + node.loc = { + start: { + line: this.loc.start.line, + column: this.loc.start.column + }, + end: { + line: this.loc.end.line, + column: this.loc.end.column + } + }; + } + }; + + return marker; + } + + function trackGroupExpression() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + expect('('); + + expr = parseExpression(); + + expect(')'); + + marker.end(); + marker.applyGroup(expr); + + return expr; + } + + function trackLeftHandSideExpression() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[')) { + if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + marker.end(); + marker.apply(expr); + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + marker.end(); + marker.apply(expr); + } + } + + return expr; + } + + function trackLeftHandSideExpressionAllowCall() { + var marker, expr; + + skipComment(); + marker = createLocationMarker(); + + expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); + + while (match('.') || match('[') || match('(')) { + if (match('(')) { + expr = { + type: Syntax.CallExpression, + callee: expr, + 'arguments': parseArguments() + }; + marker.end(); + marker.apply(expr); + } else if (match('[')) { + expr = { + type: Syntax.MemberExpression, + computed: true, + object: expr, + property: parseComputedMember() + }; + marker.end(); + marker.apply(expr); + } else { + expr = { + type: Syntax.MemberExpression, + computed: false, + object: expr, + property: parseNonComputedMember() + }; + marker.end(); + marker.apply(expr); + } + } + + return expr; + } + + function filterGroup(node) { + var n, i, entry; + + n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {}; + for (i in node) { + if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') { + entry = node[i]; + if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) { + n[i] = entry; + } else { + n[i] = filterGroup(entry); + } + } + } + return n; + } + + function wrapTrackingFunction(range, loc) { + + return function (parseFunction) { + + function isBinary(node) { + return node.type === Syntax.LogicalExpression || + node.type === Syntax.BinaryExpression; + } + + function visit(node) { + var start, end; + + if (isBinary(node.left)) { + visit(node.left); + } + if (isBinary(node.right)) { + visit(node.right); + } + + if (range) { + if (node.left.groupRange || node.right.groupRange) { + start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0]; + end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1]; + node.range = [start, end]; + } else if (typeof node.range === 'undefined') { + start = node.left.range[0]; + end = node.right.range[1]; + node.range = [start, end]; + } + } + if (loc) { + if (node.left.groupLoc || node.right.groupLoc) { + start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start; + end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end; + node.loc = { + start: start, + end: end + }; + } else if (typeof node.loc === 'undefined') { + node.loc = { + start: node.left.loc.start, + end: node.right.loc.end + }; + } + } + } + + return function () { + var marker, node; + + skipComment(); + + marker = createLocationMarker(); + node = parseFunction.apply(null, arguments); + marker.end(); + + if (range && typeof node.range === 'undefined') { + marker.apply(node); + } + + if (loc && typeof node.loc === 'undefined') { + marker.apply(node); + } + + if (isBinary(node)) { + visit(node); + } + + return node; + }; + }; + } + + function patch() { + + var wrapTracking; + + if (extra.comments) { + extra.skipComment = skipComment; + skipComment = scanComment; + } + + if (extra.raw) { + extra.createLiteral = createLiteral; + createLiteral = createRawLiteral; + } + + if (extra.range || extra.loc) { + + extra.parseGroupExpression = parseGroupExpression; + extra.parseLeftHandSideExpression = parseLeftHandSideExpression; + extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall; + parseGroupExpression = trackGroupExpression; + parseLeftHandSideExpression = trackLeftHandSideExpression; + parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall; + + wrapTracking = wrapTrackingFunction(extra.range, extra.loc); + + extra.parseAdditiveExpression = parseAdditiveExpression; + extra.parseAssignmentExpression = parseAssignmentExpression; + extra.parseBitwiseANDExpression = parseBitwiseANDExpression; + extra.parseBitwiseORExpression = parseBitwiseORExpression; + extra.parseBitwiseXORExpression = parseBitwiseXORExpression; + extra.parseBlock = parseBlock; + extra.parseFunctionSourceElements = parseFunctionSourceElements; + extra.parseCatchClause = parseCatchClause; + extra.parseComputedMember = parseComputedMember; + extra.parseConditionalExpression = parseConditionalExpression; + extra.parseConstLetDeclaration = parseConstLetDeclaration; + extra.parseEqualityExpression = parseEqualityExpression; + extra.parseExpression = parseExpression; + extra.parseForVariableDeclaration = parseForVariableDeclaration; + extra.parseFunctionDeclaration = parseFunctionDeclaration; + extra.parseFunctionExpression = parseFunctionExpression; + extra.parseLogicalANDExpression = parseLogicalANDExpression; + extra.parseLogicalORExpression = parseLogicalORExpression; + extra.parseMultiplicativeExpression = parseMultiplicativeExpression; + extra.parseNewExpression = parseNewExpression; + extra.parseNonComputedProperty = parseNonComputedProperty; + extra.parseObjectProperty = parseObjectProperty; + extra.parseObjectPropertyKey = parseObjectPropertyKey; + extra.parsePostfixExpression = parsePostfixExpression; + extra.parsePrimaryExpression = parsePrimaryExpression; + extra.parseProgram = parseProgram; + extra.parsePropertyFunction = parsePropertyFunction; + extra.parseRelationalExpression = parseRelationalExpression; + extra.parseStatement = parseStatement; + extra.parseShiftExpression = parseShiftExpression; + extra.parseSwitchCase = parseSwitchCase; + extra.parseUnaryExpression = parseUnaryExpression; + extra.parseVariableDeclaration = parseVariableDeclaration; + extra.parseVariableIdentifier = parseVariableIdentifier; + + parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression); + parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression); + parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression); + parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression); + parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression); + parseBlock = wrapTracking(extra.parseBlock); + parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements); + parseCatchClause = wrapTracking(extra.parseCatchClause); + parseComputedMember = wrapTracking(extra.parseComputedMember); + parseConditionalExpression = wrapTracking(extra.parseConditionalExpression); + parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration); + parseEqualityExpression = wrapTracking(extra.parseEqualityExpression); + parseExpression = wrapTracking(extra.parseExpression); + parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration); + parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration); + parseFunctionExpression = wrapTracking(extra.parseFunctionExpression); + parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression); + parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression); + parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression); + parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression); + parseNewExpression = wrapTracking(extra.parseNewExpression); + parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty); + parseObjectProperty = wrapTracking(extra.parseObjectProperty); + parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey); + parsePostfixExpression = wrapTracking(extra.parsePostfixExpression); + parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression); + parseProgram = wrapTracking(extra.parseProgram); + parsePropertyFunction = wrapTracking(extra.parsePropertyFunction); + parseRelationalExpression = wrapTracking(extra.parseRelationalExpression); + parseStatement = wrapTracking(extra.parseStatement); + parseShiftExpression = wrapTracking(extra.parseShiftExpression); + parseSwitchCase = wrapTracking(extra.parseSwitchCase); + parseUnaryExpression = wrapTracking(extra.parseUnaryExpression); + parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration); + parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier); + } + + if (typeof extra.tokens !== 'undefined') { + extra.advance = advance; + extra.scanRegExp = scanRegExp; + + advance = collectToken; + scanRegExp = collectRegex; + } + } + + function unpatch() { + if (typeof extra.skipComment === 'function') { + skipComment = extra.skipComment; + } + + if (extra.raw) { + createLiteral = extra.createLiteral; + } + + if (extra.range || extra.loc) { + parseAdditiveExpression = extra.parseAdditiveExpression; + parseAssignmentExpression = extra.parseAssignmentExpression; + parseBitwiseANDExpression = extra.parseBitwiseANDExpression; + parseBitwiseORExpression = extra.parseBitwiseORExpression; + parseBitwiseXORExpression = extra.parseBitwiseXORExpression; + parseBlock = extra.parseBlock; + parseFunctionSourceElements = extra.parseFunctionSourceElements; + parseCatchClause = extra.parseCatchClause; + parseComputedMember = extra.parseComputedMember; + parseConditionalExpression = extra.parseConditionalExpression; + parseConstLetDeclaration = extra.parseConstLetDeclaration; + parseEqualityExpression = extra.parseEqualityExpression; + parseExpression = extra.parseExpression; + parseForVariableDeclaration = extra.parseForVariableDeclaration; + parseFunctionDeclaration = extra.parseFunctionDeclaration; + parseFunctionExpression = extra.parseFunctionExpression; + parseGroupExpression = extra.parseGroupExpression; + parseLeftHandSideExpression = extra.parseLeftHandSideExpression; + parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall; + parseLogicalANDExpression = extra.parseLogicalANDExpression; + parseLogicalORExpression = extra.parseLogicalORExpression; + parseMultiplicativeExpression = extra.parseMultiplicativeExpression; + parseNewExpression = extra.parseNewExpression; + parseNonComputedProperty = extra.parseNonComputedProperty; + parseObjectProperty = extra.parseObjectProperty; + parseObjectPropertyKey = extra.parseObjectPropertyKey; + parsePrimaryExpression = extra.parsePrimaryExpression; + parsePostfixExpression = extra.parsePostfixExpression; + parseProgram = extra.parseProgram; + parsePropertyFunction = extra.parsePropertyFunction; + parseRelationalExpression = extra.parseRelationalExpression; + parseStatement = extra.parseStatement; + parseShiftExpression = extra.parseShiftExpression; + parseSwitchCase = extra.parseSwitchCase; + parseUnaryExpression = extra.parseUnaryExpression; + parseVariableDeclaration = extra.parseVariableDeclaration; + parseVariableIdentifier = extra.parseVariableIdentifier; + } + + if (typeof extra.scanRegExp === 'function') { + advance = extra.advance; + scanRegExp = extra.scanRegExp; + } + } + + function stringToArray(str) { + var length = str.length, + result = [], + i; + for (i = 0; i < length; ++i) { + result[i] = str.charAt(i); + } + return result; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + buffer = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + extra.raw = (typeof options.raw === 'boolean') && options.raw; + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.comment === 'boolean' && options.comment) { + extra.comments = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + if (length > 0) { + if (typeof source[0] === 'undefined') { + // Try first to convert to a string. This is good as fast path + // for old IE which understands string indexing for string + // literals only and not for string object. + if (code instanceof String) { + source = code.valueOf(); + } + + // Force accessing the characters via an array. + if (typeof source[0] === 'undefined') { + source = stringToArray(code); + } + } + } + + patch(); + try { + program = parseProgram(); + if (typeof extra.comments !== 'undefined') { + filterCommentLocation(); + program.comments = extra.comments; + } + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + if (extra.range || extra.loc) { + program.body = filterGroup(program.body); + } + } catch (e) { + throw e; + } finally { + unpatch(); + extra = {}; + } + + return program; + } + + // Sync with package.json. + exports.version = '1.0.4'; + + exports.parse = parse; + + // Deep copy. + exports.Syntax = (function () { + var name, types = {}; + + if (typeof Object.create === 'function') { + types = Object.create(null); + } + + for (name in Syntax) { + if (Syntax.hasOwnProperty(name)) { + types[name] = Syntax[name]; + } + } + + if (typeof Object.freeze === 'function') { + Object.freeze(types); + } + + return types; + }()); + +})); +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/package.json b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/package.json new file mode 100644 index 0000000..dc5f573 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/package.json @@ -0,0 +1,59 @@ +{ + "name": "esprima", + "description": "ECMAScript parsing infrastructure for multipurpose analysis", + "homepage": "http://esprima.org", + "main": "esprima.js", + "bin": { + "esparse": "./bin/esparse.js", + "esvalidate": "./bin/esvalidate.js" + }, + "files": [ + "bin", + "test/run.js", + "test/runner.js", + "test/test.js", + "test/compat.js", + "test/reflect.js", + "esprima.js" + ], + "version": "1.0.4", + "engines": { + "node": ">=0.4.0" + }, + "maintainers": [ + { + "name": "Ariya Hidayat", + "email": "ariya.hidayat@gmail.com", + "url": "http://ariya.ofilabs.com" + } + ], + "repository": { + "type": "git", + "url": "http://github.com/ariya/esprima.git" + }, + "licenses": [ + { + "type": "BSD", + "url": "http://github.com/ariya/esprima/raw/master/LICENSE.BSD" + } + ], + "keywords": [ + "ast", + "ecmascript", + "javascript", + "parser", + "syntax" + ], + "scripts": { + "test": "node test/run.js", + "benchmark": "node test/benchmarks.js", + "benchmark-quick": "node test/benchmarks.js quick" + }, + "readme": "**Esprima** ([esprima.org](http://esprima.org)) is a high performance,\nstandard-compliant [ECMAScript](http://www.ecma-international.org/publications/standards/Ecma-262.htm)\nparser written in ECMAScript (also popularly known as\n[JavaScript](http://en.wikipedia.org/wiki/JavaScript>JavaScript)).\nEsprima is created and maintained by [Ariya Hidayat](http://twitter.com/ariyahidayat),\nwith the help of [many contributors](https://github.com/ariya/esprima/contributors).\n\nEsprima runs on web browsers (IE 6+, Firefox 1+, Safari 3+, Chrome 1+, Konqueror 4.6+, Opera 8+) as well as\n[Node.js](http://nodejs.org).\n\n### Features\n\n- Full support for [ECMAScript 5.1](http://www.ecma-international.org/publications/standards/Ecma-262.htm)(ECMA-262)\n- Sensible [syntax tree format](http://esprima.org/doc/index.html#ast) compatible with Mozilla\n[Parser AST](https://developer.mozilla.org/en/SpiderMonkey/Parser_API)\n- Heavily tested (> 550 [unit tests](http://esprima.org/test/) with solid 100% statement coverage)\n- Optional tracking of syntax node location (index-based and line-column)\n- Experimental support for ES6/Harmony (module, class, destructuring, ...)\n\nEsprima is blazing fast (see the [benchmark suite](http://esprima.org/test/benchmarks.html)).\nIt is up to 3x faster than UglifyJS v1 and it is still [competitive](http://esprima.org/test/compare.html)\nwith the new generation of fast parsers.\n\n### Applications\n\nEsprima serves as the basis for many popular JavaScript development tools:\n\n- Code coverage analysis: [node-cover](https://github.com/itay/node-cover), [Istanbul](https://github.com/yahoo/Istanbul)\n- Documentation tool: [JFDoc](https://github.com/thejohnfreeman/jfdoc), [JSDuck](https://github.com/senchalabs/jsduck)\n- Language extension: [LLJS](http://mbebenita.github.com/LLJS/) (low-level JS),\n[Sweet.js](http://sweetjs.org/) (macro)\n- ES6/Harmony transpiler: [Six](https://github.com/matthewrobb/six), [Harmonizr](https://github.com/jdiamond/harmonizr)\n- Eclipse Orion smart editing ([outline view](https://github.com/aclement/esprima-outline), [content assist](http://contraptionsforprogramming.blogspot.com/2012/02/better-javascript-content-assist-in.html))\n- Source code modification: [Esmorph](https://github.com/ariya/esmorph), [Code Painter](https://github.com/fawek/codepainter),\n- Source transformation: [node-falafel](https://github.com/substack/node-falafel), [Esmangle](https://github.com/Constellation/esmangle), [escodegen](https://github.com/Constellation/escodegen)\n\n### Questions?\n- [Documentation](http://esprima.org/doc)\n- [Issue tracker](http://issues.esprima.org): [known problems](http://code.google.com/p/esprima/issues/list?q=Defect)\nand [future plans](http://code.google.com/p/esprima/issues/list?q=Enhancement)\n- [Mailing list](http://groups.google.com/group/esprima)\n- [Contribution guide](http://esprima.org/doc/index.html#contribution)\n\nFollow [@Esprima](http://twitter.com/Esprima) on Twitter to get the\ndevelopment updates.\nFeedback and contribution are welcomed!\n\n### License\n\nCopyright (C) 2012, 2011 [Ariya Hidayat](http://ariya.ofilabs.com/about)\n and other contributors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in the\n documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\nTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/ariya/esprima/issues" + }, + "_id": "esprima@1.0.4", + "_from": "esprima@>=1.0.4 <1.1.0" +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/compat.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/compat.js new file mode 100644 index 0000000..ee3a629 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/compat.js @@ -0,0 +1,239 @@ +/* + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint node: true */ +/*global document: true, window:true, esprima: true, testReflect: true */ + +var runTests; + +function getContext(esprima, reportCase, reportFailure) { + 'use strict'; + + var Reflect, Pattern; + + // Maps Mozilla Reflect object to our Esprima parser. + Reflect = { + parse: function (code) { + var result; + + reportCase(code); + + try { + result = esprima.parse(code); + } catch (error) { + result = error; + } + + return result; + } + }; + + // This is used by Reflect test suite to match a syntax tree. + Pattern = function (obj) { + var pattern; + + // Poor man's deep object cloning. + pattern = JSON.parse(JSON.stringify(obj)); + + // Special handling for regular expression literal since we need to + // convert it to a string literal, otherwise it will be decoded + // as object "{}" and the regular expression would be lost. + if (obj.type && obj.type === 'Literal') { + if (obj.value instanceof RegExp) { + pattern = { + type: obj.type, + value: obj.value.toString() + }; + } + } + + // Special handling for branch statement because SpiderMonkey + // prefers to put the 'alternate' property before 'consequent'. + if (obj.type && obj.type === 'IfStatement') { + pattern = { + type: pattern.type, + test: pattern.test, + consequent: pattern.consequent, + alternate: pattern.alternate + }; + } + + // Special handling for do while statement because SpiderMonkey + // prefers to put the 'test' property before 'body'. + if (obj.type && obj.type === 'DoWhileStatement') { + pattern = { + type: pattern.type, + body: pattern.body, + test: pattern.test + }; + } + + function adjustRegexLiteralAndRaw(key, value) { + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } else if (key === 'raw' && typeof value === "string") { + // Ignore Esprima-specific 'raw' property. + return undefined; + } + return value; + } + + if (obj.type && (obj.type === 'Program')) { + pattern.assert = function (tree) { + var actual, expected; + actual = JSON.stringify(tree, adjustRegexLiteralAndRaw, 4); + expected = JSON.stringify(obj, null, 4); + + if (expected !== actual) { + reportFailure(expected, actual); + } + }; + } + + return pattern; + }; + + return { + Reflect: Reflect, + Pattern: Pattern + }; +} + +if (typeof window !== 'undefined') { + // Run all tests in a browser environment. + runTests = function () { + 'use strict'; + + var total = 0, + failures = 0; + + function setText(el, str) { + if (typeof el.innerText === 'string') { + el.innerText = str; + } else { + el.textContent = str; + } + } + + function reportCase(code) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + total += 1; + } + + function reportFailure(expected, actual) { + var report, e; + + failures += 1; + + report = document.getElementById('report'); + + e = document.createElement('p'); + setText(e, 'Expected'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'expected'); + setText(e, expected); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Actual'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'actual'); + setText(e, actual); + report.appendChild(e); + } + + setText(document.getElementById('version'), esprima.version); + + window.setTimeout(function () { + var tick, context = getContext(esprima, reportCase, reportFailure); + + tick = new Date(); + testReflect(context.Reflect, context.Pattern); + tick = (new Date()) - tick; + + if (failures > 0) { + setText(document.getElementById('status'), total + ' tests. ' + + 'Failures: ' + failures + '. ' + tick + ' ms'); + } else { + setText(document.getElementById('status'), total + ' tests. ' + + 'No failure. ' + tick + ' ms'); + } + }, 513); + }; +} else { + (function (global) { + 'use strict'; + var esprima = require('../esprima'), + tick, + total = 0, + failures = [], + header, + current, + context; + + function reportCase(code) { + total += 1; + current = code; + } + + function reportFailure(expected, actual) { + failures.push({ + source: current, + expected: expected.toString(), + actual: actual.toString() + }); + } + + context = getContext(esprima, reportCase, reportFailure); + + tick = new Date(); + require('./reflect').testReflect(context.Reflect, context.Pattern); + tick = (new Date()) - tick; + + header = total + ' tests. ' + failures.length + ' failures. ' + + tick + ' ms'; + if (failures.length) { + console.error(header); + failures.forEach(function (failure) { + console.error(failure.source + ': Expected\n ' + + failure.expected.split('\n').join('\n ') + + '\nto match\n ' + failure.actual); + }); + } else { + console.log(header); + } + process.exit(failures.length === 0 ? 0 : 1); + }(this)); +} +/* vim: set sw=4 ts=4 et tw=80 : */ diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/reflect.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/reflect.js new file mode 100644 index 0000000..dba1ba8 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/reflect.js @@ -0,0 +1,422 @@ +// This is modified from Mozilla Reflect.parse test suite (the file is located +// at js/src/tests/js1_8_5/extensions/reflect-parse.js in the source tree). +// +// Some notable changes: +// * Removed unsupported features (destructuring, let, comprehensions...). +// * Removed tests for E4X (ECMAScript for XML). +// * Removed everything related to builder. +// * Enclosed every 'Pattern' construct with a scope. +// * Tweaked some expected tree to remove generator field. +// * Removed the test for bug 632030 and bug 632024. + +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +(function (exports) { + +function testReflect(Reflect, Pattern) { + +function program(elts) { return Pattern({ type: "Program", body: elts }) } +function exprStmt(expr) { return Pattern({ type: "ExpressionStatement", expression: expr }) } +function throwStmt(expr) { return Pattern({ type: "ThrowStatement", argument: expr }) } +function returnStmt(expr) { return Pattern({ type: "ReturnStatement", argument: expr }) } +function yieldExpr(expr) { return Pattern({ type: "YieldExpression", argument: expr }) } +function lit(val) { return Pattern({ type: "Literal", value: val }) } +var thisExpr = Pattern({ type: "ThisExpression" }); +function funDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function genFunDecl(id, params, body) { return Pattern({ type: "FunctionDeclaration", + id: id, + params: params, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function declarator(id, init) { return Pattern({ type: "VariableDeclarator", id: id, init: init }) } +function varDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "var" }) } +function letDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "let" }) } +function constDecl(decls) { return Pattern({ type: "VariableDeclaration", declarations: decls, kind: "const" }) } +function ident(name) { return Pattern({ type: "Identifier", name: name }) } +function dotExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: false, object: obj, property: id }) } +function memExpr(obj, id) { return Pattern({ type: "MemberExpression", computed: true, object: obj, property: id }) } +function forStmt(init, test, update, body) { return Pattern({ type: "ForStatement", init: init, test: test, update: update, body: body }) } +function forInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: false }) } +function forEachInStmt(lhs, rhs, body) { return Pattern({ type: "ForInStatement", left: lhs, right: rhs, body: body, each: true }) } +function breakStmt(lab) { return Pattern({ type: "BreakStatement", label: lab }) } +function continueStmt(lab) { return Pattern({ type: "ContinueStatement", label: lab }) } +function blockStmt(body) { return Pattern({ type: "BlockStatement", body: body }) } +var emptyStmt = Pattern({ type: "EmptyStatement" }); +function ifStmt(test, cons, alt) { return Pattern({ type: "IfStatement", test: test, alternate: alt, consequent: cons }) } +function labStmt(lab, stmt) { return Pattern({ type: "LabeledStatement", label: lab, body: stmt }) } +function withStmt(obj, stmt) { return Pattern({ type: "WithStatement", object: obj, body: stmt }) } +function whileStmt(test, stmt) { return Pattern({ type: "WhileStatement", test: test, body: stmt }) } +function doStmt(stmt, test) { return Pattern({ type: "DoWhileStatement", test: test, body: stmt }) } +function switchStmt(disc, cases) { return Pattern({ type: "SwitchStatement", discriminant: disc, cases: cases }) } +function caseClause(test, stmts) { return Pattern({ type: "SwitchCase", test: test, consequent: stmts }) } +function defaultClause(stmts) { return Pattern({ type: "SwitchCase", test: null, consequent: stmts }) } +function catchClause(id, guard, body) { if (guard) { return Pattern({ type: "GuardedCatchClause", param: id, guard: guard, body: body }) } else { return Pattern({ type: "CatchClause", param: id, body: body }) } } +function tryStmt(body, guarded, catches, fin) { return Pattern({ type: "TryStatement", block: body, guardedHandlers: guarded, handlers: catches, finalizer: fin }) } +function letStmt(head, body) { return Pattern({ type: "LetStatement", head: head, body: body }) } +function funExpr(id, args, body, gen) { return Pattern({ type: "FunctionExpression", + id: id, + params: args, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } +function genFunExpr(id, args, body) { return Pattern({ type: "FunctionExpression", + id: id, + params: args, + defaults: [], + body: body, + rest: null, + generator: false, + expression: false + }) } + +function unExpr(op, arg) { return Pattern({ type: "UnaryExpression", operator: op, argument: arg, prefix: true }) } +function binExpr(op, left, right) { return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }) } +function aExpr(op, left, right) { return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right }) } +function updExpr(op, arg, prefix) { return Pattern({ type: "UpdateExpression", operator: op, argument: arg, prefix: prefix }) } +function logExpr(op, left, right) { return Pattern({ type: "LogicalExpression", operator: op, left: left, right: right }) } + +function condExpr(test, cons, alt) { return Pattern({ type: "ConditionalExpression", test: test, consequent: cons, alternate: alt }) } +function seqExpr(exprs) { return Pattern({ type: "SequenceExpression", expressions: exprs }) } +function newExpr(callee, args) { return Pattern({ type: "NewExpression", callee: callee, arguments: args }) } +function callExpr(callee, args) { return Pattern({ type: "CallExpression", callee: callee, arguments: args }) } +function arrExpr(elts) { return Pattern({ type: "ArrayExpression", elements: elts }) } +function objExpr(elts) { return Pattern({ type: "ObjectExpression", properties: elts }) } +function objProp(key, value, kind) { return Pattern({ type: "Property", key: key, value: value, kind: kind }) } + +function arrPatt(elts) { return Pattern({ type: "ArrayPattern", elements: elts }) } +function objPatt(elts) { return Pattern({ type: "ObjectPattern", properties: elts }) } + +function localSrc(src) { return "(function(){ " + src + " })" } +function localPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([patt])))]) } +function blockSrc(src) { return "(function(){ { " + src + " } })" } +function blockPatt(patt) { return program([exprStmt(funExpr(null, [], blockStmt([blockStmt([patt])])))]) } + +function assertBlockStmt(src, patt) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src))); +} + +function assertBlockExpr(src, patt) { + assertBlockStmt(src, exprStmt(patt)); +} + +function assertBlockDecl(src, patt, builder) { + blockPatt(patt).assert(Reflect.parse(blockSrc(src), {builder: builder})); +} + +function assertLocalStmt(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertLocalExpr(src, patt) { + assertLocalStmt(src, exprStmt(patt)); +} + +function assertLocalDecl(src, patt) { + localPatt(patt).assert(Reflect.parse(localSrc(src))); +} + +function assertGlobalStmt(src, patt, builder) { + program([patt]).assert(Reflect.parse(src, {builder: builder})); +} + +function assertGlobalExpr(src, patt, builder) { + program([exprStmt(patt)]).assert(Reflect.parse(src, {builder: builder})); + //assertStmt(src, exprStmt(patt)); +} + +function assertGlobalDecl(src, patt) { + program([patt]).assert(Reflect.parse(src)); +} + +function assertProg(src, patt) { + program(patt).assert(Reflect.parse(src)); +} + +function assertStmt(src, patt) { + assertLocalStmt(src, patt); + assertGlobalStmt(src, patt); + assertBlockStmt(src, patt); +} + +function assertExpr(src, patt) { + assertLocalExpr(src, patt); + assertGlobalExpr(src, patt); + assertBlockExpr(src, patt); +} + +function assertDecl(src, patt) { + assertLocalDecl(src, patt); + assertGlobalDecl(src, patt); + assertBlockDecl(src, patt); +} + +function assertError(src, errorType) { + try { + Reflect.parse(src); + } catch (e) { + return; + } + throw new Error("expected " + errorType.name + " for " + uneval(src)); +} + + +// general tests + +// NB: These are useful but for now jit-test doesn't do I/O reliably. + +//program(_).assert(Reflect.parse(snarf('data/flapjax.txt'))); +//program(_).assert(Reflect.parse(snarf('data/jquery-1.4.2.txt'))); +//program(_).assert(Reflect.parse(snarf('data/prototype.js'))); +//program(_).assert(Reflect.parse(snarf('data/dojo.js.uncompressed.js'))); +//program(_).assert(Reflect.parse(snarf('data/mootools-1.2.4-core-nc.js'))); + + +// declarations + +assertDecl("var x = 1, y = 2, z = 3", + varDecl([declarator(ident("x"), lit(1)), + declarator(ident("y"), lit(2)), + declarator(ident("z"), lit(3))])); +assertDecl("var x, y, z", + varDecl([declarator(ident("x"), null), + declarator(ident("y"), null), + declarator(ident("z"), null)])); +assertDecl("function foo() { }", + funDecl(ident("foo"), [], blockStmt([]))); +assertDecl("function foo() { return 42 }", + funDecl(ident("foo"), [], blockStmt([returnStmt(lit(42))]))); + + +// Bug 591437: rebound args have their defs turned into uses +assertDecl("function f(a) { function a() { } }", + funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); +assertDecl("function f(a,b,c) { function b() { } }", + funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); + +// expressions + +assertExpr("true", lit(true)); +assertExpr("false", lit(false)); +assertExpr("42", lit(42)); +assertExpr("(/asdf/)", lit(/asdf/)); +assertExpr("this", thisExpr); +assertExpr("foo", ident("foo")); +assertExpr("foo.bar", dotExpr(ident("foo"), ident("bar"))); +assertExpr("foo[bar]", memExpr(ident("foo"), ident("bar"))); +assertExpr("(function(){})", funExpr(null, [], blockStmt([]))); +assertExpr("(function f() {})", funExpr(ident("f"), [], blockStmt([]))); +assertExpr("(function f(x,y,z) {})", funExpr(ident("f"), [ident("x"),ident("y"),ident("z")], blockStmt([]))); +assertExpr("(++x)", updExpr("++", ident("x"), true)); +assertExpr("(x++)", updExpr("++", ident("x"), false)); +assertExpr("(+x)", unExpr("+", ident("x"))); +assertExpr("(-x)", unExpr("-", ident("x"))); +assertExpr("(!x)", unExpr("!", ident("x"))); +assertExpr("(~x)", unExpr("~", ident("x"))); +assertExpr("(delete x)", unExpr("delete", ident("x"))); +assertExpr("(typeof x)", unExpr("typeof", ident("x"))); +assertExpr("(void x)", unExpr("void", ident("x"))); +assertExpr("(x == y)", binExpr("==", ident("x"), ident("y"))); +assertExpr("(x != y)", binExpr("!=", ident("x"), ident("y"))); +assertExpr("(x === y)", binExpr("===", ident("x"), ident("y"))); +assertExpr("(x !== y)", binExpr("!==", ident("x"), ident("y"))); +assertExpr("(x < y)", binExpr("<", ident("x"), ident("y"))); +assertExpr("(x <= y)", binExpr("<=", ident("x"), ident("y"))); +assertExpr("(x > y)", binExpr(">", ident("x"), ident("y"))); +assertExpr("(x >= y)", binExpr(">=", ident("x"), ident("y"))); +assertExpr("(x << y)", binExpr("<<", ident("x"), ident("y"))); +assertExpr("(x >> y)", binExpr(">>", ident("x"), ident("y"))); +assertExpr("(x >>> y)", binExpr(">>>", ident("x"), ident("y"))); +assertExpr("(x + y)", binExpr("+", ident("x"), ident("y"))); +assertExpr("(w + x + y + z)", binExpr("+", binExpr("+", binExpr("+", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x - y)", binExpr("-", ident("x"), ident("y"))); +assertExpr("(w - x - y - z)", binExpr("-", binExpr("-", binExpr("-", ident("w"), ident("x")), ident("y")), ident("z"))); +assertExpr("(x * y)", binExpr("*", ident("x"), ident("y"))); +assertExpr("(x / y)", binExpr("/", ident("x"), ident("y"))); +assertExpr("(x % y)", binExpr("%", ident("x"), ident("y"))); +assertExpr("(x | y)", binExpr("|", ident("x"), ident("y"))); +assertExpr("(x ^ y)", binExpr("^", ident("x"), ident("y"))); +assertExpr("(x & y)", binExpr("&", ident("x"), ident("y"))); +assertExpr("(x in y)", binExpr("in", ident("x"), ident("y"))); +assertExpr("(x instanceof y)", binExpr("instanceof", ident("x"), ident("y"))); +assertExpr("(x = y)", aExpr("=", ident("x"), ident("y"))); +assertExpr("(x += y)", aExpr("+=", ident("x"), ident("y"))); +assertExpr("(x -= y)", aExpr("-=", ident("x"), ident("y"))); +assertExpr("(x *= y)", aExpr("*=", ident("x"), ident("y"))); +assertExpr("(x /= y)", aExpr("/=", ident("x"), ident("y"))); +assertExpr("(x %= y)", aExpr("%=", ident("x"), ident("y"))); +assertExpr("(x <<= y)", aExpr("<<=", ident("x"), ident("y"))); +assertExpr("(x >>= y)", aExpr(">>=", ident("x"), ident("y"))); +assertExpr("(x >>>= y)", aExpr(">>>=", ident("x"), ident("y"))); +assertExpr("(x |= y)", aExpr("|=", ident("x"), ident("y"))); +assertExpr("(x ^= y)", aExpr("^=", ident("x"), ident("y"))); +assertExpr("(x &= y)", aExpr("&=", ident("x"), ident("y"))); +assertExpr("(x || y)", logExpr("||", ident("x"), ident("y"))); +assertExpr("(x && y)", logExpr("&&", ident("x"), ident("y"))); +assertExpr("(w || x || y || z)", logExpr("||", logExpr("||", logExpr("||", ident("w"), ident("x")), ident("y")), ident("z"))) +assertExpr("(x ? y : z)", condExpr(ident("x"), ident("y"), ident("z"))); +assertExpr("(x,y)", seqExpr([ident("x"),ident("y")])) +assertExpr("(x,y,z)", seqExpr([ident("x"),ident("y"),ident("z")])) +assertExpr("(a,b,c,d,e,f,g)", seqExpr([ident("a"),ident("b"),ident("c"),ident("d"),ident("e"),ident("f"),ident("g")])); +assertExpr("(new Object)", newExpr(ident("Object"), [])); +assertExpr("(new Object())", newExpr(ident("Object"), [])); +assertExpr("(new Object(42))", newExpr(ident("Object"), [lit(42)])); +assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); +assertExpr("(String())", callExpr(ident("String"), [])); +assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); +assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); +assertExpr("[]", arrExpr([])); +assertExpr("[1]", arrExpr([lit(1)])); +assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); +assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); +assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)])); +assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)])); +assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)])); +assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)])); +assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)])); +assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined])); +assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),undefined,undefined])); +assertExpr("[,,,,,]", arrExpr([undefined,undefined,undefined,undefined,undefined])); +assertExpr("({})", objExpr([])); +assertExpr("({x:1})", objExpr([objProp(ident("x"), lit(1), "init")])); +assertExpr("({x:1, y:2})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(ident("y"), lit(2), "init")])); +assertExpr("({x:1, y:2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(ident("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({x:1, 'y':2, z:3})", objExpr([objProp(ident("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({'x':1, 'y':2, z:3})", objExpr([objProp(lit("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(ident("z"), lit(3), "init") ])); +assertExpr("({'x':1, 'y':2, 3:3})", objExpr([objProp(lit("x"), lit(1), "init"), + objProp(lit("y"), lit(2), "init"), + objProp(lit(3), lit(3), "init") ])); + +// Bug 571617: eliminate constant-folding +assertExpr("2 + 3", binExpr("+", lit(2), lit(3))); + +// Bug 632026: constant-folding +assertExpr("typeof(0?0:a)", unExpr("typeof", condExpr(lit(0), lit(0), ident("a")))); + +// Bug 632056: constant-folding +program([exprStmt(ident("f")), + ifStmt(lit(1), + funDecl(ident("f"), [], blockStmt([])), + null)]).assert(Reflect.parse("f; if (1) function f(){}")); + +// statements + +assertStmt("throw 42", throwStmt(lit(42))); +assertStmt("for (;;) break", forStmt(null, null, null, breakStmt(null))); +assertStmt("for (x; y; z) break", forStmt(ident("x"), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (var x; y; z) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (var x = 42; y; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), ident("y"), ident("z"), breakStmt(null))); +assertStmt("for (x; ; z) break", forStmt(ident("x"), null, ident("z"), breakStmt(null))); +assertStmt("for (var x; ; z) break", forStmt(varDecl([declarator(ident("x"), null)]), null, ident("z"), breakStmt(null))); +assertStmt("for (var x = 42; ; z) break", forStmt(varDecl([declarator(ident("x"), lit(42))]), null, ident("z"), breakStmt(null))); +assertStmt("for (x; y; ) break", forStmt(ident("x"), ident("y"), null, breakStmt(null))); +assertStmt("for (var x; y; ) break", forStmt(varDecl([declarator(ident("x"), null)]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x = 42; y; ) break", forStmt(varDecl([declarator(ident("x"),lit(42))]), ident("y"), null, breakStmt(null))); +assertStmt("for (var x in y) break", forInStmt(varDecl([declarator(ident("x"),null)]), ident("y"), breakStmt(null))); +assertStmt("for (x in y) break", forInStmt(ident("x"), ident("y"), breakStmt(null))); +assertStmt("{ }", blockStmt([])); +assertStmt("{ throw 1; throw 2; throw 3; }", blockStmt([ throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))])); +assertStmt(";", emptyStmt); +assertStmt("if (foo) throw 42;", ifStmt(ident("foo"), throwStmt(lit(42)), null)); +assertStmt("if (foo) throw 42; else true;", ifStmt(ident("foo"), throwStmt(lit(42)), exprStmt(lit(true)))); +assertStmt("if (foo) { throw 1; throw 2; throw 3; }", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + null)); +assertStmt("if (foo) { throw 1; throw 2; throw 3; } else true;", + ifStmt(ident("foo"), + blockStmt([throwStmt(lit(1)), throwStmt(lit(2)), throwStmt(lit(3))]), + exprStmt(lit(true)))); +assertStmt("foo: for(;;) break foo;", labStmt(ident("foo"), forStmt(null, null, null, breakStmt(ident("foo"))))); +assertStmt("foo: for(;;) continue foo;", labStmt(ident("foo"), forStmt(null, null, null, continueStmt(ident("foo"))))); +assertStmt("with (obj) { }", withStmt(ident("obj"), blockStmt([]))); +assertStmt("with (obj) { obj; }", withStmt(ident("obj"), blockStmt([exprStmt(ident("obj"))]))); +assertStmt("while (foo) { }", whileStmt(ident("foo"), blockStmt([]))); +assertStmt("while (foo) { foo; }", whileStmt(ident("foo"), blockStmt([exprStmt(ident("foo"))]))); +assertStmt("do { } while (foo);", doStmt(blockStmt([]), ident("foo"))); +assertStmt("do { foo; } while (foo)", doStmt(blockStmt([exprStmt(ident("foo"))]), ident("foo"))); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]) ])); +assertStmt("switch (foo) { case 1: 1; break; case 2: 2; break; default: 3; case 42: 42; }", + switchStmt(ident("foo"), + [ caseClause(lit(1), [ exprStmt(lit(1)), breakStmt(null) ]), + caseClause(lit(2), [ exprStmt(lit(2)), breakStmt(null) ]), + defaultClause([ exprStmt(lit(3)) ]), + caseClause(lit(42), [ exprStmt(lit(42)) ]) ])); +assertStmt("try { } catch (e) { }", + tryStmt(blockStmt([]), + [], + [ catchClause(ident("e"), null, blockStmt([])) ], + null)); +assertStmt("try { } catch (e) { } finally { }", + tryStmt(blockStmt([]), + [], + [ catchClause(ident("e"), null, blockStmt([])) ], + blockStmt([]))); +assertStmt("try { } finally { }", + tryStmt(blockStmt([]), + [], + [], + blockStmt([]))); + +// redeclarations (TOK_NAME nodes with lexdef) + +assertStmt("function f() { function g() { } function g() { } }", + funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), + funDecl(ident("g"), [], blockStmt([]))]))); + +assertStmt("function f() { function g() { } function g() { return 42 } }", + funDecl(ident("f"), [], blockStmt([funDecl(ident("g"), [], blockStmt([])), + funDecl(ident("g"), [], blockStmt([returnStmt(lit(42))]))]))); + +assertStmt("function f() { var x = 42; var x = 43; }", + funDecl(ident("f"), [], blockStmt([varDecl([declarator(ident("x"),lit(42))]), + varDecl([declarator(ident("x"),lit(43))])]))); + +// getters and setters + + assertExpr("({ get x() { return 42 } })", + objExpr([ objProp(ident("x"), + funExpr(null, [], blockStmt([returnStmt(lit(42))])), + "get" ) ])); + assertExpr("({ set x(v) { return 42 } })", + objExpr([ objProp(ident("x"), + funExpr(null, [ident("v")], blockStmt([returnStmt(lit(42))])), + "set" ) ])); + +} + +exports.testReflect = testReflect; + +}(typeof exports === 'undefined' ? this : exports)); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/run.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/run.js new file mode 100644 index 0000000..32ca3fa --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/run.js @@ -0,0 +1,66 @@ +/* + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint node:true */ + +(function () { + 'use strict'; + + var child = require('child_process'), + nodejs = '"' + process.execPath + '"', + ret = 0, + suites, + index; + + suites = [ + 'runner', + 'compat' + ]; + + function nextTest() { + var suite = suites[index]; + + if (index < suites.length) { + child.exec(nodejs + ' ./test/' + suite + '.js', function (err, stdout, stderr) { + if (stdout) { + process.stdout.write(suite + ': ' + stdout); + } + if (stderr) { + process.stderr.write(suite + ': ' + stderr); + } + if (err) { + ret = err.code; + } + index += 1; + nextTest(); + }); + } else { + process.exit(ret); + } + } + + index = 0; + nextTest(); +}()); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/runner.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/runner.js new file mode 100644 index 0000000..c1a3fc9 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/runner.js @@ -0,0 +1,387 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + Copyright (C) 2011 Yusuke Suzuki + Copyright (C) 2011 Arpad Borsos + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*jslint browser:true node:true */ +/*global esprima:true, testFixture:true */ + +var runTests; + +// Special handling for regular expression literal since we need to +// convert it to a string literal, otherwise it will be decoded +// as object "{}" and the regular expression would be lost. +function adjustRegexLiteral(key, value) { + 'use strict'; + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } + return value; +} + +function NotMatchingError(expected, actual) { + 'use strict'; + Error.call(this, 'Expected '); + this.expected = expected; + this.actual = actual; +} +NotMatchingError.prototype = new Error(); + +function errorToObject(e) { + 'use strict'; + var msg = e.toString(); + + // Opera 9.64 produces an non-standard string in toString(). + if (msg.substr(0, 6) !== 'Error:') { + if (typeof e.message === 'string') { + msg = 'Error: ' + e.message; + } + } + + return { + index: e.index, + lineNumber: e.lineNumber, + column: e.column, + message: msg + }; +} + +function testParse(esprima, code, syntax) { + 'use strict'; + var expected, tree, actual, options, StringObject, i, len, err; + + // alias, so that JSLint does not complain. + StringObject = String; + + options = { + comment: (typeof syntax.comments !== 'undefined'), + range: true, + loc: true, + tokens: (typeof syntax.tokens !== 'undefined'), + raw: true, + tolerant: (typeof syntax.errors !== 'undefined') + }; + + if (typeof syntax.tokens !== 'undefined') { + if (syntax.tokens.length > 0) { + options.range = (typeof syntax.tokens[0].range !== 'undefined'); + options.loc = (typeof syntax.tokens[0].loc !== 'undefined'); + } + } + + if (typeof syntax.comments !== 'undefined') { + if (syntax.comments.length > 0) { + options.range = (typeof syntax.comments[0].range !== 'undefined'); + options.loc = (typeof syntax.comments[0].loc !== 'undefined'); + } + } + + expected = JSON.stringify(syntax, null, 4); + try { + tree = esprima.parse(code, options); + tree = (options.comment || options.tokens || options.tolerant) ? tree : tree.body[0]; + + if (options.tolerant) { + for (i = 0, len = tree.errors.length; i < len; i += 1) { + tree.errors[i] = errorToObject(tree.errors[i]); + } + } + + actual = JSON.stringify(tree, adjustRegexLiteral, 4); + + // Only to ensure that there is no error when using string object. + esprima.parse(new StringObject(code), options); + + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } + + function filter(key, value) { + if (key === 'value' && value instanceof RegExp) { + value = value.toString(); + } + return (key === 'loc' || key === 'range') ? undefined : value; + } + + if (options.tolerant) { + return; + } + + + // Check again without any location info. + options.range = false; + options.loc = false; + expected = JSON.stringify(syntax, filter, 4); + try { + tree = esprima.parse(code, options); + tree = (options.comment || options.tokens) ? tree : tree.body[0]; + + if (options.tolerant) { + for (i = 0, len = tree.errors.length; i < len; i += 1) { + tree.errors[i] = errorToObject(tree.errors[i]); + } + } + + actual = JSON.stringify(tree, filter, 4); + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } +} + +function testError(esprima, code, exception) { + 'use strict'; + var i, options, expected, actual, handleInvalidRegexFlag; + + // Different parsing options should give the same error. + options = [ + {}, + { comment: true }, + { raw: true }, + { raw: true, comment: true } + ]; + + // If handleInvalidRegexFlag is true, an invalid flag in a regular expression + // will throw an exception. In some old version V8, this is not the case + // and hence handleInvalidRegexFlag is false. + handleInvalidRegexFlag = false; + try { + 'test'.match(new RegExp('[a-z]', 'x')); + } catch (e) { + handleInvalidRegexFlag = true; + } + + expected = JSON.stringify(exception); + + for (i = 0; i < options.length; i += 1) { + + try { + esprima.parse(code, options[i]); + } catch (e) { + actual = JSON.stringify(errorToObject(e)); + } + + if (expected !== actual) { + + // Compensate for old V8 which does not handle invalid flag. + if (exception.message.indexOf('Invalid regular expression') > 0) { + if (typeof actual === 'undefined' && !handleInvalidRegexFlag) { + return; + } + } + + throw new NotMatchingError(expected, actual); + } + + } +} + +function testAPI(esprima, code, result) { + 'use strict'; + var expected, res, actual; + + expected = JSON.stringify(result.result, null, 4); + try { + if (typeof result.property !== 'undefined') { + res = esprima[result.property]; + } else { + res = esprima[result.call].apply(esprima, result.args); + } + actual = JSON.stringify(res, adjustRegexLiteral, 4); + } catch (e) { + throw new NotMatchingError(expected, e.toString()); + } + if (expected !== actual) { + throw new NotMatchingError(expected, actual); + } +} + +function runTest(esprima, code, result) { + 'use strict'; + if (result.hasOwnProperty('lineNumber')) { + testError(esprima, code, result); + } else if (result.hasOwnProperty('result')) { + testAPI(esprima, code, result); + } else { + testParse(esprima, code, result); + } +} + +if (typeof window !== 'undefined') { + // Run all tests in a browser environment. + runTests = function () { + 'use strict'; + var total = 0, + failures = 0, + category, + fixture, + source, + tick, + expected, + index, + len; + + function setText(el, str) { + if (typeof el.innerText === 'string') { + el.innerText = str; + } else { + el.textContent = str; + } + } + + function startCategory(category) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('h4'); + setText(e, category); + report.appendChild(e); + } + + function reportSuccess(code) { + var report, e; + report = document.getElementById('report'); + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + } + + function reportFailure(code, expected, actual) { + var report, e; + + report = document.getElementById('report'); + + e = document.createElement('p'); + setText(e, 'Code:'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'code'); + setText(e, code); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Expected'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'expected'); + setText(e, expected); + report.appendChild(e); + + e = document.createElement('p'); + setText(e, 'Actual'); + report.appendChild(e); + + e = document.createElement('pre'); + e.setAttribute('class', 'actual'); + setText(e, actual); + report.appendChild(e); + } + + setText(document.getElementById('version'), esprima.version); + + tick = new Date(); + for (category in testFixture) { + if (testFixture.hasOwnProperty(category)) { + startCategory(category); + fixture = testFixture[category]; + for (source in fixture) { + if (fixture.hasOwnProperty(source)) { + expected = fixture[source]; + total += 1; + try { + runTest(esprima, source, expected); + reportSuccess(source, JSON.stringify(expected, null, 4)); + } catch (e) { + failures += 1; + reportFailure(source, e.expected, e.actual); + } + } + } + } + } + tick = (new Date()) - tick; + + if (failures > 0) { + setText(document.getElementById('status'), total + ' tests. ' + + 'Failures: ' + failures + '. ' + tick + ' ms'); + } else { + setText(document.getElementById('status'), total + ' tests. ' + + 'No failure. ' + tick + ' ms'); + } + }; +} else { + (function () { + 'use strict'; + + var esprima = require('../esprima'), + vm = require('vm'), + fs = require('fs'), + total = 0, + failures = [], + tick = new Date(), + expected, + header; + + vm.runInThisContext(fs.readFileSync(__dirname + '/test.js', 'utf-8')); + + Object.keys(testFixture).forEach(function (category) { + Object.keys(testFixture[category]).forEach(function (source) { + total += 1; + expected = testFixture[category][source]; + try { + runTest(esprima, source, expected); + } catch (e) { + e.source = source; + failures.push(e); + } + }); + }); + tick = (new Date()) - tick; + + header = total + ' tests. ' + failures.length + ' failures. ' + + tick + ' ms'; + if (failures.length) { + console.error(header); + failures.forEach(function (failure) { + console.error(failure.source + ': Expected\n ' + + failure.expected.split('\n').join('\n ') + + '\nto match\n ' + failure.actual); + }); + } else { + console.log(header); + } + process.exit(failures.length === 0 ? 0 : 1); + }()); +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/test.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/test.js new file mode 100644 index 0000000..8ceee54 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/node_modules/esprima/test/test.js @@ -0,0 +1,20238 @@ +/* + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + Copyright (C) 2011 Yusuke Suzuki + Copyright (C) 2011 Arpad Borsos + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +var testFixture = { + + 'Primary Expression': { + + 'this\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'ThisExpression', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + }, + tokens: [{ + type: 'Keyword', + value: 'this', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + 'null\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: null, + raw: 'null', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 0 } + }, + tokens: [{ + type: 'Null', + value: 'null', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + '\n 42\n\n': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [5, 9], + loc: { + start: { line: 2, column: 4 }, + end: { line: 4, column: 0 } + } + }], + range: [5, 9], + loc: { + start: { line: 2, column: 4 }, + end: { line: 4, column: 0 } + }, + tokens: [{ + type: 'Numeric', + value: '42', + range: [5, 7], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }] + }, + + '(1 + 2 ) * 3': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [1, 6], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Literal', + value: 3, + raw: '3', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + } + + }, + + 'Grouping Operator': { + + '(1) + (2 ) + 3': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + right: { + type: 'Literal', + value: 3, + raw: '3', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '4 + 5 << (6)': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Literal', + value: 4, + raw: '4', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 5, + raw: '5', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 6, + raw: '6', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + } + + }, + + 'Array Initializer': { + + 'x = []': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + }, + tokens: [{ + type: 'Identifier', + value: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, { + type: 'Punctuator', + value: '=', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Punctuator', + value: '[', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: ']', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }] + }, + + 'x = [ ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x = [ 42 ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }], + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'x = [ 42, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }], + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x = [ ,, 42 ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [ + null, + null, + { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'x = [ 1, 2, 3, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 1, + raw: '1', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Literal', + value: 2, + raw: '2', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, { + type: 'Literal', + value: 3, + raw: '3', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = [ 1, 2,, 3, ]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ArrayExpression', + elements: [{ + type: 'Literal', + value: 1, + raw: '1', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Literal', + value: 2, + raw: '2', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, null, { + type: 'Literal', + value: 3, + raw: '3', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + '日本語 = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '日本語', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'T\u203F = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u203F', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'T\u200C = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u200C', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'T\u200D = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'T\u200D', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\u2163\u2161 = []': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '\u2163\u2161', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\u2163\u2161\u200A=\u2009[]': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: '\u2163\u2161', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Object Initializer': { + + 'x = {}': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x = { }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x = { answer: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'answer', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [14, 16], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 16 } + } + }, + kind: 'init', + range: [6, 16], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 16 } + } + }], + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'x = { if: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + kind: 'init', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x = { true: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + kind: 'init', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = { false: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [6, 11], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 11 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + kind: 'init', + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'x = { null: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + kind: 'init', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }], + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'x = { "answer": 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'answer', + raw: '"answer"', + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [16, 18], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 18 } + } + }, + kind: 'init', + range: [6, 18], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 18 } + } + }], + range: [4, 20], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'x = { x: 1, x: 2 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [ + { + type: 'Property', + key: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + kind: 'init', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + { + type: 'Property', + key: { + type: 'Identifier', + name: 'x', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + value: { + type: 'Literal', + value: 2, + raw: '2', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + kind: 'init', + range: [12, 16], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 16 } + } + } + ], + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'x = { get width() { return m_width } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'width', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ReturnStatement', + argument: { + type: 'Identifier', + name: 'm_width', + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }, + range: [20, 35], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 35 } + } + }], + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + kind: 'get', + range: [6, 36], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 36 } + } + }], + range: [4, 38], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'x = { get undef() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'undef', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + kind: 'get', + range: [6, 20], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 20 } + } + }], + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'x = { get if() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + kind: 'get', + range: [6, 17], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 17 } + } + }], + range: [4, 19], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'x = { get true() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + kind: 'get', + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'x = { get false() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + kind: 'get', + range: [6, 20], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 20 } + } + }], + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'x = { get null() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [17, 19], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 19 } + } + }, + kind: 'get', + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'x = { get "undef"() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'undef', + raw: '"undef"', + range: [10, 17], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 17 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + rest: null, + generator: false, + expression: false, + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + kind: 'get', + range: [6, 22], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 22 } + } + }], + range: [4, 24], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'x = { get 10() {} }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 10, + raw: '10', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + kind: 'get', + range: [6, 17], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 17 } + } + }], + range: [4, 19], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'x = { set width(w) { m_width = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'width', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_width', + range: [21, 28], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set if(w) { m_if = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'if', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_if', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + range: [18, 26], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 26 } + } + }, + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }], + range: [16, 28], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 28 } + } + }, + rest: null, + generator: false, + expression: false, + range: [16, 28], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 28 } + } + }, + kind: 'set', + range: [6, 28], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 28 } + } + }], + range: [4, 30], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'x = { set true(w) { m_true = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'true', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_true', + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + kind: 'set', + range: [6, 32], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 32 } + } + }], + range: [4, 34], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'x = { set false(w) { m_false = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'false', + range: [10, 15], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_false', + range: [21, 28], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + }, + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set null(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'null', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + kind: 'set', + range: [6, 32], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 32 } + } + }], + range: [4, 34], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'x = { set "null"(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 'null', + raw: '"null"', + range: [10, 16], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 16 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [22, 28], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 28 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [31, 32], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 32 } + } + }, + range: [22, 32], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 32 } + } + }, + range: [22, 33], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 33 } + } + }], + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }], + range: [4, 36], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'x = { set 10(w) { m_null = w } }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 10, + raw: '10', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'w', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'm_null', + range: [18, 24], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 24 } + } + }, + right: { + type: 'Identifier', + name: 'w', + range: [27, 28], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 28 } + } + }, + range: [18, 28], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 28 } + } + }, + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }], + range: [16, 30], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 30 } + } + }, + rest: null, + generator: false, + expression: false, + range: [16, 30], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 30 } + } + }, + kind: 'set', + range: [6, 30], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 30 } + } + }], + range: [4, 32], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 32 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + + 'x = { get: 42 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'get', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + kind: 'init', + range: [6, 13], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + 'x = { set: 43 }': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'set', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + value: { + type: 'Literal', + value: 43, + raw: '43', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + kind: 'init', + range: [6, 13], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 13 } + } + }], + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + } + + }, + + 'Comments': { + + '/* block comment */ 42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + range: [20, 22], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 22 } + } + }, + + '42 /*The*/ /*Answer*/': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + comments: [{ + type: 'Block', + value: 'The', + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, { + type: 'Block', + value: 'Answer', + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }] + }, + + '42 /*the*/ /*answer*/': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2] + }, + range: [0, 21] + }], + range: [0, 21], + comments: [{ + type: 'Block', + value: 'the', + range: [3, 10] + }, { + type: 'Block', + value: 'answer', + range: [11, 21] + }] + }, + + '/* multiline\ncomment\nshould\nbe\nignored */ 42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [42, 44], + loc: { + start: { line: 5, column: 11 }, + end: { line: 5, column: 13 } + } + }, + range: [42, 44], + loc: { + start: { line: 5, column: 11 }, + end: { line: 5, column: 13 } + } + }, + + '/*a\r\nb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [9, 11], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\r\nb', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\rb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\rb', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\nb*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + range: [8, 10], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\nb', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '/*a\nc*/ 42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }, + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + } + }], + loc: { + start: { line: 2, column: 4 }, + end: { line: 2, column: 6 } + }, + comments: [{ + type: 'Block', + value: 'a\nc', + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 3 } + } + }] + }, + + '// line comment\n42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [16, 18], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [16, 18], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + + '42 // line comment': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + comments: [{ + type: 'Line', + value: ' line comment', + range: [3, 18], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 18 } + } + }] + }, + + '// Hello, world!\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [17, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '// Hello, world!\n': { + type: 'Program', + body: [], + range: [17, 17], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 0 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '// Hallo, world!\n': { + type: 'Program', + body: [], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 0 } + }, + comments: [{ + type: 'Line', + value: ' Hallo, world!', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }] + }, + + '//\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }, + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [3, 5], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + }, + comments: [{ + type: 'Line', + value: '', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }] + }, + + '//': { + type: 'Program', + body: [], + range: [2, 2], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 2 } + }, + comments: [{ + type: 'Line', + value: '', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }] + }, + + '// ': { + type: 'Program', + body: [], + range: [3, 3], + comments: [{ + type: 'Line', + value: ' ', + range: [0, 3] + }] + }, + + '/**/42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }], + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + }, + comments: [{ + type: 'Block', + value: '', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }] + }, + + '// Hello, world!\n\n// Another hello\n42': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + } + }, + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + } + }], + range: [37, 39], + loc: { + start: { line: 4, column: 0 }, + end: { line: 4, column: 2 } + }, + comments: [{ + type: 'Line', + value: ' Hello, world!', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Line', + value: ' Another hello', + range: [18, 36], + loc: { + start: { line: 3, column: 0 }, + end: { line: 3, column: 18 } + } + }] + }, + + 'if (x) { // Some comment\ndoThat(); }': { + type: 'Program', + body: [{ + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + consequent: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [25, 31], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }, + 'arguments': [], + range: [25, 33], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 8 } + } + }, + range: [25, 34], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 9 } + } + }], + range: [7, 36], + loc: { + start: { line: 1, column: 7 }, + end: { line: 2, column: 11 } + } + }, + alternate: null, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 11 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 11 } + }, + comments: [{ + type: 'Line', + value: ' Some comment', + range: [9, 24], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 24 } + } + }] + }, + + 'switch (answer) { case 42: /* perfect */ bingo() }': { + type: 'Program', + body: [{ + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'bingo', + range: [41, 46], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 46 } + } + }, + 'arguments': [], + range: [41, 48], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 48 } + } + }, + range: [41, 49], + loc: { + start: { line: 1, column: 41 }, + end: { line: 1, column: 49 } + } + }], + range: [18, 49], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 49 } + } + }], + range: [0, 50], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 50 } + } + }], + range: [0, 50], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 50 } + }, + comments: [{ + type: 'Block', + value: ' perfect ', + range: [27, 40], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 40 } + } + }] + } + + }, + + 'Numeric Literals': { + + '0': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + + '42': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42, + raw: '42', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '3': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 3, + raw: '3', + range: [0, 1] + }, + range: [0, 1] + }], + range: [0, 1], + tokens: [{ + type: 'Numeric', + value: '3', + range: [0, 1] + }] + }, + + '5': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 5, + raw: '5', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + }, + tokens: [{ + type: 'Numeric', + value: '5', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }] + }, + + '.14': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0.14, + raw: '.14', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '3.14159': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 3.14159, + raw: '3.14159', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '6.02214179e+23': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 6.02214179e+23, + raw: '6.02214179e+23', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '1.492417830e-10': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 1.49241783e-10, + raw: '1.492417830e-10', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '0x0': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0x0', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '0e+100': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0, + raw: '0e+100', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '0xabc': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0xabc, + raw: '0xabc', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0xdef': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0xdef, + raw: '0xdef', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0X1A': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x1A, + raw: '0X1A', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '0x10': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x10, + raw: '0x10', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '0x100': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0x100, + raw: '0x100', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '0X04': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 0X04, + raw: '0X04', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '02': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 2, + raw: '02', + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '012': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 10, + raw: '012', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '0012': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 10, + raw: '0012', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + } + + }, + + 'String Literals': { + + '"Hello"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello', + raw: '"Hello"', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: '\n\r\t\x0B\b\f\\\'"\x00', + raw: '"\\n\\r\\t\\v\\b\\f\\\\\\\'\\"\\0"', + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + '"\\u0061"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'a', + raw: '"\\u0061"', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + '"\\x61"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'a', + raw: '"\\x61"', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '"\\u00"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'u00', + raw: '"\\u00"', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '"\\xt"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'xt', + raw: '"\\xt"', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '"Hello\\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\nworld', + raw: '"Hello\\nworld"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '"Hello\\\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Helloworld', + raw: '"Hello\\\nworld"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 14 } + } + }, + + '"Hello\\02World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0002World', + raw: '"Hello\\02World"', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + '"Hello\\012World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u000AWorld', + raw: '"Hello\\012World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\122World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\122World', + raw: '"Hello\\122World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\0122World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u000A2World', + raw: '"Hello\\0122World"', + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + '"Hello\\312World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u00CAWorld', + raw: '"Hello\\312World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\412World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\412World', + raw: '"Hello\\412World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\812World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello812World', + raw: '"Hello\\812World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\712World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\712World', + raw: '"Hello\\712World"', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '"Hello\\0World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0000World', + raw: '"Hello\\0World"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '"Hello\\\r\nworld"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Helloworld', + raw: '"Hello\\\r\nworld"', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + + '"Hello\\1World"': { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'Hello\u0001World', + raw: '"Hello\\1World"', + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + }, + + 'Regular Expression Literals': { + + 'var x = /[a-z]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[a-z]/i', + raw: '/[a-z]/i', + range: [8, 16], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }, + range: [4, 16], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }], + kind: 'var', + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[a-z]/i', + range: [8, 16], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }] + }, + + 'var x = /[x-z]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5] + }, + init: { + type: 'Literal', + value: '/[x-z]/i', + raw: '/[x-z]/i', + range: [8, 16] + }, + range: [4, 16] + }], + kind: 'var', + range: [0, 16] + }], + range: [0, 16], + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3] + }, { + type: 'Identifier', + value: 'x', + range: [4, 5] + }, { + type: 'Punctuator', + value: '=', + range: [6, 7] + }, { + type: 'RegularExpression', + value: '/[x-z]/i', + range: [8, 16] + }] + }, + + 'var x = /[a-c]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[a-c]/i', + raw: '/[a-c]/i', + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }, + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 16 } + } + }], + kind: 'var', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[a-c]/i', + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 16 } + } + }] + }, + + 'var x = /[P QR]/i': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/i', + raw: '/[P QR]/i', + range: [8, 17], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 17 } + } + }, + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }], + kind: 'var', + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }], + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/i', + range: [8, 17], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 17 } + } + }] + }, + + 'var x = /[\\]/]/': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: new RegExp('[\\]/]').toString(), + raw: '/[\\]/]/', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }, + range: [4, 15], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 15 } + } + }], + kind: 'var', + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[\\]/]/', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }] + }, + + 'var x = /foo\\/bar/': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/foo\\/bar/', + raw: '/foo\\/bar/', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }, + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }], + kind: 'var', + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/foo\\/bar/', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }] + }, + + 'var x = /=([^=\\s])+/g': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/=([^=\\s])+/g', + raw: '/=([^=\\s])+/g', + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }, + range: [4, 21], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 21 } + } + }], + kind: 'var', + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/=([^=\\s])+/g', + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }] + }, + + 'var x = /[P QR]/\\u0067': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/g', + raw: '/[P QR]/\\u0067', + range: [8, 22], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 22 } + } + }, + range: [4, 22], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/\\u0067', + range: [8, 22], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 22 } + } + }] + }, + + 'var x = /[P QR]/\\g': { + type: 'Program', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: '/[P QR]/g', + raw: '/[P QR]/\\g', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }, + range: [4, 18], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 18 } + } + }], + kind: 'var', + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }], + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + }, + tokens: [{ + type: 'Keyword', + value: 'var', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, { + type: 'Identifier', + value: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'Punctuator', + value: '=', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, { + type: 'RegularExpression', + value: '/[P QR]/\\g', + range: [8, 18], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 18 } + } + }] + } + + }, + + 'Left-Hand-Side Expression': { + + 'new Button': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'Button', + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + 'arguments': [], + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'new Button()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'Button', + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, + 'arguments': [], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + 'new new foo': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'new new foo()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'new foo().bar()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [10, 13], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + 'arguments': [], + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + range: [0, 15], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 15 } + } + }, + + 'new foo[bar]': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + range: [4, 12], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + 'new foo.bar()': { + type: 'ExpressionStatement', + expression: { + type: 'NewExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'foo', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [8, 11], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 11 } + } + }, + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + '( new foo).bar()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'NewExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [6, 9], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 9 } + } + }, + 'arguments': [], + range: [2, 9], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 9 } + } + }, + property: { + type: 'Identifier', + name: 'bar', + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + 'arguments': [], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + 'foo(bar, baz)': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'bar', + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, { + type: 'Identifier', + name: 'baz', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + '( foo )()': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'universe.milkyway': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'universe.milkyway.solarsystem': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + property: { + type: 'Identifier', + name: 'solarsystem', + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'universe.milkyway.solarsystem.Earth': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [9, 17], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + property: { + type: 'Identifier', + name: 'solarsystem', + range: [18, 29], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 29 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + property: { + type: 'Identifier', + name: 'Earth', + range: [30, 35], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + + 'universe[galaxyName, otherUselessName]': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'SequenceExpression', + expressions: [{ + type: 'Identifier', + name: 'galaxyName', + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, { + type: 'Identifier', + name: 'otherUselessName', + range: [21, 37], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 37 } + } + }], + range: [9, 37], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 37 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'universe[galaxyName]': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'galaxyName', + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'universe[42].galaxies': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: true, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'universe(42).galaxies': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'universe(42).galaxies(14, 3, 77).milkyway': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 42, + raw: '42', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }], + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + property: { + type: 'Identifier', + name: 'galaxies', + range: [13, 21], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 14, + raw: '14', + range: [22, 24], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 24 } + } + }, { + type: 'Literal', + value: 3, + raw: '3', + range: [26, 27], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 27 } + } + }, { + type: 'Literal', + value: 77, + raw: '77', + range: [29, 31], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 31 } + } + }], + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + property: { + type: 'Identifier', + name: 'milkyway', + range: [33, 41], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 41 } + } + }, + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + + 'earth.asia.Indonesia.prepareForElection(2014)': { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'earth', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + property: { + type: 'Identifier', + name: 'asia', + range: [6, 10], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + property: { + type: 'Identifier', + name: 'Indonesia', + range: [11, 20], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + property: { + type: 'Identifier', + name: 'prepareForElection', + range: [21, 39], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 39 } + } + }, + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 2014, + raw: '2014', + range: [40, 44], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 44 } + } + }], + range: [0, 45], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 45 } + } + }, + range: [0, 45], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 45 } + } + }, + + 'universe.if': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'if', + range: [9, 11], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'universe.true': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'true', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'universe.false': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'false', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'universe.null': { + type: 'ExpressionStatement', + expression: { + type: 'MemberExpression', + computed: false, + object: { + type: 'Identifier', + name: 'universe', + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + property: { + type: 'Identifier', + name: 'null', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + } + + }, + + 'Postfix Expressions': { + + 'x++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'x--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'eval++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + prefix: false, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'eval--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + prefix: false, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'arguments++': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + prefix: false, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'arguments--': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + prefix: false, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + } + + }, + + 'Unary Operators': { + + '++x': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '--x': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + '++eval': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '--eval': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + '++arguments': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, + prefix: true, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + '--arguments': { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, + prefix: true, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + '+x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '+', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '-x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '-', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '~x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '~', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + '!x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: '!', + argument: { + type: 'Identifier', + name: 'x', + range: [1, 2], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 2 } + } + }, + prefix: true, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + }, + + 'void x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'void', + argument: { + type: 'Identifier', + name: 'x', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + prefix: true, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'delete x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'delete', + argument: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + prefix: true, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'typeof x': { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'typeof', + argument: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + prefix: true, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + } + + }, + + 'Multiplicative Operators': { + + 'x * y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x / y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x % y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Additive Operators': { + + 'x + y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x - y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Bitwise Shift Operator': { + + 'x << y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >> y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >>> y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>>>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Relational Operators': { + + 'x < y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x > y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x <= y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x >= y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x in y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: 'in', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x instanceof y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: 'instanceof', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x < y < z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Equality Operators': { + + 'x == y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '==', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x != y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '!=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x === y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '===', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x !== y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '!==', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Binary Bitwise Operators': { + + 'x & y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x ^ y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'x | y': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + } + + }, + + 'Binary Expressions': { + + 'x + y + z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y + z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y - z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y - z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x + y / z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '+', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x - y % z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '-', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y / z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '/', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x * y % z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x % y * z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'BinaryExpression', + operator: '%', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x << y << z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'BinaryExpression', + operator: '<<', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x | y | z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x & y & z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x ^ y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x & y | z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x | y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x | y & z': { + type: 'ExpressionStatement', + expression: { + type: 'BinaryExpression', + operator: '|', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '&', + left: { + type: 'Identifier', + name: 'y', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Binary Logical Operators': { + + 'x || y': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x && y': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'x || y || z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x && y && z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x || y && z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [5, 11], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'x || y ^ z': { + type: 'ExpressionStatement', + expression: { + type: 'LogicalExpression', + operator: '||', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'BinaryExpression', + operator: '^', + left: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'Identifier', + name: 'z', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + } + + }, + + 'Conditional Operator': { + + 'y ? 1 : 2': { + type: 'ExpressionStatement', + expression: { + type: 'ConditionalExpression', + test: { + type: 'Identifier', + name: 'y', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + consequent: { + type: 'Literal', + value: 1, + raw: '1', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + alternate: { + type: 'Literal', + value: 2, + raw: '2', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x && y ? 1 : 2': { + type: 'ExpressionStatement', + expression: { + type: 'ConditionalExpression', + test: { + type: 'LogicalExpression', + operator: '&&', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + consequent: { + type: 'Literal', + value: 1, + raw: '1', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + alternate: { + type: 'Literal', + value: 2, + raw: '2', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + + }, + + 'Assignment Operators': { + + 'x = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'eval = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'eval', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'arguments = 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'arguments', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + 'x *= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '*=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x /= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '/=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x %= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '%=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x += 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '+=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x -= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '-=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x <<= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '<<=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'x >>= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '>>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [6, 8], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'x >>>= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '>>>=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'x &= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '&=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x ^= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '^=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + 'x |= 42': { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '|=', + left: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [5, 7], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + } + + }, + + 'Block': { + + '{ foo }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'foo', + range: [2, 5], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 5 } + } + }, + range: [2, 6], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '{ doThis(); doThat(); }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThis', + range: [2, 8], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 8 } + } + }, + 'arguments': [], + range: [2, 10], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 10 } + } + }, + range: [2, 11], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 11 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [12, 18], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 18 } + } + }, + 'arguments': [], + range: [12, 20], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 20 } + } + }, + range: [12, 21], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '{}': { + type: 'BlockStatement', + body: [], + range: [0, 2], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 2 } + } + } + + }, + + 'Variable Statement': { + + 'var x': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'var', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + 'var x, y;': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + init: null, + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }], + kind: 'var', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'var x = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [8, 10], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 10 } + } + }, + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }], + kind: 'var', + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + + 'var eval = 42, arguments = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'eval', + range: [4, 8], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 8 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'arguments', + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + range: [15, 29], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 29 } + } + }], + kind: 'var', + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'var x = 14, y = 3, z = 1977': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [8, 10], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 10 } + } + }, + range: [4, 10], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 10 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [12, 17], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 17 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [23, 27], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 27 } + } + }, + range: [19, 27], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 27 } + } + }], + kind: 'var', + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'var implements, interface, package': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'implements', + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, + init: null, + range: [4, 14], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 14 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'interface', + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, + init: null, + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'package', + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }, + init: null, + range: [27, 34], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 34 } + } + }], + kind: 'var', + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'var private, protected, public, static': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'private', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + init: null, + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'protected', + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, + init: null, + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'public', + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, + init: null, + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'static', + range: [32, 38], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 38 } + } + }, + init: null, + range: [32, 38], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 38 } + } + }], + kind: 'var', + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + } + + }, + + 'Let Statement': { + + 'let x': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'let', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + + '{ let x }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: null, + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }], + kind: 'let', + range: [2, 8], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 8 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + '{ let x = 42 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + kind: 'let', + range: [2, 13], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 13 } + } + }], + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + }, + + '{ let x = 14, y = 3, z = 1977 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + range: [14, 19], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 19 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [25, 29], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 29 } + } + }, + range: [21, 29], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 29 } + } + }], + kind: 'let', + range: [2, 30], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 30 } + } + }], + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + } + + }, + + 'Const Statement': { + + 'const x = 42': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }], + kind: 'const', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + + '{ const x = 42 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }], + kind: 'const', + range: [2, 15], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 15 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + + '{ const x = 14, y = 3, z = 1977 }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [12, 14], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 14 } + } + }, + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + range: [16, 21], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 21 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'z', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + init: { + type: 'Literal', + value: 1977, + raw: '1977', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [23, 31], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 31 } + } + }], + kind: 'const', + range: [2, 32], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 32 } + } + }], + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + } + + }, + + 'Empty Statement': { + + ';': { + type: 'EmptyStatement', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + } + + }, + + 'Expression Statement': { + + 'x': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + + 'x, y': { + type: 'ExpressionStatement', + expression: { + type: 'SequenceExpression', + expressions: [{ + type: 'Identifier', + name: 'x', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, { + type: 'Identifier', + name: 'y', + range: [3, 4], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 4 } + } + }], + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + + '\\u0061': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'a', + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }, + + 'a\\u0061': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'aa', + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 7], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 7 } + } + }, + + '\\ua': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'ua', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + + 'a\\u': { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'au', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + } + + }, + + 'If Statement': { + + 'if (morning) goodMorning()': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodMorning', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + alternate: null, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'if (morning) (function(){})': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [24, 26], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 26 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: null, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'if (morning) var x = 0;': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + range: [17, 22], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [13, 23], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 23 } + } + }, + alternate: null, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + 'if (morning) function a(){}': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'a', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [25, 27], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 27 } + } + }, + rest: null, + generator: false, + expression: false, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: null, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'if (morning) goodMorning(); else goodDay()': { + type: 'IfStatement', + test: { + type: 'Identifier', + name: 'morning', + range: [4, 11], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 11 } + } + }, + consequent: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodMorning', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 27], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 27 } + } + }, + alternate: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'goodDay', + range: [33, 40], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 40 } + } + }, + 'arguments': [], + range: [33, 42], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 42 } + } + }, + range: [33, 42], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 42 } + } + }, + range: [0, 42], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 42 } + } + } + + }, + + 'Iteration Statements': { + + 'do keep(); while (true)': { + type: 'DoWhileStatement', + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'keep', + range: [3, 7], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [3, 9], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 9 } + } + }, + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + 'do keep(); while (true);': { + type: 'DoWhileStatement', + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'keep', + range: [3, 7], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 7 } + } + }, + 'arguments': [], + range: [3, 9], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 9 } + } + }, + range: [3, 10], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 10 } + } + }, + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'do { x++; y--; } while (x < 10)': { + type: 'DoWhileStatement', + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + prefix: false, + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + range: [5, 9], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 9 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + prefix: false, + range: [10, 13], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 13 } + } + }, + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }], + range: [3, 16], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 16 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + right: { + type: 'Literal', + value: 10, + raw: '10', + range: [28, 30], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 30 } + } + }, + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + '{ do { } while (false) false }': { + type: 'BlockStatement', + body: [{ + type: 'DoWhileStatement', + body: { + type: 'BlockStatement', + body: [], + range: [5, 8], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 8 } + } + }, + test: { + type: 'Literal', + value: false, + raw: 'false', + range: [16, 21], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 21 } + } + }, + range: [2, 22], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 22 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: false, + raw: 'false', + range: [23, 28], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 28 } + } + }, + range: [23, 29], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 29 } + } + }], + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'while (true) doSomething()': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doSomething', + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'while (x < 10) { x++; y--; }': { + type: 'WhileStatement', + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + right: { + type: 'Literal', + value: 10, + raw: '10', + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + range: [7, 13], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 13 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }, + prefix: false, + range: [17, 20], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 20 } + } + }, + range: [17, 21], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 21 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + prefix: false, + range: [22, 25], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 25 } + } + }, + range: [22, 26], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 26 } + } + }], + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + }, + + 'for(;;);': { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'for(;;){}': { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'BlockStatement', + body: [], + range: [7, 9], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 9 } + } + }, + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + }, + + 'for(x = 0;;);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'for(var x = 0;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }], + kind: 'var', + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'for(let x = 0;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }], + kind: 'let', + range: [4, 13], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 13 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }, + + 'for(var x = 0, y = 1;;);': { + type: 'ForStatement', + init: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'Literal', + value: 0, + raw: '0', + range: [12, 13], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 13 } + } + }, + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + init: { + type: 'Literal', + value: 1, + raw: '1', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }], + kind: 'var', + range: [4, 20], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 20 } + } + }, + test: null, + update: null, + body: { + type: 'EmptyStatement', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'for(x = 0; x < 42;);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: null, + body: { + type: 'EmptyStatement', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + 'for(x = 0; x < 42; x++);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + prefix: false, + range: [19, 22], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 22 } + } + }, + body: { + type: 'EmptyStatement', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'for(x = 0; x < 42; x++) process(x);': { + type: 'ForStatement', + init: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + test: { + type: 'BinaryExpression', + operator: '<', + left: { + type: 'Identifier', + name: 'x', + range: [11, 12], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Literal', + value: 42, + raw: '42', + range: [15, 17], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 17 } + } + }, + range: [11, 17], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 17 } + } + }, + update: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'x', + range: [19, 20], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 20 } + } + }, + prefix: false, + range: [19, 22], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 22 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [24, 31], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 31 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [32, 33], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 33 } + } + }], + range: [24, 34], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 34 } + } + }, + range: [24, 35], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 35 } + } + }, + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + } + }, + + 'for(x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [15, 22], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 22 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }], + range: [15, 25], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 25 } + } + }, + range: [15, 26], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 26 } + } + }, + each: false, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'for (var x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: null, + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }], + kind: 'var', + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }], + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + each: false, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + 'for (var x = 42 in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + range: [9, 15], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 15 } + } + }], + kind: 'var', + range: [5, 15], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [19, 23], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 23 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [25, 32], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 32 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [25, 35], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 35 } + } + }, + range: [25, 36], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 36 } + } + }, + each: false, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'for (let x in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: null, + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }], + kind: 'let', + range: [5, 10], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }], + range: [20, 30], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 30 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + each: false, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + }, + + 'for (let x = 42 in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'Literal', + value: 42, + raw: '42', + range: [13, 15], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 15 } + } + }, + range: [9, 15], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 15 } + } + }], + kind: 'let', + range: [5, 15], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [19, 23], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 23 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [25, 32], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 32 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [25, 35], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 35 } + } + }, + range: [25, 36], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 36 } + } + }, + each: false, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'for (var i = function() { return 10 in [] } in list) process(x);': { + type: 'ForInStatement', + left: { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'i', + range: [9, 10], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 10 } + } + }, + init: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ReturnStatement', + argument: { + type: 'BinaryExpression', + operator: 'in', + left: { + type: 'Literal', + value: 10, + raw: '10', + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + range: [33, 41], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 41 } + } + }, + range: [26, 42], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 42 } + } + }], + range: [24, 43], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 43 } + } + }, + rest: null, + generator: false, + expression: false, + range: [13, 43], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 43 } + } + }, + range: [9, 43], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 43 } + } + }], + kind: 'var', + range: [5, 43], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 43 } + } + }, + right: { + type: 'Identifier', + name: 'list', + range: [47, 51], + loc: { + start: { line: 1, column: 47 }, + end: { line: 1, column: 51 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'process', + range: [53, 60], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 60 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'x', + range: [61, 62], + loc: { + start: { line: 1, column: 61 }, + end: { line: 1, column: 62 } + } + }], + range: [53, 63], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 63 } + } + }, + range: [53, 64], + loc: { + start: { line: 1, column: 53 }, + end: { line: 1, column: 64 } + } + }, + each: false, + range: [0, 64], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 64 } + } + } + + }, + + 'continue statement': { + + 'while (true) { continue; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: null, + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + } + ], + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + }, + + 'while (true) { continue }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: null, + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + } + ], + range: [13, 25], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 25 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + 'done: while (true) { continue done }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: { + type: 'Identifier', + name: 'done', + range: [30, 34], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 34 } + } + }, + range: [21, 35], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 35 } + } + } + ], + range: [19, 36], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 36 } + } + }, + range: [6, 36], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + } + }, + + 'done: while (true) { continue done; }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'ContinueStatement', + label: { + type: 'Identifier', + name: 'done', + range: [30, 34], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 34 } + } + }, + range: [21, 35], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 35 } + } + } + ], + range: [19, 37], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 37 } + } + }, + range: [6, 37], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 37 } + } + }, + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + } + } + + }, + + 'break statement': { + + 'while (true) { break }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: null, + range: [15, 21], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 21 } + } + } + ], + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + 'done: while (true) { break done }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'done', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + } + ], + range: [19, 33], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 33 } + } + }, + range: [6, 33], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 33 } + } + }, + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + }, + + 'done: while (true) { break done; }': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'done', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [13, 17], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 17 } + } + }, + body: { + type: 'BlockStatement', + body: [ + { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'done', + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [21, 32], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 32 } + } + } + ], + range: [19, 34], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 34 } + } + }, + range: [6, 34], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + } + + }, + + 'return statement': { + + '(function(){ return })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 20], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 20 } + } + } + ], + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 21], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 21 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + }, + + '(function(){ return; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 20], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 20 } + } + } + ], + range: [11, 22], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 22 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 22], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '(function(){ return x; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + range: [13, 22], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 22 } + } + } + ], + range: [11, 24], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + '(function(){ return x * y })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + range: [20, 25], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 25 } + } + }, + range: [13, 26], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 26 } + } + } + ], + range: [11, 27], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 27 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 27], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 27 } + } + }, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + } + }, + + 'with statement': { + + 'with (x) foo = bar': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [15, 18], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [0, 18], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 18 } + } + }, + + 'with (x) foo = bar;': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [9, 12], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 12 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [15, 18], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + range: [9, 19], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 19 } + } + }, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'with (x) { foo = bar }': { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'foo', + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + right: { + type: 'Identifier', + name: 'bar', + range: [17, 20], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 20 } + } + }, + range: [11, 20], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 20 } + } + }, + range: [11, 21], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 21 } + } + }], + range: [9, 22], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 22 } + } + }, + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + } + } + + }, + + 'switch statement': { + + 'switch (x) {}': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'x', + range: [8, 9], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 9 } + } + }, + cases:[], + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, + + 'switch (answer) { case 42: hi(); break; }': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hi', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + 'arguments': [], + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, { + type: 'BreakStatement', + label: null, + range: [33, 39], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 39 } + } + }], + range: [18, 39], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + } + }, + + 'switch (answer) { case 42: hi(); break; default: break }': { + type: 'SwitchStatement', + discriminant: { + type: 'Identifier', + name: 'answer', + range: [8, 14], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 14 } + } + }, + cases: [{ + type: 'SwitchCase', + test: { + type: 'Literal', + value: 42, + raw: '42', + range: [23, 25], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 25 } + } + }, + consequent: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'hi', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + 'arguments': [], + range: [27, 31], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 31 } + } + }, + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, { + type: 'BreakStatement', + label: null, + range: [33, 39], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 39 } + } + }], + range: [18, 39], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 39 } + } + }, { + type: 'SwitchCase', + test: null, + consequent: [{ + type: 'BreakStatement', + label: null, + range: [49, 55], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 55 } + } + }], + range: [40, 55], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 55 } + } + }], + range: [0, 56], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 56 } + } + } + + }, + + 'Labelled Statements': { + + 'start: for (;;) break start': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'start', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + body: { + type: 'ForStatement', + init: null, + test: null, + update: null, + body: { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'start', + range: [22, 27], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 27 } + } + }, + range: [16, 27], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 27 } + } + }, + range: [7, 27], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 27 } + } + }, + range: [0, 27], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 27 } + } + }, + + 'start: while (true) break start': { + type: 'LabeledStatement', + label: { + type: 'Identifier', + name: 'start', + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + body: { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + body: { + type: 'BreakStatement', + label: { + type: 'Identifier', + name: 'start', + range: [26, 31], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 31 } + } + }, + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + range: [7, 31], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 31 } + } + }, + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + } + } + + }, + + 'throw statement': { + + 'throw x;': { + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + range: [0, 8], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 8 } + } + }, + + 'throw x * y': { + type: 'ThrowStatement', + argument: { + type: 'BinaryExpression', + operator: '*', + left: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + right: { + type: 'Identifier', + name: 'y', + range: [10, 11], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 11 } + } + }, + range: [6, 11], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 11 } + } + }, + range: [0, 11], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 11 } + } + }, + + 'throw { message: "Error" }': { + type: 'ThrowStatement', + argument: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'message', + range: [8, 15], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 15 } + } + }, + value: { + type: 'Literal', + value: 'Error', + raw: '"Error"', + range: [17, 24], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 24 } + } + }, + kind: 'init', + range: [8, 24], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 24 } + } + }], + range: [6, 26], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 26 } + } + }, + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + } + } + + }, + + 'try statement': { + + 'try { } catch (e) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [18, 21], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 21 } + } + }, + range: [8, 21], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 21 } + } + }], + finalizer: null, + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + } + }, + + 'try { } catch (eval) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'eval', + range: [15, 19], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 19 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + range: [8, 24], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 24 } + } + }], + finalizer: null, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'try { } catch (arguments) { }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'arguments', + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [26, 29], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 29 } + } + }, + range: [8, 29], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 29 } + } + }], + finalizer: null, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'try { } catch (e) { say(e) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }], + range: [20, 26], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 26 } + } + }, + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }], + range: [18, 28], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 28 } + } + }, + range: [8, 28], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 28 } + } + }], + finalizer: null, + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + } + }, + + 'try { } finally { cleanup(stuff) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [4, 7], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 7 } + } + }, + guardedHandlers: [], + handlers: [], + finalizer: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'cleanup', + range: [18, 25], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 25 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'stuff', + range: [26, 31], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 31 } + } + }], + range: [18, 32], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 32 } + } + }, + range: [18, 33], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 33 } + } + }], + range: [16, 34], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 34 } + } + }, + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'try { doThat(); } catch (e) { say(e) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [34, 35], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 35 } + } + }], + range: [30, 36], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 36 } + } + }, + range: [30, 37], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 37 } + } + }], + range: [28, 38], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 38 } + } + }, + range: [18, 38], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 38 } + } + }], + finalizer: null, + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + 'try { doThat(); } catch (e) { say(e) } finally { cleanup(stuff) }': { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'doThat', + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, + 'arguments': [], + range: [6, 14], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 14 } + } + }, + range: [6, 15], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 15 } + } + }], + range: [4, 17], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 17 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'e', + range: [25, 26], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 26 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'say', + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'e', + range: [34, 35], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 35 } + } + }], + range: [30, 36], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 36 } + } + }, + range: [30, 37], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 37 } + } + }], + range: [28, 38], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 38 } + } + }, + range: [18, 38], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 38 } + } + }], + finalizer: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'cleanup', + range: [49, 56], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 56 } + } + }, + 'arguments': [{ + type: 'Identifier', + name: 'stuff', + range: [57, 62], + loc: { + start: { line: 1, column: 57 }, + end: { line: 1, column: 62 } + } + }], + range: [49, 63], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 63 } + } + }, + range: [49, 64], + loc: { + start: { line: 1, column: 49 }, + end: { line: 1, column: 64 } + } + }], + range: [47, 65], + loc: { + start: { line: 1, column: 47 }, + end: { line: 1, column: 65 } + } + }, + range: [0, 65], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 65 } + } + } + + }, + + 'debugger statement': { + + 'debugger;': { + type: 'DebuggerStatement', + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 9 } + } + } + + }, + + 'Function Definition': { + + 'function hello() { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [19, 24], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 24 } + } + }, + 'arguments': [], + range: [19, 26], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 26 } + } + }, + range: [19, 27], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 27 } + } + }], + range: [17, 29], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 29 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'function eval() { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [16, 19], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 19 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + } + }, + + 'function arguments() { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'arguments', + range: [9, 18], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 18 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + } + }, + + 'function test(t, t) { }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'test', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [{ + type: 'Identifier', + name: 't', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, { + type: 'Identifier', + name: 't', + range: [17, 18], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 18 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + } + }, + + '(function test(t, t) { })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'test', + range: [10, 14], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 't', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Identifier', + name: 't', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [21, 24], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 24 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 24 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 25 } + } + }, + + 'function eval() { function inner() { "use strict" } }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [9, 13], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 13 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'inner', + range: [27, 32], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\"use strict\"', + range: [37, 49], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 49 } + } + }, + range: [37, 50], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 50 } + } + }], + range: [35, 51], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 51 } + } + }, + rest: null, + generator: false, + expression: false, + range: [18, 51], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 51 } + } + }], + range: [16, 53], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 53 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 53], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 53 } + } + }, + + 'function hello(a) { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 'a', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [20, 25], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 25 } + } + }, + 'arguments': [], + range: [20, 27], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 27 } + } + }, + range: [20, 28], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 28 } + } + }], + range: [18, 30], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 30 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 30], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 30 } + } + }, + + 'function hello(a, b) { sayHi(); }': { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [{ + type: 'Identifier', + name: 'a', + range: [15, 16], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 16 } + } + }, { + type: 'Identifier', + name: 'b', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [23, 28], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 28 } + } + }, + 'arguments': [], + range: [23, 30], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 30 } + } + }, + range: [23, 31], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 31 } + } + }], + range: [21, 33], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + } + }, + + 'var hi = function() { sayHi() };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [22, 27], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 27 } + } + }, + 'arguments': [], + range: [22, 29], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 29 } + } + }, + range: [22, 30], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 30 } + } + }], + range: [20, 31], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 31 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 31], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 31 } + } + }, + range: [4, 31], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 31 } + } + }], + kind: 'var', + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 32 } + } + }, + + 'var hi = function eval() { };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'eval', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [25, 28], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 28 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 28], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 28 } + } + }, + range: [4, 28], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 28 } + } + }], + kind: 'var', + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 29 } + } + }, + + 'var hi = function arguments() { };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hi', + range: [4, 6], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 6 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'arguments', + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [30, 33], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [9, 33], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 33 } + } + }, + range: [4, 33], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 33 } + } + }], + kind: 'var', + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + } + }, + + 'var hello = function hi() { sayHi() };': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'hello', + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }, + init: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'hi', + range: [21, 23], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 23 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'sayHi', + range: [28, 33], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 33 } + } + }, + 'arguments': [], + range: [28, 35], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 35 } + } + }, + range: [28, 36], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 36 } + } + }], + range: [26, 37], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [12, 37], + loc: { + start: { line: 1, column: 12 }, + end: { line: 1, column: 37 } + } + }, + range: [4, 37], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 37 } + } + }], + kind: 'var', + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + } + }, + + '(function(){})': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [11, 13], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 13 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 13], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 13 } + } + }, + range: [0, 14], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 14 } + } + } + + }, + + 'Automatic semicolon insertion': { + + '{ x\n++y }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + range: [2, 4], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 2, column: 2 }, + end: { line: 2, column: 3 } + } + }, + prefix: true, + range: [4, 7], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 3 } + } + }, + range: [4, 8], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 4 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '{ x\n--y }': { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + range: [2, 4], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'y', + range: [6, 7], + loc: { + start: { line: 2, column: 2 }, + end: { line: 2, column: 3 } + } + }, + prefix: true, + range: [4, 7], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 3 } + } + }, + range: [4, 8], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 4 } + } + }], + range: [0, 9], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + 'var x /* comment */;': { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + init: null, + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }], + kind: 'var', + range: [0, 20], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 20 } + } + }, + + '{ var x = 14, y = 3\nz; }': { + type: 'BlockStatement', + body: [{ + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [6, 7], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 7 } + } + }, + init: { + type: 'Literal', + value: 14, + raw: '14', + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + range: [6, 12], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 12 } + } + }, { + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'y', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + init: { + type: 'Literal', + value: 3, + raw: '3', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + range: [14, 19], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 19 } + } + }], + kind: 'var', + range: [2, 20], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'z', + range: [20, 21], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [20, 22], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + }], + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 4 } + } + }, + + 'while (true) { continue\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [24, 29], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [24, 30], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 32], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { continue // Comment\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [35, 40], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [35, 41], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 43], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { continue /* Multiline\nComment */there; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'ContinueStatement', + label: null, + range: [15, 23], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 23 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [47, 52], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [47, 53], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [13, 55], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 18 } + } + }, + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + }, + + 'while (true) { break\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [21, 26], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [21, 27], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 29], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 29], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { break // Comment\nthere; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [32, 37], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [32, 38], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [13, 40], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 8 } + } + }, + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + 'while (true) { break /* Multiline\nComment */there; }': { + type: 'WhileStatement', + test: { + type: 'Literal', + value: true, + raw: 'true', + range: [7, 11], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 11 } + } + }, + body: { + type: 'BlockStatement', + body: [{ + type: 'BreakStatement', + label: null, + range: [15, 20], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 20 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'there', + range: [44, 49], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [44, 50], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [13, 52], + loc: { + start: { line: 1, column: 13 }, + end: { line: 2, column: 18 } + } + }, + range: [0, 52], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + }, + + '(function(){ return\nx; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [20, 21], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [20, 22], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + } + ], + range: [11, 24], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 4 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 24], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 4 } + } + }, + range: [0, 25], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '(function(){ return // Comment\nx; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [31, 32], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 1 } + } + }, + range: [31, 33], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 2 } + } + } + ], + range: [11, 35], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 4 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 35], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 4 } + } + }, + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 5 } + } + }, + + '(function(){ return/* Multiline\nComment */x; })': { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [ + { + type: 'ReturnStatement', + argument: null, + range: [13, 19], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 19 } + } + }, + { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'x', + range: [42, 43], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 11 } + } + }, + range: [42, 44], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 12 } + } + } + ], + range: [11, 46], + loc: { + start: { line: 1, column: 11 }, + end: { line: 2, column: 14 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 46], + loc: { + start: { line: 1, column: 1 }, + end: { line: 2, column: 14 } + } + }, + range: [0, 47], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 15 } + } + }, + + '{ throw error\nerror; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 14], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [14, 19], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [14, 20], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + '{ throw error// Comment\nerror; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 24], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 0 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [24, 29], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 5 } + } + }, + range: [24, 30], + loc: { + start: { line: 2, column: 0 }, + end: { line: 2, column: 6 } + } + }], + range: [0, 32], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 8 } + } + }, + + '{ throw error/* Multiline\nComment */error; }': { + type: 'BlockStatement', + body: [{ + type: 'ThrowStatement', + argument: { + type: 'Identifier', + name: 'error', + range: [8, 13], + loc: { + start: { line: 1, column: 8 }, + end: { line: 1, column: 13 } + } + }, + range: [2, 36], + loc: { + start: { line: 1, column: 2 }, + end: { line: 2, column: 10 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'error', + range: [36, 41], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 15 } + } + }, + range: [36, 42], + loc: { + start: { line: 2, column: 10 }, + end: { line: 2, column: 16 } + } + }], + range: [0, 44], + loc: { + start: { line: 1, column: 0 }, + end: { line: 2, column: 18 } + } + } + + }, + + 'Source elements': { + + '': { + type: 'Program', + body: [], + range: [0, 0], + loc: { + start: { line: 0, column: 0 }, + end: { line: 0, column: 0 } + }, + tokens: [] + } + }, + + 'Invalid syntax': { + + '{': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected end of input' + }, + + '}': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token }' + }, + + '3ea': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3in []': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e+': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3e-': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3x': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3x0': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '0x': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '09': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '018': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '01a': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '3in[]': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '0x3in[]': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"Hello\nWorld"': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\u005c': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'x\\u002a': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'var x = /(s/g': { + index: 13, + lineNumber: 1, + column: 14, + message: 'Error: Line 1: Invalid regular expression' + }, + + '/': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + '/test': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + 'var x = /[a-z]/\\ux': { + index: 18, + lineNumber: 1, + column: 19, + message: 'Error: Line 1: Invalid regular expression' + }, + + '3 = 4': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + 'func() = 4': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '(1 + 1) = 10': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1++': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1--': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '++1': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '--1': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + 'for((1 + 1) in list) process(x);': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + '[': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected end of input' + }, + + '[,': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + {': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + { t:t ': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected end of input' + }, + + '1 + { t:t,': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'var x = /\n/': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + 'var x = "\n': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'var if = 42': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token if' + }, + + 'i + 2 = 42': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '+i = 42': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }, + + '1 + (': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + '\n\n\n{': { + index: 4, + lineNumber: 4, + column: 2, + message: 'Error: Line 4: Unexpected end of input' + }, + + '\n/* Some multiline\ncomment */\n)': { + index: 30, + lineNumber: 4, + column: 1, + message: 'Error: Line 4: Unexpected token )' + }, + + '{ set 1 }': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + '{ get 2 }': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + '({ set: s(if) { } })': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token if' + }, + + '({ set s(.) { } })': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token .' + }, + + '({ set s() { } })': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token )' + }, + + '({ set: s() { } })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ set: s(a, b) { } })': { + index: 16, + lineNumber: 1, + column: 17, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ get: g(d) { } })': { + index: 13, + lineNumber: 1, + column: 14, + message: 'Error: Line 1: Unexpected token {' + }, + + '({ get i() { }, i: 42 })': { + index: 21, + lineNumber: 1, + column: 22, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ i: 42, get i() { } })': { + index: 21, + lineNumber: 1, + column: 22, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ set i(x) { }, i: 42 })': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ i: 42, set i(x) { } })': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }, + + '({ get i() { }, get i() { } })': { + index: 27, + lineNumber: 1, + column: 28, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }, + + '({ set i(x) { }, set i(x) { } })': { + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }, + + 'function t(if) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token if' + }, + + 'function t(true) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token true' + }, + + 'function t(false) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token false' + }, + + 'function t(null) { }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Unexpected token null' + }, + + 'function null() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token null' + }, + + 'function true() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token true' + }, + + 'function false() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token false' + }, + + 'function if() { }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token if' + }, + + 'a b;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected identifier' + }, + + 'if.a;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token .' + }, + + 'a if;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token if' + }, + + 'a class;': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected reserved word' + }, + + 'break\n': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal break statement' + }, + + 'break 1;': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected number' + }, + + 'continue\n': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'continue 2;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected number' + }, + + 'throw': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'throw;': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'throw\n': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal newline after throw' + }, + + 'for (var i, i2 in {});': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Unexpected token in' + }, + + 'for ((i in {}));': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token )' + }, + + 'for (i + 1 in {});': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + 'for (+i in {});': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }, + + 'if(false)': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'if(false) doThis(); else': { + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'do': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'while(false)': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'for(;;)': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'with(x)': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'try { }': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Missing catch or finally after try' + }, + + 'try {} catch (42) {} ': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected number' + }, + + 'try {} catch (answer()) {} ': { + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Unexpected token (' + }, + + 'try {} catch (-x) {} ': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token -' + }, + + + '\u203F = 10': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'const x = 12, y;': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'const x, y = 12;': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ,' + }, + + 'const x;': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ;' + }, + + 'if(true) let a = 1;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token let' + }, + + 'if(true) const a = 1;': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token const' + }, + + 'switch (c) { default: default: }': { + index: 30, + lineNumber: 1, + column: 31, + message: 'Error: Line 1: More than one default clause in switch statement' + }, + + 'new X()."s"': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Unexpected string' + }, + + '/*': { + index: 2, + lineNumber: 1, + column: 3, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*\n\n\n': { + index: 5, + lineNumber: 4, + column: 1, + message: 'Error: Line 4: Unexpected token ILLEGAL' + }, + + '/**': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*\n\n*': { + index: 5, + lineNumber: 3, + column: 2, + message: 'Error: Line 3: Unexpected token ILLEGAL' + }, + + '/*hello': { + index: 7, + lineNumber: 1, + column: 8, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '/*hello *': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\n]': { + index: 1, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\r]': { + index: 1, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\r\n]': { + index: 2, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '\n\r]': { + index: 2, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '//\r\n]': { + index: 4, + lineNumber: 2, + column: 1, + message: 'Error: Line 2: Unexpected token ]' + }, + + '//\n\r]': { + index: 4, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/a\\\n/': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Invalid regular expression: missing /' + }, + + '//\r \n]': { + index: 5, + lineNumber: 3, + column: 1, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/*\r\n*/]': { + index: 6, + lineNumber: 2, + column: 3, + message: 'Error: Line 2: Unexpected token ]' + }, + + '/*\n\r*/]': { + index: 6, + lineNumber: 3, + column: 3, + message: 'Error: Line 3: Unexpected token ]' + }, + + '/*\r \n*/]': { + index: 7, + lineNumber: 3, + column: 3, + message: 'Error: Line 3: Unexpected token ]' + }, + + '\\\\': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\\u005c': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + + '\\x': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\\u0000': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\u200C = []': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '\u200D = []': { + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"\\': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + '"\\u': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected token ILLEGAL' + }, + + 'try { } catch() {}': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Unexpected token )' + }, + + 'return': { + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Illegal return statement' + }, + + 'break': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Illegal break statement' + }, + + 'continue': { + index: 8, + lineNumber: 1, + column: 9, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'switch (x) { default: continue; }': { + index: 31, + lineNumber: 1, + column: 32, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'do { x } *': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token *' + }, + + 'while (true) { break x; }': { + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'while (true) { continue x; }': { + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { break x; }); }': { + index: 40, + lineNumber: 1, + column: 41, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { continue x; }); }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Undefined label \'x\'' + }, + + 'x: while (true) { (function () { break; }); }': { + index: 39, + lineNumber: 1, + column: 40, + message: 'Error: Line 1: Illegal break statement' + }, + + 'x: while (true) { (function () { continue; }); }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Illegal continue statement' + }, + + 'x: while (true) { x: while (true) { } }': { + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Label \'x\' has already been declared' + }, + + '(function () { \'use strict\'; delete i; }())': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' + }, + + '(function () { \'use strict\'; with (i); }())': { + index: 28, + lineNumber: 1, + column: 29, + message: 'Error: Line 1: Strict mode code may not include a with statement' + }, + + 'function hello() {\'use strict\'; ({ i: 42, i: 42 }) }': { + index: 47, + lineNumber: 1, + column: 48, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ hasOwnProperty: 42, hasOwnProperty: 42 }) }': { + index: 73, + lineNumber: 1, + column: 74, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; var eval = 10; }': { + index: 40, + lineNumber: 1, + column: 41, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; var arguments = 10; }': { + index: 45, + lineNumber: 1, + column: 46, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; try { } catch (eval) { } }': { + index: 51, + lineNumber: 1, + column: 52, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; try { } catch (arguments) { } }': { + index: 56, + lineNumber: 1, + column: 57, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; eval = 10; }': { + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; arguments = 10; }': { + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ++eval; }': { + index: 38, + lineNumber: 1, + column: 39, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; --eval; }': { + index: 38, + lineNumber: 1, + column: 39, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; ++arguments; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; --arguments; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; eval++; }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; eval--; }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; arguments++; }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; arguments--; }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }, + + 'function hello() {\'use strict\'; function eval() { } }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; function arguments() { } }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function eval() {\'use strict\'; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function arguments() {\'use strict\'; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; (function eval() { }()) }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; (function arguments() { }()) }': { + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function eval() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function arguments() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + 'function hello() {\'use strict\'; ({ s: function eval() { } }); }': { + index: 47, + lineNumber: 1, + column: 48, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }, + + '(function package() {\'use strict\'; })()': { + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() {\'use strict\'; ({ i: 10, set s(eval) { } }); }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ set s(eval) { } }); }': { + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() {\'use strict\'; ({ s: function s(eval) { } }); }': { + index: 49, + lineNumber: 1, + column: 50, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello(eval) {\'use strict\';}': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello(arguments) {\'use strict\';}': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() { \'use strict\'; function inner(eval) {} }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function hello() { \'use strict\'; function inner(arguments) {} }': { + index: 48, + lineNumber: 1, + column: 49, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + ' "\\1"; \'use strict\';': { + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; "\\1"; }': { + index: 33, + lineNumber: 1, + column: 34, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; 021; }': { + index: 33, + lineNumber: 1, + column: 34, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; ({ "\\1": 42 }); }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { \'use strict\'; ({ 021: 42 }); }': { + index: 36, + lineNumber: 1, + column: 37, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "octal directive\\1"; "use strict"; }': { + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "octal directive\\1"; "octal directive\\2"; "use strict"; }': { + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "use strict"; function inner() { "octal directive\\1"; } }': { + index: 52, + lineNumber: 1, + column: 53, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }, + + 'function hello() { "use strict"; var implements; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var interface; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var package; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var private; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var protected; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var public; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var static; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var yield; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello() { "use strict"; var let; }': { + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function hello(static) { "use strict"; }': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function static() { "use strict"; }': { + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'var yield': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token yield' + }, + + 'var let': { + index: 4, + lineNumber: 1, + column: 5, + message: 'Error: Line 1: Unexpected token let' + }, + + '"use strict"; function static() { }': { + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function a(t, t) { "use strict"; }': { + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + 'function a(eval) { "use strict"; }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + 'function a(package) { "use strict"; }': { + index: 11, + lineNumber: 1, + column: 12, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'function a() { "use strict"; function b(t, t) { }; }': { + index: 43, + lineNumber: 1, + column: 44, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + '(function a(t, t) { "use strict"; })': { + index: 15, + lineNumber: 1, + column: 16, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + 'function a() { "use strict"; (function b(t, t) { }); }': { + index: 44, + lineNumber: 1, + column: 45, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }, + + '(function a(eval) { "use strict"; })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }, + + '(function a(package) { "use strict"; })': { + index: 12, + lineNumber: 1, + column: 13, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }, + + 'var': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'let': { + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Unexpected end of input' + }, + + 'const': { + index: 5, + lineNumber: 1, + column: 6, + message: 'Error: Line 1: Unexpected end of input' + } + + }, + + 'API': { + 'parse()': { + call: 'parse', + args: [], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'undefined' + } + }] + } + }, + + 'parse(null)': { + call: 'parse', + args: [null], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: null + } + }] + } + }, + + 'parse(42)': { + call: 'parse', + args: [42], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42 + } + }] + } + }, + + 'parse(true)': { + call: 'parse', + args: [true], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: true + } + }] + } + }, + + 'parse(undefined)': { + call: 'parse', + args: [void 0], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'undefined' + } + }] + } + }, + + 'parse(new String("test"))': { + call: 'parse', + args: [new String('test')], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Identifier', + name: 'test' + } + }] + } + }, + + 'parse(new Number(42))': { + call: 'parse', + args: [new Number(42)], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 42 + } + }] + } + }, + + 'parse(new Boolean(true))': { + call: 'parse', + args: [new Boolean(true)], + result: { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: true + } + }] + } + }, + + 'Syntax': { + property: 'Syntax', + result: { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SwitchStatement: 'SwitchStatement', + SwitchCase: 'SwitchCase', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement' + } + } + + }, + + 'Tolerant parse': { + 'return': { + type: 'Program', + body: [{ + type: 'ReturnStatement', + 'argument': null, + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + } + }], + range: [0, 6], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 6 } + }, + errors: [{ + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Illegal return statement' + }] + }, + + '(function () { \'use strict\'; with (i); }())': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [15, 27], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 27 } + } + }, + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, { + type: 'WithStatement', + object: { + type: 'Identifier', + name: 'i', + range: [35, 36], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 36 } + } + }, + body: { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }, + range: [29, 38], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 38 } + } + }], + range: [13, 40], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 40 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 40], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 40 } + } + }, + 'arguments': [], + range: [1, 42], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 42 } + } + }, + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + } + }], + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + }, + errors: [{ + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Strict mode code may not include a with statement' + }] + }, + + '(function () { \'use strict\'; 021 }())': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'CallExpression', + callee: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [15, 27], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 27 } + } + }, + range: [15, 28], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 28 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 17, + raw: "021", + range: [29, 32], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 32 } + } + }, + range: [29, 33], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 33 } + } + }], + range: [13, 34], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [1, 34], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 34 } + } + }, + 'arguments': [], + range: [1, 36], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 36 } + } + }, + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + } + }], + range: [0, 37], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 37 } + }, + errors: [{ + index: 29, + lineNumber: 1, + column: 30, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; delete x': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UnaryExpression', + operator: 'delete', + argument: { + type: 'Identifier', + name: 'x', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + prefix: true, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }], + range: [0, 22], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 22 } + }, + errors: [{ + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Delete of an unqualified identifier in strict mode.' + }] + }, + + '"use strict"; try {} catch (eval) {}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'eval', + range: [28, 32], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 32 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [34, 36], + loc: { + start: { line: 1, column: 34 }, + end: { line: 1, column: 36 } + } + }, + range: [21, 36], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 36 } + } + }], + finalizer: null, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; try {} catch (arguments) {}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'TryStatement', + block: { + type: 'BlockStatement', + body: [], + range: [18, 20], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 20 } + } + }, + guardedHandlers: [], + handlers: [{ + type: 'CatchClause', + param: { + type: 'Identifier', + name: 'arguments', + range: [28, 37], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 37 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + range: [21, 41], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 41 } + } + }], + finalizer: null, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 37, + lineNumber: 1, + column: 38, + message: 'Error: Line 1: Catch variable may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; var eval;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'eval', + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }, + init: null, + range: [18, 22], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 22 } + } + }], + kind: 'var', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + }, + errors: [{ + index: 22, + lineNumber: 1, + column: 23, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; var arguments;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'arguments', + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }, + init: null, + range: [18, 27], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 27 } + } + }], + kind: 'var', + range: [14, 28], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 28 } + } + }], + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + }, + errors: [{ + index: 27, + lineNumber: 1, + column: 28, + message: 'Error: Line 1: Variable name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; eval = 0;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'eval', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [21, 22], + loc: { + start: { line: 1, column: 21 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 22], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 22 } + } + }, + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }], + range: [0, 23], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 23 } + }, + errors: [{ + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; eval++;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'eval', + range: [14, 18], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 18 } + } + }, + prefix: false, + range: [14, 20], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 20 } + } + }, + range: [14, 21], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + errors: [{ + index: 18, + lineNumber: 1, + column: 19, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; --eval;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'eval', + range: [16, 20], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 20 } + } + }, + prefix: true, + range: [14, 20], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 20 } + } + }, + range: [14, 21], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 21 } + } + }], + range: [0, 21], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 21 } + }, + errors: [{ + index: 20, + lineNumber: 1, + column: 21, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; arguments = 0;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'arguments', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }, + right: { + type: 'Literal', + value: 0, + raw: '0', + range: [26, 27], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 27 } + } + }, + range: [14, 27], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 27 } + } + }, + range: [14, 28], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 28 } + } + }], + range: [0, 28], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 28 } + }, + errors: [{ + index: 14, + lineNumber: 1, + column: 15, + message: 'Error: Line 1: Assignment to eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; arguments--;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Identifier', + name: 'arguments', + range: [14, 23], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 23 } + } + }, + prefix: false, + range: [14, 25], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 25 } + } + }, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }], + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Postfix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + '"use strict"; ++arguments;': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Identifier', + name: 'arguments', + range: [16, 25], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 25 } + } + }, + prefix: true, + range: [14, 25], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 25 } + } + }, + range: [14, 26], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 26 } + } + }], + range: [0, 26], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 26 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Prefix increment/decrement may not have eval or arguments operand in strict mode' + }] + }, + + + '"use strict";x={y:1,y:1}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [13, 14], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 14 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'y', + range: [16, 17], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 17 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + kind: 'init', + range: [16, 19], + loc: { + start: { line: 1, column: 16 }, + end: { line: 1, column: 19 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'y', + range: [20, 21], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 21 } + } + }, + value: { + type: 'Literal', + value: 1, + raw: '1', + range: [22, 23], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 23 } + } + }, + kind: 'init', + range: [20, 23], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 23 } + } + }], + range: [15, 24], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 24 } + } + }, + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }, + range: [13, 24], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 24 } + } + }], + range: [0, 24], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 24 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Duplicate data property in object literal not allowed in strict mode' + }] + }, + + '"use strict"; function eval() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'eval', + range: [23, 27], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 27 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [30, 32], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 32 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 32], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 32 } + } + }, { + type: 'EmptyStatement', + range: [32, 33], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 33 } + } + }], + range: [0, 33], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 33 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; function arguments() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'arguments', + range: [23, 32], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [35, 37], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 37], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 37 } + } + }, { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }], + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; function interface() {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'interface', + range: [23, 32], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 32 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [35, 37], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 37 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 37], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 37 } + } + }, { + type: 'EmptyStatement', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }], + range: [0, 38], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 38 } + }, + errors: [{ + index: 23, + lineNumber: 1, + column: 24, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }] + }, + + '"use strict"; (function eval() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'eval', + range: [24, 28], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 28 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [31, 33], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 33], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 33 } + } + }, + range: [14, 35], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 35 } + } + }], + range: [0, 35], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 35 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; (function arguments() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'arguments', + range: [24, 33], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 33 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 38], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 38 } + } + }, + range: [14, 40], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 40 } + } + }], + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Function name may not be eval or arguments in strict mode' + }] + }, + + '"use strict"; (function interface() {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'interface', + range: [24, 33], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 33 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 38], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 38 } + } + }, + range: [14, 40], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 40 } + } + }], + range: [0, 40], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 40 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Use of future reserved word in strict mode' + }] + }, + + '"use strict"; function f(eval) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'eval', + range: [25, 29], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 29 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [31, 33], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 33 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 33], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 33 } + } + }, { + type: 'EmptyStatement', + range: [33, 34], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 34 } + } + }], + range: [0, 34], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 34 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; function f(arguments) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'arguments', + range: [25, 34], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 34 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 38], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 38 } + } + }, { + type: 'EmptyStatement', + range: [38, 39], + loc: { + start: { line: 1, column: 38 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + }, + errors: [{ + index: 25, + lineNumber: 1, + column: 26, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; function f(foo, foo) {};': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'f', + range: [23, 24], + loc: { + start: { line: 1, column: 23 }, + end: { line: 1, column: 24 } + } + }, + params: [{ + type: 'Identifier', + name: 'foo', + range: [25, 28], + loc: { + start: { line: 1, column: 25 }, + end: { line: 1, column: 28 } + } + }, { + type: 'Identifier', + name: 'foo', + range: [31, 34], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 34 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [36, 38], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 38 } + } + }, + rest: null, + generator: false, + expression: false, + range: [14, 38], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 38 } + } + }, { + type: 'EmptyStatement', + range: [38, 39], + loc: { + start: { line: 1, column: 38 }, + end: { line: 1, column: 39 } + } + }], + range: [0, 39], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 39 } + }, + errors: [{ + index: 31, + lineNumber: 1, + column: 32, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }] + }, + + '"use strict"; (function f(eval) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'eval', + range: [26, 30], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 30 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 34], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 34 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + + '"use strict"; (function f(arguments) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'arguments', + range: [26, 35], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 35 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [37, 39], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 39 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 39], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 39 } + } + }, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + '"use strict"; (function f(foo, foo) {});': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'FunctionExpression', + id: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + params: [{ + type: 'Identifier', + name: 'foo', + range: [26, 29], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 29 } + } + }, { + type: 'Identifier', + name: 'foo', + range: [32, 35], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 35 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [37, 39], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 39 } + } + }, + rest: null, + generator: false, + expression: false, + range: [15, 39], + loc: { + start: { line: 1, column: 15 }, + end: { line: 1, column: 39 } + } + }, + range: [14, 41], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 41 } + } + }], + range: [0, 41], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 41 } + }, + errors: [{ + index: 32, + lineNumber: 1, + column: 33, + message: 'Error: Line 1: Strict mode function may not have duplicate parameter names' + }] + }, + + '"use strict"; x = { set f(eval) {} }' : { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Identifier', + name: 'x', + range: [14, 15], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 15 } + } + }, + right: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'f', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + value : { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'eval', + range: [26, 30], + loc: { + start: { line: 1, column: 26 }, + end: { line: 1, column: 30 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + kind: 'set', + range: [20, 34], + loc: { + start: { line: 1, column: 20 }, + end: { line: 1, column: 34 } + } + }], + range: [18, 36], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 36 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }, + range: [14, 36], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 36 } + } + }], + range: [0, 36], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 36 } + }, + errors: [{ + index: 26, + lineNumber: 1, + column: 27, + message: 'Error: Line 1: Parameter name eval or arguments is not allowed in strict mode' + }] + }, + + 'function hello() { "octal directive\\1"; "use strict"; }': { + type: 'Program', + body: [{ + type: 'FunctionDeclaration', + id: { + type: 'Identifier', + name: 'hello', + range: [9, 14], + loc: { + start: { line: 1, column: 9 }, + end: { line: 1, column: 14 } + } + }, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'octal directive\u0001', + raw: '"octal directive\\1"', + range: [19, 38], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 38 } + } + }, + range: [19, 39], + loc: { + start: { line: 1, column: 19 }, + end: { line: 1, column: 39 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [40, 52], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 52 } + } + }, + range: [40, 53], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 53 } + } + }], + range: [17, 55], + loc: { + start: { line: 1, column: 17 }, + end: { line: 1, column: 55 } + } + }, + rest: null, + generator: false, + expression: false, + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 55 } + } + }], + range: [0, 55], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 55 } + }, + errors: [{ + index: 19, + lineNumber: 1, + column: 20, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"\\1"; \'use strict\';': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: '\u0001', + raw: '"\\1"', + range: [0, 4], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 4 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, { + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '\'use strict\'', + range: [6, 18], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 18 } + } + }, + range: [6, 19], + loc: { + start: { line: 1, column: 6 }, + end: { line: 1, column: 19 } + } + }], + range: [0, 19], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 19 } + }, + errors: [{ + index: 0, + lineNumber: 1, + column: 1, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; var x = { 014: 3}': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Literal', + value: 12, + raw: '014', + range: [24, 27], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 27 } + } + }, + value: { + type: 'Literal', + value: 3, + raw: '3', + range: [29, 30], + loc: { + start: { line: 1, column: 29 }, + end: { line: 1, column: 30 } + } + }, + kind: 'init', + range: [24, 30], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 30 } + } + }], + range: [22, 31], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 31 } + } + }, + range: [18, 31], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 31 } + } + }], + kind: 'var', + range: [14, 31], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 31 } + } + }], + range: [0, 31], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 31 } + }, + errors: [{ + index: 24, + lineNumber: 1, + column: 25, + message: 'Error: Line 1: Octal literals are not allowed in strict mode.' + }] + }, + + '"use strict"; var x = { get i() {}, get i() {} }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + rest: null, + generator: false, + expression: false, + range: [32, 34], + loc: { + start: { line: 1, column: 32 }, + end: { line: 1, column: 34 } + } + }, + kind: 'get', + range: [24, 34], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 34 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [40, 41], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 41 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [44, 46], + loc: { + start: { line: 1, column: 44 }, + end: { line: 1, column: 46 } + } + }, + rest: null, + generator: false, + expression: false, + range: [44, 46], + loc: { + start: { line: 1, column: 44 }, + end: { line: 1, column: 46 } + } + }, + kind: 'get', + range: [36, 46], + loc: { + start: { line: 1, column: 36 }, + end: { line: 1, column: 46 } + } + }], + range: [22, 48], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 48 } + } + }, + range: [18, 48], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 48 } + } + }], + kind: 'var', + range: [14, 48], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 48 } + } + }], + range: [0, 48], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 48 } + }, + errors: [{ + index: 46, + lineNumber: 1, + column: 47, + message: 'Error: Line 1: Object literal may not have multiple get/set accessors with the same name' + }] + }, + + '"use strict"; var x = { i: 42, get i() {} }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [24, 25], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 25 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [27, 29], + loc: { + start: { line: 1, column: 27 }, + end: { line: 1, column: 29 } + } + }, + kind: 'init', + range: [24, 29], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 29 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [35, 36], + loc: { + start: { line: 1, column: 35 }, + end: { line: 1, column: 36 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + rest: null, + generator: false, + expression: false, + range: [39, 41], + loc: { + start: { line: 1, column: 39 }, + end: { line: 1, column: 41 } + } + }, + kind: 'get', + range: [31, 41], + loc: { + start: { line: 1, column: 31 }, + end: { line: 1, column: 41 } + } + }], + range: [22, 43], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 43 } + } + }, + range: [18, 43], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 43 } + } + }], + kind: 'var', + range: [14, 43], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 43 } + } + }], + range: [0, 43], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 43 } + }, + errors: [{ + index: 41, + lineNumber: 1, + column: 42, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }] + }, + + '"use strict"; var x = { set i(x) {}, i: 42 }': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'Literal', + value: 'use strict', + raw: '"use strict"', + range: [0, 12], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 12 } + } + }, + range: [0, 13], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 13 } + } + }, { + type: 'VariableDeclaration', + declarations: [{ + type: 'VariableDeclarator', + id: { + type: 'Identifier', + name: 'x', + range: [18, 19], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 19 } + } + }, + init: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [28, 29], + loc: { + start: { line: 1, column: 28 }, + end: { line: 1, column: 29 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [{ + type: 'Identifier', + name: 'x', + range: [30, 31], + loc: { + start: { line: 1, column: 30 }, + end: { line: 1, column: 31 } + } + }], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + rest: null, + generator: false, + expression: false, + range: [33, 35], + loc: { + start: { line: 1, column: 33 }, + end: { line: 1, column: 35 } + } + }, + kind: 'set', + range: [24, 35], + loc: { + start: { line: 1, column: 24 }, + end: { line: 1, column: 35 } + } + }, { + type: 'Property', + key: { + type: 'Identifier', + name: 'i', + range: [37, 38], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 38 } + } + }, + value: { + type: 'Literal', + value: 42, + raw: '42', + range: [40, 42], + loc: { + start: { line: 1, column: 40 }, + end: { line: 1, column: 42 } + } + }, + kind: 'init', + range: [37, 42], + loc: { + start: { line: 1, column: 37 }, + end: { line: 1, column: 42 } + } + }], + range: [22, 44], + loc: { + start: { line: 1, column: 22 }, + end: { line: 1, column: 44 } + } + }, + range: [18, 44], + loc: { + start: { line: 1, column: 18 }, + end: { line: 1, column: 44 } + } + }], + kind: 'var', + range: [14, 44], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 44 } + } + }], + range: [0, 44], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 44 } + }, + errors: [{ + index: 42, + lineNumber: 1, + column: 43, + message: 'Error: Line 1: Object literal may not have data and accessor property with the same name' + }] + + + }, + + '({ set s() { } })': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'ObjectExpression', + properties: [{ + type: 'Property', + key: { + type: 'Identifier', + name: 's', + range: [7, 8], + loc: { + start: { line: 1, column: 7 }, + end: { line: 1, column: 8 } + } + }, + value: { + type: 'FunctionExpression', + id: null, + params: [], + defaults: [], + body: { + type: 'BlockStatement', + body: [], + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + rest: null, + generator: false, + expression: false, + range: [11, 14], + loc: { + start: { line: 1, column: 11 }, + end: { line: 1, column: 14 } + } + }, + kind: 'set', + range: [3, 14], + loc: { + start: { line: 1, column: 3 }, + end: { line: 1, column: 14 } + } + }], + range: [1, 16], + loc: { + start: { line: 1, column: 1 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + } + }], + range: [0, 17], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 17 } + }, + errors: [{ + index: 9, + lineNumber: 1, + column: 10, + message: 'Error: Line 1: Unexpected token )' + }] + }, + + 'foo("bar") = baz': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'CallExpression', + callee: { + type: 'Identifier', + name: 'foo', + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + 'arguments': [{ + type: 'Literal', + value: 'bar', + raw: '"bar"', + range: [4, 9], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 9 } + } + }], + range: [0, 10], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 10 } + } + }, + right: { + type: 'Identifier', + name: 'baz', + range: [13, 16], + loc: { + start: { line: 1, column: 13 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + errors: [{ + index: 10, + lineNumber: 1, + column: 11, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '1 = 2': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'AssignmentExpression', + operator: '=', + left: { + type: 'Literal', + value: 1, + raw: '1', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + right: { + type: 'Literal', + value: 2, + raw: '2', + range: [4, 5], + loc: { + start: { line: 1, column: 4 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }, + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + } + }], + range: [0, 5], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 5 } + }, + errors: [{ + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '3++': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '++', + argument: { + type: 'Literal', + value: 3, + raw: '3', + range: [0, 1], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 1 } + } + }, + prefix: false, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + }, + errors: [{ + index: 1, + lineNumber: 1, + column: 2, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + '--4': { + type: 'Program', + body: [{ + type: 'ExpressionStatement', + expression: { + type: 'UpdateExpression', + operator: '--', + argument: { + type: 'Literal', + value: 4, + raw: '4', + range: [2, 3], + loc: { + start: { line: 1, column: 2 }, + end: { line: 1, column: 3 } + } + }, + prefix: true, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }, + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + } + }], + range: [0, 3], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 3 } + }, + errors: [{ + index: 3, + lineNumber: 1, + column: 4, + message: 'Error: Line 1: Invalid left-hand side in assignment' + }] + }, + + 'for (5 in []) {}': { + type: 'Program', + body: [{ + type: 'ForInStatement', + left: { + type: 'Literal', + value: 5, + raw: '5', + range: [5, 6], + loc: { + start: { line: 1, column: 5 }, + end: { line: 1, column: 6 } + } + }, + right: { + type: 'ArrayExpression', + elements: [], + range: [10, 12], + loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 12 } + } + }, + body: { + type: 'BlockStatement', + body: [], + range: [14, 16], + loc: { + start: { line: 1, column: 14 }, + end: { line: 1, column: 16 } + } + }, + each: false, + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + } + }], + range: [0, 16], + loc: { + start: { line: 1, column: 0 }, + end: { line: 1, column: 16 } + }, + errors: [{ + index: 6, + lineNumber: 1, + column: 7, + message: 'Error: Line 1: Invalid left-hand side in for-in' + }] + } + + + } +}; + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/package.json b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/package.json new file mode 100644 index 0000000..601b3ea --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/package.json @@ -0,0 +1,45 @@ +{ + "name": "redeyed", + "version": "0.4.4", + "description": "Takes JavaScript code, along with a config and returns the original code with tokens wrapped as configured.", + "author": { + "name": "Thorsten Lorenz", + "email": "thlorenz@gmx.de", + "url": "thlorenz.com" + }, + "main": "redeyed.js", + "scripts": { + "test": "tap test/*.js", + "demo-log": "node examples/replace-log", + "demo": "cd examples/browser; open index.html" + }, + "repository": { + "type": "git", + "url": "git://github.com/thlorenz/redeyed.git" + }, + "keywords": [ + "ast", + "syntax", + "tree", + "source", + "wrap", + "metadata" + ], + "license": "MIT", + "devDependencies": { + "tap": "~0.4.8", + "readdirp": "~0.3.3", + "cardinal": "~0.4.4" + }, + "dependencies": { + "esprima": "~1.0.4" + }, + "readme": "# redeyed [![build status](https://secure.travis-ci.org/thlorenz/redeyed.png?branch=master)](http://travis-ci.org/thlorenz/redeyed)\n\n*Add color to your JavaScript!*\n\n![frog](http://allaboutfrogs.org/gallery/photos/redeyes/red1.gif)\n\n[Red Eyed Tree Frog](http://allaboutfrogs.org/info/species/redeye.html) *(Agalychnis callidryas)*\n\n## What?\n\nTakes JavaScript code, along with a config and returns the original code with tokens wrapped and/or replaced as configured.\n\n## Where?\n\n- server side using nodejs\n- in the [browser](#browser-support)\n\n## What for?\n\nOne usecase is adding metadata to your code that can then be used to apply syntax highlighting.\n\n## How?\n\n- copy the [config.js](https://github.com/thlorenz/redeyed/blob/master/config.js) and edit it in order to specify how\n certain tokens are to be surrounded/replaced\n- replace the `undefined` of each token you want to configure with one of the following\n\n### {String} config\n\n`'before:after'`\n\nwraps the token inside before/after \n\n### {Object} config\n\n`{ _before: 'before', _after: 'after' }`\n\nwraps token inside before/after\n\n#### Missing before and after resolution for {String} and {Object} config\n\nFor the `{String}` and `{Object}` configurations, 'before' or 'after' may be omitted:\n\n- `{String}`: \n - `'before:'` (omitting 'after')\n - `':after'` (omitting 'before')\n- `{Object}`: \n - `{ _before: 'before' }` (omitting '_after')\n - `{ _after: 'after' }` (omitting '_before')\n\nIn these cases the missing half is resolved as follows:\n\n- from the `parent._default` (i.e., `Keyword._default`) if found\n- otherwise from the `config._default` if found\n- otherwise `''` (empty string)\n\n### {Function} config\n\n`function (tokenString, info) { return {String}|{Object}; }`\n\n#### Inputs\n\n- tokenString: the content of the token that is currently being processed\n- info: an object with the following structure\n\n```js\n{\n // {Int}\n // the index of the token being processed inside tokens\n tokenIndex\n\n // {Array}\n // all tokens that are being processed including comments \n // (i.e. the result of merging esprima tokens and comments)\n , tokens \n\n // {Object} \n // the abstract syntax tree of the parsed code\n , ast \n\n // {String}\n // the code that was parsed (same string as the one passed to redeyed(code ..)\n , code\n}\n```\n\nIn most cases the `tokenString` is all you need. The extra info object is passed in case you need to gather more\ninformation about the `token`'s surroundings in order to decide how to transform it. \nSee: [replace-log-example](https://github.com/thlorenz/redeyed/blob/master/examples/replace-log.js)\n\n#### Output\n\nYou can return a {String} or an {Object} from a {Function} config.\n\n- when returning a {String}, the token value will be replaced with it\n- when returning an {Object}, it should be of the following form:\n\n```js\n{\n // {String}\n // the string that should be substituted for the value of the current and all skipped tokens\n replacement\n\n // {Object} (Token)\n // the token after which processing should continue\n // all tokens in between the current one and this one inclusive will be ignored\n , skipPastToken\n}\n```\n\n### Transforming JavaScript code\n\n***redeyed(code, config[, opts])***\n\nInvoke redeyed with your **config**uration, a **code** snippet and maybe **opts** as in the below example:\n\n```javascript\nvar redeyed = require('redeyed')\n , config = require('./path/to/config')\n , code = 'var a = 3;'\n , result;\n\n// redeyed will throw an error (caused by the esprima parser) if the code has invalid javascript\ntry {\n result = redeyed(code, config);\n console.log(result.code);\n} catch(err) {\n console.error(err);\n}\n```\n\n***opts***:\n```js\n{ // {Boolean}\n // if true `result.code` is not assigned and therefore `undefined`\n // if false (default) `result.code` property contains the result of `split.join`\n nojoin: true|false\n}\n```\n\n***return value***:\n\n```js\n{ ast \n , tokens \n , comments \n , splits \n , code \n}\n```\n\n- ast `{Array}`: [abstract syntax tree](http://en.wikipedia.org/wiki/Abstract_syntax_tree) as returned by [esprima\n parse](http://en.wikipedia.org/wiki/Abstract_syntax_tree)\n- tokens `{Array}`: [tokens](http://en.wikipedia.org/wiki/Token_(parser)) provided by esprima (excluding\n comments)\n- comments `{Array}`: block and line comments as provided by esprima\n- splits `{Array}`: code pieces split up, some of which where transformed as configured\n- code `{String}`: transformed code, same as `splits.join('')` unless this step has been skipped (see opts)\n\n## Browser Support\n\n### AMD\n\nEnsure to include [esprima](https://github.com/ariya/esprima) as one of your dependencies\n\n```js\ndefine(['redeyed'], function (redeyed) {\n [ .. ]\n});\n```\n\n### Attached to global window object\n\nThe `redeyed {Function}` will be exposed globally as `window.redeyed` - big surprise!\n\n```html\n\n\n```\n\n## redeyed in the wild\n\n- [cardinal](https://github.com/thlorenz/cardinal): Syntax highlights JavaScript code with ANSI colors to be printed to\n the terminal\n- [peacock](http://thlorenz.github.com/peacock/): JavaScript syntax highlighter that generates html that is compatible\n with pygments styles.\n\n## Examples\n\n- `npm explore redeyed; npm demo` will let you try the [browser example](https://github.com/thlorenz/redeyed/tree/master/examples/browser)\n- `npm explore redeyed; npm demo-log` will let you try the [replace log example](https://github.com/thlorenz/redeyed/blob/master/examples/replace-log.js)\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/thlorenz/redeyed/issues" + }, + "homepage": "https://github.com/thlorenz/redeyed", + "_id": "redeyed@0.4.4", + "_from": "redeyed@>=0.4.0 <0.5.0" +} diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/redeyed.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/redeyed.js new file mode 100644 index 0000000..7a326cb --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/redeyed.js @@ -0,0 +1,291 @@ +;(function () { + +'use strict'; +/*jshint laxbreak: true, browser:true */ +/*global define*/ + +var esprima + , exportFn + , toString = Object.prototype.toString + ; + +if (typeof module === 'object' && typeof module.exports === 'object' && typeof require === 'function') { + // server side + esprima = require('esprima'); + exportFn = function (redeyed) { module.exports = redeyed; }; + bootstrap(esprima, exportFn); +} else if (typeof define === 'function' && define.amd) { + // client side + // amd + define(['esprima'], function (esprima) { + return bootstrap(esprima); + }); +} else if (typeof window === 'object') { + // no amd -> attach to window if it exists + // Note that this requires 'esprima' to be defined on the window, so that script has to be loaded first + window.redeyed = bootstrap(window.esprima); +} + +function bootstrap(esprima, exportFn) { + + function isFunction (obj) { + return toString.call(obj) === '[object Function]'; + } + + function isString (obj) { + return toString.call(obj) === '[object String]'; + } + + function isNumber (obj) { + return toString.call(obj) === '[object Number]'; + } + + function isObject (obj) { + return toString.call(obj) === '[object Object]'; + } + + function surroundWith (before, after) { + return function (s) { return before + s + after; }; + } + + function isNonCircular(key) { + return key !== '_parent'; + } + + function objectizeString (value) { + var vals = value.split(':'); + + if (0 === vals.length || vals.length > 2) + throw new Error( + 'illegal string config: ' + value + + '\nShould be of format "before:after"' + ); + + if (vals.length === 1 || vals[1].length === 0) { + return vals.indexOf(':') < 0 ? { _before: vals[0] } : { _after: vals[0] }; + } else { + return { _before: vals[0], _after: vals[1] }; + } + } + + function objectize (node) { + + // Converts 'bef:aft' to { _before: bef, _after: aft } + // and resolves undefined before/after from parent or root + + function resolve (value, key) { + // resolve before/after from root or parent if it isn't present on the current node + if (!value._parent) return undefined; + + // Immediate parent + if (value._parent._default && value._parent._default[key]) return value._parent._default[key]; + + // Root + var root = value._parent._parent; + if (!root) return undefined; + + return root._default ? root._default[key] : undefined; + } + + function process (key) { + var value = node[key]; + + if (!value) return; + if (isFunction(value)) return; + + // normalize all strings to objects + if (isString(value)) { + node[key] = value = objectizeString(value); + } + + value._parent = node; + if (isObject(value)) { + if (!value._before && !value._after) return objectize (value); + + // resolve missing _before or _after from parent(s) + // in case we only have either one on this node + value._before = value._before || resolve(value, '_before'); + value._after = value._after || resolve(value, '_after'); + + return; + } + + throw new Error('nodes need to be either {String}, {Object} or {Function}.' + value + ' is neither.'); + } + + // Process _default ones first so children can resolve missing before/after from them + if (node._default) process('_default'); + + Object.keys(node) + .filter(function (key) { + return isNonCircular(key) + && node.hasOwnProperty(key) + && key !== '_before' + && key !== '_after' + && key !== '_default'; + }) + .forEach(process); + } + + function functionize (node) { + Object.keys(node) + .filter(function (key) { + return isNonCircular(key) && node.hasOwnProperty(key); + }) + .forEach(function (key) { + var value = node[key]; + + if (isFunction(value)) return; + + if (isObject(value)) { + + if (!value._before && !value._after) return functionize(value); + + // at this point before/after were "inherited" from the parent or root + // (see objectize) + var before = value._before || ''; + var after = value._after || ''; + + node[key] = surroundWith (before, after); + return node[key]; + } + }); + } + + function normalize (root) { + objectize(root); + functionize(root); + } + + function mergeTokensAndComments(tokens, comments) { + var all = {}; + + function addToAllByRangeStart(t) { all[ t.range[0] ] = t; } + + tokens.forEach(addToAllByRangeStart); + comments.forEach(addToAllByRangeStart); + + // keys are sorted automatically + return Object.keys(all) + .map(function (k) { return all[k]; }); + } + + function redeyed (code, config, opts) { + opts = opts || {}; + + // remove shebang + code = code.replace(/^\#\!.*/, ''); + + var ast = esprima.parse(code, { tokens: true, comment: true, range: true, tolerant: true }) + , tokens = ast.tokens + , comments = ast.comments + , lastSplitEnd = 0 + , splits = [] + , transformedCode + , all + , info + ; + + normalize(config); + + function tokenIndex(tokens, tkn, start) { + var current + , rangeStart = tkn.range[0]; + + for (current = start; current < tokens.length; current++) { + if (tokens[current].range[0] === rangeStart) return current; + } + + throw new Error('Token %s not found at or after index: %d', tkn, start); + } + + function process(surround) { + var result + , currentIndex + , nextIndex + , skip = 0 + , splitEnd + ; + + result = surround(code.slice(start, end), info); + if (isObject(result)) { + splits.push(result.replacement); + + currentIndex = info.tokenIndex; + nextIndex = tokenIndex(info.tokens, result.skipPastToken, currentIndex); + skip = nextIndex - currentIndex; + splitEnd = skip > 0 ? tokens[nextIndex - 1].range[1] : end; + } else { + splits.push(result); + splitEnd = end; + } + + return { skip: skip, splitEnd: splitEnd }; + } + + function addSplit (start, end, surround, info) { + var result + , nextIndex + , skip = 0 + ; + + if (start >= end) return; + if (surround) { + result = process(surround); + skip = result.skip; + lastSplitEnd = result.splitEnd; + } else { + splits.push(code.slice(start, end)); + lastSplitEnd = end; + } + + return skip; + } + + all = mergeTokensAndComments(tokens, comments); + for (var tokenIdx = 0; tokenIdx < all.length; tokenIdx++) { + var token = all[tokenIdx] + , surroundForType = config[token.type] + , surround + , start + , end; + + // At least the type (e.g., 'Keyword') needs to be specified for the token to be surrounded + if (surroundForType) { + + // root defaults are only taken into account while resolving before/after otherwise + // a root default would apply to everything, even if no type default was specified + surround = surroundForType + && surroundForType.hasOwnProperty(token.value) + && surroundForType[token.value] + && isFunction(surroundForType[token.value]) + ? surroundForType[token.value] + : surroundForType._default; + + start = token.range[0]; + end = token.range[1]; + + addSplit(lastSplitEnd, start); + info = { tokenIndex: tokenIdx, tokens: all, ast: ast, code: code }; + tokenIdx += addSplit(start, end, surround, info); + } + } + + if (lastSplitEnd < code.length) { + addSplit(lastSplitEnd, code.length); + } + + transformedCode = opts.nojoin ? undefined : splits.join(''); + + return { + ast : ast + , tokens : tokens + , comments : comments + , splits : splits + , code : transformedCode + }; + } + + return exportFn ? exportFn(redeyed) : redeyed; +} +})(); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-before-after-config.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-before-after-config.js new file mode 100644 index 0000000..d0f8284 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-before-after-config.js @@ -0,0 +1,54 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var result = redeyed(code, opts).code + this.equals(result, expected, inspect(code) + ' => ' + inspect(expected)) + return this; + } + + t.end() +}) +test('\nbefore/after config, keywords', function (t) { + + var opts001 = { Keyword: { _default: { _before: '*', _after: '&' } } }; + t.test('\n# ' + inspect(opts001), function (t) { + t.assertSurrounds('this', opts001, '*this&') + t.assertSurrounds('if (a == 1) return', opts001, '*if& (a == 1) *return&') + t.assertSurrounds('var n = new Test();', opts001, '*var& n = *new& Test();') + t.end() + }) + + var opts002 = { + Keyword: { + 'function': { _before: '^' } + , 'return': { _before: '(', _after: ')' } + , _default: { _before: '*' , _after: '&' } + } + }; + + t.test('\n# ' + inspect(opts002), function (t) { + t.assertSurrounds( + [ 'function foo (bar) {' + , ' var a = 3;' + , ' return bar + a;' + , '}' + ].join('\n') + , opts002 + , [ '^function& foo (bar) {' + , ' *var& a = 3;' + , ' (return) bar + a;' + , '}' + ].join('\n')) + t.end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-browser.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-browser.js new file mode 100644 index 0000000..ddb25ce --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-browser.js @@ -0,0 +1,69 @@ +'use strict' +/*jshint asi: true, browser: true*/ +/*global define window */ + +var test = require('tap').test + , util = require('util') + , redeyedExport = require('..') + , redeyedkey = require.resolve('..') + , esprima = require('esprima') + +function setup() { + // remove redeyed from require cache to force re-require for each test + delete require.cache[redeyedkey]; + + // remove globals + delete global.window; + delete global.define; +} + +// TODO: need to run in vm in order to properly simulate require and module not being present +return; +test('define and window exist', function (t) { + var defineCb + , deps + + setup() + + // declare browser globals + global.window = { } + + global.define = function (deps_, cb) { + deps_ = deps + defineCb = cb + } + + define.amd = true + + var redeyed = require('..') + , definedredeyed = defineCb(esprima) + + t.equal(window.redeyed, undefined, 'redeyed is not attached to window') + t.notEqual(redeyed.toString(), redeyedExport.toString(), 'redeyed is not exported') + t.equal(definedredeyed.toString(), redeyedExport.toString(), 'redeyed is defined') + + t.end() +}) + +test('window exists, but define doesn\'t', function (t) { + setup() + + // declare browser globals + global.window = { esprima: esprima } + + var redeyed = require('..') + + t.equal(window.redeyed.toString(), redeyedExport.toString(), 'redeyed is attached to window') + t.notEqual(redeyed.toString(), redeyedExport.toString(), 'redeyed is not exported') + t.end() +}) + +test('neither window nor define exist', function (t) { + setup() + + var redeyed = require('..') + + t.equal(redeyed.toString(), redeyedExport.toString(), 'redeyed is exported') + t.end() +}) + diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-comments.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-comments.js new file mode 100644 index 0000000..09392cc --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-comments.js @@ -0,0 +1,71 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var result = redeyed(code, opts) + this.equals(result.code, expected, inspect(code) + ' => ' + inspect(expected)) + return this; + } + + t.end() +}) + +test('\nstring config, Line comments', function (t) { + var opts = { Line: { _default: '*:&' } }; + t.test('\n# ' + inspect(opts), function (t) { + + t.assertSurrounds( + '// a comment' + , opts + , '*// a comment&' + ) + t.assertSurrounds( + '// comment then new line\nif (a == 1) return' + , opts + , '*// comment then new line&\nif (a == 1) return' + ) + t.assertSurrounds( + 'var n = new Test();// some comment after\n//more comment\nvar s = 3;' + , opts + , 'var n = new Test();*// some comment after&\n*//more comment&\nvar s = 3;' + ) + t.end() + }) +}) + +test('\nstring config, Block comments', function (t) { + var opts = { Block: { _default: '_:-' } }; + t.test('\n# ' + inspect(opts), function (t) { + + t.assertSurrounds( + '/* a comment */' + , opts + , '_/* a comment */-' + ) + t.assertSurrounds( + '/* comment then new line*/\nif (a == 1) /* inline */ return' + , opts + , '_/* comment then new line*/-\nif (a == 1) _/* inline */- return' + ) + t.assertSurrounds( + 'var n = new Test();/* some comment after*/\n/*more comment*/\nvar s = 3;' + , opts + , 'var n = new Test();_/* some comment after*/-\n_/*more comment*/-\nvar s = 3;' + ) + t.assertSurrounds( + 'var a = 4;\n/* Multi line comment\n * Next line\n * and another\n*/ var morecode = "here";' + , opts + , 'var a = 4;\n_/* Multi line comment\n * Next line\n * and another\n*/- var morecode = "here";' + ) + t.end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-config-with-undefineds.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-config-with-undefineds.js new file mode 100644 index 0000000..5ddc40d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-config-with-undefineds.js @@ -0,0 +1,60 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var optsi = inspect(opts); + var result = redeyed(code, opts).code + + this.equals( result + , expected + , util.format('%s: %s => %s', optsi, inspect(code), inspect(expected)) + ) + return this; + } + + t.end() +}) + +test('\n undefineds only', function (t) { + t.assertSurrounds('1 + 2', { Numeric: { _default: undefined } }, '1 + 2') + t.assertSurrounds('1 + 2', { Numeric: { _default: undefined }, _default: undefined }, '1 + 2') + + t.assertSurrounds( + 'return true' + , { 'Boolean': { 'true': undefined, 'false': undefined, _default: undefined } , _default: undefined } + , 'return true' + ) + + t.end() +}) + +test('\n mixed', function (t) { + t.assertSurrounds( + 'return true || false' + , { 'Boolean': { 'true': '&:', 'false': undefined, _default: undefined } , _default: undefined } + , 'return &true || false' + ) + + t.assertSurrounds( + 'return true || false' + , { 'Boolean': { 'true': '&:', 'false': undefined, _default: ':?' } , _default: undefined } + , 'return &true? || false?' + ) + + t.assertSurrounds( + 'return true || false' + , { 'Boolean': { 'true': '&:', 'false': undefined, _default: undefined } , _default: ':?' } + , 'return &true? || false' + ) + + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-extra-params.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-extra-params.js new file mode 100644 index 0000000..f962b7c --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-extra-params.js @@ -0,0 +1,57 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('function - config passing idx and tokens', function (t) { + + var args = [] + , opts001 = { + Boolean: { + _default: identity + } + , Keyword: { + _default: identity + } + , Identifier: { + _default: identity + } + , Punctuator: { + _default: identity + } + } + , code = 'var fn = function () { return true; }' + + function identity (s, info) { + args.push( { value: s, idx: info.tokenIndex, tokens: info.tokens, code: info.code }) + // returning unchanged string will keep the splits be equal to the original tokens + return s + } + + function tokenValue (t) { return t.value; } + + t.test(inspect(opts001) + ' -- ' + code, function (t) { + + var result = redeyed(code, opts001, { splits: true }) + , tokens = result.tokens + + t.equals(args.length, tokens.length, 'called with all tokens') + + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i] + , arg = args[i] + + t.equals(arg.value, token.value, 'passes correct value: ' + inspect([ arg.value, token.value ])) + t.equals(arg.idx, i, 'passes correct index') + t.equals(arg.code, code, 'passes code') + t.deepEquals(arg.tokens, tokens, 'passes all tokens') + } + t.end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-skipping-tokens.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-skipping-tokens.js new file mode 100644 index 0000000..ff14273 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config-skipping-tokens.js @@ -0,0 +1,89 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + + +test('given i skip 2 more tokens after each semicolon', function (t) { + var calls = 0 + , opts = { + Punctuator: { + ';': function identity (s, info) { + // tell it to skip past second to last token that is 2 ahead of the current one + calls++ + var skipToken = info.tokens[info.tokenIndex + 2] + return skipToken ? { replacement: s, skipPastToken: skipToken } : s; + } + } + } + ; + + [ { code: ';;;' , expectedCalls: 1 } + , { code: ';;;;' , expectedCalls: 2 } + , { code: '; ; ; ;' , expectedCalls: 2 } + , { code: ';;; ;;; ;;; ;' , expectedCalls: 4 } + , { code: ';;; ;;; ;;; ;;; ;' , expectedCalls: 5 } + , { code: ';;; ;;; ;;; ;;; ;;;' , expectedCalls: 5 } + , { code: ';;; ;;; ;;; ;;; ;;; ;' , expectedCalls: 6 } + ].forEach(function (x) { + calls = 0 + redeyed(x.code, opts); + t.equals(calls, x.expectedCalls, 'calls ' + x.expectedCalls + ' times for ' + x.code) + }); + t.end() +}) + +test('replace log', function (t) { + var kinds = [ 'info', 'warn', 'error' ] + , opts = { + Identifier: { + console: function replaceLog(s, info) { + var code = info.code + , idx = info.tokenIndex + , tokens = info.tokens + , kind = tokens[idx + 2].value + , openParen = tokens[idx + 3].value + , firstArgTkn = tokens[idx + 4] + , argIdx = idx + 3 + , open + , tkn + ; + + open = 1; + while (open) { + tkn = tokens[++argIdx]; + + if (tkn.value === '(') open++; + if (tkn.value === ')') open--; + } + + var argsIncludingClosingParen = code.slice(firstArgTkn.range[0], tkn.range[1]) + , result = 'log.' + kind + '("main-logger", ' + argsIncludingClosingParen; + + return { replacement: result, skipPastToken: tkn }; + } + } + } + + , origCode = [ + 'console.info("info ", 1);' + , 'console.warn("warn ", 3);' + , 'console.error("error ", new Error("oh my!"));' + ].join('\n') + + , expectedCode = [ + 'log.info("main-logger", "info ", 1));' + , 'log.warn("main-logger", "warn ", 3));' + , 'log.error("main-logger", "error ", new Error("oh my!")));' + ].join('\n') + , code = redeyed(origCode, opts).code + + t.equals(code, expectedCode, 'transforms all log statements') + t.end() +}); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config.js new file mode 100644 index 0000000..6c5ed29 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-function-config.js @@ -0,0 +1,142 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var result = redeyed(code, opts).code + this.equals(result, expected, inspect(code) + ' => ' + inspect(expected)) + return this; + } + + t.end() +}) + +test('\nfunction config, keywords', function (t) { + + var opts001 = { Keyword: { _default: function (s) { return '*' + s + '&'; } } }; + t.test('\n# ' + inspect(opts001), function (t) { + t.assertSurrounds('this', opts001, '*this&') + + t.assertSurrounds('this ', opts001, '*this& ') + t.assertSurrounds(' this', opts001, ' *this&') + t.assertSurrounds(' this ', opts001, ' *this& ') + t.assertSurrounds('if (a == 1) return', opts001, '*if& (a == 1) *return&') + t.assertSurrounds('var n = new Test();', opts001, '*var& n = *new& Test();') + t.assertSurrounds( + [ 'function foo (bar) {' + , ' var a = 3;' + , ' return bar + a;' + , '}' + ].join('\n') + , opts001 + , [ '*function& foo (bar) {' + , ' *var& a = 3;' + , ' *return& bar + a;' + , '}' + ].join('\n')) + t.end() + }) + + var opts002 = { + Keyword: { + 'function': function (s) { return '^' + s + '&' } + , 'return': function (s) { return '(' + s + ')' } + , _default: function (s) { return '*' + s + '&' } + } + }; + + t.test('\n# ' + inspect(opts002), function (t) { + t.assertSurrounds( + [ 'function foo (bar) {' + , ' var a = 3;' + , ' return bar + a;' + , '}' + ].join('\n') + , opts002 + , [ '^function& foo (bar) {' + , ' *var& a = 3;' + , ' (return) bar + a;' + , '}' + ].join('\n')) + t.end() + }) +}) + +test('#\n functin config - resolving', function (t) { + var opts001 = { + Keyword: { + 'var': function (s) { return '^' + s + '&' } + } + , _default: function (s) { return '*' + s + '&' } + }; + t.test('\n# specific but no type default and root default - root default not applied' + inspect(opts001), function (t) { + t.assertSurrounds('var n = new Test();', opts001, '^var& n = new Test();').end(); + }) + + var opts002 = { + Keyword: { + 'var': function (s) { return '^' + s + '&' } + , _default: function (s) { return '*' + s + '&' } + } + , _default: function (s) { return '(' + s + ')' } + }; + t.test('\n# no type default but root default' + inspect(opts002), function (t) { + t.assertSurrounds('var n = new Test();', opts002, '^var& n = *new& Test();').end(); + }) +}) + +test('#\n function config - replacing', function (t) { + var opts001 = { + Keyword: { + 'var': function () { return 'const' } + } + }; + t.test('\n# type default and root default (type wins)' + inspect(opts001), function (t) { + t.assertSurrounds('var n = new Test();', opts001, 'const n = new Test();').end(); + }) + + var opts002 = { + Keyword: { + _default: function () { return 'const' } + } + }; + t.test('\n# type default' + inspect(opts002), function (t) { + t.assertSurrounds('var n = new Test();', opts002, 'const n = const Test();').end(); + }) + + var opts003 = { + Keyword: { + 'new': function () { return 'NEW'; } + , _default: function () { return 'const' } + } + }; + t.test('\n# specific and type default' + inspect(opts003), function (t) { + t.assertSurrounds('var n = new Test();', opts003, 'const n = NEW Test();').end(); + }) + + var opts004 = { + Keyword: { + _default: function (s) { return s.toUpperCase() } + } + , _default: function (s) { return 'not applied'; } + }; + t.test('\n# type default and root default (type wins)' + inspect(opts004), function (t) { + t.assertSurrounds('var n = new Test();', opts004, 'VAR n = NEW Test();').end(); + }) + + var opts005 = { + Keyword: { } + , _default: function (s) { return s.toUpperCase() } + }; + t.test('\n# no type default only root default - not applied' + inspect(opts005), function (t) { + t.assertSurrounds('var n = new Test();', opts005, 'var n = new Test();').end(); + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-mixed.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-mixed.js new file mode 100644 index 0000000..2346ba9 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-mixed.js @@ -0,0 +1,46 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var result = redeyed(code, opts).code + this.equals(result, expected, inspect(code) + ' => ' + inspect(expected)) + return this; + } + + t.end() +}) + +test('\nmixed config, keywords', function (t) { + var opts001 = { + Keyword: { + 'this': function (s) { return '_' + s; } + , 'if': { _before: '^' } + , _default: '*:&' + } + }; + t.test('\n# ' + inspect(opts001), function (t) { + t.assertSurrounds('if (this.hello) return "world";', opts001, '^if& (_this.hello) *return& "world";').end() + }) + + var opts002 = { + Keyword: { + 'this': function (s) { return '_' + s; } + , 'if': { _before: '^' } + , 'return': ':)' + , _default: ':&' + } + , _default: '*:&' + }; + t.test('\n# ' + inspect(opts002), function (t) { + t.assertSurrounds('if (this.hello) return "world";', opts002, '^if& (_this.hello) *return) "world";').end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-result.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-result.js new file mode 100644 index 0000000..9a138dc --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-result.js @@ -0,0 +1,48 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + , esprima = require('esprima') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('redeyed result has esprima ast, tokens, comments and splits and transformed code', function (t) { + var code = '// a comment\nvar a = 3;' + , conf = { Keyword: { _default: '_:-' } } + + , ast = esprima.parse(code, { tokens: true, comment: true, range: true, tolerant: true }) + , tokens = ast.tokens + , comments = ast.comments + + , result = redeyed(code, conf) + + console.log(ast) + t.deepEquals(result.ast, ast, 'ast') + t.deepEquals(result.tokens, tokens, 'tokens') + t.deepEquals(result.comments, comments, 'comments') + t.notEquals(result.code, undefined, 'code') + + t.end() +}); + +test('redeyed result - { nojoin } has esprima ast, tokens, comments and splits but no transformed code', function (t) { + var code = '// a comment\nvar a = 3;' + , conf = { Keyword: { _default: '_:-' } } + + , ast = esprima.parse(code, { tokens: true, comment: true, range: true, tolerant: true }) + , tokens = ast.tokens + , comments = ast.comments + + , result = redeyed(code, conf, { nojoin: true }) + + t.deepEquals(result.ast, ast, 'ast') + t.deepEquals(result.tokens, tokens, 'tokens') + t.deepEquals(result.comments, comments, 'comments') + t.equals(result.code, undefined, 'code') + + t.end() +}); diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-script-level-return.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-script-level-return.js new file mode 100644 index 0000000..bbdbbb7 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-script-level-return.js @@ -0,0 +1,22 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('properly handles script level return -- no blow up', function (t) { + var code = [ + , 'return 1;' + ].join('\n') + , opts = { Keyword: { 'return': '%:^' } } + , expected = '\n%return^ 1;' + , res = redeyed(code, opts).code + + t.equals(res, expected, inspect(code) + ' opts: ' + inspect(opts) + ' => ' + inspect(expected)) + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-shebang.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-shebang.js new file mode 100644 index 0000000..f94ee39 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-shebang.js @@ -0,0 +1,23 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('removes shebang from the code before parsing it', function (t) { + var code = [ + '#!/usr/bin/env node' + , 'var util = require("util");' + ].join('\n') + , opts = { Keyword: { 'var': '%:^' } } + , expected = '\n%var^ util = require("util");' + , res = redeyed(code, opts).code + + t.equals(res, expected, inspect(code) + ' opts: ' + inspect(opts) + ' => ' + inspect(expected)) + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-smoke.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-smoke.js new file mode 100644 index 0000000..cf6c81b --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-smoke.js @@ -0,0 +1,57 @@ +'use strict'; +/*jshint asi: true*/ + +// applying redeyed to a bunch of files of contained libraries as a smoke test +var test = require('tap').test + , path = require('path') + , fs = require('fs') + , readdirp = require('readdirp') + , redeyed = require('..') + , node_modules = path.join(__dirname, '..', 'node_modules') + , tapdir = path.join(node_modules, 'tap') + , esprimadir = path.join(node_modules, 'esprima') + +test('tap', function (t) { + var invalidTapFiles = [ + 'async-map-ordered.js' + , 'prof.js' + ] + + readdirp({ root: tapdir, fileFilter: '*.js' }) + .on('data', function (entry) { + + if (~invalidTapFiles.indexOf(entry.name)) return + + var code = fs.readFileSync(entry.fullPath, 'utf-8') + , result = redeyed(code, { Keyword: { 'var': '+:-' } }).code + + t.assert(~result.indexOf('+var-') || !(~result.indexOf('var ')), 'redeyed ' + entry.path) + }) + .on('end', t.end.bind(t)) +}) + +test('esprima', function (t) { + + readdirp({ root: esprimadir, fileFilter: '*.js' }) + .on('data', function (entry) { + + var code = fs.readFileSync(entry.fullPath, 'utf-8') + , result = redeyed(code, { Keyword: { 'var': '+:-' } }).code + + t.assert(~result.indexOf('+var-') || !(~result.indexOf('var ')), 'redeyed ' + entry.path) + }) + .on('end', t.end.bind(t)) +}) + +test('redeyed', function (t) { + + readdirp({ root: path.join(__dirname, '..'), fileFilter: '*.js', directoryFilter: ['!.git', '!node_modules' ] }) + .on('data', function (entry) { + + var code = fs.readFileSync(entry.fullPath, 'utf-8') + , result = redeyed(code, { Keyword: { 'var': '+:-' } }).code + + t.assert(~result.indexOf('+var-') || !(~result.indexOf('var ')), 'redeyed ' + entry.path) + }) + .on('end', t.end.bind(t)) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-string-config.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-string-config.js new file mode 100644 index 0000000..25a8953 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-string-config.js @@ -0,0 +1,124 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var result = redeyed(code, opts).code + this.equals(result, expected, inspect(code) + ' => ' + inspect(expected)) + return this; + } + + t.end() +}) + +test('\nstring config, keywords', function (t) { + + var opts001 = { Keyword: { _default: '*:&' } }; + t.test('\n# ' + inspect(opts001), function (t) { + t.assertSurrounds('this', opts001, '*this&') + t.assertSurrounds('if (a == 1) return', opts001, '*if& (a == 1) *return&') + t.assertSurrounds('var n = new Test();', opts001, '*var& n = *new& Test();') + t.end() + }) + + var opts002 = { + Keyword: { + 'function': '^:' + , 'return': '(:)' + , _default: '*:&' + } + }; + + t.test('\n# ' + inspect(opts002), function (t) { + t.assertSurrounds( + [ 'function foo (bar) {' + , ' var a = 3;' + , ' return bar + a;' + , '}' + ].join('\n') + , opts002 + , [ '^function& foo (bar) {' + , ' *var& a = 3;' + , ' (return) bar + a;' + , '}' + ].join('\n')) + t.end() + }) +}) + +test('\nstring configs resolve from type and root', function (t) { + var code = 'var a = new Test();' + + function run(t, conf, expected, code_) { + t.test('\n# ' + inspect(conf), function (t) { + t.assertSurrounds(code_ || code, conf, expected); + t.end() + }) + } + + // at least the token kind has to be configured in order for the root_default to be applied + // otherwise a root._default would affect all tokens, even the ones we want to leave unchanged + run(t, { _default: '*:' }, 'var a = new Test();') + + t.test('\n\n# only before or after specified, but no root._default', function (t) { + run(t, { Keyword: { _default: '*:' } }, '*var a = *new Test();') + run(t, { Keyword: { _default: ':-' } }, 'var- a = new- Test();') + t.end() + }) + + t.test('\n\n# resolve missing from root._default', function (t) { + run(t, { Keyword: { _default: '*:' }, _default: '(:-' }, '*var- a = *new- Test();') + run(t, { Keyword: { _default: ':-' }, _default: '*:)' }, '*var- a = *new- Test();') + t.end() + }) + + t.test('\n\n# no resolve if all specified', function (t) { + run(t, { Keyword: { _default: '+:-' }, _default: '*:)' }, '+var- a = +new- Test();') + run(t, { Keyword: { _default: ':-' }, _default: ':)' }, 'var- a = new- Test();') + t.end() + }) + + t.test('\n\n# resolve specific token no defaults', function (t) { + run(t, { Keyword: { 'var': '*:' } }, '*var a = new Test();') + run(t, { Keyword: { 'var': ':-' } }, 'var- a = new Test();') + t.end() + }) + + t.test('\n\n# resolve specific token with type defaults', function (t) { + run(t, { Keyword: { 'var': '*:', _default: ':-' } }, '*var- a = new- Test();') + run(t, { Keyword: { 'var': '*:', _default: '(:-' } }, '*var- a = (new- Test();') + run(t, { Keyword: { 'var': ':-', _default: '*:' } }, '*var- a = *new Test();') + run(t, { Keyword: { 'var': ':-', _default: '*:)' } }, '*var- a = *new) Test();') + run(t, { Keyword: { 'var': ':-', 'new': ':&', _default: '*:' } }, '*var- a = *new& Test();') + t.end() + }) + + t.test( + '\n\n# resolve specific token with root defaults, but no type default - root default not applied to unspecified tokens' + , function (t) { + run(t, { Keyword: { 'var': '*:' }, _default: ':-' }, '*var- a = new Test();') + run(t, { Keyword: { 'var': ':-' }, _default: '*:' }, '*var- a = new Test();') + t.end() + } + ) + + t.test('\n\n# resolve specific token with type and root defaults', function (t) { + run(t, { Keyword: { 'var': '*:', _default: '+:-' }, _default: ':)' }, '*var- a = +new- Test();') + run(t, { Keyword: { 'var': ':-', _default: '*:+' }, _default: '(:' }, '*var- a = *new+ Test();') + t.end() + }) + + t.test('all exact tokens undefined, but type default', function (t) { + run(t, { 'Boolean': { 'true': undefined, 'false': undefined, _default: '+:-' } }, 'return +true- || +false-;', 'return true || false;') + }) + + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-types.js b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-types.js new file mode 100644 index 0000000..ca4837d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/node_modules/redeyed/test/redeyed-types.js @@ -0,0 +1,71 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , redeyed = require('..') + +function inspect (obj) { + return util.inspect(obj, false, 5, true) +} + +test('adding custom asserts ... ', function (t) { + t.constructor.prototype.assertSurrounds = function (code, opts, expected) { + var optsi = inspect(opts); + var result = redeyed(code, opts).code + + this.equals( result + , expected + , util.format('%s: %s => %s', optsi, inspect(code), inspect(expected)) + ) + return this; + } + + t.end() +}) + +test('types', function (t) { + t.test('\n# Boolean', function (t) { + t.assertSurrounds('return true;', { 'Boolean': { _default: '$:%' } }, 'return $true%;') + t.assertSurrounds( 'return true; return false;' + , { 'Boolean': { 'false': '#:', _default: '$:%' } } + , 'return $true%; return #false%;') + t.end() + }) + + t.test('\n# Identifier', function (t) { + t.assertSurrounds('var a = 1;', { 'Identifier': { _default: '$:%' } }, 'var $a% = 1;') + t.assertSurrounds( 'var a = 1; const b = 2;' + , { 'Identifier': { 'b': '#:', _default: '$:%' } } + , 'var $a% = 1; const #b% = 2;') + t.end() + }) + + t.test('\n# Null', function (t) { + t.assertSurrounds('return null;', { 'Null': { _default: '$:%' } }, 'return $null%;').end() + }) + + t.test('\n# Numeric', function (t) { + t.assertSurrounds('return 1;', { 'Numeric': { _default: '$:%' } }, 'return $1%;') + t.assertSurrounds( 'return 1; return 2;' + , { 'Numeric': { '2': '#:', _default: '$:%' } } + , 'return $1%; return #2%;') + t.end() + }) + + t.test('\n# Punctuator', function (t) { + t.assertSurrounds('return 2 * 2;', { 'Punctuator': { _default: '$:%' } }, 'return 2 $*% 2$;%') + t.assertSurrounds( 'return 2 * 2;' + , { 'Punctuator': {'*': '#:', _default: '$:%' } } + , 'return 2 #*% 2$;%') + t.end() + }) + + t.test('\n# String', function (t) { + t.assertSurrounds('return "hello";', { 'String': { _default: '$:%' } }, 'return $"hello"%;') + t.assertSurrounds( 'return "hello"; return "world";' + , { 'String': { '"world"': '#:', _default: '$:%' } } + , 'return $"hello"%; return #"world"%;') + t.end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/package.json b/node_modules/mysql2/node_modules/cardinal/package.json new file mode 100644 index 0000000..43166c5 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/package.json @@ -0,0 +1,50 @@ +{ + "name": "cardinal", + "version": "0.4.4", + "description": "Syntax highlights JavaScript code with ANSI colors to be printed to the terminal.", + "main": "cardinal.js", + "scripts": { + "test": "tap ./test/*.js", + "demo": "node examples/highlight-string.js; node examples/highlight-self; node examples/highlight-self-hide-semicolons;" + }, + "bin": { + "cdl": "./bin/cdl.js" + }, + "repository": { + "type": "git", + "url": "git://github.com/thlorenz/cardinal.git" + }, + "keywords": [ + "syntax", + "highlight", + "theme", + "javascript", + "json", + "terminal", + "console", + "print", + "output" + ], + "author": { + "name": "Thorsten Lorenz", + "email": "thlorenz@gmx.de", + "url": "thlorenz.com" + }, + "license": "MIT", + "dependencies": { + "redeyed": "~0.4.0", + "ansicolors": "~0.2.1" + }, + "devDependencies": { + "tap": "~0.3.1", + "readdirp": "~0.2.1" + }, + "readme": "# cardinal [![Build Status](https://secure.travis-ci.org/thlorenz/cardinal.png)](http://travis-ci.org/thlorenz/cardinal)\n\n[![NPM](https://nodei.co/npm/cardinal.png?downloads=true&stars=true)](https://nodei.co/npm/cardinal/)\n\n**car·di·nal** *(kärdn-l, kärdnl)* - crested thick-billed North American finch having bright red plumage in the male.\n\n![screenshot](https://github.com/thlorenz/cardinal/raw/master/assets/screen-shot.png)\n\n## Features\n\n- highlights JavaScript code with ANSI colors to improve terminal output\n- theming support, see [custom color themes](https://github.com/thlorenz/cardinal/tree/master/themes)\n- optionally print line numbers\n- API and command line interface (`cdl`)\n- `.cardinalrc` config to customize settings\n- supports UNIX pipes\n\n***\n\n**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*\n\n- [Installation](#installation)\n - [As library](#as-library)\n - [As Commandline Tool](#as-commandline-tool)\n- [Commandline](#commandline)\n - [Highlight a file](#highlight-a-file)\n - [As part of a UNIX pipe](#as-part-of-a-unix-pipe)\n - [Theme](#theme)\n- [API](#api)\n - [*highlight(code[, opts])*](#highlightcode-opts)\n - [*highlightFileSync(fullPath[, opts])*](#highlightfilesyncfullpath-opts)\n - [*highlightFile(fullPath[, opts], callback)*](#highlightfilefullpath-opts-callback)\n - [opts](#opts)\n- [Examples ([*browse*](https://github.com/thlorenz/cardinal/tree/master/examples))](#examples-[browse]https://githubcom/thlorenz/cardinal/tree/master/examples)\n\n\n## Installation\n\n### As library\n\n npm install cardinal\n\n### As Commandline Tool\n\n [sudo] npm install -g cardinal\n\n**Note:** \n\nWhen installed globally, cardinal exposes itself as the `cdl` command.\n\n## Commandline\n\n### Highlight a file\n\n cdl [options]\n\n**options**:\n - `--nonum`: turns off line number printing (relevant if it is turned on inside `~/.cardinalrc`\n\n### As part of a UNIX pipe\n\n cat file.js | grep console | cdl\n\n**Note:**\n\nNot all code lines may be parsable JavaScript. In these cases the line is printed to the terminal without\nhighlighting it.\n\n### Theme\n\nThe default theme will be used for highlighting.\n\nTo use a different theme, include a `.cardinalrc` file in your `HOME` directory.\n\nThis is a JSON file of the following form:\n\n```json\n{\n \"theme\": \"hide-semicolons\",\n \"linenos\": true|false\n}\n```\n\n- `theme` can be the name of any of the [built-in themes](https://github.com/thlorenz/cardinal/tree/master/themes) or the\nfull path to a custom theme anywhere on your computer.\n- linenos toggles line number printing\n\n## API\n\n### *highlight(code[, opts])*\n\n- returns the highlighted version of the passed code ({String}) or throws an error if it was not able to parse it\n- opts (see below)\n\n### *highlightFileSync(fullPath[, opts])*\n\n- returns the highlighted version of the file whose fullPath ({String}) was passed or throws an error if it was not able\n to parse it\n- opts (see below)\n\n### *highlightFile(fullPath[, opts], callback)*\n\n- calls back with the highlighted version of the file whose fullPath ({String}) was passed or with an error if it was not able\n to parse it\n- opts (see below)\n- `callback` ({Function}) has the following signature: `function (err, highlighted) { .. }`\n\n### opts\n\nopts is an {Object} with the following properties:\n\n- `theme` {Object} is used to optionally override the theme used to highlight\n- `linenos` {Boolean} if `true` line numbers are included in the highlighted code\n- `firstline` {Integer} sets line number of the first line when line numbers are printed\n- `json` {Boolean} if `true` highlights JSON in addition to JavaScript (`true` by default if file extension is `.json`)\n\n## Examples ([*browse*](https://github.com/thlorenz/cardinal/tree/master/examples))\n\n- [sample .cardinalrc](https://github.com/thlorenz/cardinal/blob/master/examples/.cardinalrc)\n- [highlighting a code snippet](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-string.js) via\n ***highlight()***\n- [file that highlights itself](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-self.js) via\n ***highlightFile()*** including line numbers\n- [file that highlights itself hiding all\n semicolons](https://github.com/thlorenz/cardinal/blob/master/examples/highlight-self-hide-semicolons.js) via\n ***highlightFileSync()***\n\n\n\n\n[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/thlorenz/cardinal/trend.png)](https://bitdeli.com/free \"Bitdeli Badge\")\n\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/thlorenz/cardinal/issues" + }, + "homepage": "https://github.com/thlorenz/cardinal", + "_id": "cardinal@0.4.4", + "_from": "cardinal@>=0.4.4 <0.5.0" +} diff --git a/node_modules/mysql2/node_modules/cardinal/settings.js b/node_modules/mysql2/node_modules/cardinal/settings.js new file mode 100644 index 0000000..f31817a --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/settings.js @@ -0,0 +1,51 @@ +var path = require('path') + , util = require('util') + , fs = require('fs') + , utl = require('./utl') + , home = process.env.HOME + , settings; + +function getSettings (home_) { + if (settings) return settings; + try { + settingsJson = fs.readFileSync(path.join(home_ || home, '.cardinalrc'), 'utf-8'); + } catch (_) { + // no .cardinalrc found - not a problem + return undefined; + } + try { + return JSON.parse(settingsJson); + } catch (e) { + // Have a .cardinalrc, but something about it is wrong - warn the user + // Coudn't parse the contained JSON + console.error(e); + return undefined; + } +} + +// home_ mainly to be used during tests +// Resolves the preferred theme from the .cardinalrc found in the HOME directory +// If it couldn't be resolved, undefined is returned +function resolveTheme (home_) { + var themePath + , settings = getSettings(home_); + + if (!settings || !settings.theme) return undefined; + + try { + // allow specifying just the name of a built-in theme or a full path to a custom theme + themePath = utl.isPath(settings.theme) ? settings.theme : path.join(__dirname, 'themes', settings.theme); + + return require(themePath); + } catch (e) { + // Specified theme path is invalid + console.error(e); + return undefined; + } +} + +module.exports = { + resolveTheme: resolveTheme + , getSettings: getSettings +}; + diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-block-comment.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-block-comment.js new file mode 100644 index 0000000..6b99a1b --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-block-comment.js @@ -0,0 +1,25 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , fs = require('fs') + , customTheme = require('./fixtures/custom') + , cardinal = require('..') + +function inspect(obj, depth) { + console.log(require('util').inspect(obj, false, depth || 5, true)); +} + +test('\nhighlighting a block comment without line numbers', function (t) { + var code = fs.readFileSync(__dirname + '/fixtures/block-comment.js', 'utf8'); + var highlighted = cardinal.highlight(code, { theme: customTheme }); + t.equal(highlighted, '\n\u001b[90m/**\n * This is a meaningless block jsdoc for a meaningless function.\n * Joins two strings, separating them to appear on two lines.\n * \n * @name foo\n * @function\n * @param uno {String} first string\n * @param dos {String} second string\n * @return {String} result of the join\n */\u001b[39m\n\u001b[96mmodule\u001b[39m\u001b[32m.\u001b[39m\u001b[96mexports\u001b[39m \u001b[93m=\u001b[39m \u001b[94mfunction\u001b[39m \u001b[96mfoo\u001b[39m \u001b[90m(\u001b[39m\u001b[96muno\u001b[39m\u001b[32m,\u001b[39m \u001b[96mdos\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m\n \u001b[31mreturn\u001b[39m \u001b[96muno\u001b[39m \u001b[93m+\u001b[39m \u001b[92m\'\\n\'\u001b[39m \u001b[93m+\u001b[39m \u001b[96mdos\u001b[39m\u001b[90m;\u001b[39m\n\u001b[33m}\u001b[39m\n') + t.end() +}) + +test('\nhighlighting a block comment with line numbers', function (t) { + var code = fs.readFileSync(__dirname + '/fixtures/block-comment.js', 'utf8'); + var highlighted = cardinal.highlight(code, { theme: customTheme, linenos: true }); + t.equal(highlighted, '\u001b[90m 1: \n\u001b[90m 2: \u001b[90m/**\n\u001b[90m 3: * This is a meaningless block jsdoc for a meaningless function.\n\u001b[90m 4: * Joins two strings, separating them to appear on two lines.\n\u001b[90m 5: * \n\u001b[90m 6: * @name foo\n\u001b[90m 7: * @function\n\u001b[90m 8: * @param uno {String} first string\n\u001b[90m 9: * @param dos {String} second string\n\u001b[90m10: * @return {String} result of the join\n\u001b[90m11: */\u001b[39m\n\u001b[90m12: \u001b[96mmodule\u001b[39m\u001b[32m.\u001b[39m\u001b[96mexports\u001b[39m \u001b[93m=\u001b[39m \u001b[94mfunction\u001b[39m \u001b[96mfoo\u001b[39m \u001b[90m(\u001b[39m\u001b[96muno\u001b[39m\u001b[32m,\u001b[39m \u001b[96mdos\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m\n\u001b[90m13: \u001b[31mreturn\u001b[39m \u001b[96muno\u001b[39m \u001b[93m+\u001b[39m \u001b[92m\'\\n\'\u001b[39m \u001b[93m+\u001b[39m \u001b[96mdos\u001b[39m\u001b[90m;\u001b[39m\n\u001b[90m14: \u001b[33m}\u001b[39m') + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-diff-spike.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-diff-spike.js new file mode 100644 index 0000000..eec5317 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-diff-spike.js @@ -0,0 +1,95 @@ +/*jshint asi:true */ +'use strict'; + +var fs = require('fs') + , path = require('path') + , utl = require('../utl') + , highlighter = require('..') + , colors = require('ansicolors') + , diffFile = path.join(__dirname, 'fixtures', 'git-diff.txt') + , diff = fs.readFileSync(diffFile, 'utf-8') + + +// @@ is not a valid js token, so when we see it, we can be sure that we are dealing with a git or svn diff +var diffRegex = /^@@[^@]+@@$/m; +var diffIndRegex = /^(@@[^@]+@@)(.*)$/; +var addRemRegex = /^[+\-]/; +var lines = diff.split('\n'); + +function isDiff(lines) { + return !!lines + .filter(function (line) { + return diffRegex.test(line); + }) + .length; +} + +var diff = isDiff(lines); + +function tryHighlight(code) { + + // TODO: need to remove symbols added to get valid code + // this should be done by getting the splits instead of the actual code from the highlighter + // now we can remove first / last one after highlighting completed + function tryAppending(appended, tryNext) { + try { + return highlighter.highlight(code + appended); + } catch (e) { + return tryNext(code); + } + } + + function tryRemoveLeadingComma(tryNext) { + var success; + try { + success = highlighter.highlight(code.replace(/^( +),(.+)$/, '$1 $2')); + return success; + } catch (e) { + return tryNext(code); + } + } + + function tryPlain() { + try { + return highlighter.highlight(code); + } catch (e) { + return tryCloseMustache(); + } + } + + function tryCloseMustache() { return tryAppending('}', tryCloseParen); } + + function tryCloseParen() { return tryAppending('\\)', tryCloseMustacheParen); } + + function tryCloseMustacheParen() { return tryAppending('})', tryRemovingCommas);} + + function tryRemovingCommas() { return tryRemoveLeadingComma(giveUp); } + + function giveUp() { return code; } + + return tryPlain(); +} + +function highlightDiffInd(line, matches) { + var highlighted = colors.brightBlue(matches[1]) + , code = matches[2]; + return code ? highlighted + tryHighlight(code) : highlighted; +} + +function colorsAddRemove(c) { + return addRemRegex.test(c) ? colors.yellow(c) : c; +} + +function highlightDiff(line) { + var diffIndMatches = diffIndRegex.exec(line); + + return diffIndMatches + ? highlightDiffInd(line, diffIndMatches) + : colorsAddRemove(line[0]) + tryHighlight(line.slice(1)); +} + +var highlightFn = diff ? highlightDiff : tryHighlight; +var highlightedLines = lines.map(highlightFn); + +console.log(highlightedLines.join('\n')); + diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-async.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-async.js new file mode 100644 index 0000000..02b8d96 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-async.js @@ -0,0 +1,48 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , fs = require('fs') + , path = require('path') + , customTheme = require('./fixtures/custom') + , cardinal = require('..') + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var file = path.join(__dirname, 'fixtures/foo.js') + , fileWithErrors = path.join(__dirname, 'fixtures/foo-with-errors.js') + +test('supplying custom theme', function (t) { + cardinal.highlightFile(file, { theme: customTheme }, function (err, highlighted) { + + t.equals(null, err, 'no error') + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[96mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \n \u001b[32mvar\u001b[39m \u001b[96ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[96ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[31mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \n\u001b[33m}\u001b[39m\n') + t.end() + }) +}) + +test('not supplying custom theme', function (t) { + cardinal.highlightFile(file, function (err, highlighted) { + + t.equals(null, err, 'no error') + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \n \u001b[32mvar\u001b[39m \u001b[37ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[37ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[91mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \n\u001b[33m}\u001b[39m\n') + t.end() + }) +}) + +test('errornous code', function (t) { + cardinal.highlightFile(fileWithErrors, function (err, highlighted) { + t.similar(err.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token [(]/) + t.end() + }) +}) + +test('non existing file', function (t) { + cardinal.highlightFile('./not/existing', function (err, highlighted) { + t.similar(err.message, /ENOENT, .*not.existing/) + t.end() + }) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-sync.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-sync.js new file mode 100644 index 0000000..7b16e4e --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-file-sync.js @@ -0,0 +1,48 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , fs = require('fs') + , path = require('path') + , customTheme = require('./fixtures/custom') + , cardinal = require('..') + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var file = path.join(__dirname, 'fixtures/foo.js') + , fileWithErrors = path.join(__dirname, 'fixtures/foo-with-errors.js') + +test('supplying custom theme', function (t) { + var highlighted = cardinal.highlightFileSync(file, { theme: customTheme }); + + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[96mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \n \u001b[32mvar\u001b[39m \u001b[96ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[96ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[31mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \n\u001b[33m}\u001b[39m\n') + t.end() +}) + +test('not supplying custom theme', function (t) { + var highlighted = cardinal.highlightFileSync(file); + + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \n \u001b[32mvar\u001b[39m \u001b[37ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[37ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[91mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \n\u001b[33m}\u001b[39m\n') + t.end() +}) + +test('errornous code', function (t) { + try { + cardinal.highlightFileSync(fileWithErrors); + } catch (e) { + t.similar(e.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token [(]/) + t.end() + } +}) + +test('non existing file', function (t) { + try { + cardinal.highlightFileSync('./not/existing'); + } catch (e) { + t.similar(e.message, /ENOENT, .*not.existing/) + t.end() + } +}) diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-git-diff.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-git-diff.js new file mode 100644 index 0000000..9f7482d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-git-diff.js @@ -0,0 +1,3 @@ + +// Test Cases +// highlightDiff('@@ -25,22 +31,47 @@ function resolveTheme (config) { }') diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-async.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-async.js new file mode 100644 index 0000000..54fd169 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-async.js @@ -0,0 +1,31 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , path = require('path') + , cardinal = require('..') + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var file = path.join(__dirname, 'fixtures/json.json'); + +test('json option set from extension', function (t) { + cardinal.highlightFile(file, function (err, highlighted) { + + t.equals(null, err, 'no error'); + t.equals(highlighted, '\u001b[33m{\u001b[39m\u001b[32m"foo"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"bar"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"baz"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"quux"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"bam"\u001b[39m\u001b[93m:\u001b[39m\u001b[90mnull\u001b[39m\u001b[33m}\u001b[39m'); + t.end(); + }); +}); + +test('json option respected if false', function (t) { + cardinal.highlightFile(file, { json: false }, function (err, highlighted) { + + t.similar(err.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token /); + t.end(); + + }); +}); diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-sync.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-sync.js new file mode 100644 index 0000000..0f75077 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json-file-sync.js @@ -0,0 +1,29 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , path = require('path') + , cardinal = require('..') + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var file = path.join(__dirname, 'fixtures/json.json'); + +test('json option set from extension', function (t) { + var highlighted = cardinal.highlightFileSync(file); + + t.equals(highlighted, '\u001b[33m{\u001b[39m\u001b[32m"foo"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"bar"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"baz"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"quux"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"bam"\u001b[39m\u001b[93m:\u001b[39m\u001b[90mnull\u001b[39m\u001b[33m}\u001b[39m'); + t.end(); +}); + +test('json option respected if false', function (t) { + try { + var highlighted = cardinal.highlightFileSync(file, { json: false }); + } catch (e) { + t.similar(e.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token /); + t.end(); + } +}); diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json.js new file mode 100644 index 0000000..bbbe27d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-json.js @@ -0,0 +1,41 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , customTheme = require('./fixtures/custom') + , cardinal = require('..') + + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var json = JSON.stringify({ + foo: 'bar', + baz: 'quux', + bam: null +}); + +test('supplying custom theme', function (t) { + var highlighted = cardinal.highlight(json, { json: true, theme: customTheme }); + + t.equals(highlighted, '\u001b[33m{\u001b[39m\u001b[92m"foo"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"bar"\u001b[39m\u001b[32m,\u001b[39m\u001b[92m"baz"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"quux"\u001b[39m\u001b[32m,\u001b[39m\u001b[92m"bam"\u001b[39m\u001b[93m:\u001b[39m\u001b[90mnull\u001b[39m\u001b[33m}\u001b[39m') + t.end(); +}); + +test('not supplying custom theme', function (t) { + var highlighted = cardinal.highlight(json, { json: true }); + + t.equals(highlighted, '\u001b[33m{\u001b[39m\u001b[32m"foo"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"bar"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"baz"\u001b[39m\u001b[93m:\u001b[39m\u001b[92m"quux"\u001b[39m\u001b[32m,\u001b[39m\u001b[32m"bam"\u001b[39m\u001b[93m:\u001b[39m\u001b[90mnull\u001b[39m\u001b[33m}\u001b[39m') + t.end(); +}); + +test('without json option', function (t) { + try { + cardinal.highlight(json); + } catch (e) { + t.similar(e.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token /) + t.end(); + } +}); diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-string.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-string.js new file mode 100644 index 0000000..beefe0d --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-highlight-string.js @@ -0,0 +1,70 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , util = require('util') + , fs = require('fs') + , customTheme = require('./fixtures/custom') + , cardinal = require('..') + +function inspect (obj) { + return console.log(util.inspect(obj, false, 5, false)) +} + +var code = 'function foo() { var a = 3; return a > 2 ? true : false; }' + , codeWithErrors = 'function () { var a = 3; return a > 2 ? true : false; }'; + +test('supplying custom theme', function (t) { + var highlighted = cardinal.highlight(code, { theme: customTheme }); + + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[96mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \u001b[32mvar\u001b[39m \u001b[96ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[96ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[31mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \u001b[33m}\u001b[39m') + t.end() +}) + +test('not supplying custom theme', function (t) { + var highlighted = cardinal.highlight(code); + + t.equals(highlighted, '\u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \u001b[32mvar\u001b[39m \u001b[37ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[37ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[91mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \u001b[33m}\u001b[39m') + t.end() +}) + +test('errornous code', function (t) { + try { + cardinal.highlight(codeWithErrors); + } catch (e) { + t.similar(e.message, /Unable to perform highlight. The code contained syntax errors.* Line 1: Unexpected token [(]/) + t.end() + } +}) + +test('line numbers no firstline given', function (t) { + var highlighted = cardinal.highlight(code, { linenos: true }); + t.equals(highlighted, '\u001b[90m1: \u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \u001b[32mvar\u001b[39m \u001b[37ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[37ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[91mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \u001b[33m}\u001b[39m') + t.end() +}) + +test('line numbers firstline 99', function (t) { + var highlighted = cardinal.highlight(code, { linenos: true, firstline: 99 }); + t.equals(highlighted, '\u001b[90m99: \u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m \u001b[32mvar\u001b[39m \u001b[37ma\u001b[39m \u001b[93m=\u001b[39m \u001b[34m3\u001b[39m\u001b[90m;\u001b[39m \u001b[31mreturn\u001b[39m \u001b[37ma\u001b[39m \u001b[93m>\u001b[39m \u001b[34m2\u001b[39m \u001b[93m?\u001b[39m \u001b[91mtrue\u001b[39m \u001b[93m:\u001b[39m \u001b[91mfalse\u001b[39m\u001b[90m;\u001b[39m \u001b[33m}\u001b[39m') + t.end() +}) + +test('line numbers multi line no first line given', function (t) { + var multilineCode = '' + + function foo () { + return 1; + }; + var highlighted = cardinal.highlight(multilineCode, { linenos: true }); + t.equals(highlighted,'\u001b[90m1: \u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m\n\u001b[90m2: \u001b[31mreturn\u001b[39m \u001b[34m1\u001b[39m\u001b[90m;\u001b[39m\n\u001b[90m3: \u001b[33m}\u001b[39m') + t.end() +}) + +test('line numbers multi line first line 99', function (t) { + var multilineCode = '' + + function foo () { + return 1; + }; + var highlighted = cardinal.highlight(multilineCode, { linenos: true, firstline: 99 }); + t.equals(highlighted,'\u001b[90m 99: \u001b[94mfunction\u001b[39m \u001b[37mfoo\u001b[39m\u001b[90m(\u001b[39m\u001b[90m)\u001b[39m \u001b[33m{\u001b[39m\n\u001b[90m100: \u001b[31mreturn\u001b[39m \u001b[34m1\u001b[39m\u001b[90m;\u001b[39m\n\u001b[90m101: \u001b[33m}\u001b[39m') + t.end() +}) diff --git a/node_modules/mysql2/node_modules/cardinal/test/cardinal-smoke.js b/node_modules/mysql2/node_modules/cardinal/test/cardinal-smoke.js new file mode 100644 index 0000000..f2d0e18 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/cardinal-smoke.js @@ -0,0 +1,44 @@ +'use strict'; +/*jshint asi: true*/ + +// applying esprima to a bunch of files of contained libraries as a smoke test +var test = require('tap').test + , path = require('path') + , fs = require('fs') + , readdirp = require('readdirp') + , cardinal = require('..') + , node_modules = path.join(__dirname, '..', 'node_modules') + , tapdir = path.join(node_modules, 'tap') + , redeyeddir = path.join(node_modules, 'redeyed') + + +test('tap', function (t) { + var invalidTapFiles = [ + 'async-map-ordered.js' + , 'prof.js' + ] + + readdirp({ root: tapdir, fileFilter: '*.js' }) + .on('data', function (entry) { + + if (~invalidTapFiles.indexOf(entry.name)) return + + var code = fs.readFileSync(entry.fullPath, 'utf-8') + , result = cardinal.highlight(code); + + t.assert(~result.indexOf('[32mvar\u001b[39m') || !(~result.indexOf('var ')), 'highlighted ' + entry.path) + }) + .on('end', t.end.bind(t)) +}) + +test('redeyed', function (t) { + readdirp({ root: redeyeddir, fileFilter: 'redeyed.js' }) + .on('data', function (entry) { + + var code = fs.readFileSync(entry.fullPath, 'utf-8') + , result = cardinal.highlight(code); + + t.assert(~result.indexOf('[32mvar\u001b[39m') || !(~result.indexOf('var ')), 'highlighted ' + entry.path) + }) + .on('end', t.end.bind(t)) +}) diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/block-comment.js b/node_modules/mysql2/node_modules/cardinal/test/fixtures/block-comment.js new file mode 100644 index 0000000..597bc69 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/block-comment.js @@ -0,0 +1,14 @@ + +/** + * This is a meaningless block jsdoc for a meaningless function. + * Joins two strings, separating them to appear on two lines. + * + * @name foo + * @function + * @param uno {String} first string + * @param dos {String} second string + * @return {String} result of the join + */ +module.exports = function foo (uno, dos) { + return uno + '\n' + dos; +} diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/custom.js b/node_modules/mysql2/node_modules/cardinal/test/fixtures/custom.js new file mode 100644 index 0000000..fc369fc --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/custom.js @@ -0,0 +1,144 @@ +var colors = require('ansicolors'); + +// Change the below definitions in order to tweak the color theme. +module.exports = { + + 'Boolean': { + // changed from default + 'true' : colors.red + + , 'false' : undefined + , _default : colors.brightRed + } + + , 'Identifier': { + 'undefined' : colors.brightBlack + , 'self' : colors.brightRed + , 'console' : colors.blue + , 'log' : colors.blue + , 'warn' : colors.red + , 'error' : colors.brightRed + // + // changed from default + , _default : colors.brightCyan + } + + , 'Null': { + _default: colors.brightBlack + } + + , 'Numeric': { + _default: colors.blue + } + + , 'String': { + _default: colors.brightGreen + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : colors.cyan + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : colors.red + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : colors.cyan + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : colors.red + , 'return' : colors.red + , 'switch' : undefined + + , 'this' : colors.brightRed + , 'throw' : undefined + , 'try' : colors.cyan + , 'typeof' : undefined + + , 'var' : colors.green + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : colors.brightBlue + } + , 'Punctuator': { + ';': colors.brightBlack + , '.': colors.green + , ',': colors.green + + , '{': colors.yellow + , '}': colors.yellow + , '(': colors.brightBlack + , ')': colors.brightBlack + , '[': colors.yellow + , ']': colors.yellow + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: colors.brightYellow + } + + // line comment + , Line: { + _default: colors.brightBlack + } + + /* block comment */ + , Block: { + _default: colors.brightBlack + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo-with-errors.js b/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo-with-errors.js new file mode 100644 index 0000000..fefebe2 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo-with-errors.js @@ -0,0 +1,3 @@ +function () { + var a = 3; return a > 2 ? true : false; +}; diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo.js b/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo.js new file mode 100644 index 0000000..bd9a3e0 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/foo.js @@ -0,0 +1,3 @@ +function foo() { + var a = 3; return a > 2 ? true : false; +} diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/git-diff.txt b/node_modules/mysql2/node_modules/cardinal/test/fixtures/git-diff.txt new file mode 100644 index 0000000..e324b67 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/git-diff.txt @@ -0,0 +1,78 @@ +diff --git a/test/settings.js b/test/settings.js +index 7b28d66..642688f 100644 +--- a/test/settings.js ++++ b/test/settings.js +@@ -1,14 +1,20 @@ + 'use strict'; + /*jshint asi: true*/ + +-var test = require('tap').test +- , path = require('path') +- , fs = require('fs') +- , settings = require('../settings') +- , existsSync = fs.existsSync || path.existsSync ++var test = require('tap').test ++ , path = require('path') ++ , fs = require('fs') + , hideSemicolonsTheme = require('../themes/hide-semicolons') + , home = path.join(__dirname, 'fixtures', 'home') + , rcpath = path.join(home, '.cardinalrc') ++ , existsSync = fs.existsSync || path.existsSync ++ , settingsResolve = require.resolve('../settings') ++ , settings ++ ++function setup () { ++ delete require.cache[settingsResolve] ++ settings = require(settingsResolve) ++} + + function writerc(config) { + fs.writeFileSync(rcpath, JSON.stringify(config), 'utf-8') +@@ -25,22 +31,47 @@ function resolveTheme (config) { + return result; + } + ++function getSettings (config) { ++ writerc(config) ++ var result = settings.getSettings(home) ++ removerc() ++ return result; ++} ++ + if (!existsSync(home)) fs.mkdirSync(home); + + test('no .cardinalrc in home', function (t) { ++ setup() + var theme = settings.resolveTheme(home) + t.equals(theme, undefined, 'resolves no theme') + t.end() + }) + + test('.cardinalrc with theme "hide-semicolons" in home', function (t) { ++ setup() + var theme = resolveTheme({ theme: "hide-semicolons" }) + t.deepEquals(theme, hideSemicolonsTheme, 'resolves hide-semicolons theme') + t.end() + }) + + test('.cardinalrc with full path to "hide-semicolons.js" in home', function (t) { ++ setup() + var theme = resolveTheme({ theme: path.join(__dirname, '..', 'themes', 'hide-semicolons.js') }) + t.deepEquals(theme, hideSemicolonsTheme, 'resolves hide-semicolons theme') + t.end() + }) ++ ++test('.cardinalrc with linenos: true', function (t) { ++ setup() ++ var opts = { linenos: true } ++ t.deepEquals(getSettings(opts), opts) ++ t.end() ++}) ++ ++test('.cardinalrc with linenos: true and theme', function (t) { ++ setup() ++ var opts = { linenos: true, theme: 'some theme' } ++ t.deepEquals(getSettings(opts), opts) ++ t.end() ++}) ++ diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/json.json b/node_modules/mysql2/node_modules/cardinal/test/fixtures/json.json new file mode 100644 index 0000000..0c39df4 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/json.json @@ -0,0 +1 @@ +{"foo":"bar","baz":"quux","bam":null} \ No newline at end of file diff --git a/node_modules/mysql2/node_modules/cardinal/test/fixtures/svn-diff.txt b/node_modules/mysql2/node_modules/cardinal/test/fixtures/svn-diff.txt new file mode 100644 index 0000000..635b056 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/fixtures/svn-diff.txt @@ -0,0 +1,23 @@ +Index: grunt.js +=================================================================== +--- grunt.js (revision 31200) ++++ grunt.js (working copy) +@@ -12,6 +12,7 @@ + + module.exports = function (grunt) { + ++ console.log('hello world'); + // Project configuration. + grunt.initConfig({ + lint: { +@@ -19,10 +20,6 @@ + 'packages/services.web/{!(test)/**/,}*.js', + 'packages/error/**/*.js' + ], +- scripts: [ +- 'grunt.js', +- 'db/**/*.js' +- ], + browser: [ + 'packages/web/server.js', + 'packages/web/server/**/*.js', diff --git a/node_modules/mysql2/node_modules/cardinal/test/settings.js b/node_modules/mysql2/node_modules/cardinal/test/settings.js new file mode 100644 index 0000000..642688f --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/settings.js @@ -0,0 +1,77 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , path = require('path') + , fs = require('fs') + , hideSemicolonsTheme = require('../themes/hide-semicolons') + , home = path.join(__dirname, 'fixtures', 'home') + , rcpath = path.join(home, '.cardinalrc') + , existsSync = fs.existsSync || path.existsSync + , settingsResolve = require.resolve('../settings') + , settings + +function setup () { + delete require.cache[settingsResolve] + settings = require(settingsResolve) +} + +function writerc(config) { + fs.writeFileSync(rcpath, JSON.stringify(config), 'utf-8') +} + +function removerc () { + fs.unlinkSync(rcpath) +} + +function resolveTheme (config) { + writerc(config) + var result = settings.resolveTheme(home) + removerc() + return result; +} + +function getSettings (config) { + writerc(config) + var result = settings.getSettings(home) + removerc() + return result; +} + +if (!existsSync(home)) fs.mkdirSync(home); + +test('no .cardinalrc in home', function (t) { + setup() + var theme = settings.resolveTheme(home) + t.equals(theme, undefined, 'resolves no theme') + t.end() +}) + +test('.cardinalrc with theme "hide-semicolons" in home', function (t) { + setup() + var theme = resolveTheme({ theme: "hide-semicolons" }) + t.deepEquals(theme, hideSemicolonsTheme, 'resolves hide-semicolons theme') + t.end() +}) + +test('.cardinalrc with full path to "hide-semicolons.js" in home', function (t) { + setup() + var theme = resolveTheme({ theme: path.join(__dirname, '..', 'themes', 'hide-semicolons.js') }) + t.deepEquals(theme, hideSemicolonsTheme, 'resolves hide-semicolons theme') + t.end() +}) + +test('.cardinalrc with linenos: true', function (t) { + setup() + var opts = { linenos: true } + t.deepEquals(getSettings(opts), opts) + t.end() +}) + +test('.cardinalrc with linenos: true and theme', function (t) { + setup() + var opts = { linenos: true, theme: 'some theme' } + t.deepEquals(getSettings(opts), opts) + t.end() +}) + diff --git a/node_modules/mysql2/node_modules/cardinal/test/themes.js b/node_modules/mysql2/node_modules/cardinal/test/themes.js new file mode 100644 index 0000000..590cdca --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/test/themes.js @@ -0,0 +1,22 @@ +'use strict'; +/*jshint asi: true*/ + +var test = require('tap').test + , path = require('path') + , fs = require('fs') + , themesdir = path.join(__dirname, '..', 'themes') + , allFiles = fs.readdirSync(themesdir) + +test('validate themes by requiring all of them', function (t) { + allFiles + .filter(function (file) { return path.extname(file) === '.js'; }) + .forEach(function (theme) { + try { + t.ok(require(path.join(themesdir, theme)), theme + ' is valid') + } catch (e) { + t.fail('theme: ' + theme + ' is invalid! ' + e.message) + } + }) + t.end() +}) + diff --git a/node_modules/mysql2/node_modules/cardinal/themes/README.md b/node_modules/mysql2/node_modules/cardinal/themes/README.md new file mode 100644 index 0000000..fe2a443 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/themes/README.md @@ -0,0 +1,31 @@ +# cardinal themes + +These are the built in themes that come with cardinal. + +You can create more themes by copying and then editing the [empty +theme](https://github.com/thlorenz/cardinal/blob/master/themes/empty.js) which is provided for that purpose. + +The [hide semicolons theme](https://github.com/thlorenz/cardinal/blob/master/themes/hide-semicolons.js) has the added +benefit of making all semicolons invisible. This makes code more readable at times. + +Find out how to change the theme used by cardinal [here](https://github.com/thlorenz/cardinal#theme). + +# sharing themes + +To add your theme to the cardinal built-in themes, follow the below steps: + +1. fork the cardinal repository +2. add your theme to the themes folder and commit your changes +3. create a pull request + +If you believe that your theme is better than the current default theme, let me know by creating an issue. + +This will allow others to cast their vote. If enough people agree, your theme will be promoted to be the default. + +## Contributed Themes + +### tomorrow night + +[![tomorrow-night](https://github.com/thlorenz/cardinal/raw/master/assets/theme-tomorrow-night.png)](https://github.com/thlorenz/cardinal/blob/master/themes/tomorrow-night.js) + +*by [firede](https://github.com/firede)* diff --git a/node_modules/mysql2/node_modules/cardinal/themes/default.js b/node_modules/mysql2/node_modules/cardinal/themes/default.js new file mode 100644 index 0000000..86ee59a --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/themes/default.js @@ -0,0 +1,147 @@ +var colors = require('ansicolors'); + +// Change the below definitions in order to tweak the color theme. +module.exports = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : colors.brightRed + } + + , 'Identifier': { + 'undefined' : colors.brightBlack + , 'self' : colors.brightRed + , 'console' : colors.blue + , 'log' : colors.blue + , 'warn' : colors.red + , 'error' : colors.brightRed + , _default : colors.white + } + + , 'Null': { + _default: colors.brightBlack + } + + , 'Numeric': { + _default: colors.blue + } + + , 'String': { + _default: function (s, info) { + var nextToken = info.tokens[info.tokenIndex + 1]; + + // show keys of object literals and json in different color + return (nextToken && nextToken.type === 'Punctuator' && nextToken.value === ':') + ? colors.green(s) + : colors.brightGreen(s); + } + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : colors.cyan + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : colors.red + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : colors.cyan + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : colors.red + , 'return' : colors.red + , 'switch' : undefined + + , 'this' : colors.brightRed + , 'throw' : undefined + , 'try' : colors.cyan + , 'typeof' : undefined + + , 'var' : colors.green + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : colors.brightBlue + } + , 'Punctuator': { + ';': colors.brightBlack + , '.': colors.green + , ',': colors.green + + , '{': colors.yellow + , '}': colors.yellow + , '(': colors.brightBlack + , ')': colors.brightBlack + , '[': colors.yellow + , ']': colors.yellow + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: colors.brightYellow + } + + // line comment + , Line: { + _default: colors.brightBlack + } + + /* block comment */ + , Block: { + _default: colors.brightBlack + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/themes/empty.js b/node_modules/mysql2/node_modules/cardinal/themes/empty.js new file mode 100644 index 0000000..3203aac --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/themes/empty.js @@ -0,0 +1,140 @@ +/* + * Copy this file and use it as a starting point for your custom cardinal color theme. + * Just fill in or change the entries for the tokens you want to color + * Keep in mind that more specific configurations override less specific ones. + */ + +var colors = require('ansicolors'); + +// Change the below definitions in order to tweak the color theme. +module.exports = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : undefined + } + + , 'Identifier': { + _default: undefined + } + + , 'Null': { + _default: undefined + } + + , 'Numeric': { + _default: undefined + } + + , 'String': { + _default: undefined + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : undefined + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : undefined + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : undefined + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : undefined + , 'return' : undefined + , 'switch' : undefined + + , 'this' : undefined + , 'throw' : undefined + , 'try' : undefined + , 'typeof' : undefined + + , 'var' : undefined + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : undefined + } + , 'Punctuator': { + ';': undefined + , '.': undefined + , ',': undefined + + , '{': undefined + , '}': undefined + , '(': undefined + , ')': undefined + , '[': undefined + , ']': undefined + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: undefined + } + + // line comment + , Line: { + _default: undefined + } + + /* block comment */ + , Block: { + _default: undefined + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/themes/hide-semicolons.js b/node_modules/mysql2/node_modules/cardinal/themes/hide-semicolons.js new file mode 100644 index 0000000..c1871ee --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/themes/hide-semicolons.js @@ -0,0 +1,149 @@ +var colors = require('ansicolors'); + +// Change the below definitions in order to tweak the color theme. +module.exports = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : colors.brightRed + } + + , 'Identifier': { + 'undefined' : colors.brightBlack + , 'self' : colors.brightRed + , 'console' : colors.blue + , 'log' : colors.blue + , 'warn' : colors.red + , 'error' : colors.brightRed + , _default : colors.white + } + + , 'Null': { + _default: colors.brightBlack + } + + , 'Numeric': { + _default: colors.blue + } + + , 'String': { + _default: function (s, info) { + var nextToken = info.tokens[info.tokenIndex + 1]; + + // show keys of object literals and json in different color + return (nextToken && nextToken.type === 'Punctuator' && nextToken.value === ':') + ? colors.green(s) + : colors.brightGreen(s); + } + } + + , 'Keyword': { + 'break' : undefined + + , 'case' : undefined + , 'catch' : colors.cyan + , 'continue' : undefined + + , 'debugger' : undefined + , 'default' : undefined + , 'delete' : colors.red + , 'do' : undefined + + , 'else' : undefined + + , 'finally' : colors.cyan + , 'for' : undefined + , 'function' : undefined + + , 'if' : undefined + , 'in' : undefined + , 'instanceof' : undefined + + , 'new' : colors.red + , 'return' : colors.red + , 'switch' : undefined + + , 'this' : colors.brightRed + , 'throw' : undefined + , 'try' : colors.cyan + , 'typeof' : undefined + + , 'var' : colors.green + , 'void' : undefined + + , 'while' : undefined + , 'with' : undefined + , _default : colors.brightBlue + } + , 'Punctuator': { + // setting semicolon's color to the same as the terminal background makes it invisible + ';': colors.black + + , '.': colors.green + , ',': colors.green + + , '{': colors.yellow + , '}': colors.yellow + , '(': colors.brightBlack + , ')': colors.brightBlack + , '[': colors.yellow + , ']': colors.yellow + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': undefined + , '^': undefined + , '!': undefined + , '~': undefined + , '?': undefined + , ':': undefined + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: colors.brightYellow + } + + // line comment + , Line: { + _default: colors.brightBlack + } + + /* block comment */ + , Block: { + _default: colors.brightBlack + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/themes/tomorrow-night.js b/node_modules/mysql2/node_modules/cardinal/themes/tomorrow-night.js new file mode 100644 index 0000000..9e0fc58 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/themes/tomorrow-night.js @@ -0,0 +1,161 @@ +var colors = require('ansicolors'); + +// Change the below definitions in order to tweak the color theme. +module.exports = { + + 'Boolean': { + 'true' : undefined + , 'false' : undefined + , _default : colors.yellow + } + + , 'Identifier': { + 'undefined' : colors.yellow + , 'self' : colors.yellow + , 'type' : colors.yellow + , 'value' : colors.yellow + , 'console' : undefined + , 'log' : colors.blue + , 'warn' : colors.blue + , 'error' : colors.blue + , 'join' : colors.blue + , _default : function (s, info) { + var prevToken = info.tokens[info.tokenIndex - 1]; + var nextToken = info.tokens[info.tokenIndex + 1]; + + return (nextToken + && nextToken.type === 'Punctuator' + && nextToken.value === '(' + && prevToken + && prevToken.type === 'Keyword' + && prevToken.value === 'function' + ) ? colors.blue(s) : colors.white(s); + } + } + + , 'Null': { + _default: colors.yellow + } + + , 'Numeric': { + _default: colors.yellow + } + + , 'String': { + _default: function (s, info) { + var nextToken = info.tokens[info.tokenIndex + 1]; + + // show keys of object literals and json in different color + return (nextToken && nextToken.type === 'Punctuator' && nextToken.value === ':') + ? colors.green(s) + : colors.brightGreen(s); + } + } + + , 'Keyword': { + 'break' : colors.magenta + + , 'case' : colors.magenta + , 'catch' : colors.magenta + , 'continue' : colors.magenta + + , 'debugger' : colors.magenta + , 'default' : colors.magenta + , 'delete' : colors.red + , 'do' : colors.magenta + + , 'else' : colors.magenta + + , 'finally' : colors.magenta + , 'for' : colors.magenta + , 'function' : colors.magenta + + , 'if' : colors.magenta + , 'in' : colors.cyan + , 'instanceof' : colors.cyan + + , 'new' : colors.cyan + , 'return' : colors.magenta + , 'switch' : colors.magenta + + , 'this' : colors.red + , 'throw' : colors.magenta + , 'try' : colors.magenta + , 'typeof' : colors.cyan + + , 'var' : colors.magenta + , 'void' : colors.magenta + + , 'while' : colors.magenta + , 'with' : colors.cyan + , _default : colors.white + } + , 'Punctuator': { + ';': colors.white + , '.': colors.white + , ',': colors.white + + , '{': colors.white + , '}': colors.white + , '(': colors.white + , ')': colors.white + , '[': colors.white + , ']': colors.white + + , '<': undefined + , '>': undefined + , '+': undefined + , '-': undefined + , '*': undefined + , '%': undefined + , '&': undefined + , '|': colors.white + , '^': undefined + , '!': undefined + , '~': undefined + , '?': colors.white + , ':': colors.white + , '=': undefined + + , '<=': undefined + , '>=': undefined + , '==': undefined + , '!=': undefined + , '++': undefined + , '--': undefined + , '<<': undefined + , '>>': undefined + , '&&': undefined + , '||': undefined + , '+=': undefined + , '-=': undefined + , '*=': undefined + , '%=': undefined + , '&=': undefined + , '|=': undefined + , '^=': undefined + , '/=': undefined + + , '===': undefined + , '!==': undefined + , '>>>': undefined + , '<<=': undefined + , '>>=': undefined + + , '>>>=': undefined + + , _default: colors.cyan + } + + // line comment + , Line: { + _default: colors.brightBlack + } + + /* block comment */ + , Block: { + _default: colors.brightBlack + } + + , _default: undefined +}; diff --git a/node_modules/mysql2/node_modules/cardinal/utl.js b/node_modules/mysql2/node_modules/cardinal/utl.js new file mode 100644 index 0000000..0f36e40 --- /dev/null +++ b/node_modules/mysql2/node_modules/cardinal/utl.js @@ -0,0 +1,11 @@ +var util = require('util'); + +module.exports.isPath = function (s) { + return (/[\/\\]/).test(s); +}; + +module.exports.inspect = function(obj, depth) { + console.log(util.inspect(obj, false, depth || 5, true)); +}; + + diff --git a/node_modules/mysql2/node_modules/fastqueue/README.md b/node_modules/mysql2/node_modules/fastqueue/README.md new file mode 100644 index 0000000..c3e8c69 --- /dev/null +++ b/node_modules/mysql2/node_modules/fastqueue/README.md @@ -0,0 +1,26 @@ +# Fast Queue + +While normal JavaScript arrays can be used as FIFO queues, the `.shift()` call is very slow if the queue gets large because it has to reindex all the remaining items on every shift. + +This library is a fast queue that only implements `.push(item)`, `.shift()`, `.unshift(item)` and `.length` from the Array interface. + +Internally it uses two arrays and cycles them and uses counters so that the `.shift()` calls are still fast. + +## Usage + +```js +var Queue = require('fastqueue'); + +var q = new Queue; +q.push(1); +q.push(2); +q.push(3); +var i = 4; +while (q.length > 0) { + console.log(q.length, q.shift()); + q.unshift(i++); + console.log(q.length, q.shift()); + q.push(i++); + console.log(q.length, q.shift()); +} +``` diff --git a/node_modules/mysql2/node_modules/fastqueue/package.json b/node_modules/mysql2/node_modules/fastqueue/package.json new file mode 100644 index 0000000..ed13b08 --- /dev/null +++ b/node_modules/mysql2/node_modules/fastqueue/package.json @@ -0,0 +1,28 @@ +{ + "name": "fastqueue", + "version": "0.1.0", + "description": "A fast push/shift sync queue", + "main": "queue.js", + "readme": "# Fast Queue\n\nWhile normal JavaScript arrays can be used as FIFO queues, the `.shift()` call is very slow if the queue gets large because it has to reindex all the remaining items on every shift.\n\nThis library is a fast queue that only implements `.push(item)`, `.shift()`, `.unshift(item)` and `.length` from the Array interface.\n\nInternally it uses two arrays and cycles them and uses counters so that the `.shift()` calls are still fast.\n\n## Usage\n\n```js\nvar Queue = require('fastqueue');\n\nvar q = new Queue;\nq.push(1);\nq.push(2);\nq.push(3);\nvar i = 4;\nwhile (q.length > 0) {\n console.log(q.length, q.shift());\n q.unshift(i++);\n console.log(q.length, q.shift());\n q.push(i++);\n console.log(q.length, q.shift());\n}\n```\n", + "readmeFilename": "README.md", + "_id": "fastqueue@0.1.0", + "dist": { + "shasum": "6c691016b3806186476eeb05a717babb8f633c19", + "tarball": "http://registry.npmjs.org/fastqueue/-/fastqueue-0.1.0.tgz" + }, + "_from": "fastqueue@>=0.1.0 <0.2.0", + "_npmVersion": "1.2.15", + "_npmUser": { + "name": "creationix", + "email": "tim@creationix.com" + }, + "maintainers": [ + { + "name": "creationix", + "email": "tim@creationix.com" + } + ], + "directories": {}, + "_shasum": "6c691016b3806186476eeb05a717babb8f633c19", + "_resolved": "https://registry.npmjs.org/fastqueue/-/fastqueue-0.1.0.tgz" +} diff --git a/node_modules/mysql2/node_modules/fastqueue/queue.js b/node_modules/mysql2/node_modules/fastqueue/queue.js new file mode 100644 index 0000000..5c4f9ab --- /dev/null +++ b/node_modules/mysql2/node_modules/fastqueue/queue.js @@ -0,0 +1,67 @@ +module.exports = Queue; + +function Queue() { + this.head = []; + this.tail = []; + this.index = 0; + this.headLength = 0; + this.length = 0; +} + +// Get an item from the front of the queue. +Queue.prototype.shift = function () { + if (this.index >= this.headLength) { + // When the head is empty, swap it with the tail to get fresh items. + var t = this.head; + t.length = 0; + this.head = this.tail; + this.tail = t; + this.index = 0; + this.headLength = this.head.length; + if (!this.headLength) { + return; + } + } + + // There was an item in the head, let's pull it out. + var value = this.head[this.index]; + // And remove it from the head + if (this.index < 0) { + delete this.head[this.index++]; + } + else { + this.head[this.index++] = undefined; + } + this.length--; + return value; +}; + +// Insert a new item at the front of the queue. +Queue.prototype.unshift = function (item) { + this.head[--this.index] = item; + this.length++; + return this; +}; + +// Push a new item on the end of the queue. +Queue.prototype.push = function (item) { + // Pushes always go to the write-only tail + this.length++; + this.tail.push(item); + return this; +}; + +/* +var q = new Queue; +q.push(1); +q.push(2); +q.push(3); +var i = 4; +while (q.length > 0) { + console.log(q.length, q.shift()); + q.unshift(i++); + console.log(q.length, q.shift()); + q.push(i++); + console.log(q.length, q.shift()); +} +*/ diff --git a/node_modules/mysql2/package.json b/node_modules/mysql2/package.json new file mode 100644 index 0000000..8dcaf4d --- /dev/null +++ b/node_modules/mysql2/package.json @@ -0,0 +1,62 @@ +{ + "name": "mysql2", + "version": "0.12.5", + "description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS", + "main": "index.js", + "directories": { + "example": "examples" + }, + "scripts": { + "test": "./test/run.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/sidorares/node-mysql2" + }, + "keywords": [ + "mysql", + "client", + "server" + ], + "author": { + "name": "Andrey Sidorov", + "email": "sidorares@yandex.ru" + }, + "license": "MIT", + "dependencies": { + "bn.js": "0.11.7", + "cardinal": "^0.4.4", + "fastqueue": "~0.1.0" + }, + "devDependencies": { + "urun": "0.0.6" + }, + "bugs": { + "url": "https://github.com/sidorares/node-mysql2/issues" + }, + "homepage": "https://github.com/sidorares/node-mysql2", + "_id": "mysql2@0.12.5", + "_shasum": "b2d527d276da40490d89d66ae2c0f44c1b9cdcaf", + "_from": "mysql2@*", + "_npmVersion": "1.4.9", + "_npmUser": { + "name": "sidorares", + "email": "sidorares@yandex.com" + }, + "maintainers": [ + { + "name": "sidorares", + "email": "sidorares@yandex.com" + }, + { + "name": "iarna", + "email": "me@re-becca.org" + } + ], + "dist": { + "shasum": "b2d527d276da40490d89d66ae2c0f44c1b9cdcaf", + "tarball": "http://registry.npmjs.org/mysql2/-/mysql2-0.12.5.tgz" + }, + "_resolved": "https://registry.npmjs.org/mysql2/-/mysql2-0.12.5.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mysql2/test/common.js b/node_modules/mysql2/test/common.js new file mode 100644 index 0000000..02c71a9 --- /dev/null +++ b/node_modules/mysql2/test/common.js @@ -0,0 +1,116 @@ +var config = { + host: process.env.MYSQL_HOST || '127.0.0.1', + user: process.env.MYSQL_USER || 'root', + password: process.env.CI ? null : process.env.MYSQL_PASSWORD || 'test', + database: process.env.MYSQL_DATABASE || 'test', + port: process.env.MYSQL_PORT || 3306 +} + +module.exports.createConnection = function(args, callback) { + // hrtime polyfill for old node versions: + if (!process.hrtime) + process.hrtime = function(start) { + start = [0, 0] || start; + var timestamp = Date.now(); + var seconds = Math.ceil(timestamp/1000); + return [seconds - start[0], (timestamp-seconds*1000)*1000 - start[1]]; + }; + + if (process.env.BENCHMARK_MARIA) { + var Client = require('mariasql'); + var c = new Client(); + c.connect({ + host: config.host, + user: config.user, + password: config.password, + db: config.database + }); + //c.on('connect', function() { + // + //}); + setTimeout( function() { + console.log('altering client...'); + c.oldQuery = c.query; + c.query = function(sql, callback) { + var rows = []; + var q = c.oldQuery(sql); + q.on('result', function(res) { + res.on('row', function(row) { rows.push(row) }); + res.on('end', function() { + callback(null, rows); + }); + }); + }; + }, 1000); + return c; + } + + var driver = require('../index.js'); + if (process.env.BENCHMARK_MYSQL1) + driver = require('mysql'); + + return driver.createConnection({ + host: config.host, + user: config.user, + password: config.password, + database: config.database, + multipleStatements: args ? args.multipleStatements : false, + port: (args && args.port) || config.port, + dateStrings: args && args.dateStrings + }); +}; + +module.exports.createPool = function(callback) { + var driver = require('../index.js'); + if (process.env.BENCHMARK_MYSQL1) + driver = require('mysql'); + + return driver.createPool(config); +}; + +module.exports.createTemplate = function() { + var jade = require('jade'); + var template = require('fs').readFileSync(__dirname + '/template.jade', 'ascii'); + return jade.compile(template); +}; + +module.exports.createServer = function(cb) { + var server = require('../index.js').createServer(); + server.on('connection', function(conn) { + conn.on('error', function() { + // we are here when client drops connection + }); + conn.serverHandshake({ + protocolVersion: 10, + serverVersion: 'node.js rocks', + connectionId: 1234, + statusFlags: 2, + characterSet: 8, + capabilityFlags: 0xffffff + }); + conn.on('query', function(sql) { + conn.writeTextResult([ { '1': '1' } ], [ { catalog: 'def', + schema: '', + table: '', + orgTable: '', + name: '1', + orgName: '', + characterSet: 63, + columnLength: 1, + columnType: 8, + flags: 129, + decimals: 0 } ]); + }); + //conn.on('end', ); + }); + server.listen(3307, undefined, undefined, cb); + return server; +} + +module.exports.useTestDb = function(cb) { + // no-op in my setup, need it for compatibility with node-mysql tests +} + +module.exports.hrdiff = function(t1, t2) { + return t2[1] - t1[1] + (t2[0] - t1[0])*1e9; +}; diff --git a/node_modules/mysql2/test/create-500k-random-ints-doubles-table.sql b/node_modules/mysql2/test/create-500k-random-ints-doubles-table.sql new file mode 100644 index 0000000..ee4bcc7 --- /dev/null +++ b/node_modules/mysql2/test/create-500k-random-ints-doubles-table.sql @@ -0,0 +1,32 @@ +-- from http://sixarm.com/about/mysql-create-random-data-text-strings.html + +drop table if exists ints; +drop procedure if exists randomize_nums; + +CREATE TABLE ints ( + id int(11) NOT NULL AUTO_INCREMENT, + val1 int(11), + val2 double, + PRIMARY KEY (id) + ); + +delimiter $$ +create procedure randomize_nums() + begin + declare i int Default 0 ; + declare random int(20); + declare random1 double; + myloop: loop + set random=floor(rand() * 99999); + set random1=rand() * 99999 ; + insert into ints VALUES (i+1,random, random1) ; + set i=i+1; + if i=500000 then + leave myloop; + end if; + end loop myloop; + end $$ +delimiter ; + +call randomize_nums; + diff --git a/node_modules/mysql2/test/create-500k-random-rows-table.sql b/node_modules/mysql2/test/create-500k-random-rows-table.sql new file mode 100644 index 0000000..2f6a419 --- /dev/null +++ b/node_modules/mysql2/test/create-500k-random-rows-table.sql @@ -0,0 +1,29 @@ +-- from http://sixarm.com/about/mysql-create-random-data-text-strings.html + +drop table if exists foos; +drop procedure if exists randomizer; + +CREATE TABLE foos ( + id int(11) NOT NULL AUTO_INCREMENT, + name char(20), + PRIMARY KEY (id) + ); + +delimiter $$ +create procedure randomizer() + begin + declare i int Default 0 ; + declare random char(20); + myloop: loop + set random=conv(floor(rand() * 99999999999999), 20, 36) ; + insert into `foos` (`id`, `name`) VALUES (i+1,random) ; + set i=i+1; + if i=500000 then + leave myloop; + end if; + end loop myloop; + end $$ +delimiter ; + +call randomizer; + diff --git a/node_modules/mysql2/test/integration/connection/test-binary-charset-string.js b/node_modules/mysql2/test/integration/connection/test-binary-charset-string.js new file mode 100644 index 0000000..403011d --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-binary-charset-string.js @@ -0,0 +1,78 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; +var rows1 = undefined; +var fields1 = undefined; +var rows2 = undefined; +var fields2 = undefined; +var rows3 = undefined; +var fields3 = undefined; + +var rows4 = undefined; +var fields4 = undefined; +var rows5 = undefined; +var fields5 = undefined; + +var query = "SELECT x'010203'"; +var query1 = "SELECT '010203'"; + +connection.query(query, function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.query(query, function(err, _rows, _fields) { + if (err) throw err; + rows5 = _rows; + fields5 = _fields; +}); + +connection.query(query1, function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; + fields1 = _fields; +}); + +connection.execute(query, [], function(err, _rows, _fields) { + if (err) throw err; + rows2 = _rows; + fields2 = _fields; +}); + +// repeat same query - test cached fields and parser +connection.execute(query, [], function(err, _rows, _fields) { + if (err) throw err; + rows4 = _rows; + fields4 = _fields; +}); + +connection.execute(query1, [], function(err, _rows, _fields) { + if (err) throw err; + rows3 = _rows; + fields3 = _fields; +}); + +connection.end(); + + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{"x'010203'": Buffer([1, 2, 3])}]); + assert.equal(fields[0].name, "x'010203'"); + assert.deepEqual(rows1, [{'010203': '010203'}]); + assert.equal(fields1[0].name, "010203"); + assert.deepEqual(rows2, [{"x'010203'": Buffer([1, 2, 3])}]); + assert.equal(fields2[0].name, "x'010203'"); + assert.deepEqual(rows3, [{'010203': '010203'}]); + assert.equal(fields3[0].name, "010203"); + + assert.deepEqual(rows4, [{"x'010203'": Buffer([1, 2, 3])}]); + assert.equal(fields4[0].name, "x'010203'"); + assert.deepEqual(rows5, [{"x'010203'": Buffer([1, 2, 3])}]); + assert.equal(fields5[0].name, "x'010203'"); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-buffer-params.js b/node_modules/mysql2/test/integration/connection/test-buffer-params.js new file mode 100644 index 0000000..59a0950 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-buffer-params.js @@ -0,0 +1,28 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var rows1 = undefined; +var fields = undefined; +var fields1 = undefined; + +var buf = Buffer([0x80, 0x90, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 100, 255, 255]); +connection.execute('SELECT HEX(?) as buf', [buf], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.query('SELECT HEX(?) as buf', [buf], function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; + fields1 = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{buf: buf.toString('hex').toUpperCase()}]); + assert.deepEqual(rows1, [{buf: buf.toString('hex').toUpperCase()}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-custom-date-parameter.js b/node_modules/mysql2/test/integration/connection/test-custom-date-parameter.js new file mode 100644 index 0000000..dae6fa7 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-custom-date-parameter.js @@ -0,0 +1,25 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; + +Date = function() { + var NativeDate = Date; + function CustomDate(str) { + return new NativeDate(str); + } + return CustomDate; +}(); + +connection.execute('SELECT UNIX_TIMESTAMP(?) t', [new Date('1990-08-08 UTC')], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + console.log(_rows, _fields); +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{t: 650073600}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-date-parameter.js b/node_modules/mysql2/test/integration/connection/test-date-parameter.js new file mode 100644 index 0000000..e2b1ddb --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-date-parameter.js @@ -0,0 +1,17 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; + +connection.execute('SELECT UNIX_TIMESTAMP(?) t', [new Date('1990-01-01 UTC')], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + console.log(_rows, _fields); +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{t: 631152000}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-datetime.js b/node_modules/mysql2/test/integration/connection/test-datetime.js new file mode 100644 index 0000000..a608db6 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-datetime.js @@ -0,0 +1,73 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var connection1 = common.createConnection({ dateStrings: true }); +var assert = require('assert'); + +var rows, rows1, rows2, rows3, rows4, rows5; + +var date = new Date('1990-01-01 08:15:11 UTC'); +var date1 = new Date('2000-03-03 08:15:11 UTC'); +var date2 = '2010-12-10 14:12:09.019473'; +connection.query('CREATE TEMPORARY TABLE t (d1 DATE)'); +connection.query('INSERT INTO t set d1=?', [date]); + +connection1.query('CREATE TEMPORARY TABLE t (d1 DATE, d2 TIMESTAMP, d3 DATETIME)'); +connection1.query('INSERT INTO t set d1=?, d2=?, d3=?', [date, date1, date2]); + +var dateAsStringExpected = [ + { d1: '1990-01-01', + d2: '2000-03-03 08:15:11', + d3: '2010-12-10 14:12:09' } ]; + + +connection.execute('select from_unixtime(?) t', [(+date).valueOf()/1000], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; +}); + +connection.query('select from_unixtime(631152000) t', function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; +}); + +connection.query('select * from t', function(err, _rows, _fields) { + if (err) throw err; + rows2 = _rows; +}); + +connection.execute('select * from t', function(err, _rows, _fields) { + if (err) throw err; + rows3 = _rows; +}); + +connection1.query('select * from t', function(err, _rows, _fields) { + console.log(_rows); + if (err) throw err; + rows4 = _rows; +}); + +connection1.execute('select * from t', function(err, _rows, _fields) { + console.log(_rows); + if (err) throw err; + rows5 = _rows; +}); + +connection.end(); +connection1.end(); + +process.on('exit', function() { + assert.equal(rows[0].t.constructor, Date); + assert.equal(rows[0].t.getDate(), date.getDate()); + assert.equal(rows[0].t.getHours(), date.getHours()); + assert.equal(rows[0].t.getMinutes(), date.getMinutes()); + assert.equal(rows[0].t.getSeconds(), date.getSeconds()); + + assert.equal(rows1[0].t.constructor, Date); + assert.equal(rows1[0].t - new Date('Mon Jan 01 1990 11:00:00 GMT+1100 (EST)'), 0); + + assert.equal(rows2[0].d1.getDate(), date.getDate()); + assert.equal(rows3[0].d1.getDate(), date.getDate()); + + assert.deepEqual(rows4, dateAsStringExpected); + assert.deepEqual(rows5, dateAsStringExpected); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-disconnects.js b/node_modules/mysql2/test/integration/connection/test-disconnects.js new file mode 100644 index 0000000..ed84064 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-disconnects.js @@ -0,0 +1,38 @@ +var common = require('../../common'); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; +var err; +var server; + +function test() { + var connection = common.createConnection({port: 3307}); + //var connection = require('mysql').createConnection({port: 3307}); + connection.query('SELECT 123', function(err, _rows, _fields) { + if (err) throw err; + + rows = _rows; + fields = _fields; + connection.on('error', function(_err) { + err = _err; + }); + server.connections.forEach(function(conn) { conn.stream.end() } ); + server._server.close(function() { + assert.equal(err.code, 'PROTOCOL_CONNECTION_LOST'); + }); + + // TODO: tests for 'commands after close' behavior + // connection.query('SELECT 123', function(err, a, b) { + // console.log(err, a, b); + // }); + }); + + // TODO: test connection.end() etc where we expect disconnect to happen +} +server = common.createServer(test); + +process.on('exit', function() { + assert.deepEqual(rows, [{1: 1}]); + assert.equal(fields[0].name, '1'); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-domains.js b/node_modules/mysql2/test/integration/connection/test-domains.js new file mode 100644 index 0000000..f7ee8b4 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-domains.js @@ -0,0 +1,60 @@ +var assert = require('assert'); +var domain = require('domain'); +var d1 = domain.create(); +var d2 = domain.create(); +var d3 = domain.create(); +var d4 = domain.create(); +var err1, err2, err3, err4; + +d1.run(function() { + var common = require('../../common'); + var connection = common.createConnection(); + var assert = require('assert'); + + d2.run(function() { + connection.query('SELECT 1', function(err, _rows, _fields) { + if (err) throw err; + throw new Error('inside domain 2'); + }); + }); + + d3.run(function() { + connection.execute('SELECT 1', function(err, _rows, _fields) { + if (err) throw err; + throw new Error('inside domain 3'); + }); + }); + + d4.run(function() { + connection.ping(function() { + throw new Error('inside domain 4'); + }); + }); + + connection.end(); + setTimeout(function() { + throw new Error('inside domain 1'); + }, 100); + + d2.on('error', function(err) { + err2 = err; + }); + d3.on('error', function(err) { + err3 = err; + }); + d4.on('error', function(err) { + err4 = err; + }); + +}); + +d1.on('error', function(err) { + err1 = err; +}); + +process.on('exit', function() { + assert.equal(''+err1, 'Error: inside domain 1') + assert.equal(''+err2, 'Error: inside domain 2') + assert.equal(''+err3, 'Error: inside domain 3') + assert.equal(''+err4, 'Error: inside domain 4') +}); diff --git a/node_modules/mysql2/test/integration/connection/test-errors.js b/node_modules/mysql2/test/integration/connection/test-errors.js new file mode 100644 index 0000000..999f273 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-errors.js @@ -0,0 +1,42 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var onExecuteResultError = undefined; +var onQueryResultError = undefined; +var onExecuteErrorEvent = undefined; +var onQueryErrorEvent = undefined; +var onExecuteErrorEvent1 = undefined; +var onQueryErrorEvent1 = undefined; + +connection.execute('error in execute', [], function(err, _rows, _fields) { + if (err) { + onExecuteResultError = true; + } +}).on('error', function() { + onExecuteErrorEvent = true; +}); +connection.query('error in query', [], function(err, _rows, _fields) { + if (err) { + onQueryResultError = true; + } +}).on('error', function() { + onQueryErrorEvent = true; +}); +connection.execute('error in execute 1', []).on('error', function() { + onExecuteErrorEvent1 = true; +}); +connection.query('error in query 1').on('error', function() { + onQueryErrorEvent1 = true; +}); + +connection.end(); + +process.on('exit', function() { + assert.equal(onExecuteResultError, true); + assert.equal(onQueryResultError, true); + assert.equal(onExecuteErrorEvent, undefined); + assert.equal(onQueryErrorEvent, undefined); + assert.equal(onExecuteErrorEvent1, true); + assert.equal(onQueryErrorEvent1, true); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-execute-1.js b/node_modules/mysql2/test/integration/connection/test-execute-1.js new file mode 100644 index 0000000..47c4255 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-execute-1.js @@ -0,0 +1,54 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var rows1 = undefined; +var fields = undefined; + +connection.query([ + 'CREATE TEMPORARY TABLE `announcements` (', + '`id` int(11) NOT NULL AUTO_INCREMENT,', + '`title` varchar(255) DEFAULT NULL,', + '`text` varchar(255) DEFAULT NULL,', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n'), function(err) { + if (err) throw err; +}); + +connection.execute('SELECT 1+? as test', [123], function(err, _rows, _fields) { + if (err) throw err; + + rows = _rows; + fields = _fields; +}); +connection.execute('SELECT 1 as test', function(err, _rows, _fields) { + if (err) throw err; + + rows1 = _rows; + fields = _fields; +}); + +connection.execute('INSERT INTO announcements(title, text) VALUES(?, ?)', ['Есть место, где заканчивается тротуар', 'Расти борода, расти'], function(err) { + if (err) throw err; +}); +connection.execute('INSERT INTO announcements(title, text) VALUES(?, ?)', ['Граждане Российской Федерации имеют право собираться мирно без оружия', 'проводить собрания, митинги и демонстрации, шествия и пикетирование'], function(err) { + if (err) throw err; +}); +connection.execute('SELECT * FROM announcements', function (err, rows) { + if (err) throw err; + assert.equal(rows.length, 2); + assert.equal(rows[0].title, 'Есть место, где заканчивается тротуар'); + assert.equal(rows[0].text, 'Расти борода, расти'); + assert.equal(rows[1].title, 'Граждане Российской Федерации имеют право собираться мирно без оружия'); + assert.equal(rows[1].text, 'проводить собрания, митинги и демонстрации, шествия и пикетирование'); +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{'test': 124}]); + assert.deepEqual(rows1, [{'test': 1}]); + assert.equal(fields[0].name, 'test'); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-execute-newdecimal.js b/node_modules/mysql2/test/integration/connection/test-execute-newdecimal.js new file mode 100644 index 0000000..7b317b1 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-execute-newdecimal.js @@ -0,0 +1,19 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +connection.query('CREATE TEMPORARY TABLE t (f DECIMAL(19,4))'); +connection.query('INSERT INTO t VALUES(12345.67)'); + +var rows, fields; +connection.execute('SELECT f FROM t', function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{'f': '12345.6700'}]); + assert.equal(fields[0].name, 'f'); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-execute-null-bitmap.js b/node_modules/mysql2/test/integration/connection/test-execute-null-bitmap.js new file mode 100644 index 0000000..4f03916 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-execute-null-bitmap.js @@ -0,0 +1,22 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var params = [1, 2]; +var query = 'select ? + ?'; + +function dotest() { + connection.execute(query + ' as t', params, function(err, _rows, _fields) { + assert.equal(err, null); + if (params.length < 50) { + assert.equal(_rows[0].t, params.reduce(function(x,y) {return x+y;})); + query += ' + ?'; + params.push(params.length); + dotest(); + } else { + connection.end(); + } + }); +} + +dotest(); diff --git a/node_modules/mysql2/test/integration/connection/test-execute-signed.js b/node_modules/mysql2/test/integration/connection/test-execute-signed.js new file mode 100644 index 0000000..1caef2a --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-execute-signed.js @@ -0,0 +1,31 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; + +connection.query([ + 'CREATE TEMPORARY TABLE `test_table` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`num` int(15),', + '`l` long,', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +connection.query('insert into test_table(num,l) values(?, 3)', [1]); +connection.query('insert into test_table(num,l) values(3-?, -10)', [5]); +connection.query('insert into test_table(num,l) values(4+?, 4000000-?)', [-5, 8000000]); + +connection.execute('SELECT * from test_table', [], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{"id":1,"num":1,"l": 3},{"id":2,"num":-2,"l":-10},{"id":3,"num":-1,"l":-4000000}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-execute-type-casting.js b/node_modules/mysql2/test/integration/connection/test-execute-type-casting.js new file mode 100644 index 0000000..d0eb809 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-execute-type-casting.js @@ -0,0 +1,72 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var tests = require('./type-casting-tests')(connection); + +var table = 'type_casting'; + +var schema = []; +var inserts = []; + +tests.forEach(function(test, index) { + var escaped = test.insertRaw || connection.escape(test.insert); + + test.columnName = test.type + '_' + index; + + schema.push('`' + test.columnName + '` ' + test.type + ','); + inserts.push('`' + test.columnName + '` = ' + escaped); +}); + +var createTable = [ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,' + ].concat(schema).concat([ + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +]).join('\n'); + +connection.query(createTable); + +connection.query('INSERT INTO ' + table + ' SET' + inserts.join(',\n')); + +var row; +connection.execute('SELECT * FROM ' + table + ' WHERE id = ?;', [1], function(err, rows) { + if (err) throw err; + + row = rows[0]; +}); + +connection.end(); + +process.on('exit', function() { + tests.forEach(function(test) { + var expected = test.expect || test.insert; + var got = row[test.columnName]; + var message; + + if (expected instanceof Date) { + assert.equal(got instanceof Date, true, test.type); + + expected = String(expected); + got = String(got); + } else if (Buffer.isBuffer(expected)) { + assert.equal(Buffer.isBuffer(got), true, test.type); + + expected = String(Array.prototype.slice.call(expected)); + got = String(Array.prototype.slice.call(got)); + } + + if (test.deep) { + message = 'got: "' + JSON.stringify(got) + '" expected: "' + JSON.stringify(expected) + + '" test: ' + test.type + ''; + assert.deepEqual(expected, got, message); + } else { + message = 'got: "' + got + '" (' + (typeof got) + ') expected: "' + expected + + '" (' + (typeof expected) + ') test: ' + test.type + ''; + assert.strictEqual(expected, got, message); + } + }); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-handshake-errors.js b/node_modules/mysql2/test/integration/connection/test-handshake-errors.js new file mode 100644 index 0000000..364d8ef --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-handshake-errors.js @@ -0,0 +1,24 @@ +var common = require('../../common'); +var assert = require('assert'); + +var conns = []; + +function spawn() { + var c = common.createConnection(); + c.ping(spawn); + conns.push(c); + + c.on('error', function(err) { + conns.forEach(function(c) { if (c) c.end(); }) + }); +} + +spawn(); + +process.on('uncaughtException', function(e) { + assert(false, 'should not have uncaught exceptions'); +}); + +process.on('exit', function() { + assert(conns.length > 0); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-insert-bigint.js b/node_modules/mysql2/test/integration/connection/test-insert-bigint.js new file mode 100644 index 0000000..885c797 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-insert-bigint.js @@ -0,0 +1,46 @@ +var common = require('../../common'); +var connection = common.createConnection({ bigNumberString: true }); +var assert = require('assert'); +var bn = require('bn.js'); + +var table = 'insert_test'; +connection.query([ + 'CREATE TEMPORARY TABLE `bigs` (', + '`id` bigint NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +var result, result2; +connection.query("INSERT INTO bigs SET title='test', id=123"); +connection.query("INSERT INTO bigs SET title='test1'", function(err, result) { + if (err) throw err; + assert.strictEqual(result.insertId, 124); + // > 24 bits + connection.query("INSERT INTO bigs SET title='test', id=123456789"); + connection.query("INSERT INTO bigs SET title='test2'", function(err, result) { + assert.strictEqual(result.insertId, 123456790); + // big int + connection.query("INSERT INTO bigs SET title='test', id=9007199254740992"); + connection.query("INSERT INTO bigs SET title='test3'", function(err, result) { + assert.strictEqual((new bn("9007199254740993")).cmp(result.insertId), 0); + connection.query("INSERT INTO bigs SET title='test', id=90071992547409924"); + connection.config.bigNumberStrings = true; + connection.query("INSERT INTO bigs SET title='test4'", function(err, result) { + assert.strictEqual(result.insertId, "90071992547409925"); + connection.query("select * from bigs", function(err, result) { + assert.strictEqual(result[0].id, 123); + assert.strictEqual(result[1].id, 124); + assert.strictEqual(result[2].id, 123456789); + assert.strictEqual(result[3].id, 123456790); + assert.strictEqual(result[4].id, 9007199254740992); + assert.strictEqual(result[5].id, "9007199254740993"); + assert.strictEqual(result[6].id, "90071992547409924"); + assert.strictEqual(result[7].id, "90071992547409925"); + connection.end(); + }); + }); + }); + }); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-insert-results.js b/node_modules/mysql2/test/integration/connection/test-insert-results.js new file mode 100644 index 0000000..4fa7fe2 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-insert-results.js @@ -0,0 +1,34 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +//common.useTestDb(connection); + +var table = 'insert_test'; +//var text = "本日は晴天なり"; +var text = " test test test "; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +var result, result2; +connection.query('INSERT INTO ' + table + ' SET title="' + text + '"', function(err, _result) { + if (err) throw err; + result = _result; + connection.query('SELECT * FROM ' + table + ' WHERE id = ' + result.insertId, function(err, _result2) { + result2 = _result2; + connection.end(); + }); +}); + +process.on('exit', function() { + assert.strictEqual(result.insertId, 1); + assert.strictEqual(result2.length, 1); + // TODO: type conversions + assert.equal(result2[0].id, String(result.insertId)); + assert.equal(result2[0].title, text); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-invalid-date-result.js b/node_modules/mysql2/test/integration/connection/test-invalid-date-result.js new file mode 100644 index 0000000..26d38a5 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-invalid-date-result.js @@ -0,0 +1,21 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; + +connection.execute('SELECT TIMESTAMP(0000-00-00) t', [], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; +}); + +connection.end(); + +function isInvalidTime(t) { + return isNaN(t.getTime()); +} + +process.on('exit', function() { + assert.deepEqual(Object.prototype.toString.call(rows[0].t), "[object Date]"); + assert.deepEqual(isInvalidTime(rows[0].t), true); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-multiple-results.js b/node_modules/mysql2/test/integration/connection/test-multiple-results.js new file mode 100644 index 0000000..5637acb --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-multiple-results.js @@ -0,0 +1,142 @@ +var mysql = require('../../common').createConnection({multipleStatements: true}); +var assert = require('assert'); +mysql.query('CREATE TEMPORARY TABLE no_rows (test int)'); +mysql.query('CREATE TEMPORARY TABLE some_rows (test int)'); +mysql.query('INSERT INTO some_rows values(0)'); +mysql.query('INSERT INTO some_rows values(42)'); +mysql.query('INSERT INTO some_rows values(314149)'); + +var clone = function(obj) { return JSON.parse(JSON.stringify(obj)); }; + +var rs1 = { + affectedRows: 0, + fieldCount: 0, + insertId: 0, + serverStatus: 10, + warningStatus: 0 +}; +var rs2 = clone(rs1); +rs2.serverStatus = 2; + +var twoInsertResult = [[rs1, rs2], [undefined, undefined], 2]; +var select1 = [{"1":"1"}]; +var select2 = [{"2":"2"}]; +var fields1 = [{ + catalog: "def", + characterSet: 63, + columnLength: 1, + columnType: 8, + decimals: 0, + flags: 129, + name: "1", + orgName: "", + orgTable: "", + schema: "", + table: "" +}]; +var nr_fields = [{ + catalog: "def", + characterSet: 63, + columnLength: 11, + columnType: 3, + decimals: 0, + flags: 0, + name: "test", + orgName: "test", + orgTable: "no_rows", + schema: "test", + table: "no_rows" +}]; +var sr_fields = clone(nr_fields); +sr_fields[0].orgTable = "some_rows"; +sr_fields[0].table = "some_rows"; +var select3 = [{"test":0},{"test":42},{"test":314149}]; + +var fields2 = clone(fields1); +fields2[0].name = "2"; + +var tests = [ + ["select * from some_rows", [select3,sr_fields,1]], // select 3 rows + ["SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT; SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS;", twoInsertResult], + ["/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;", twoInsertResult], // issue #26 + ["set @a = 1", [rs2, undefined, 1]], // one insert result + ["set @a = 1; set @b = 2", twoInsertResult], + ["select 1; select 2", [[select1,select2],[fields1,fields2], 2]], + ["set @a = 1; select 1", [[rs1, select1], [undefined, fields1], 2]], + ["select 1; set @a = 1", [[select1, rs2], [fields1, undefined], 2]], + ["select * from no_rows", [[], nr_fields, 1]], // select 0 rows" + ["set @a = 1; select * from no_rows", [[rs1, []], [undefined, nr_fields], 2]], // insert + select 0 rows + ["select * from no_rows; set @a = 1", [[[], rs2], [nr_fields, undefined], 2]], // select 0 rows + insert + ["set @a = 1; select * from some_rows", [[rs1, select3],[undefined,sr_fields],2]], // insert + select 3 rows + ["select * from some_rows; set @a = 1", [[select3,rs2],[sr_fields,undefined],2]] // select 3 rows + insert +]; + +// TODO: tests with error in the query with different index +// TODO: multiple results from single query + +function do_test(testIndex) { + var entry = tests[testIndex]; + var sql = entry[0]; + var expectation = entry[1]; + mysql.query(sql, function(err, _rows, _columns) { + var _numResults = 0; + if (_rows.constructor.name == 'ResultSetHeader') + _numResults = 1; + else if (_rows.length === 0) { + // empty select + _numResults = 1; + } + else if (_rows.length > 0) { + if (_rows.constructor.name == 'Array' && _rows[0].constructor.name == 'TextRow') + _numResults = 1; + if (_rows.constructor.name == 'Array' && + (_rows[0].constructor.name == 'Array' || _rows[0].constructor.name =='ResultSetHeader')) + _numResults = _rows.length + } + if (err) { + console.log(err); + process.exit(-1); + } + assert.deepEqual(expectation, [_rows, _columns, _numResults]); + var q = mysql.query(sql); + var resIndex = 0; + var rowIndex = 0; + function checkRow(row, index) { + if (_numResults == 1) { + assert.equal(index, 0); + if (row.constructor.name == 'ResultSetHeader') + assert.deepEqual(_rows, row); + else + assert.deepEqual(_rows[rowIndex], row); + } else { + if (resIndex != index) { + rowIndex = 0; + resIndex = index; + } + if (row.constructor.name == 'ResultSetHeader') + assert.deepEqual(_rows[index], row); + else + assert.deepEqual(_rows[index][rowIndex], row); + } + rowIndex++; + } + function checkFields(fields, index) { + if (_numResults == 1) { + assert.equal(index, 0); + assert.deepEqual(_columns, fields); + } + else + assert.deepEqual(_columns[index], fields); + } + q.on('result', checkRow); + q.on('fields', checkFields); + q.on('end', function() { + if (testIndex + 1 < tests.length) + do_test(testIndex + 1); + else { + mysql.end(); + } + }); + }); +} +do_test(0); diff --git a/node_modules/mysql2/test/integration/connection/test-nested-tables-query.js b/node_modules/mysql2/test/integration/connection/test-nested-tables-query.js new file mode 100644 index 0000000..c6315e9 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-nested-tables-query.js @@ -0,0 +1,86 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var table = 'nested_test'; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +connection.query('INSERT INTO ' + table + ' SET ?', {title: 'test'}); + +var options1 = { + nestTables: true, + sql: 'SELECT * FROM ' + table +}; +var options2 = { + nestTables: '_', + sql: 'SELECT * FROM ' + table +}; +var options3 = { + rowsAsArray: true, + sql: 'SELECT * FROM ' + table +}; +var rows1, rows2, rows3, rows1e, rows2e, rows3e; + +connection.query(options1, function(err, _rows) { + if (err) throw err; + + rows1 = _rows; +}); + +connection.query(options2, function(err, _rows) { + if (err) throw err; + + rows2 = _rows; +}); + +connection.query(options3, function(err, _rows) { + if (err) throw err; + + rows3 = _rows; +}); + +connection.execute(options1, function(err, _rows) { + if (err) throw err; + + rows1e = _rows; +}); + +connection.execute(options2, function(err, _rows) { + if (err) throw err; + + rows2e = _rows; +}); + +connection.execute(options3, function(err, _rows) { + if (err) throw err; + + rows3e = _rows; +}); + +connection.end(); + +process.on('exit', function() { + assert.equal(rows1.length, 1); + assert.equal(rows1[0].nested_test.id, 1); + assert.equal(rows1[0].nested_test.title, 'test'); + + assert.equal(rows2.length, 1); + assert.equal(rows2[0].nested_test_id, 1); + assert.equal(rows2[0].nested_test_title, 'test'); + + assert.equal(Array.isArray(rows3[0]), true); + assert.equal(rows3[0][0], 1); + assert.equal(rows3[0][1], 'test'); + + assert.deepEqual(rows1, rows1e); + assert.deepEqual(rows2, rows2e); + assert.deepEqual(rows3, rows3e); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-null-double.js b/node_modules/mysql2/test/integration/connection/test-null-double.js new file mode 100644 index 0000000..3fa1eeb --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-null-double.js @@ -0,0 +1,21 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows; + +connection.query('CREATE TEMPORARY TABLE t (i int)'); +connection.query('INSERT INTO t VALUES(null)'); +connection.query('INSERT INTO t VALUES(123)'); + +connection.query('SELECT * from t', function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows[0], {i: null}); + assert.deepEqual(rows[1], {i: 123}); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-null-int.js b/node_modules/mysql2/test/integration/connection/test-null-int.js new file mode 100644 index 0000000..3fa1eeb --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-null-int.js @@ -0,0 +1,21 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows; + +connection.query('CREATE TEMPORARY TABLE t (i int)'); +connection.query('INSERT INTO t VALUES(null)'); +connection.query('INSERT INTO t VALUES(123)'); + +connection.query('SELECT * from t', function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows[0], {i: null}); + assert.deepEqual(rows[1], {i: 123}); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-null.js b/node_modules/mysql2/test/integration/connection/test-null.js new file mode 100644 index 0000000..1ea2b9e --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-null.js @@ -0,0 +1,28 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows, rows1; +var fields, fields1; + +connection.query('CREATE TEMPORARY TABLE t (i int)'); +connection.query('INSERT INTO t VALUES(null)'); +connection.query('SELECT cast(NULL AS CHAR)', function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); +connection.query('SELECT * from t', function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; + fields1 = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{'cast(NULL AS CHAR)': null}]); + assert.equal(fields[0].columnType, 253); + assert.deepEqual(rows1, [{'i': null}]); + assert.equal(fields1[0].columnType, 3); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-select-1.js b/node_modules/mysql2/test/integration/connection/test-select-1.js new file mode 100644 index 0000000..cc59619 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-select-1.js @@ -0,0 +1,19 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; +connection.query('SELECT 1', function(err, _rows, _fields) { + if (err) throw err; + + rows = _rows; + fields = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{1: 1}]); + assert.equal(fields[0].name, '1'); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-select-empty-string.js b/node_modules/mysql2/test/integration/connection/test-select-empty-string.js new file mode 100644 index 0000000..8e10ce7 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-select-empty-string.js @@ -0,0 +1,16 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows; +connection.query('SELECT ""', function(err, _rows) { + if (err) throw err; + + rows = _rows; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{'': ''}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-select-negative.js b/node_modules/mysql2/test/integration/connection/test-select-negative.js new file mode 100644 index 0000000..9442988 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-select-negative.js @@ -0,0 +1,27 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var rows1 = undefined; +var fields = undefined; +var fields1 = undefined; + +connection.execute('SELECT -1 v', [], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.query('SELECT -1 v', function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; + fields1 = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{v: -1}]); + assert.deepEqual(rows1, [{v: -1}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-select-utf8.js b/node_modules/mysql2/test/integration/connection/test-select-utf8.js new file mode 100644 index 0000000..54b5fc7 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-select-utf8.js @@ -0,0 +1,19 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; +var multibyteText = '本日は晴天なり'; +connection.query("SELECT '" + multibyteText + "'", function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.equal(rows[0][multibyteText], multibyteText); + assert.equal(fields[0].name, multibyteText); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-select-utf8mb4.js b/node_modules/mysql2/test/integration/connection/test-select-utf8mb4.js new file mode 100644 index 0000000..e26342d --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-select-utf8mb4.js @@ -0,0 +1,19 @@ +var common = require('../../common'); +var connection = common.createConnection({charset: 'UTF8MB4_GENERAL_CI'}); +var assert = require('assert'); + +var rows = undefined; +var fields = undefined; +var multibyteText = '𠜎 𠜱 𠝹 𠱓 𠱸 𠲖 𠳏 𠳕 𠴕 𠵼 𠵿 𠸎 𠸏 𠹷 𠺝 𠺢 '; +connection.query("SELECT '" + multibyteText + "'", function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); + +connection.end(); + +process.on('exit', function() { + assert.equal(rows[0][multibyteText], multibyteText); + assert.equal(fields[0].name, multibyteText); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-signed-tinyint.js b/node_modules/mysql2/test/integration/connection/test-signed-tinyint.js new file mode 100644 index 0000000..19fba63 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-signed-tinyint.js @@ -0,0 +1,20 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +var rows = undefined; + +connection.query('CREATE TEMPORARY TABLE signed_ints (b11 tinyint NOT NULL, b12 tinyint NOT NULL, b21 smallint NOT NULL)'); +connection.query('INSERT INTO signed_ints values (-3, -120, 500)'); +connection.query('INSERT INTO signed_ints values (3, -110, -500)'); + +connection.execute('SELECT * from signed_ints', [5], function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; +}); + +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows, [{"b11":-3,"b12":-120,"b21":500},{"b11":3,"b12":-110,"b21":-500}]); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-timestamp.js b/node_modules/mysql2/test/integration/connection/test-timestamp.js new file mode 100644 index 0000000..1773ed9 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-timestamp.js @@ -0,0 +1,36 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +connection.query('CREATE TEMPORARY TABLE t (f TIMESTAMP)'); +connection.query('INSERT INTO t VALUES(\'0000-00-00 00:00:00\')'); +connection.query('INSERT INTO t VALUES(\'2013-01-22 01:02:03\')'); + +var rows, fields; +var rows1, fields1; +connection.query('SELECT f FROM t', function(err, _rows, _fields) { + if (err) throw err; + rows = _rows; + fields = _fields; +}); +connection.execute('SELECT f FROM t', function(err, _rows, _fields) { + if (err) throw err; + rows1 = _rows; + fields1 = _fields; +}); +connection.end(); + +process.on('exit', function() { + assert.deepEqual(rows[0].f.toString(), 'Invalid Date'); + assert(rows[0].f instanceof Date); + assert(rows[1].f instanceof Date); + assert.equal(rows[1].f.getYear(), 113); + assert.equal(rows[1].f.getMonth(), 0); + assert.equal(rows[1].f.getDate(), 22); + assert.equal(rows[1].f.getHours(), 1); + assert.equal(rows[1].f.getMinutes(), 2); + assert.equal(rows[1].f.getSeconds(), 3); + assert.equal(fields[0].name, 'f'); + assert.deepEqual(rows[1], rows1[1]); + assert.deepEqual(fields, fields1); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-transaction-commit.js b/node_modules/mysql2/test/integration/connection/test-transaction-commit.js new file mode 100644 index 0000000..88386a9 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-transaction-commit.js @@ -0,0 +1,37 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var table = 'transaction_test'; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' + ].join('\n')); + +connection.beginTransaction(function (err) { + assert.ifError(err); + + var row = { + id: 1, + title: 'Test row' + }; + + connection.query('INSERT INTO ' + table + ' SET ?', row, function(err) { + assert.ifError(err); + + connection.commit(function(err) { + assert.ifError(err); + + connection.query('SELECT * FROM ' + table, function(err, rows) { + assert.ifError(err); + connection.end(); + assert.equal(rows.length, 1); + }); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/mysql2/test/integration/connection/test-transaction-rollback.js b/node_modules/mysql2/test/integration/connection/test-transaction-rollback.js new file mode 100644 index 0000000..7cbae39 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-transaction-rollback.js @@ -0,0 +1,37 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var table = 'transaction_test'; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`title` varchar(255),', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' + ].join('\n')); + +connection.beginTransaction(function (err) { + assert.ifError(err); + + var row = { + id: 1, + title: 'Test row' + }; + + connection.query('INSERT INTO ' + table + ' SET ?', row, function(err) { + assert.ifError(err); + + connection.rollback(function(err) { + assert.ifError(err); + + connection.query('SELECT * FROM ' + table, function(err, rows) { + assert.ifError(err); + connection.end(); + assert.equal(rows.length, 0); + }); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/mysql2/test/integration/connection/test-type-cast-null-fields.js b/node_modules/mysql2/test/integration/connection/test-type-cast-null-fields.js new file mode 100644 index 0000000..f5718f4 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-type-cast-null-fields.js @@ -0,0 +1,34 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var table = 'insert_test'; +connection.query([ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,', + '`date` DATETIME NULL,', + '`number` INT NULL,', + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +].join('\n')); + +connection.query('INSERT INTO ' + table + ' SET ?', { + date : null, + number : null, +}); + +var results; +connection.query('SELECT * FROM ' + table, function(err, _results) { + if (err) throw err; + + results = _results; +}); + +connection.end(); + +process.on('exit', function() { + assert.strictEqual(results[0].date, null); + assert.strictEqual(results[0].number, null); +}); diff --git a/node_modules/mysql2/test/integration/connection/test-type-casting.js b/node_modules/mysql2/test/integration/connection/test-type-casting.js new file mode 100644 index 0000000..5ad7761 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/test-type-casting.js @@ -0,0 +1,72 @@ +var common = require('../../common'); +var connection = common.createConnection(); +var assert = require('assert'); + +common.useTestDb(connection); + +var tests = require('./type-casting-tests')(connection); + +var table = 'type_casting'; + +var schema = []; +var inserts = []; + +tests.forEach(function(test, index) { + var escaped = test.insertRaw || connection.escape(test.insert); + + test.columnName = test.type + '_' + index; + + schema.push('`' + test.columnName + '` ' + test.type + ','); + inserts.push('`' + test.columnName + '` = ' + escaped); +}); + +var createTable = [ + 'CREATE TEMPORARY TABLE `' + table + '` (', + '`id` int(11) unsigned NOT NULL AUTO_INCREMENT,' + ].concat(schema).concat([ + 'PRIMARY KEY (`id`)', + ') ENGINE=InnoDB DEFAULT CHARSET=utf8' +]).join('\n'); + +connection.query(createTable); + +connection.query('INSERT INTO ' + table + ' SET' + inserts.join(',\n')); + +var row; +connection.query('SELECT * FROM type_casting', function(err, rows) { + if (err) throw err; + + row = rows[0]; +}); + +connection.end(); + +process.on('exit', function() { + tests.forEach(function(test) { + var expected = test.expect || test.insert; + var got = row[test.columnName]; + var message; + + if (expected instanceof Date) { + assert.equal(got instanceof Date, true, test.type); + + expected = String(expected); + got = String(got); + } else if (Buffer.isBuffer(expected)) { + assert.equal(Buffer.isBuffer(got), true, test.type); + + expected = String(Array.prototype.slice.call(expected)); + got = String(Array.prototype.slice.call(got)); + } + + if (test.deep) { + message = 'got: "' + JSON.stringify(got) + '" expected: "' + JSON.stringify(expected) + + '" test: ' + test.type + ''; + assert.deepEqual(expected, got, message); + } else { + message = 'got: "' + got + '" (' + (typeof got) + ') expected: "' + expected + + '" (' + (typeof expected) + ') test: ' + test.type + ''; + assert.strictEqual(expected, got, message); + } + }); +}); diff --git a/node_modules/mysql2/test/integration/connection/type-casting-tests.js b/node_modules/mysql2/test/integration/connection/type-casting-tests.js new file mode 100644 index 0000000..66f8173 --- /dev/null +++ b/node_modules/mysql2/test/integration/connection/type-casting-tests.js @@ -0,0 +1,53 @@ +module.exports = function(connection){ + return [ + {type: 'decimal(4,3)', insert: '1.234'}, +// {type: 'decimal(3,3)', insert: 0.33}, + {type: 'tinyint', insert: 1}, + {type: 'smallint', insert: 2}, + {type: 'int', insert: 3}, + {type: 'float', insert: 4.5}, + {type: 'double', insert: 5.5}, + {type: 'bigint', insert: '6', expect: 6}, + {type: 'bigint', insert: 6}, + {type: 'mediumint', insert: 7}, + {type: 'year', insert: 2012}, + {type: 'timestamp', insert: new Date('2012-05-12 11:00:23')}, + {type: 'datetime', insert: new Date('2012-05-12 12:00:23')}, + {type: 'date', insert: new Date('2012-05-12 00:00:00')}, + {type: 'time', insert: '13:13:23'}, + {type: 'time', insert: '-13:13:23'}, + {type: 'time', insert: '413:13:23'}, + {type: 'time', insert: '-413:13:23'}, + {type: 'binary(4)', insert: new Buffer([0, 1, 254, 255])}, + {type: 'varbinary(4)', insert: new Buffer([0, 1, 254, 255])}, + {type: 'tinyblob', insert: new Buffer([0, 1, 254, 255])}, + {type: 'mediumblob', insert: new Buffer([0, 1, 254, 255])}, + {type: 'longblob', insert: new Buffer([0, 1, 254, 255])}, + {type: 'blob', insert: new Buffer([0, 1, 254, 255])}, + {type: 'bit(32)', insert: new Buffer([0, 1, 254, 255])}, + {type: 'char(5)', insert: 'Hello'}, + {type: 'varchar(5)', insert: 'Hello'}, + {type: 'varchar(3) character set utf8 collate utf8_bin', insert: 'bin'}, + {type: 'tinytext', insert: 'Hello World'}, + {type: 'mediumtext', insert: 'Hello World'}, + {type: 'longtext', insert: 'Hello World'}, + {type: 'text', insert: 'Hello World'}, + {type: 'point', insertRaw: 'POINT(1.2,-3.4)', expect: {x:1.2, y:-3.4}, deep: true}, + {type: 'point', insertRaw: (function() { + var buffer = new Buffer(21); + buffer.writeUInt8(1, 0); + buffer.writeUInt32LE(1, 1); + buffer.writeDoubleLE(-5.6, 5); + buffer.writeDoubleLE(10.23, 13); + return 'GeomFromWKB(' + connection.escape(buffer) + ')'; + })(), expect: {x:-5.6, y:10.23}, deep: true}, + {type: 'point', insertRaw: '', insert: null, expect: null}, + {type: 'linestring', insertRaw: 'LINESTRING(POINT(1.2,-3.4),POINT(-5.6,10.23),POINT(0.2,0.7))', expect: [{x:1.2, y:-3.4}, {x:-5.6, y:10.23}, {x:0.2, y:0.7}], deep: true}, + {type: 'polygon', insertRaw: "GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))')", expect: [[{x:0,y:0},{x:10,y:0},{x:10,y:10},{x:0,y:10},{x:0,y:0}],[{x:5,y:5},{x:7,y:5},{x:7,y:7},{x:5,y:7},{x:5,y:5}]], deep: true}, + {type: 'geometry', insertRaw: 'POINT(1.2,-3.4)', expect: {x:1.2, y:-3.4}, deep: true}, + {type: 'multipoint', insertRaw: "GeomFromText('MULTIPOINT(0 0, 20 20, 60 60)')", expect: [{x:0, y:0}, {x:20, y:20}, {x:60, y:60}], deep: true}, + {type: 'multilinestring', insertRaw: "GeomFromText('MULTILINESTRING((10 10, 20 20), (15 15, 30 15))')", expect: [[{x:10,y:10},{x:20,y:20}],[{x:15,y:15},{x:30,y:15}]], deep: true}, + {type: 'multipolygon', insertRaw: "GeomFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))')", expect: [[[{x:0,y:0},{x:10,y:0},{x:10,y:10},{x:0,y:10},{x:0,y:0}]],[[{x:5,y:5},{x:7,y:5},{x:7,y:7},{x:5,y:7},{x:5,y:5}]]], deep: true}, + {type: 'geometrycollection', insertRaw: "GeomFromText('GEOMETRYCOLLECTION(POINT(11 10), POINT(31 30), LINESTRING(15 15, 20 20))')", expect: [{x:11,y:10},{x:31,y:30},[{x:15,y:15},{x:20,y:20}]], deep: true} + ]; +}; diff --git a/node_modules/mysql2/test/run.js b/node_modules/mysql2/test/run.js new file mode 100755 index 0000000..42fdee2 --- /dev/null +++ b/node_modules/mysql2/test/run.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +var options = {}; + +if (process.env.FILTER) { + options.include = new RegExp(process.env.FILTER + '.*\\.js$'); +} +require('urun')(__dirname, options); diff --git a/node_modules/mysql2/test/template.jade b/node_modules/mysql2/test/template.jade new file mode 100644 index 0000000..a475e51 --- /dev/null +++ b/node_modules/mysql2/test/template.jade @@ -0,0 +1,5 @@ +html + body + ul#users + each record in records + li(class='user-' + record.id) #{record.name} diff --git a/node_modules/mysql2/test/unit/packets/test-ok-autoinc.js b/node_modules/mysql2/test/unit/packets/test-ok-autoinc.js new file mode 100644 index 0000000..74bbda5 --- /dev/null +++ b/node_modules/mysql2/test/unit/packets/test-ok-autoinc.js @@ -0,0 +1,9 @@ +var assert = require('assert'); +var packets = require('../../../lib/packets/index.js'); + +var packet = packets.OK.toPacket({affectedRows: 0, insertId: 1}); + +// 5 bytes for an OK packet, plus one byte to store affectedRows plus one byte to store the insertId +assert.equal( packet.length(), 7, + 'OK packets with 0 affectedRows and a minimal insertId should be '+ + '7 bytes long, got '+packet.length()+' byte(s)' ); diff --git a/node_modules/mysql2/ttt.js b/node_modules/mysql2/ttt.js new file mode 100644 index 0000000..fc1b3e2 --- /dev/null +++ b/node_modules/mysql2/ttt.js @@ -0,0 +1,17 @@ +var fs = require('fs'); +var mysql = require('./index.js'); +var conn = mysql.createConnection({ + user: 'root', + password: '', + database: 'test', + host: '127.0.0.1', + port: '3307', + debug: true, + compress: 1, + }); + +setTimeout(function() { +conn.query('select * from mil limit 1000', function(err, res) { + console.log(res); +}); +}, 10); diff --git a/node_modules/pg/.jshintrc b/node_modules/pg/.jshintrc new file mode 100644 index 0000000..c6c11ef --- /dev/null +++ b/node_modules/pg/.jshintrc @@ -0,0 +1,5 @@ +{ + "trailing": true, + "indent": 2, + "evil": true +} diff --git a/node_modules/pg/.npmignore b/node_modules/pg/.npmignore new file mode 100644 index 0000000..2bd9cb3 --- /dev/null +++ b/node_modules/pg/.npmignore @@ -0,0 +1,2 @@ +.lock-wscript +build/ diff --git a/node_modules/pg/.travis.yml b/node_modules/pg/.travis.yml new file mode 100644 index 0000000..98ec2cc --- /dev/null +++ b/node_modules/pg/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - "0.10" +before_script: + - node script/create-test-tables.js pg://postgres@127.0.0.1:5432/postgres diff --git a/node_modules/pg/Makefile b/node_modules/pg/Makefile new file mode 100644 index 0000000..ee973b6 --- /dev/null +++ b/node_modules/pg/Makefile @@ -0,0 +1,73 @@ +SHELL := /bin/sh + +connectionString=postgres:// + +params := $(connectionString) + +node-command := xargs -n 1 -I file node file $(params) + +.PHONY : test test-connection test-integration bench test-native \ + build/default/binding.node jshint upgrade-pg publish + +all: + npm install + +build: + node-gyp rebuild + +help: + @echo "make prepare-test-db [connectionString=postgres://]" + @echo "make test-all [connectionString=postgres://]" + +test: test-unit + +test-all: jshint test-unit test-integration test-native test-binary + +test-travis: test-all upgrade-pg + #@make test-all connectionString=postgres://postgres@localhost:5433/postgres + +upgrade-pg: + #@chmod 755 script/travis-pg-9.2-install.sh + #@./script/travis-pg-9.2-install.sh + +bench: + @find benchmark -name "*-bench.js" | $(node-command) + +build/default/binding.node: + @node-gyp rebuild + +test-unit: + @find test/unit -name "*-tests.js" | $(node-command) + +test-connection: + @echo "***Testing connection***" + @node script/test-connection.js $(params) + +test-connection-binary: + @echo "***Testing binary connection***" + @node script/test-connection.js $(params) binary + +test-native: build/default/binding.node + @echo "***Testing native bindings***" + @find test/native -name "*-tests.js" | $(node-command) + @find test/integration -name "*-tests.js" | $(node-command) native + +test-integration: test-connection build/default/binding.node + @echo "***Testing Pure Javascript***" + @find test/integration -name "*-tests.js" | $(node-command) + +test-binary: test-connection-binary + @echo "***Testing Pure Javascript (binary)***" + @find test/integration -name "*-tests.js" | $(node-command) binary + +prepare-test-db: + @echo "***Preparing the database for tests***" + @find script/create-test-tables.js | $(node-command) + +jshint: + @echo "***Starting jshint***" + @./node_modules/.bin/jshint lib + +publish: + @rm -r build || (exit 0) + @npm publish diff --git a/node_modules/pg/NEWS.md b/node_modules/pg/NEWS.md new file mode 100644 index 0000000..99885ab --- /dev/null +++ b/node_modules/pg/NEWS.md @@ -0,0 +1,149 @@ +All major and minor releases are briefly explained below. + +For richer information consult the commit log on github with referenced pull requests. + +We do not include break-fix version release in this file. + +### v3.6.0 +- Include support for (parsing JSONB)[https://github.com/brianc/node-pg-types/pull/13] (supported in postgres 9.4) + +### v3.5.0 +- Include support for parsing boolean arrays + +### v3.4.0 +- Include port as connection parameter to [unix sockets](https://github.com/brianc/node-postgres/pull/604) +- Better support for odd [date parsing](https://github.com/brianc/node-pg-types/pull/8) + +### v3.2.0 + +- Add support for parsing [date arrays](https://github.com/brianc/node-pg-types/pull/3) +- Expose array parsers on [pg.types](https://github.com/brianc/node-pg-types/pull/2) +- Allow [pool](https://github.com/brianc/node-postgres/pull/591) to be configured + + +### v3.1.0 + +- Add [count of the number of times a client has been checked out from the pool](https://github.com/brianc/node-postgres/pull/556) +- Emit `end` from `pg` object [when a pool is drained](https://github.com/brianc/node-postgres/pull/571) + +### v3.0.0 + +#### Breaking changes +- [Parse the DATE PostgreSQL type as local time](https://github.com/brianc/node-postgres/pull/514) + +After [some discussion](https://github.com/brianc/node-postgres/issues/510) it was decided node-postgres was non-compliant in how it was handling DATE results. They were being converted to UTC, but the PostgreSQL documentation specifies they should be returned in the client timezone. This is a breaking change, and if you use the `date` type you might want to examine your code and make sure nothing is impacted. + +- [Fix possible numeric precision loss on numeric & int8 arrays](https://github.com/brianc/node-postgres/pull/501) + +pg@v2.0 included changes to not convert large integers into their JavaScript number representation because of possibility for numeric precision loss. The same types in arrays were not taken into account. This fix applies the same type of type-coercion rules to arrays of those types, so there will be no more possible numeric loss on an array of very large int8s for example. This is a breaking change because now a return type from a query of `int8[]` will contain _string_ representations +of the integers. Use your favorite JavaScript bignum module to represent them without precision loss, or punch over the type converter to return the old style arrays again. + +- [Fix to input array of dates being improperly converted to utc](https://github.com/benesch/node-postgres/commit/c41eedc3e01e5527a3d5c242fa1896f02ef0b261#diff-7172adb1fec2457a2700ed29008a8e0aR108) + +Single `date` parameters were properly sent to the PostgreSQL server properly in local time, but an input array of dates was being changed into utc dates. This is a violation of what PostgreSQL expects. Small breaking change, but none-the-less something you should check out if you are inserting an array of dates. + +- [Query no longer emits `end` event if it ends due to an error](https://github.com/brianc/node-postgres/commit/357b64d70431ec5ca721eb45a63b082c18e6ffa3) + +This is a small change to bring the semantics of query more in line with other EventEmitters. The tests all passed after this change, but I suppose it could still be a breaking change in certain use cases. If you are doing clever things with the `end` and `error` events of a query object you might want to check to make sure its still behaving normally, though it is most likely not an issue. + +#### New features +- [Supercharge `prepareValue`](https://github.com/brianc/node-postgres/pull/555) + +The long & short of it is now any object you supply in the list of query values will be inspected for a `.toPostgres` method. If the method is present it will be called and its result used as the raw text value sent to PostgreSQL for that value. This allows the same type of custom type coercion on query parameters as was previously afforded to query result values. + +- [Domain aware connection pool](https://github.com/brianc/node-postgres/pull/531) + +If domains are active node-postgres will honor them and do everything it can to ensure all callbacks are properly fired in the active domain. If you have tried to use domains with node-postgres (or many other modules which pool long lived event emitters) you may have run into an issue where the active domain changes before and after a callback. This has been a longstanding footgun within node-postgres and I am happy to get it fixed. + +- [Disconnected clients now removed from pool](https://github.com/brianc/node-postgres/pull/543) + +Avoids a scenario where your pool could fill up with disconnected & unusable clients. + +- [Break type parsing code into separate module](https://github.com/brianc/node-postgres/pull/541) + +To provide better documentation and a clearer explanation of how to override the query result parsing system we broke the type converters [into their own module](https://github.com/brianc/node-pg-types). There is still work around removing the 'global-ness' of the type converters so each query or connection can return types differently, but this is a good first step and allow a lot more obvious way to return int8 results as JavaScript numbers, for example + +### v2.11.0 +- Add support for [application_name](https://github.com/brianc/node-postgres/pull/497) + +### v2.10.0 +- Add support for [the password file](http://www.postgresql.org/docs/9.3/static/libpq-pgpass.html) + +### v2.9.0 +- Add better support for [unix domain socket](https://github.com/brianc/node-postgres/pull/487) connections + +### v2.8.0 +- Add support for parsing JSON[] and UUID[] result types + +### v2.7.0 +- Use single row mode in native bindings when available [@rpedela] + - reduces memory consumption when handling row values in 'row' event +- Automatically bind buffer type parameters as binary [@eugeneware] + +### v2.6.0 +- Respect PGSSLMODE environment variable + +### v2.5.0 +- Ability to opt-in to int8 parsing via `pg.defaults.parseInt8 = true` + +### v2.4.0 +- Use eval in the result set parser to increase performance + +### v2.3.0 +- Remove built-in support for binary Int64 parsing. +_Due to the low usage & required compiled dependency this will be pushed into a 3rd party add-on_ + +### v2.2.0 +- [Add support for excapeLiteral and escapeIdentifier in both JavaScript and the native bindings](https://github.com/brianc/node-postgres/pull/396) + +### v2.1.0 +- Add support for SSL connections in JavaScript driver + - this means you can connect to heroku postgres from your local machine without the native bindings! +- [Add field metadata to result object](https://github.com/brianc/node-postgres/blob/master/test/integration/client/row-description-on-results-tests.js) +- [Add ability for rows to be returned as arrays instead of objects](https://github.com/brianc/node-postgres/blob/master/test/integration/client/results-as-array-tests.js) + +### v2.0.0 + +- Properly handle various PostgreSQL to JavaScript type conversions to avoid data loss: + +``` +PostgreSQL | pg@v2.0 JavaScript | pg@v1.0 JavaScript +--------------------------------|---------------- +float4 | number (float) | string +float8 | number (float) | string +int8 | string | number (int) +numeric | string | number (float) +decimal | string | number (float) +``` + +For more information see https://github.com/brianc/node-postgres/pull/353 +If you are unhappy with these changes you can always [override the built in type parsing fairly easily](https://github.com/brianc/node-pg-parse-float). + +### v1.3.0 + +- Make client_encoding configurable and optional + +### v1.2.0 + +- return field metadata on result object: access via result.fields[i].name/dataTypeID + +### v1.1.0 + +- built in support for `JSON` data type for PostgreSQL Server @ v9.2.0 or greater + +### v1.0.0 + +- remove deprecated functionality + - Callback function passed to `pg.connect` now __requires__ 3 arguments + - Client#pauseDrain() / Client#resumeDrain removed + - numeric, decimal, and float data types no longer parsed into float before being returned. Will be returned from query results as `String` + +### v0.15.0 + +- client now emits `end` when disconnected from back-end server +- if client is disconnected in the middle of a query, query receives an error + +### v0.14.0 + +- add deprecation warnings in prep for v1.0 +- fix read/write failures in native module under node v0.9.x diff --git a/node_modules/pg/README.md b/node_modules/pg/README.md new file mode 100644 index 0000000..f87d810 --- /dev/null +++ b/node_modules/pg/README.md @@ -0,0 +1,168 @@ +#node-postgres + +[![Build Status](https://secure.travis-ci.org/brianc/node-postgres.png?branch=master)](http://travis-ci.org/brianc/node-postgres) + +PostgreSQL client for node.js. Pure JavaScript and native libpq bindings. + +## Installation + + npm install pg + + +## Examples + +### Client pooling + +Generally you will access the PostgreSQL server through a pool of clients. A client takes a non-trivial amount of time to establish a new connection. A client also consumes a non-trivial amount of resources on the PostgreSQL server - not something you want to do on every http request. Good news: node-postgres ships with built in client pooling. + +```javascript +var pg = require('pg'); +var conString = "postgres://username:password@localhost/database"; + +pg.connect(conString, function(err, client, done) { + if(err) { + return console.error('error fetching client from pool', err); + } + client.query('SELECT $1::int AS number', ['1'], function(err, result) { + //call `done()` to release the client back to the pool + done(); + + if(err) { + return console.error('error running query', err); + } + console.log(result.rows[0].number); + //output: 1 + }); +}); + +``` + +[Check this out for the get up and running quickly example](https://github.com/brianc/node-postgres/wiki/Example) + +### Simple + +Sometimes you may not want to use a pool of connections. You can easily connect a single client to a postgres instance, run a query, and disconnect. + +```javascript +var pg = require('pg'); +//or native libpq bindings +//var pg = require('pg').native + +var conString = "postgres://username:password@localhost/database"; + +var client = new pg.Client(conString); +client.connect(function(err) { + if(err) { + return console.error('could not connect to postgres', err); + } + client.query('SELECT NOW() AS "theTime"', function(err, result) { + if(err) { + return console.error('error running query', err); + } + console.log(result.rows[0].theTime); + //output: Tue Jan 15 2013 19:12:47 GMT-600 (CST) + client.end(); + }); +}); + +``` + +## [Documentation](https://github.com/brianc/node-postgres/wiki) + +## Native Bindings + +node-postgres contains a pure JavaScript driver and also exposes JavaScript bindings via libpq. You can use either interface. I personally use the JavaScript bindings as they are quite fast, and I like having everything implemented in JavaScript. + +To use native libpq bindings replace `require('pg')` with `require('pg').native`. If you __do not__ need or want the native bindings at all, consider using [node-postgres-pure](https://github.com/brianc/node-postgres-pure) instead which does not include them. + +The two share the same interface so __no other code changes should be required__. If you find yourself having to change code other than the require statement when switching from `pg` to `pg.native` or `pg.js`, please report an issue. + +## Features + +* pure JavaScript client and native libpq bindings share _the same api_ +* optional connection pooling +* extensible js<->postgresql data-type coercion +* supported PostgreSQL features + * parameterized queries + * named statements with query plan caching + * async notifications with `LISTEN/NOTIFY` + * bulk import & export with `COPY TO/COPY FROM` + +## Contributing + +__I love contributions.__ + +You are welcome contribute via pull requests. If you need help getting the tests running locally feel free to email me or gchat me. + +I will __happily__ accept your pull request if it: +- _)has tests__ +- looks reasonable +- does not break backwards compatibility +- satisfies jshint + +Information about the testing processes is in the [wiki](https://github.com/brianc/node-postgres/wiki/Testing). + +If you need help or have questions about constructing a pull request I'll be glad to help out as well. + +## Support + +If at all possible when you open an issue please provide +- version of node +- version of postgres +- smallest possible snippet of code to reproduce the problem + +Usually I'll pop the code into the repo as a test. Hopefully the test fails. Then I make the test pass. Then everyone's happy! + + +If you need help or run into _any_ issues getting node-postgres to work on your system please report a bug or contact me directly. I am usually available via google-talk at my github account public email address. + +I usually tweet about any important status updates or changes to node-postgres. +Follow me [@briancarlson](https://twitter.com/briancarlson) to keep up to date. + + +## Extras + +node-postgres is by design _low level_ with the bare minimum of abstraction. These might help out: + +- [brianc/node-pg-native](https://github.com/brianc/node-pg-native) - Simple interface abstraction on top of [libpq](https://github.com/brianc/node-libpq) +- [brianc/node-pg-query-stream](https://github.com/brianc/node-pg-query-stream) - Query results from node-postgres as a readable (object) stream +- [brianc/node-pg-cursor](https://github.com/brianc/node-pg-cursor) - Query cursor extension for node-postgres +- [brianc/node-pg-copy-streams](https://github.com/brianc/node-pg-copy-streams) - COPY FROM / COPY TO for node-postgres. Stream from one database to another, and stuff. +- [brianc/node-postgres-pure](https://github.com/brianc/node-postgres-pure) - node-postgres without any of the C/C++ stuff +- [brianc/node-pg-types](https://github.com/brianc/node-pg-types) - Type parsing for node-postgres +- [Suor/pg-bricks](https://github.com/Suor/pg-bricks) - A higher level wrapper around node-postgres to handle connection settings, sql generation, transactions and ease data access. +- [grncdr/node-any-db](https://github.com/grncdr/node-any-db) - Thin and less-opinionated database abstraction layer for node. +- [brianc/node-sql](https://github.com/brianc/node-sql) - SQL generation for node.js +- [hiddentao/suqel](https://hiddentao.github.io/squel/) - SQL query string builder for Javascript +- [CSNW/sql-bricks](https://github.com/CSNW/sql-bricks) - Transparent, Schemaless SQL Generation + + +### Windows + + 1. Install Visual Studio C++ (successfully built with Express 2010). Express is free. + 2. Add your Postgre Installation's `bin` folder to the system path (i.e. `C:\Program Files\PostgreSQL\9.3\bin`). + 3. Make sure that both `libpq.dll` and `pg_config.exe` are in that folder. + 4. `npm install pg` + + +## License + +Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/node_modules/pg/benchmark/4e822a1.txt b/node_modules/pg/benchmark/4e822a1.txt new file mode 100644 index 0000000..ce94b25 --- /dev/null +++ b/node_modules/pg/benchmark/4e822a1.txt @@ -0,0 +1,17 @@ +benchmark +starting simple-query-parsing +4166 ops/sec - (100/0.024) +8333 ops/sec - (1000/0.12) +10405 ops/sec - (10000/0.961) +10515 ops/sec - (10000/0.951) +10638 ops/sec - (10000/0.94) +10460 ops/sec - (10000/0.956) +starting prepared-statement-parsing +4166 ops/sec - (100/0.024) +8264 ops/sec - (1000/0.121) +7530 ops/sec - (10000/1.328) +8250 ops/sec - (10000/1.212) +8156 ops/sec - (10000/1.226) +8110 ops/sec - (10000/1.233) +done + diff --git a/node_modules/pg/benchmark/835f71a76f.txt b/node_modules/pg/benchmark/835f71a76f.txt new file mode 100644 index 0000000..8d35cd4 --- /dev/null +++ b/node_modules/pg/benchmark/835f71a76f.txt @@ -0,0 +1,17 @@ +benchmark +starting simple-query-parsing +3703 ops/sec - (100/0.027) +7299 ops/sec - (1000/0.137) +8888 ops/sec - (10000/1.125) +8733 ops/sec - (10000/1.145) +8810 ops/sec - (10000/1.135) +8771 ops/sec - (10000/1.14) +starting prepared-statement-parsing +3846 ops/sec - (100/0.026) +7299 ops/sec - (1000/0.137) +7225 ops/sec - (10000/1.384) +7288 ops/sec - (10000/1.372) +7225 ops/sec - (10000/1.384) +7457 ops/sec - (10000/1.341) +done + diff --git a/node_modules/pg/benchmark/df766c913.txt b/node_modules/pg/benchmark/df766c913.txt new file mode 100644 index 0000000..80f2674 --- /dev/null +++ b/node_modules/pg/benchmark/df766c913.txt @@ -0,0 +1,17 @@ +benchmark +starting simple-query-parsing +3571 ops/sec - (100/0.028) +7299 ops/sec - (1000/0.137) +8873 ops/sec - (10000/1.127) +8536 ops/sec - (40000/4.686) +8494 ops/sec - (40000/4.709) +7695 ops/sec - (40000/5.198) +starting prepared-statement-parsing +4000 ops/sec - (100/0.025) +6944 ops/sec - (1000/0.144) +7153 ops/sec - (10000/1.398) +7127 ops/sec - (40000/5.612) +7208 ops/sec - (40000/5.549) +6460 ops/sec - (40000/6.191) +done + diff --git a/node_modules/pg/benchmark/index.js b/node_modules/pg/benchmark/index.js new file mode 100644 index 0000000..a07fe45 --- /dev/null +++ b/node_modules/pg/benchmark/index.js @@ -0,0 +1,42 @@ +var async = require('async'); +var max = 10000; +var maxTimes = 3; +var doLoops = function(bench, loops, times, cb) { + var start = new Date(); + var count = 0; + + var done = function() { + var duration = (new Date() - start) + var seconds = (duration / 1000); + console.log("%d ops/sec - (%d/%d)", ~~(loops/seconds), loops, seconds); + var next = loops * 10; + if(next > max) { + if(times > maxTimes) return cb(); + times++; + next = max; + } + setTimeout(function() { + doLoops(bench, next, times, cb); + }, 100); + } + + var run = function() { + if(count++ >= loops){ + return done(); + } + bench(function() { + setImmediate(run); + }); + } + run(); +} +var bench = require(__dirname + '/simple-query-parsing'); +console.log(); +var benches = ['simple-query-parsing', 'prepared-statement-parsing']; +async.forEachSeries(benches, function(name, cb) { + var bench = require(__dirname + '/' + name)(); + console.log('starting ', name); + doLoops(bench, 100, 1, cb); +}, function(err, res) { + console.log('done') +}) diff --git a/node_modules/pg/benchmark/prepare-values.js b/node_modules/pg/benchmark/prepare-values.js new file mode 100644 index 0000000..49e973e --- /dev/null +++ b/node_modules/pg/benchmark/prepare-values.js @@ -0,0 +1,46 @@ +var utils = require("../lib/utils"); + +var numArr = []; +for (var i = 0; i < 1000; i++) numArr[i] = i; +console.time("prepare-number-array"); +for (var i = 0; i < 100; i++) { + utils.prepareValue(numArr); +} +console.timeEnd("prepare-number-array"); + + +var strArr = new Array(10000); +console.time("prepare-string-array"); +for (var i = 0; i < 100; i++) { + utils.prepareValue(strArr); +} +console.timeEnd("prepare-string-array"); + + +var objArr = []; +for (var i = 0; i < 1000; i++) objArr[i] = { x: { y: 42 }}; +console.time("prepare-object-array"); +for (var i = 0; i < 100; i++) { + utils.prepareValue(objArr); +} +console.timeEnd("prepare-object-array"); + + +var obj = { x: { y: 42 }}; +console.time("prepare-object"); +for (var i = 0; i < 100000; i++) { + utils.prepareValue(obj); +} +console.timeEnd("prepare-object"); + + +var customType = { + toPostgres: function () { + return { toPostgres: function () { return new Date(); } }; + } +}; +console.time("prepare-custom-type"); +for (var i = 0; i < 100000; i++) { + utils.prepareValue(customType); +} +console.timeEnd("prepare-custom-type"); diff --git a/node_modules/pg/benchmark/prepared-statement-parsing.js b/node_modules/pg/benchmark/prepared-statement-parsing.js new file mode 100644 index 0000000..d869d5c --- /dev/null +++ b/node_modules/pg/benchmark/prepared-statement-parsing.js @@ -0,0 +1,73 @@ +var Client = require(__dirname + '/../lib/client'); +var buffers = require(__dirname + '/../test/test-buffers'); +require(__dirname + '/../test/unit/test-helper'); + +var stream = new MemoryStream(); +stream.readyState = 'open'; +var client = new Client({ + stream: stream +}); + +var rowDescription = new buffers.rowDescription([{ + name: 'id', + tableID: 1, + attributeNumber: 1, + dataTypeID: 23, //int4 + typeModifer: 0, + formatCode: 0 +},{ + name: 'name', + tableID: 1, + attributeNumber: 2, + dataTypeID: 25, //text + typeModifer: 0, + formatCode: 0 //text format +}, { + name: 'comment', + tableID: 1, + attributeNumber: 3, + dataTypeID: 25, //text + typeModifer: 0, + formatCode: 0 //text format +}]); +var row1 = buffers.dataRow(['1', 'Brian', 'Something groovy']); +var row2 = buffers.dataRow(['2', 'Bob', 'Testint test']); +var row3 = buffers.dataRow(['3', 'The amazing power of the everlasting gobstopper', 'okay now']); +var parseCompleteBuffer = buffers.parseComplete(); +var bindCompleteBuffer = buffers.bindComplete(); +var portalSuspendedBuffer = buffers.portalSuspended(); +var complete = buffers.commandComplete('SELECT 3'); +var ready = buffers.readyForQuery(); +var buffer = Buffer.concat([parseCompleteBuffer, + bindCompleteBuffer, + rowDescription, + row1, + row2, + row3, + portalSuspendedBuffer, + row1, + row2, + row3, + portalSuspendedBuffer, + row1, + row2, + row3, + portalSuspendedBuffer, + complete, ready]); + +var bufferSlice = require('buffer-slice'); +var buffers = bufferSlice(10, buffer); + +client.connect(assert.calls(function() { + client.connection.emit('readyForQuery'); + module.exports = function() { + return function(done) { + client.query('SELECT * FROM whatever WHERE this = "doesnt even matter"', ['whatever'], function(err, res) { + assert.equal(res.rows.length, 9); + done(); + }); + buffers.forEach(stream.emit.bind(stream, 'data')); + }; + }; +})); +client.connection.emit('readyForQuery'); diff --git a/node_modules/pg/benchmark/simple-query-parsing.js b/node_modules/pg/benchmark/simple-query-parsing.js new file mode 100644 index 0000000..fb4895d --- /dev/null +++ b/node_modules/pg/benchmark/simple-query-parsing.js @@ -0,0 +1,59 @@ +var Client = require(__dirname + '/../lib/client'); +var buffers = require(__dirname + '/../test/test-buffers'); +require(__dirname + '/../test/unit/test-helper'); + +var stream = new MemoryStream(); +stream.readyState = 'open'; +var client = new Client({ + stream: stream +}); + +var rowDescription = new buffers.rowDescription([{ + name: 'id', + tableID: 1, + attributeNumber: 1, + dataTypeID: 23, //int4 + typeModifer: 0, + formatCode: 0 +},{ + name: 'name', + tableID: 1, + attributeNumber: 2, + dataTypeID: 25, //text + typeModifer: 0, + formatCode: 0 //text format +}, { + name: 'comment', + tableID: 1, + attributeNumber: 3, + dataTypeID: 25, //text + typeModifer: 0, + formatCode: 0 //text format +}]); +var row1 = buffers.dataRow(['1', 'Brian', 'Something groovy']); +var row2 = buffers.dataRow(['2', 'Bob', 'Testint test']); +var row3 = buffers.dataRow(['3', 'The amazing power of the everlasting gobstopper', 'okay now']); +var complete = buffers.commandComplete('SELECT 3'); +var ready = buffers.readyForQuery(); +var buffer = Buffer.concat([ + rowDescription, + row1, row2, row3, + row1, row2, row3, + row1, row2, row3, + complete, ready]); +var bufferSlice = require('buffer-slice'); +buffers = bufferSlice(10, buffer); + +client.connect(assert.calls(function() { + client.connection.emit('readyForQuery'); + module.exports = function() { + return function(done) { + client.query('SELECT * FROM whatever WHERE this = "doesnt even matter"', function(err, res) { + assert.equal(res.rows.length, 9); + done(); + }); + buffers.forEach(stream.emit.bind(stream, 'data')); + }; + }; +})); +client.connection.emit('readyForQuery'); diff --git a/node_modules/pg/binding.gyp b/node_modules/pg/binding.gyp new file mode 100644 index 0000000..bdc9dfd --- /dev/null +++ b/node_modules/pg/binding.gyp @@ -0,0 +1,38 @@ +{ + 'targets': [ + { + 'target_name': 'binding', + 'sources': ['src/binding.cc'], + 'include_dirs': [ + ' 0; +}; + + +//associates row metadata from the supplied +//message with this query object +//metadata used when parsing row results +Query.prototype.handleRowDescription = function(msg) { + this._result.addFields(msg.fields); +}; + +Query.prototype.handleDataRow = function(msg) { + var row = this._result.parseRow(msg.fields); + this.emit('row', row, this._result); + + //if there is a callback collect rows + if(this.callback) { + this._result.addRow(row); + } +}; + +Query.prototype.handleCommandComplete = function(msg, con) { + this._result.addCommandComplete(msg); + //need to sync after each command complete of a prepared statement + if(this.isPreparedStatement) { + con.sync(); + } +}; + +Query.prototype.handleReadyForQuery = function() { + if(this._canceledDueToError) { + return this.handleError(this._canceledDueToError); + } + if(this.callback) { + this.callback(null, this._result); + } + this.emit('end', this._result); +}; + +Query.prototype.handleError = function(err, connection) { + //need to sync after error during a prepared statement + if(this.isPreparedStatement) { + connection.sync(); + } + if(this._canceledDueToError) { + err = this._canceledDueToError; + this._canceledDueToError = false; + } + //if callback supplied do not emit error event as uncaught error + //events will bubble up to node process + if(this.callback) { + return this.callback(err); + } + this.emit('error', err); +}; + +Query.prototype.submit = function(connection) { + if(this.requiresPreparation()) { + this.prepare(connection); + } else { + connection.query(this.text); + } +}; + +Query.prototype.hasBeenParsed = function(connection) { + return this.name && connection.parsedStatements[this.name]; +}; + +Query.prototype.handlePortalSuspended = function(connection) { + this._getRows(connection, this.rows); +}; + +Query.prototype._getRows = function(connection, rows) { + connection.execute({ + portal: this.portalName, + rows: rows + }, true); + connection.flush(); +}; + +Query.prototype.prepare = function(connection) { + var self = this; + //prepared statements need sync to be called after each command + //complete or when an error is encountered + this.isPreparedStatement = true; + //TODO refactor this poor encapsulation + if(!this.hasBeenParsed(connection)) { + connection.parse({ + text: self.text, + name: self.name, + types: self.types + }, true); + } + + //TODO is there some better way to prepare values for the database? + if(self.values) { + for(var i = 0, len = self.values.length; i < len; i++) { + self.values[i] = utils.prepareValue(self.values[i]); + } + } + + //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY + connection.bind({ + portal: self.portalName, + statement: self.name, + values: self.values, + binary: self.binary + }, true); + + connection.describe({ + type: 'P', + name: self.portalName || "" + }, true); + + this._getRows(connection, this.rows); +}; + +Query.prototype.handleCopyInResponse = function (connection) { + if(this.stream) this.stream.startStreamingToConnection(connection); + else connection.sendCopyFail('No source stream defined'); +}; + +Query.prototype.handleCopyData = function (msg, connection) { + var chunk = msg.chunk; + if(this.stream) { + this.stream.handleChunk(chunk); + } + //if there are no stream (for example when copy to query was sent by + //query method instead of copyTo) error will be handled + //on copyOutResponse event, so silently ignore this error here +}; +module.exports = Query; diff --git a/node_modules/pg/lib/result.js b/node_modules/pg/lib/result.js new file mode 100644 index 0000000..ae99255 --- /dev/null +++ b/node_modules/pg/lib/result.js @@ -0,0 +1,102 @@ +var types = require('pg-types'); + +//result object returned from query +//in the 'end' event and also +//passed as second argument to provided callback +var Result = function(rowMode) { + this.command = null; + this.rowCount = null; + this.oid = null; + this.rows = []; + this.fields = []; + this._parsers = []; + this.RowCtor = null; + this.rowAsArray = rowMode == "array"; + if(this.rowAsArray) { + this.parseRow = this._parseRowAsArray; + } +}; + +var matchRegexp = /([A-Za-z]+) ?(\d+ )?(\d+)?/; + +//adds a command complete message +Result.prototype.addCommandComplete = function(msg) { + var match; + if(msg.text) { + //pure javascript + match = matchRegexp.exec(msg.text); + } else { + //native bindings + match = matchRegexp.exec(msg.command); + } + if(match) { + this.command = match[1]; + //match 3 will only be existing on insert commands + if(match[3]) { + //msg.value is from native bindings + this.rowCount = parseInt(match[3] || msg.value, 10); + this.oid = parseInt(match[2], 10); + } else { + this.rowCount = parseInt(match[2], 10); + } + } +}; + +Result.prototype._parseRowAsArray = function(rowData) { + var row = []; + for(var i = 0, len = rowData.length; i < len; i++) { + var rawValue = rowData[i]; + if(rawValue !== null) { + row.push(this._parsers[i](rawValue)); + } else { + row.push(null); + } + } + return row; +}; + +//rowData is an array of text or binary values +//this turns the row into a JavaScript object +Result.prototype.parseRow = function(rowData) { + return new this.RowCtor(this._parsers, rowData); +}; + +Result.prototype.addRow = function(row) { + this.rows.push(row); +}; + +var inlineParser = function(fieldName, i) { + return "\nthis['" + + //fields containing single quotes will break + //the evaluated javascript unless they are escaped + //see https://github.com/brianc/node-postgres/issues/507 + fieldName.replace("'", "\\'") + + "'] = " + + "rowData[" + i + "] == null ? null : parsers[" + i + "](rowData[" + i + "]);"; +}; + +Result.prototype.addFields = function(fieldDescriptions) { + //clears field definitions + //multiple query statements in 1 action can result in multiple sets + //of rowDescriptions...eg: 'select NOW(); select 1::int;' + //you need to reset the fields + if(this.fields.length) { + this.fields = []; + this._parsers = []; + } + var ctorBody = ""; + for(var i = 0; i < fieldDescriptions.length; i++) { + var desc = fieldDescriptions[i]; + this.fields.push(desc); + var parser = types.getTypeParser(desc.dataTypeID, desc.format || 'text'); + this._parsers.push(parser); + //this is some craziness to compile the row result parsing + //results in ~60% speedup on large query result sets + ctorBody += inlineParser(desc.name, i); + } + if(!this.rowAsArray) { + this.RowCtor = Function("parsers", "rowData", ctorBody); + } +}; + +module.exports = Result; diff --git a/node_modules/pg/lib/utils.js b/node_modules/pg/lib/utils.js new file mode 100644 index 0000000..e28c26a --- /dev/null +++ b/node_modules/pg/lib/utils.js @@ -0,0 +1,108 @@ + +// convert a JS array to a postgres array literal +// uses comma separator so won't work for types like box that use +// a different array separator. +function arrayString(val) { + var result = '{'; + for (var i = 0 ; i < val.length; i++) { + if(i > 0) { + result = result + ','; + } + if(val[i] === null || typeof val[i] === 'undefined') { + result = result + 'NULL'; + } + else if(Array.isArray(val[i])) { + result = result + arrayString(val[i]); + } + else + { + result = result + JSON.stringify(prepareValue(val[i])); + } + } + result = result + '}'; + return result; +} + +//converts values from javascript types +//to their 'raw' counterparts for use as a postgres parameter +//note: you can override this function to provide your own conversion mechanism +//for complex types, etc... +var prepareValue = function(val, seen) { + if (val instanceof Buffer) { + return val; + } + if(val instanceof Date) { + return dateToString(val); + } + if(Array.isArray(val)) { + return arrayString(val); + } + if(val === null || typeof val === 'undefined') { + return null; + } + if(typeof val === 'object') { + return prepareObject(val, seen); + } + return val.toString(); +}; + +function prepareObject(val, seen) { + if(val.toPostgres && typeof val.toPostgres === 'function') { + seen = seen || []; + if (seen.indexOf(val) !== -1) { + throw new Error('circular reference detected while preparing "' + val + '" for query'); + } + seen.push(val); + + return prepareValue(val.toPostgres(prepareValue), seen); + } + return JSON.stringify(val); +} + +function dateToString(date) { + function pad(number, digits) { + number = ""+number; + while(number.length < digits) + number = "0"+number; + return number; + } + + var offset = -date.getTimezoneOffset(); + var ret = pad(date.getFullYear(), 4) + '-' + + pad(date.getMonth() + 1, 2) + '-' + + pad(date.getDate(), 2) + 'T' + + pad(date.getHours(), 2) + ':' + + pad(date.getMinutes(), 2) + ':' + + pad(date.getSeconds(), 2) + '.' + + pad(date.getMilliseconds(), 3); + + if(offset < 0) { + ret += "-"; + offset *= -1; + } + else + ret += "+"; + + return ret + pad(Math.floor(offset/60), 2) + ":" + pad(offset%60, 2); +} + +function normalizeQueryConfig (config, values, callback) { + //can take in strings or config objects + config = (typeof(config) == 'string') ? { text: config } : config; + if(values) { + if(typeof values === 'function') { + config.callback = values; + } else { + config.values = values; + } + } + if(callback) { + config.callback = callback; + } + return config; +} + +module.exports = { + prepareValue: prepareValue, + normalizeQueryConfig: normalizeQueryConfig +}; diff --git a/node_modules/pg/node_modules/bindings/README.md b/node_modules/pg/node_modules/bindings/README.md new file mode 100644 index 0000000..585cf51 --- /dev/null +++ b/node_modules/pg/node_modules/bindings/README.md @@ -0,0 +1,97 @@ +node-bindings +============= +### Helper module for loading your native module's .node file + +This is a helper module for authors of Node.js native addon modules. +It is basically the "swiss army knife" of `require()`ing your native module's +`.node` file. + +Throughout the course of Node's native addon history, addons have ended up being +compiled in a variety of different places, depending on which build tool and which +version of node was used. To make matters worse, now the _gyp_ build tool can +produce either a _Release_ or _Debug_ build, each being built into different +locations. + +This module checks _all_ the possible locations that a native addon would be built +at, and returns the first one that loads successfully. + + +Installation +------------ + +Install with `npm`: + +``` bash +$ npm install bindings +``` + +Or add it to the `"dependencies"` section of your _package.json_ file. + + +Example +------- + +`require()`ing the proper bindings file for the current node version, platform +and architecture is as simple as: + +``` js +var bindings = require('bindings')('binding.node') + +// Use your bindings defined in your C files +bindings.your_c_function() +``` + + +Nice Error Output +----------------- + +When the `.node` file could not be loaded, `node-bindings` throws an Error with +a nice error message telling you exactly what was tried. You can also check the +`err.tries` Array property. + +``` +Error: Could not load the bindings file. Tried: + → /Users/nrajlich/ref/build/binding.node + → /Users/nrajlich/ref/build/Debug/binding.node + → /Users/nrajlich/ref/build/Release/binding.node + → /Users/nrajlich/ref/out/Debug/binding.node + → /Users/nrajlich/ref/Debug/binding.node + → /Users/nrajlich/ref/out/Release/binding.node + → /Users/nrajlich/ref/Release/binding.node + → /Users/nrajlich/ref/build/default/binding.node + → /Users/nrajlich/ref/compiled/0.8.2/darwin/x64/binding.node + at bindings (/Users/nrajlich/ref/node_modules/bindings/bindings.js:84:13) + at Object. (/Users/nrajlich/ref/lib/ref.js:5:47) + at Module._compile (module.js:449:26) + at Object.Module._extensions..js (module.js:467:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + ... +``` + + +License +------- + +(The MIT License) + +Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pg/node_modules/bindings/bindings.js b/node_modules/pg/node_modules/bindings/bindings.js new file mode 100644 index 0000000..93dcf85 --- /dev/null +++ b/node_modules/pg/node_modules/bindings/bindings.js @@ -0,0 +1,166 @@ + +/** + * Module dependencies. + */ + +var fs = require('fs') + , path = require('path') + , join = path.join + , dirname = path.dirname + , exists = fs.existsSync || path.existsSync + , defaults = { + arrow: process.env.NODE_BINDINGS_ARROW || ' → ' + , compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled' + , platform: process.platform + , arch: process.arch + , version: process.versions.node + , bindings: 'bindings.node' + , try: [ + // node-gyp's linked version in the "build" dir + [ 'module_root', 'build', 'bindings' ] + // node-waf and gyp_addon (a.k.a node-gyp) + , [ 'module_root', 'build', 'Debug', 'bindings' ] + , [ 'module_root', 'build', 'Release', 'bindings' ] + // Debug files, for development (legacy behavior, remove for node v0.9) + , [ 'module_root', 'out', 'Debug', 'bindings' ] + , [ 'module_root', 'Debug', 'bindings' ] + // Release files, but manually compiled (legacy behavior, remove for node v0.9) + , [ 'module_root', 'out', 'Release', 'bindings' ] + , [ 'module_root', 'Release', 'bindings' ] + // Legacy from node-waf, node <= 0.4.x + , [ 'module_root', 'build', 'default', 'bindings' ] + // Production "Release" buildtype binary (meh...) + , [ 'module_root', 'compiled', 'version', 'platform', 'arch', 'bindings' ] + ] + } + +/** + * The main `bindings()` function loads the compiled bindings for a given module. + * It uses V8's Error API to determine the parent filename that this function is + * being invoked from, which is then used to find the root directory. + */ + +function bindings (opts) { + + // Argument surgery + if (typeof opts == 'string') { + opts = { bindings: opts } + } else if (!opts) { + opts = {} + } + opts.__proto__ = defaults + + // Get the module root + if (!opts.module_root) { + opts.module_root = exports.getRoot(exports.getFileName()) + } + + // Ensure the given bindings name ends with .node + if (path.extname(opts.bindings) != '.node') { + opts.bindings += '.node' + } + + var tries = [] + , i = 0 + , l = opts.try.length + , n + , b + , err + + for (; i 0; +}); + +if(process.argv[2]) { + scripts = [process.argv[2]] +} + + +var run = function() { + async.map(versions, clone, function(err, results) { + if(err) throw err; + exports.compare = { }; + var suites = []; + scripts.forEach(function(script) { + for(var i = 0; i < results.length; i++) { + var result = results[i]; + var benchPath = path.join(result.dir, 'benchmark', script); + var suite = {}; + suites.push(suite); + if(fs.existsSync(benchPath)) { + var bench = require(benchPath); + suite[script + '@' + result.rev] = bench; + } else { + console.log('%s missing at revision %s', benchPath, result.rev); + } + } + suite[script + '@HEAD'] = require(__dirname + '/' + script); + }); + var compare = function(suite, cb) { + console.log('running...') + bench.compare(suite, null, null, null, function(err, data) { + if(err) return cb(err); + bench.show(data); + cb(null); + }); + } + async.eachSeries(suites, compare, function(err, res) { + console.log('all suites done') + }) + }); +}; + +run(); diff --git a/node_modules/pg/node_modules/buffer-writer/benchmark/int-16-benchmark.js b/node_modules/pg/node_modules/buffer-writer/benchmark/int-16-benchmark.js new file mode 100644 index 0000000..4a4e676 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/benchmark/int-16-benchmark.js @@ -0,0 +1,31 @@ +var Writer = require(__dirname + '/../'); + +module.exports = function() { + var writer = new Writer(); + writer.addInt16(-100000000); + writer.addInt16(-1000); + writer.addInt16(-1); + writer.addInt16(0); + writer.addInt16(1); + writer.addInt16(1000); + writer.addInt16(1000000000); + writer.addInt16(-100000000); + writer.addInt16(-100000000); + writer.addInt16(-1000); + writer.addInt16(-1); + writer.addInt16(0); + writer.addInt16(1); + writer.addInt16(1000); + writer.addInt16(1000000000); + writer.addInt16(-1000); + writer.addInt16(-1); + writer.addInt16(0); + writer.addInt16(1); + writer.addInt16(1000); + writer.addInt16(1000000000); +}; + +if(!module.parent) { + module.exports(); + console.log('benchmark ok'); +} diff --git a/node_modules/pg/node_modules/buffer-writer/benchmark/int-32-benchmark.js b/node_modules/pg/node_modules/buffer-writer/benchmark/int-32-benchmark.js new file mode 100644 index 0000000..bff4ace --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/benchmark/int-32-benchmark.js @@ -0,0 +1,17 @@ +var Writer = require(__dirname + '/../'); + +module.exports = function() { + var writer = new Writer(); + writer.addInt32(-10000000000000); + writer.addInt32(-1000); + writer.addInt32(-1); + writer.addInt32(0); + writer.addInt32(1); + writer.addInt32(1000); + writer.addInt32(10000000000000); +}; + +if(!module.parent) { + module.exports(); + console.log('benchmark ok'); +} diff --git a/node_modules/pg/node_modules/buffer-writer/benchmark/join-benchmark.js b/node_modules/pg/node_modules/buffer-writer/benchmark/join-benchmark.js new file mode 100644 index 0000000..49e4238 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/benchmark/join-benchmark.js @@ -0,0 +1,16 @@ +var Writer = require(__dirname + '/../'); + +var writer = new Writer(); +writer.addCString('hello'); +writer.addCString('something else, really'); +writer.addInt32(38013); +writer.addCString('and that\'s all she wrote, folks\n...\n...not really'); + +module.exports = function() { + writer.join(0x50); +}; + +if(!module.parent) { + module.exports(); + console.log('benchmark ok'); +} diff --git a/node_modules/pg/node_modules/buffer-writer/benchmark/resize-benchmark.js b/node_modules/pg/node_modules/buffer-writer/benchmark/resize-benchmark.js new file mode 100644 index 0000000..3845566 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/benchmark/resize-benchmark.js @@ -0,0 +1,23 @@ +var Writer = require(__dirname + '/../'); + +var string = ""; +for(var i = 0; i < 10; i++) { + string += 'Once upon a time long ago there lived a little programming language named JavaScript'; +} + +module.exports = function() { + var writer = new Writer(4); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); + writer.addCString(string); +}; + +if(!module.parent) { + module.exports(); + console.log('benchmark ok'); +} diff --git a/node_modules/pg/node_modules/buffer-writer/benchmark/small-benchmark.js b/node_modules/pg/node_modules/buffer-writer/benchmark/small-benchmark.js new file mode 100644 index 0000000..1c129f3 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/benchmark/small-benchmark.js @@ -0,0 +1,14 @@ +var Writer = require(__dirname + '/../'); + +module.exports = function() { + var writer = new Writer(); + writer.addInt32(10); + writer.addInt16(5); + writer.addCString('test'); + writer.flush('X'); +}; + +if(!module.parent) { + module.exports(); + console.log('benchmark ok'); +} diff --git a/node_modules/pg/node_modules/buffer-writer/index.js b/node_modules/pg/node_modules/buffer-writer/index.js new file mode 100644 index 0000000..23ad167 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/index.js @@ -0,0 +1,126 @@ +//binary data writer tuned for creating +//postgres message packets as effeciently as possible by reusing the +//same buffer to avoid memcpy and limit memory allocations +var Writer = module.exports = function(size) { + this.size = size || 1024; + this.buffer = Buffer(this.size + 5); + this.offset = 5; + this.headerPosition = 0; +}; + +//resizes internal buffer if not enough size left +Writer.prototype._ensure = function(size) { + var remaining = this.buffer.length - this.offset; + if(remaining < size) { + var oldBuffer = this.buffer; + this.buffer = new Buffer(oldBuffer.length + size); + oldBuffer.copy(this.buffer); + } +}; + +Writer.prototype.addInt32 = function(num) { + this._ensure(4); + this.buffer[this.offset++] = (num >>> 24 & 0xFF); + this.buffer[this.offset++] = (num >>> 16 & 0xFF); + this.buffer[this.offset++] = (num >>> 8 & 0xFF); + this.buffer[this.offset++] = (num >>> 0 & 0xFF); + return this; +}; + +Writer.prototype.addInt16 = function(num) { + this._ensure(2); + this.buffer[this.offset++] = (num >>> 8 & 0xFF); + this.buffer[this.offset++] = (num >>> 0 & 0xFF); + return this; +}; + +//for versions of node requiring 'length' as 3rd argument to buffer.write +var writeString = function(buffer, string, offset, len) { + buffer.write(string, offset, len); +}; + +//overwrite function for older versions of node +if(Buffer.prototype.write.length === 3) { + writeString = function(buffer, string, offset, len) { + buffer.write(string, offset); + }; +} + +Writer.prototype.addCString = function(string) { + //just write a 0 for empty or null strings + if(!string) { + this._ensure(1); + } else { + var len = Buffer.byteLength(string); + this._ensure(len + 1); //+1 for null terminator + writeString(this.buffer, string, this.offset, len); + this.offset += len; + } + + this.buffer[this.offset++] = 0; // null terminator + return this; +}; + +Writer.prototype.addChar = function(c) { + this._ensure(1); + writeString(this.buffer, c, this.offset, 1); + this.offset++; + return this; +}; + +Writer.prototype.addString = function(string) { + string = string || ""; + var len = Buffer.byteLength(string); + this._ensure(len); + this.buffer.write(string, this.offset); + this.offset += len; + return this; +}; + +Writer.prototype.getByteLength = function() { + return this.offset - 5; +}; + +Writer.prototype.add = function(otherBuffer) { + this._ensure(otherBuffer.length); + otherBuffer.copy(this.buffer, this.offset); + this.offset += otherBuffer.length; + return this; +}; + +Writer.prototype.clear = function() { + this.offset = 5; + this.headerPosition = 0; + this.lastEnd = 0; +}; + +//appends a header block to all the written data since the last +//subsequent header or to the beginning if there is only one data block +Writer.prototype.addHeader = function(code, last) { + var origOffset = this.offset; + this.offset = this.headerPosition; + this.buffer[this.offset++] = code; + //length is everything in this packet minus the code + this.addInt32(origOffset - (this.headerPosition+1)); + //set next header position + this.headerPosition = origOffset; + //make space for next header + this.offset = origOffset; + if(!last) { + this._ensure(5); + this.offset += 5; + } +}; + +Writer.prototype.join = function(code) { + if(code) { + this.addHeader(code, true); + } + return this.buffer.slice(code ? 0 : 5, this.offset); +}; + +Writer.prototype.flush = function(code) { + var result = this.join(code); + this.clear(); + return result; +}; diff --git a/node_modules/pg/node_modules/buffer-writer/package.json b/node_modules/pg/node_modules/buffer-writer/package.json new file mode 100644 index 0000000..2c5df26 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/package.json @@ -0,0 +1,57 @@ +{ + "name": "buffer-writer", + "version": "1.0.0", + "description": "a fast, efficient buffer writer", + "main": "index.js", + "scripts": { + "test": "mocha" + }, + "repository": { + "type": "git", + "url": "git://github.com/brianc/node-buffer-writer.git" + }, + "keywords": [ + "buffer", + "writer", + "builder" + ], + "author": { + "name": "Brian M. Carlson" + }, + "license": "MIT", + "devDependencies": { + "mocha": "~1.8.1", + "benchmark": "~1.0.0", + "microtime": "~0.3.3", + "bench": "~0.3.5", + "okay": "0.0.2", + "cloned": "0.0.1", + "rmdir": "~1.0.0", + "async": "~0.2.6" + }, + "readme": "# buffer-writer\n\n[![Build Status](https://secure.travis-ci.org/brianc/node-buffer-writer.png?branch=master)](http://travis-ci.org/brianc/node-buffer-writer)\n\nFast & efficient buffer writer used to keep memory usage low by internally recycling a single large buffer.\n\nUsed as the binary protocol writer in [node-postgres](https://github.com/brianc/node-postgres)\n\nSince postgres requires big endian encoding, this only writes big endian numbers for now, but can & probably will easily be extended to write little endian as well.\n\nI'll admit this has a few postgres specific things I might need to take out in the future, such as `addHeader`\n\n## api\n\n`var writer = new (require('buffer-writer')());`\n\n### writer.addInt32(num)\n\nWrites a 4-byte big endian binary encoded number to the end of the buffer.\n\n### writer.addInt16(num)\n\nWrites a 2-byte big endian binary encoded number to the end of the buffer.\n\n### writer.addCString(string)\n\nWrites a string to the buffer `utf8` encoded and adds a null character (`\\0`) at the end.\n\n### var buffer = writer.addHeader(char)\n\nWrites the 5 byte PostgreSQL required header to the beginning of the buffer. (1 byte for character, 1 BE Int32 for length of the buffer)\n\n### var buffer = writer.join()\n\nCollects all data in the writer and joins it into a single, new buffer.\n\n### var buffer = writer.flush(char)\n\nWrites the 5 byte postgres required message header, collects all data in the writer and joins it into a single, new buffer, and then resets the writer.\n\n## thoughts\n\nThis is kind of node-postgres specific. If you're interested in using this for a more general purpose thing, lemme know.\nI would love to work with you on getting this more reusable for your needs.\n\n## license\n\nMIT\n", + "readmeFilename": "README.md", + "bugs": { + "url": "https://github.com/brianc/node-buffer-writer/issues" + }, + "_id": "buffer-writer@1.0.0", + "dist": { + "shasum": "6c29c3b2dea0c9e455a1f261a199a48a04f88b08", + "tarball": "http://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.0.tgz" + }, + "_from": "buffer-writer@1.0.0", + "_npmVersion": "1.3.11", + "_npmUser": { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + }, + "maintainers": [ + { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + } + ], + "directories": {}, + "_shasum": "6c29c3b2dea0c9e455a1f261a199a48a04f88b08", + "_resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.0.tgz" +} diff --git a/node_modules/pg/node_modules/buffer-writer/test/mocha.opts b/node_modules/pg/node_modules/buffer-writer/test/mocha.opts new file mode 100644 index 0000000..5efaf24 --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/test/mocha.opts @@ -0,0 +1 @@ +--ui tdd diff --git a/node_modules/pg/node_modules/buffer-writer/test/writer-tests.js b/node_modules/pg/node_modules/buffer-writer/test/writer-tests.js new file mode 100644 index 0000000..685298a --- /dev/null +++ b/node_modules/pg/node_modules/buffer-writer/test/writer-tests.js @@ -0,0 +1,218 @@ +var Writer = require(__dirname + "/../"); + +var assert = require('assert'); +var util = require('util'); + +assert.equalBuffers = function(actual, expected) { + var spit = function(actual, expected) { + console.log(""); + console.log("actual " + util.inspect(actual)); + console.log("expect " + util.inspect(expected)); + console.log(""); + }; + if(actual.length != expected.length) { + spit(actual, expected); + assert.equal(actual.length, expected.length); + } + for(var i = 0; i < actual.length; i++) { + if(actual[i] != expected[i]) { + spit(actual, expected); + } + assert.equal(actual[i],expected[i]); + } +}; + +suite('adding int32', function() { + var testAddingInt32 = function(int, expectedBuffer) { + test('writes ' + int, function() { + var subject = new Writer(); + var result = subject.addInt32(int).join(); + assert.equalBuffers(result, expectedBuffer); + }); + }; + + testAddingInt32(0, [0, 0, 0, 0]); + testAddingInt32(1, [0, 0, 0, 1]); + testAddingInt32(256, [0, 0, 1, 0]); + test('writes largest int32', function() { + //todo need to find largest int32 when I have internet access + return false; + }); + + test('writing multiple int32s', function() { + var subject = new Writer(); + var result = subject.addInt32(1).addInt32(10).addInt32(0).join(); + assert.equalBuffers(result, [0, 0, 0, 1, 0, 0, 0, 0x0a, 0, 0, 0, 0]); + }); + + suite('having to resize the buffer', function() { + test('after resize correct result returned', function() { + var subject = new Writer(10); + subject.addInt32(1).addInt32(1).addInt32(1); + assert.equalBuffers(subject.join(), [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]); + }); + }); +}); + +suite('int16', function() { + test('writes 0', function() { + var subject = new Writer(); + var result = subject.addInt16(0).join(); + assert.equalBuffers(result, [0,0]); + }); + + test('writes 400', function() { + var subject = new Writer(); + var result = subject.addInt16(400).join(); + assert.equalBuffers(result, [1, 0x90]); + }); + + test('writes many', function() { + var subject = new Writer(); + var result = subject.addInt16(0).addInt16(1).addInt16(2).join(); + assert.equalBuffers(result, [0, 0, 0, 1, 0, 2]); + }); + + test('resizes if internal buffer fills up', function() { + var subject = new Writer(3); + var result = subject.addInt16(2).addInt16(3).join(); + assert.equalBuffers(result, [0, 2, 0, 3]); + }); + +}); + +suite('cString', function() { + test('writes empty cstring', function() { + var subject = new Writer(); + var result = subject.addCString().join(); + assert.equalBuffers(result, [0]); + }); + + test('writes two empty cstrings', function() { + var subject = new Writer(); + var result = subject.addCString("").addCString("").join(); + assert.equalBuffers(result, [0, 0]); + }); + + + test('writes non-empty cstring', function() { + var subject = new Writer(); + var result = subject.addCString("!!!").join(); + assert.equalBuffers(result, [33, 33, 33, 0]); + }); + + test('resizes if reached end', function() { + var subject = new Writer(3); + var result = subject.addCString("!!!").join(); + assert.equalBuffers(result, [33, 33, 33, 0]); + }); + + test('writes multiple cstrings', function() { + var subject = new Writer(); + var result = subject.addCString("!").addCString("!").join(); + assert.equalBuffers(result, [33, 0, 33, 0]); + }); + +}); + +test('writes char', function() { + var subject = new Writer(2); + var result = subject.addChar('a').addChar('b').addChar('c').join(); + assert.equalBuffers(result, [0x61, 0x62, 0x63]); +}); + +test('gets correct byte length', function() { + var subject = new Writer(5); + assert.equal(subject.getByteLength(), 0); + subject.addInt32(0); + assert.equal(subject.getByteLength(), 4); + subject.addCString("!"); + assert.equal(subject.getByteLength(), 6); +}); + +test('can add arbitrary buffer to the end', function() { + var subject = new Writer(4); + subject.addCString("!!!") + var result = subject.add(Buffer("@@@")).join(); + assert.equalBuffers(result, [33, 33, 33, 0, 0x40, 0x40, 0x40]); +}); + +suite('can write normal string', function() { + var subject = new Writer(4); + var result = subject.addString("!").join(); + assert.equalBuffers(result, [33]); + test('can write cString too', function() { + var result = subject.addCString("!").join(); + assert.equalBuffers(result, [33, 33, 0]); + }); + test('can resize', function() { + var result = subject.addString("!!").join(); + assert.equalBuffers(result, [33, 33, 0, 33, 33]); + }); +}); + + +suite('clearing', function() { + var subject = new Writer(); + subject.addCString("@!!#!#"); + subject.addInt32(10401); + test('clears', function() { + subject.clear(); + assert.equalBuffers(subject.join(), []); + }); + test('writing more', function() { + var joinedResult = subject.addCString("!").addInt32(9).addInt16(2).join(); + assert.equalBuffers(joinedResult, [33, 0, 0, 0, 0, 9, 0, 2]); + }); + test('returns result', function() { + var flushedResult = subject.flush(); + assert.equalBuffers(flushedResult, [33, 0, 0, 0, 0, 9, 0, 2]) + }); + test('clears the writer', function() { + assert.equalBuffers(subject.join(), []) + assert.equalBuffers(subject.flush(), []) + }); +}); + +test("resizing to much larger", function() { + var subject = new Writer(2); + var string = "!!!!!!!!"; + var result = subject.addCString(string).flush(); + assert.equalBuffers(result, [33, 33, 33, 33, 33, 33, 33, 33, 0]); +}); + +suite("flush", function() { + test('added as a hex code to a full writer', function() { + var subject = new Writer(2); + var result = subject.addCString("!").flush(0x50); + assert.equalBuffers(result, [0x50, 0, 0, 0, 6, 33, 0]); + }); + + test('added as a hex code to a non-full writer', function() { + var subject = new Writer(10).addCString("!"); + var joinedResult = subject.join(0x50); + var result = subject.flush(0x50); + assert.equalBuffers(result, [0x50, 0, 0, 0, 6, 33, 0]); + }); + + test('added as a hex code to a buffer which requires resizing', function() { + var result = new Writer(2).addCString("!!!!!!!!").flush(0x50); + assert.equalBuffers(result, [0x50, 0, 0, 0, 0x0D, 33, 33, 33, 33, 33, 33, 33, 33, 0]); + }); +}); + +suite("header", function() { + test('adding two packets with headers', function() { + var subject = new Writer(10).addCString("!"); + subject.addHeader(0x50); + subject.addCString("!!"); + subject.addHeader(0x40); + subject.addCString("!"); + var result = subject.flush(0x10); + assert.equalBuffers(result, [0x50, 0, 0, 0, 6, 33, 0, 0x40, 0, 0, 0, 7, 33, 33, 0, 0x10, 0, 0, 0, 6, 33, 0 ]); + }); +}); + + + + diff --git a/node_modules/pg/node_modules/generic-pool/.npmignore b/node_modules/pg/node_modules/generic-pool/.npmignore new file mode 100644 index 0000000..fcb718b --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/.npmignore @@ -0,0 +1,4 @@ +fabfile.pyc +node-pool.iml +node-pool.tmproj +node_modules diff --git a/node_modules/pg/node_modules/generic-pool/.travis.yml b/node_modules/pg/node_modules/generic-pool/.travis.yml new file mode 100644 index 0000000..8111245 --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 \ No newline at end of file diff --git a/node_modules/pg/node_modules/generic-pool/Makefile b/node_modules/pg/node_modules/generic-pool/Makefile new file mode 100644 index 0000000..669888d --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/Makefile @@ -0,0 +1,4 @@ +all: + +check: + npm test diff --git a/node_modules/pg/node_modules/generic-pool/README.md b/node_modules/pg/node_modules/generic-pool/README.md new file mode 100644 index 0000000..01dd65c --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/README.md @@ -0,0 +1,349 @@ +[![build status](https://secure.travis-ci.org/coopernurse/node-pool.png)](http://travis-ci.org/coopernurse/node-pool) + +# About + + Generic resource pool. Can be used to reuse or throttle expensive resources such as + database connections. + +## 2.0 Release Warning + +The 2.0.0 release removed support for variable argument callbacks. When you acquire +a resource from the pool, your callback *must* accept two arguments: (err, obj) + +Previously this library attempted to determine the arity of the callback, but this resulted +in a variety of issues. This change eliminates these issues, and makes the acquire callback +parameter order consistent with the factory.create callback. + +## Installation + + $ npm install generic-pool + +## History + + 2.1.0 - June 19 2014 + - Merged #72 - Add optional returnToHead flag, if true, resources are returned to head of queue (stack like + behaviour) upon release (contributed by calibr), also see #68 for further discussion. + + 2.0.4 - July 27 2013 + - Merged #64 - Fix for not removing idle objects (contributed by PiotrWpl) + + 2.0.3 - January 16 2013 + - Merged #56/#57 - Add optional refreshIdle flag. If false, idle resources at the pool minimum will not be + destroyed/re-created. (contributed by wshaver) + - Merged #54 - Factory can be asked to validate pooled objects (contributed by tikonen) + + 2.0.2 - October 22 2012 + - Fix #51, #48 - createResource() should check for null clientCb in err case (contributed by pooyasencha) + - Merged #52 - fix bug of infinite wait when create object aync error (contributed by windyrobin) + - Merged #53 - change the position of dispense and callback to ensure the time order (contributed by windyrobin) + + 2.0.1 - August 29 2012 + - Fix #44 - leak of 'err' and 'obj' in createResource() + - Add devDependencies block to package.json + - Add travis-ci.org integration + + 2.0.0 - July 31 2012 + - Non-backwards compatible change: remove adjustCallback + - acquire() callback must accept two params: (err, obj) + - Add optional 'min' param to factory object that specifies minimum number of + resources to keep in pool + - Merged #38 (package.json/Makefile changes - contributed by strk) + + 1.0.12 - June 27 2012 + - Merged #37 (Clear remove idle timer after destroyAllNow - contributed by dougwilson) + + 1.0.11 - June 17 2012 + - Merged #36 ("pooled" method to perform function decoration for pooled methods - contributed by cosbynator) + + 1.0.10 - May 3 2012 + - Merged #35 (Remove client from availbleObjects on destroy(client) - contributed by blax) + + 1.0.9 - Dec 18 2011 + - Merged #25 (add getName() - contributed by BryanDonovan) + - Merged #27 (remove sys import - contributed by botker) + - Merged #26 (log levels - contributed by JoeZ99) + + 1.0.8 - Nov 16 2011 + - Merged #21 (add getter methods to see pool size, etc. - contributed by BryanDonovan) + + 1.0.7 - Oct 17 2011 + - Merged #19 (prevent release on the same obj twice - contributed by tkrynski) + - Merged #20 (acquire() returns boolean indicating whether pool is full - contributed by tilgovi) + + 1.0.6 - May 23 2011 + - Merged #13 (support error variable in acquire callback - contributed by tmcw) + - Note: This change is backwards compatible. But new code should use the two + parameter callback format in pool.create() functions from now on. + - Merged #15 (variable scope issue in dispense() - contributed by eevans) + + 1.0.5 - Apr 20 2011 + - Merged #12 (ability to drain pool - contributed by gdusbabek) + + 1.0.4 - Jan 25 2011 + - Fixed #6 (objects reaped with undefined timeouts) + - Fixed #7 (objectTimeout issue) + + 1.0.3 - Dec 9 2010 + - Added priority queueing (thanks to sylvinus) + - Contributions from Poetro + - Name changes to match conventions described here: http://en.wikipedia.org/wiki/Object_pool_pattern + - borrow() renamed to acquire() + - returnToPool() renamed to release() + - destroy() removed from public interface + - added JsDoc comments + - Priority queueing enhancements + + 1.0.2 - Nov 9 2010 + - First NPM release + +## Example + +### Step 1 - Create pool using a factory object + +```js +// Create a MySQL connection pool with +// a max of 10 connections, a min of 2, and a 30 second max idle time +var poolModule = require('generic-pool'); +var pool = poolModule.Pool({ + name : 'mysql', + create : function(callback) { + var Client = require('mysql').Client; + var c = new Client(); + c.user = 'scott'; + c.password = 'tiger'; + c.database = 'mydb'; + c.connect(); + + // parameter order: err, resource + // new in 1.0.6 + callback(null, c); + }, + destroy : function(client) { client.end(); }, + max : 10, + // optional. if you set this, make sure to drain() (see step 3) + min : 2, + // specifies how long a resource can stay idle in pool before being removed + idleTimeoutMillis : 30000, + // if true, logs via console.log - can also be a function + log : true +}); +``` + +### Step 2 - Use pool in your code to acquire/release resources + +```js +// acquire connection - callback function is called +// once a resource becomes available +pool.acquire(function(err, client) { + if (err) { + // handle error - this is generally the err from your + // factory.create function + } + else { + client.query("select * from foo", [], function() { + // return object back to pool + pool.release(client); + }); + } +}); +``` + +### Step 3 - Drain pool during shutdown (optional) + +If you are shutting down a long-lived process, you may notice +that node fails to exit for 30 seconds or so. This is a side +effect of the idleTimeoutMillis behavior -- the pool has a +setTimeout() call registered that is in the event loop queue, so +node won't terminate until all resources have timed out, and the pool +stops trying to manage them. + +This behavior will be more problematic when you set factory.min > 0, +as the pool will never become empty, and the setTimeout calls will +never end. + +In these cases, use the pool.drain() function. This sets the pool +into a "draining" state which will gracefully wait until all +idle resources have timed out. For example, you can call: + +```js +// Only call this once in your application -- at the point you want +// to shutdown and stop using this pool. +pool.drain(function() { + pool.destroyAllNow(); +}); +``` + +If you do this, your node process will exit gracefully. + + +## Documentation + + Pool() accepts an object with these slots: + + name : name of pool (string, optional) + create : function that returns a new resource + should call callback() with the created resource + destroy : function that accepts a resource and destroys it + max : maximum number of resources to create at any given time + optional (default=1) + min : minimum number of resources to keep in pool at any given time + if this is set > max, the pool will silently set the min + to factory.max - 1 + optional (default=0) + refreshIdle : boolean that specifies whether idle resources at or below the min threshold + should be destroyed/re-created. optional (default=true) + idleTimeoutMillis : max milliseconds a resource can go unused before it should be destroyed + (default 30000) + reapIntervalMillis : frequency to check for idle resources (default 1000), + returnToHead : boolean, if true the most recently released resources will be the first to be allocated. + This in effect turns the pool's behaviour from a queue into a stack. optional (default false) + priorityRange : int between 1 and x - if set, borrowers can specify their + relative priority in the queue if no resources are available. + see example. (default 1) + validate : function that accepts a pooled resource and returns true if the resource + is OK to use, or false if the object is invalid. Invalid objects will be destroyed. + This function is called in acquire() before returning a resource from the pool. + Optional. Default function always returns true. + log : true/false or function - + If a log is a function, it will be called with two parameters: + - log string + - log level ('verbose', 'info', 'warn', 'error') + Else if log is true, verbose log info will be sent to console.log() + Else internal log messages be ignored (this is the default) + +## Priority Queueing + +The pool now supports optional priority queueing. This becomes relevant when no resources +are available and the caller has to wait. `acquire()` accepts an optional priority int which +specifies the caller's relative position in the queue. + +```js + // create pool with priorityRange of 3 + // borrowers can specify a priority 0 to 2 + var pool = poolModule.Pool({ + name : 'mysql', + create : function(callback) { + // do something + }, + destroy : function(client) { + // cleanup. omitted for this example + }, + max : 10, + idleTimeoutMillis : 30000, + priorityRange : 3 + }); + + // acquire connection - no priority - will go at front of line (same as high priority) + pool.acquire(function(err, client) { + pool.release(client); + }); + + // acquire connection - high priority - will go into front slot + pool.acquire(function(err, client) { + pool.release(client); + }, 0); + + // acquire connection - medium priority - will go into middle slot + pool.acquire(function(err, client) { + pool.release(client); + }, 1); + + // etc.. +``` + +## Draining + +If you know would like to terminate all the resources in your pool before +their timeouts have been reached, you can use `destroyAllNow()` in conjunction +with `drain()`: + +```js +pool.drain(function() { + pool.destroyAllNow(); +}); +``` + +One side-effect of calling `drain()` is that subsequent calls to `acquire()` +will throw an Error. + +## Pooled function decoration + +To transparently handle object acquisition for a function, +one can use `pooled()`: + +```js +var privateFn, publicFn; +publicFn = pool.pooled(privateFn = function(client, arg, cb) { + // Do something with the client and arg. Client is auto-released when cb is called + cb(null, arg); +}); +``` + +Keeping both private and public versions of each function allows for pooled +functions to call other pooled functions with the same member. This is a handy +pattern for database transactions: + +```js +var privateTop, privateBottom, publicTop, publicBottom; +publicBottom = pool.pooled(privateBottom = function(client, arg, cb) { + //Use client, assumed auto-release +}); + +publicTop = pool.pooled(privateTop = function(client, cb) { + // e.g., open a database transaction + privateBottom(client, "arg", function(err, retVal) { + if(err) { return cb(err); } + // e.g., close a transaction + cb(); + }); +}); +``` + +## Pool info + +The following functions will let you get information about the pool: + +```js +// returns factory.name for this pool +pool.getName() + +// returns number of resources in the pool regardless of +// whether they are free or in use +pool.getPoolSize() + +// returns number of unused resources in the pool +pool.availableObjectsCount() + +// returns number of callers waiting to acquire a resource +pool.waitingClientsCount() +``` + +## Run Tests + + $ npm install expresso + $ expresso -I lib test/*.js + +## License + +(The MIT License) + +Copyright (c) 2010-2014 James Cooper <james@bitmechanic.com> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pg/node_modules/generic-pool/fabfile.py b/node_modules/pg/node_modules/generic-pool/fabfile.py new file mode 100644 index 0000000..becfc46 --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/fabfile.py @@ -0,0 +1,27 @@ +# +# dependencies: +# fabric (apt-get install fabric) +# node-jslint (http://github.com/reid/node-jslint) +# expresso (or replace with whatever node.js test tool you're using) +# + +from fabric.api import local +import os, os.path + +def test(): + local('expresso -I lib test/*', capture=False) + +def jslint(): + ignore = [ "/lib-cov/" ] + for root, subFolders, files in os.walk("."): + for file in files: + if file.endswith(".js"): + filename = os.path.join(root,file) + processFile = True + for i in ignore: + if filename.find(i) != -1: + processFile = False + if processFile: + print filename + local('jslint %s' % filename, capture=False) + diff --git a/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js b/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js new file mode 100644 index 0000000..fbf3d3a --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/lib/generic-pool.js @@ -0,0 +1,475 @@ +var PriorityQueue = function(size) { + var me = {}, slots, i, total = null; + + // initialize arrays to hold queue elements + size = Math.max(+size | 0, 1); + slots = []; + for (i = 0; i < size; i += 1) { + slots.push([]); + } + + // Public methods + me.size = function () { + var i; + if (total === null) { + total = 0; + for (i = 0; i < size; i += 1) { + total += slots[i].length; + } + } + return total; + }; + + me.enqueue = function (obj, priority) { + var priorityOrig; + + // Convert to integer with a default value of 0. + priority = priority && + priority | 0 || 0; + + // Clear cache for total. + total = null; + if (priority) { + priorityOrig = priority; + if (priority < 0 || priority >= size) { + priority = (size - 1); + // put obj at the end of the line + console.error("invalid priority: " + priorityOrig + " must be between 0 and " + priority); + } + } + + slots[priority].push(obj); + }; + + me.dequeue = function (callback) { + var obj = null, i, sl = slots.length; + + // Clear cache for total. + total = null; + for (i = 0; i < sl; i += 1) { + if (slots[i].length) { + obj = slots[i].shift(); + break; + } + } + return obj; + }; + + return me; +}; + +/** + * Generate an Object pool with a specified `factory`. + * + * @param {Object} factory + * Factory to be used for generating and destorying the items. + * @param {String} factory.name + * Name of the factory. Serves only logging purposes. + * @param {Function} factory.create + * Should create the item to be acquired, + * and call it's first callback argument with the generated item as it's argument. + * @param {Function} factory.destroy + * Should gently close any resources that the item is using. + * Called before the items is destroyed. + * @param {Function} factory.validate + * Should return true if connection is still valid and false + * If it should be removed from pool. Called before item is + * acquired from pool. + * @param {Number} factory.max + * Maximum number of items that can exist at the same time. Default: 1. + * Any further acquire requests will be pushed to the waiting list. + * @param {Number} factory.min + * Minimum number of items in pool (including in-use). Default: 0. + * When the pool is created, or a resource destroyed, this minimum will + * be checked. If the pool resource count is below the minimum, a new + * resource will be created and added to the pool. + * @param {Number} factory.idleTimeoutMillis + * Delay in milliseconds after the idle items in the pool will be destroyed. + * And idle item is that is not acquired yet. Waiting items doesn't count here. + * @param {Number} factory.reapIntervalMillis + * Cleanup is scheduled in every `factory.reapIntervalMillis` milliseconds. + * @param {Boolean|Function} factory.log + * Whether the pool should log activity. If function is specified, + * that will be used instead. The function expects the arguments msg, loglevel + * @param {Number} factory.priorityRange + * The range from 1 to be treated as a valid priority + * @param {RefreshIdle} factory.refreshIdle + * Should idle resources be destroyed and recreated every idleTimeoutMillis? Default: true. + * @param {Bool} [factory.returnToHead=false] + * Returns released object to head of available objects list + * @returns {Object} An Object pool that works with the supplied `factory`. + */ +exports.Pool = function (factory) { + var me = {}, + + idleTimeoutMillis = factory.idleTimeoutMillis || 30000, + reapInterval = factory.reapIntervalMillis || 1000, + refreshIdle = ('refreshIdle' in factory) ? factory.refreshIdle : true, + availableObjects = [], + waitingClients = new PriorityQueue(factory.priorityRange || 1), + count = 0, + removeIdleScheduled = false, + removeIdleTimer = null, + draining = false, + returnToHead = factory.returnToHead || false, + + // Prepare a logger function. + log = factory.log ? + (function (str, level) { + if (typeof factory.log === 'function') { + factory.log(str, level); + } + else { + console.log(level.toUpperCase() + " pool " + factory.name + " - " + str); + } + } + ) : + function () {}; + + factory.validate = factory.validate || function() { return true; }; + + factory.max = parseInt(factory.max, 10); + factory.min = parseInt(factory.min, 10); + + factory.max = Math.max(isNaN(factory.max) ? 1 : factory.max, 1); + factory.min = Math.min(isNaN(factory.min) ? 0 : factory.min, factory.max-1); + + /////////////// + + /** + * Request the client to be destroyed. The factory's destroy handler + * will also be called. + * + * This should be called within an acquire() block as an alternative to release(). + * + * @param {Object} obj + * The acquired item to be destoyed. + */ + me.destroy = function(obj) { + count -= 1; + availableObjects = availableObjects.filter(function(objWithTimeout) { + return (objWithTimeout.obj !== obj); + }); + factory.destroy(obj); + + ensureMinimum(); + }; + + /** + * Checks and removes the available (idle) clients that have timed out. + */ + function removeIdle() { + var toRemove = [], + now = new Date().getTime(), + i, + al, tr, + timeout; + + removeIdleScheduled = false; + + // Go through the available (idle) items, + // check if they have timed out + for (i = 0, al = availableObjects.length; i < al && (refreshIdle || (count - factory.min > toRemove.length)); i += 1) { + timeout = availableObjects[i].timeout; + if (now >= timeout) { + // Client timed out, so destroy it. + log("removeIdle() destroying obj - now:" + now + " timeout:" + timeout, 'verbose'); + toRemove.push(availableObjects[i].obj); + } + } + + for (i = 0, tr = toRemove.length; i < tr; i += 1) { + me.destroy(toRemove[i]); + } + + // Replace the available items with the ones to keep. + al = availableObjects.length; + + if (al > 0) { + log("availableObjects.length=" + al, 'verbose'); + scheduleRemoveIdle(); + } else { + log("removeIdle() all objects removed", 'verbose'); + } + } + + + /** + * Schedule removal of idle items in the pool. + * + * More schedules cannot run concurrently. + */ + function scheduleRemoveIdle() { + if (!removeIdleScheduled) { + removeIdleScheduled = true; + removeIdleTimer = setTimeout(removeIdle, reapInterval); + } + } + + /** + * Handle callbacks with either the [obj] or [err, obj] arguments in an + * adaptive manner. Uses the `cb.length` property to determine the number + * of arguments expected by `cb`. + */ + function adjustCallback(cb, err, obj) { + if (!cb) return; + if (cb.length <= 1) { + cb(obj); + } else { + cb(err, obj); + } + } + + /** + * Try to get a new client to work, and clean up pool unused (idle) items. + * + * - If there are available clients waiting, shift the first one out (LIFO), + * and call its callback. + * - If there are no waiting clients, try to create one if it won't exceed + * the maximum number of clients. + * - If creating a new client would exceed the maximum, add the client to + * the wait list. + */ + function dispense() { + var obj = null, + objWithTimeout = null, + err = null, + clientCb = null, + waitingCount = waitingClients.size(); + + log("dispense() clients=" + waitingCount + " available=" + availableObjects.length, 'info'); + if (waitingCount > 0) { + while (availableObjects.length > 0) { + log("dispense() - reusing obj", 'verbose'); + objWithTimeout = availableObjects[0]; + if (!factory.validate(objWithTimeout.obj)) { + me.destroy(objWithTimeout.obj); + continue; + } + availableObjects.shift(); + clientCb = waitingClients.dequeue(); + return clientCb(err, objWithTimeout.obj); + } + if (count < factory.max) { + createResource(); + } + } + } + + function createResource() { + count += 1; + log("createResource() - creating obj - count=" + count + " min=" + factory.min + " max=" + factory.max, 'verbose'); + factory.create(function () { + var err, obj; + var clientCb = waitingClients.dequeue(); + if (arguments.length > 1) { + err = arguments[0]; + obj = arguments[1]; + } else { + err = (arguments[0] instanceof Error) ? arguments[0] : null; + obj = (arguments[0] instanceof Error) ? null : arguments[0]; + } + if (err) { + count -= 1; + if (clientCb) { + clientCb(err, obj); + } + process.nextTick(function(){ + dispense(); + }); + } else { + if (clientCb) { + clientCb(err, obj); + } else { + me.release(obj); + } + } + }); + } + + function ensureMinimum() { + var i, diff; + if (!draining && (count < factory.min)) { + diff = factory.min - count; + for (i = 0; i < diff; i++) { + createResource(); + } + } + } + + /** + * Request a new client. The callback will be called, + * when a new client will be availabe, passing the client to it. + * + * @param {Function} callback + * Callback function to be called after the acquire is successful. + * The function will receive the acquired item as the first parameter. + * + * @param {Number} priority + * Optional. Integer between 0 and (priorityRange - 1). Specifies the priority + * of the caller if there are no available resources. Lower numbers mean higher + * priority. + * + * @returns {Object} `true` if the pool is not fully utilized, `false` otherwise. + */ + me.acquire = function (callback, priority) { + if (draining) { + throw new Error("pool is draining and cannot accept work"); + } + waitingClients.enqueue(callback, priority); + dispense(); + return (count < factory.max); + }; + + me.borrow = function (callback, priority) { + log("borrow() is deprecated. use acquire() instead", 'warn'); + me.acquire(callback, priority); + }; + + /** + * Return the client to the pool, in case it is no longer required. + * + * @param {Object} obj + * The acquired object to be put back to the pool. + */ + me.release = function (obj) { + // check to see if this object has already been released (i.e., is back in the pool of availableObjects) + if (availableObjects.some(function(objWithTimeout) { return (objWithTimeout.obj === obj); })) { + log("release called twice for the same resource: " + (new Error().stack), 'error'); + return; + } + //log("return to pool"); + var objWithTimeout = { obj: obj, timeout: (new Date().getTime() + idleTimeoutMillis) }; + if(returnToHead){ + availableObjects.splice(0, 0, objWithTimeout); + } + else{ + availableObjects.push(objWithTimeout); + } + log("timeout: " + objWithTimeout.timeout, 'verbose'); + dispense(); + scheduleRemoveIdle(); + }; + + me.returnToPool = function (obj) { + log("returnToPool() is deprecated. use release() instead", 'warn'); + me.release(obj); + }; + + /** + * Disallow any new requests and let the request backlog dissapate. + * + * @param {Function} callback + * Optional. Callback invoked when all work is done and all clients have been + * released. + */ + me.drain = function(callback) { + log("draining", 'info'); + + // disable the ability to put more work on the queue. + draining = true; + + var check = function() { + if (waitingClients.size() > 0) { + // wait until all client requests have been satisfied. + setTimeout(check, 100); + } else if (availableObjects.length != count) { + // wait until all objects have been released. + setTimeout(check, 100); + } else { + if (callback) { + callback(); + } + } + }; + check(); + }; + + /** + * Forcibly destroys all clients regardless of timeout. Intended to be + * invoked as part of a drain. Does not prevent the creation of new + * clients as a result of subsequent calls to acquire. + * + * Note that if factory.min > 0, the pool will destroy all idle resources + * in the pool, but replace them with newly created resources up to the + * specified factory.min value. If this is not desired, set factory.min + * to zero before calling destroyAllNow() + * + * @param {Function} callback + * Optional. Callback invoked after all existing clients are destroyed. + */ + me.destroyAllNow = function(callback) { + log("force destroying all objects", 'info'); + var willDie = availableObjects; + availableObjects = []; + var obj = willDie.shift(); + while (obj !== null && obj !== undefined) { + me.destroy(obj.obj); + obj = willDie.shift(); + } + removeIdleScheduled = false; + clearTimeout(removeIdleTimer); + if (callback) { + callback(); + } + }; + + /** + * Decorates a function to use a acquired client from the object pool when called. + * + * @param {Function} decorated + * The decorated function, accepting a client as the first argument and + * (optionally) a callback as the final argument. + * + * @param {Number} priority + * Optional. Integer between 0 and (priorityRange - 1). Specifies the priority + * of the caller if there are no available resources. Lower numbers mean higher + * priority. + */ + me.pooled = function(decorated, priority) { + return function() { + var callerArgs = arguments; + var callerCallback = callerArgs[callerArgs.length - 1]; + var callerHasCallback = typeof callerCallback === 'function'; + me.acquire(function(err, client) { + if(err) { + if(callerHasCallback) { + callerCallback(err); + } + return; + } + + var args = [client].concat(Array.prototype.slice.call(callerArgs, 0, callerHasCallback ? -1 : undefined)); + args.push(function() { + me.release(client); + if(callerHasCallback) { + callerCallback.apply(null, arguments); + } + }); + + decorated.apply(null, args); + }, priority); + }; + }; + + me.getPoolSize = function() { + return count; + }; + + me.getName = function() { + return factory.name; + }; + + me.availableObjectsCount = function() { + return availableObjects.length; + }; + + me.waitingClientsCount = function() { + return waitingClients.size(); + }; + + + // create initial resources (if factory.min > 0) + ensureMinimum(); + + return me; +}; diff --git a/node_modules/pg/node_modules/generic-pool/package.json b/node_modules/pg/node_modules/generic-pool/package.json new file mode 100644 index 0000000..7444067 --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/package.json @@ -0,0 +1,84 @@ +{ + "name": "generic-pool", + "description": "Generic resource pooling for Node.JS", + "version": "2.1.1", + "author": { + "name": "James Cooper", + "email": "james@bitmechanic.com" + }, + "contributors": [ + { + "name": "James Cooper", + "email": "james@bitmechanic.com" + }, + { + "name": "Peter Galiba", + "email": "poetro@poetro.hu", + "url": "http://poetro.hu/" + }, + { + "name": "Gary Dusbabek" + }, + { + "name": "Tom MacWright", + "url": "http://www.developmentseed.org/" + }, + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com", + "url": "http://somethingdoug.com/" + }, + { + "name": "calibr" + } + ], + "keywords": [ + "pool", + "pooling", + "throttle" + ], + "main": "lib/generic-pool.js", + "repository": { + "type": "git", + "url": "http://github.com/coopernurse/node-pool.git" + }, + "devDependencies": { + "expresso": ">0.0.0" + }, + "engines": { + "node": ">= 0.2.0" + }, + "scripts": { + "test": "expresso -I lib test/*.js" + }, + "license": "MIT", + "gitHead": "f66bba2d4c56867223e2f7bae386587cfb6c0b96", + "bugs": { + "url": "https://github.com/coopernurse/node-pool/issues" + }, + "homepage": "https://github.com/coopernurse/node-pool", + "_id": "generic-pool@2.1.1", + "_shasum": "af04dc2c325cfcb975023fa52bfce9617a7435fd", + "_from": "generic-pool@2.1.1", + "_npmVersion": "1.5.0-alpha-1", + "_npmUser": { + "name": "sandfox", + "email": "james.butler@sandfox.co.uk" + }, + "maintainers": [ + { + "name": "coopernurse", + "email": "james@bitmechanic.com" + }, + { + "name": "sandfox", + "email": "james.butler@sandfox.co.uk" + } + ], + "dist": { + "shasum": "af04dc2c325cfcb975023fa52bfce9617a7435fd", + "tarball": "http://registry.npmjs.org/generic-pool/-/generic-pool-2.1.1.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.1.1.tgz" +} diff --git a/node_modules/pg/node_modules/generic-pool/test/generic-pool.test.js b/node_modules/pg/node_modules/generic-pool/test/generic-pool.test.js new file mode 100644 index 0000000..d7ac17a --- /dev/null +++ b/node_modules/pg/node_modules/generic-pool/test/generic-pool.test.js @@ -0,0 +1,619 @@ +var assert = require('assert'); +var poolModule = require('..'); + +module.exports = { + + 'expands to max limit' : function (beforeExit) { + var createCount = 0; + var destroyCount = 0; + var borrowCount = 0; + + var factory = { + name : 'test1', + create : function(callback) { + callback(null, { count: ++createCount }); + }, + destroy : function(client) { destroyCount++; }, + max : 2, + idleTimeoutMillis : 100 + }; + + var pool = poolModule.Pool(factory); + + for (var i = 0; i < 10; i++) { + var full = !pool.acquire(function(err, obj) { + return function(err, obj) { + assert.equal(typeof obj.count, 'number'); + setTimeout(function() { + borrowCount++; + pool.release(obj); + }, 100); + }; + }()); + assert.ok((i < 1) ^ full); + } + + beforeExit(function() { + assert.equal(0, factory.min); + assert.equal(2, createCount); + assert.equal(2, destroyCount); + assert.equal(10, borrowCount); + }); + }, + + 'respects min limit' : function (beforeExit) { + var createCount = 0; + var destroyCount = 0; + var borrowCount = 0; + + var pool = poolModule.Pool({ + name : 'test-min', + create : function(callback) { + callback(null, { count: ++createCount }); + }, + destroy : function(client) { destroyCount++; }, + min : 1, + max : 2, + idleTimeoutMillis : 100 + }); + pool.drain(); + + beforeExit(function() { + assert.equal(0, pool.availableObjectsCount()); + assert.equal(1, createCount); + assert.equal(1, destroyCount); + }); + }, + + 'min and max limit defaults' : function (beforeExit) { + var factory = { + name : "test-limit-defaults", + create : function(callback) { callback(null, {}); }, + destroy : function(client) { }, + idleTimeoutMillis: 100 + }; + var pool = poolModule.Pool(factory); + + beforeExit(function() { + assert.equal(1, factory.max); + assert.equal(0, factory.min); + }); + }, + + 'malformed min and max limits are ignored' : function (beforeExit) { + var factory = { + name : "test-limit-defaults2", + create : function(callback) { callback(null, {}); }, + destroy : function(client) { }, + idleTimeoutMillis: 100, + min : "asf", + max : [ ] + }; + var pool = poolModule.Pool(factory); + + beforeExit(function() { + assert.equal(1, factory.max); + assert.equal(0, factory.min); + }); + }, + + 'min greater than max sets to max minus one' : function (beforeExit) { + var factory = { + name : "test-limit-defaults3", + create : function(callback) { callback(null, {}); }, + destroy : function(client) { }, + idleTimeoutMillis: 100, + min : 5, + max : 3 + }; + var pool = poolModule.Pool(factory); + pool.drain(); + + beforeExit(function() { + assert.equal(3, factory.max); + assert.equal(2, factory.min); + }); + }, + + 'supports priority on borrow' : function(beforeExit) { + var borrowTimeLow = 0; + var borrowTimeHigh = 0; + var borrowCount = 0; + var i; + + var pool = poolModule.Pool({ + name : 'test2', + create : function(callback) { callback(); }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 100, + priorityRange : 2 + }); + + for (i = 0; i < 10; i++) { + pool.acquire(function(err, obj) { + return function() { + setTimeout(function() { + var t = new Date().getTime(); + if (t > borrowTimeLow) { borrowTimeLow = t; } + borrowCount++; + pool.release(obj); + }, 50); + }; + }(), 1); + } + + for (i = 0; i < 10; i++) { + pool.acquire(function(obj) { + return function() { + setTimeout(function() { + var t = new Date().getTime(); + if (t > borrowTimeHigh) { borrowTimeHigh = t; } + borrowCount++; + pool.release(obj); + }, 50); + }; + }(), 0); + } + + beforeExit(function() { + assert.equal(20, borrowCount); + assert.equal(true, borrowTimeLow > borrowTimeHigh); + }); + }, + + 'removes correct object on reap' : function (beforeExit) { + var destroyed = []; + var clientCount = 0; + + var pool = poolModule.Pool({ + name : 'test3', + create : function(callback) { callback(null, { id : ++clientCount }); }, + destroy : function(client) { destroyed.push(client.id); }, + max : 2, + idleTimeoutMillis : 100 + }); + + pool.acquire(function(err, client) { + assert.equal(typeof client.id, 'number'); + // should be removed second + setTimeout(function() { pool.release(client); }, 5); + }); + pool.acquire(function(err, client) { + assert.equal(typeof client.id, 'number'); + // should be removed first + pool.release(client); + }); + + setTimeout(function() { }, 102); + + beforeExit(function() { + assert.equal(2, destroyed[0]); + assert.equal(1, destroyed[1]); + }); + }, + + 'tests drain' : function (beforeExit) { + var created = 0; + var destroyed = 0; + var count = 5; + var acquired = 0; + + var pool = poolModule.Pool({ + name : 'test4', + create : function(callback) { callback(null, {id: ++created}); }, + destroy : function(client) { destroyed += 1; }, + max : 2, + idletimeoutMillis : 300000 + }); + + for (var i = 0; i < count; i++) { + pool.acquire(function(err, client) { + acquired += 1; + assert.equal(typeof client.id, 'number'); + setTimeout(function() { pool.release(client); }, 250); + }); + } + + assert.notEqual(count, acquired); + pool.drain(function() { + assert.equal(count, acquired); + // short circuit the absurdly long timeouts above. + pool.destroyAllNow(); + beforeExit(function() {}); + }); + + // subsequent calls to acquire should return an error. + assert.throws(function() { + pool.acquire(function(client) {}); + }, Error); + }, + + 'handle creation errors' : function (beforeExit) { + var created = 0; + var pool = poolModule.Pool({ + name : 'test6', + create : function(callback) { + if (created < 5) { + callback(new Error('Error occurred.')); + } else { + callback({ id : created }); + } + created++; + }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 1000 + }); + // ensure that creation errors do not populate the pool. + for (var i = 0; i < 5; i++) { + pool.acquire(function(err, client) { + assert.ok(err instanceof Error); + assert.ok(client === null); + }); + } + + var called = false; + pool.acquire(function(err, client) { + assert.ok(err === null); + assert.equal(typeof client.id, 'number'); + called = true; + }); + beforeExit(function() { + assert.ok(called); + assert.equal(pool.waitingClientsCount(), 0); + }); + }, + + 'handle creation errors for delayed creates' : function (beforeExit) { + var created = 0; + var pool = poolModule.Pool({ + name : 'test6', + create : function(callback) { + if (created < 5) { + setTimeout(function() { + callback(new Error('Error occurred.')); + }, 0); + } else { + setTimeout(function() { + callback({ id : created }); + }, 0); + } + created++; + }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 1000 + }); + // ensure that creation errors do not populate the pool. + for (var i = 0; i < 5; i++) { + pool.acquire(function(err, client) { + assert.ok(err instanceof Error); + assert.ok(client === null); + }); + } + var called = false; + pool.acquire(function(err, client) { + assert.ok(err === null); + assert.equal(typeof client.id, 'number'); + called = true; + }); + beforeExit(function() { + assert.ok(called); + assert.equal(pool.waitingClientsCount(), 0); + }); + }, + + 'pooled decorator should acquire and release' : function (beforeExit) { + var assertion_count = 0; + var destroyed_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); }, + destroy : function(client) { destroyed_count += 1; }, + max : 1, + idleTimeoutMillis : 100 + }); + + var pooledFn = pool.pooled(function(client, cb) { + assert.equal(typeof client.id, 'number'); + assert.equal(pool.getPoolSize(), 1); + assertion_count += 2; + cb(); + }); + + assert.equal(pool.getPoolSize(), 0); + assertion_count += 1; + + pooledFn(function(err) { + if (err) { throw err; } + assert.ok(true); + assertion_count += 1; + }); + + beforeExit(function() { + assert.equal(assertion_count, 4); + assert.equal(destroyed_count, 1); + }); + }, + + 'pooled decorator should pass arguments and return values' : function(beforeExit) { + var assertion_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 100 + }); + + var pooledFn = pool.pooled(function(client, arg1, arg2, cb) { + assert.equal(arg1, "First argument"); + assert.equal(arg2, "Second argument"); + assertion_count += 2; + cb(null, "First return", "Second return"); + }); + + pooledFn("First argument", "Second argument", function(err, retVal1, retVal2) { + if(err) { throw err; } + assert.equal(retVal1, "First return"); + assert.equal(retVal2, "Second return"); + assertion_count += 2; + }); + + beforeExit(function() { + assert.equal(assertion_count, 4); + }); + }, + + 'pooled decorator should allow undefined callback' : function(beforeExit) { + var assertion_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 100 + }); + + var pooledFn = pool.pooled(function(client, arg, cb) { + assert.equal(arg, "Arg!"); + assertion_count += 1; + cb(); + }); + + pooledFn("Arg!"); + + beforeExit(function() { + assert.equal(pool.getPoolSize(), 0); + assert.equal(assertion_count, 1); + }); + + }, + + 'pooled decorator should forward pool errors' : function(beforeExit) { + var assertion_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback(new Error('Pool error')); }, + destroy : function(client) { }, + max : 1, + idleTimeoutMillis : 100 + }); + + var pooledFn = pool.pooled(function(cb) { + assert.ok(false, "Pooled function shouldn't be called due to a pool error"); + }); + + pooledFn(function(err, obj) { + assert.equal(err.message, 'Pool error'); + assertion_count += 1; + }); + + beforeExit(function() { + assert.equal(assertion_count, 1); + }); + }, + + 'getPoolSize' : function (beforeExit) { + var assertion_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); }, + destroy : function(client) { }, + max : 2, + idleTimeoutMillis : 100 + }); + + assert.equal(pool.getPoolSize(), 0); + assertion_count += 1; + pool.acquire(function(err, obj1) { + if (err) { throw err; } + assert.equal(pool.getPoolSize(), 1); + assertion_count += 1; + pool.acquire(function(err, obj2) { + if (err) { throw err; } + assert.equal(pool.getPoolSize(), 2); + assertion_count += 1; + + pool.release(obj1); + pool.release(obj2); + + pool.acquire(function(err, obj3) { + if (err) { throw err; } + // should still be 2 + assert.equal(pool.getPoolSize(), 2); + assertion_count += 1; + pool.release(obj3); + }); + }); + }); + + beforeExit(function() { + assert.equal(assertion_count, 4); + }); + }, + + 'availableObjectsCount' : function (beforeExit) { + var assertion_count = 0; + var pool = poolModule.Pool({ + name : 'test1', + create : function(callback) { callback({id: Math.floor(Math.random()*1000)}); }, + destroy : function(client) { }, + max : 2, + idleTimeoutMillis : 100 + }); + + assert.equal(pool.availableObjectsCount(), 0); + assertion_count += 1; + pool.acquire(function(err, obj1) { + if (err) { throw err; } + assert.equal(pool.availableObjectsCount(), 0); + assertion_count += 1; + + pool.acquire(function(err, obj2) { + if (err) { throw err; } + assert.equal(pool.availableObjectsCount(), 0); + assertion_count += 1; + + pool.release(obj1); + assert.equal(pool.availableObjectsCount(), 1); + assertion_count += 1; + + pool.release(obj2); + assert.equal(pool.availableObjectsCount(), 2); + assertion_count += 1; + + pool.acquire(function(err, obj3) { + if (err) { throw err; } + assert.equal(pool.availableObjectsCount(), 1); + assertion_count += 1; + pool.release(obj3); + + assert.equal(pool.availableObjectsCount(), 2); + assertion_count += 1; + }); + }); + }); + + beforeExit(function() { + assert.equal(assertion_count, 7); + }); + }, + + 'logPassesLogLevel': function(beforeExit){ + var loglevels = {'verbose':0, 'info':1, 'warn':2, 'error':3}; + var logmessages = {verbose:[], info:[], warn:[], error:[]}; + var factory = { + name : 'test1', + create : function(callback) {callback(null, {id:Math.floor(Math.random()*1000)}); }, + destroy : function(client) {}, + max : 2, + idleTimeoutMillis: 100, + log : function(msg, level) {testlog(msg, level);} + }; + var testlog = function(msg, level){ + assert.ok(level in loglevels); + logmessages[level].push(msg); + }; + var pool = poolModule.Pool(factory); + + var pool2 = poolModule.Pool({ + name : 'testNoLog', + create : function(callback) {callback(null, {id:Math.floor(Math.random()*1000)}); }, + destroy : function(client) {}, + max : 2, + idleTimeoutMillis: 100 + }); + assert.equal(pool2.getName(), 'testNoLog'); + + pool.acquire(function(err, obj){ + if (err) {throw err;} + assert.equal(logmessages.verbose[0], 'createResource() - creating obj - count=1 min=0 max=2'); + assert.equal(logmessages.info[0], 'dispense() clients=1 available=0'); + logmessages.info = []; + logmessages.verbose = []; + pool2.borrow(function(err, obj){ + assert.equal(logmessages.info.length, 0); + assert.equal(logmessages.verbose.length, 0); + assert.equal(logmessages.warn.length, 0); + }); + }); + }, + + 'removes from available objects on destroy': function(beforeExit){ + var destroyCalled = false; + var factory = { + name: 'test', + create: function(callback) {callback(null, {}); }, + destroy: function(client) {destroyCalled = true; }, + max: 2, + idleTimeoutMillis: 100 + }; + + var pool = poolModule.Pool(factory); + pool.acquire(function(err, obj){ + pool.destroy(obj); + }); + assert.equal(destroyCalled, true); + assert.equal(pool.availableObjectsCount(), 0); + }, + + 'removes from available objects on validation failure': function(beforeExit){ + var destroyCalled = false, + validateCalled = false, + count = 0; + var factory = { + name: 'test', + create: function(callback) {callback(null, {count: count++}); }, + destroy: function(client) {destroyCalled = client.count; }, + validate: function(client) {validateCalled = true; return client.count != 0;}, + max: 2, + idleTimeoutMillis: 100 + }; + + var pool = poolModule.Pool(factory); + pool.acquire(function(err, obj){ + pool.release(obj); + assert.equal(obj.count, 0); + + pool.acquire(function(err, obj){ + pool.release(obj); + assert.equal(obj.count, 1); + }); + }); + assert.equal(validateCalled, true); + assert.equal(destroyCalled, 0); + assert.equal(pool.availableObjectsCount(), 1); + }, + + 'do schedule again if error occured when creating new Objects async': function(beforeExit){ + var factory = { + name: 'test', + create: function(callback) { + process.nextTick(function(){ + var err = new Error('Create Error'); + callback(err); + }) + }, + destroy: function(client) {}, + max: 1, + idleTimeoutMillis: 100 + }; + + var getFlag = 0; + var pool = poolModule.Pool(factory); + pool.acquire(function(){}); + pool.acquire(function(err, obj){ + getFlag = 1; + assert(err); + assert.equal(pool.availableObjectsCount(), 0); + }); + + beforeExit(function() { + assert.equal(getFlag, 1); + }); + } + + +}; diff --git a/node_modules/pg/node_modules/nan/.dntrc b/node_modules/pg/node_modules/nan/.dntrc new file mode 100644 index 0000000..47971da --- /dev/null +++ b/node_modules/pg/node_modules/nan/.dntrc @@ -0,0 +1,30 @@ +## DNT config file +## see https://github.com/rvagg/dnt + +NODE_VERSIONS="\ + master \ + v0.11.13 \ + v0.10.30 \ + v0.10.29 \ + v0.10.28 \ + v0.10.26 \ + v0.10.25 \ + v0.10.24 \ + v0.10.23 \ + v0.10.22 \ + v0.10.21 \ + v0.10.20 \ + v0.10.19 \ + v0.8.28 \ + v0.8.27 \ + v0.8.26 \ + v0.8.24 \ +" +OUTPUT_PREFIX="nan-" +TEST_CMD=" \ + cd /dnt/ && \ + npm install && \ + node_modules/.bin/node-gyp --nodedir /usr/src/node/ rebuild --directory test && \ + node_modules/.bin/tap --gc test/js/*-test.js \ +" + diff --git a/node_modules/pg/node_modules/nan/CHANGELOG.md b/node_modules/pg/node_modules/nan/CHANGELOG.md new file mode 100644 index 0000000..146cbb5 --- /dev/null +++ b/node_modules/pg/node_modules/nan/CHANGELOG.md @@ -0,0 +1,200 @@ +# NAN ChangeLog + +### Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30 + + +**1.3.0 Aug 2 2014** + + - Added NanNew(std::string) + - Added NanNew(std::string&) + - Added NanAsciiString helper class + - Added NanUtf8String helper class + - Added NanUcs2String helper class + - Deprecated NanRawString() + - Deprecated NanCString() + - Added NanGetIsolateData(v8::Isolate *isolate) + - Added NanMakeCallback(v8::Handle target, v8::Handle func, int argc, v8::Handle* argv) + - Added NanMakeCallback(v8::Handle target, v8::Handle symbol, int argc, v8::Handle* argv) + - Added NanMakeCallback(v8::Handle target, const char* method, int argc, v8::Handle* argv) + - Added NanSetTemplate(v8::Handle templ, v8::Handle name , v8::Handle value, v8::PropertyAttribute attributes) + - Added NanSetPrototypeTemplate(v8::Local templ, v8::Handle name, v8::Handle value, v8::PropertyAttribute attributes) + - Added NanSetInstanceTemplate(v8::Local templ, const char *name, v8::Handle value) + - Added NanSetInstanceTemplate(v8::Local templ, v8::Handle name, v8::Handle value, v8::PropertyAttribute attributes) + +**1.2.0 Jun 5 2014** + + - Add NanSetPrototypeTemplate + - Changed NAN_WEAK_CALLBACK internals, switched _NanWeakCallbackData to class, + introduced _NanWeakCallbackDispatcher + - Removed -Wno-unused-local-typedefs from test builds + - Made test builds Windows compatible ('Sleep()') + +**1.1.2 May 28 2014** + + - Release to fix more stuff-ups in 1.1.1 + +**1.1.1 May 28 2014** + + - Release to fix version mismatch in nan.h and lack of changelog entry for 1.1.0 + +**1.1.0 May 25 2014** + + - Remove nan_isolate, use v8::Isolate::GetCurrent() internally instead + - Additional explicit overloads for NanNew(): (char*,int), (uint8_t*[,int]), + (uint16_t*[,int), double, int, unsigned int, bool, v8::String::ExternalStringResource*, + v8::String::ExternalAsciiStringResource* + - Deprecate NanSymbol() + - Added SetErrorMessage() and ErrorMessage() to NanAsyncWorker + +**1.0.0 May 4 2014** + + - Heavy API changes for V8 3.25 / Node 0.11.13 + - Use cpplint.py + - Removed NanInitPersistent + - Removed NanPersistentToLocal + - Removed NanFromV8String + - Removed NanMakeWeak + - Removed NanNewLocal + - Removed NAN_WEAK_CALLBACK_OBJECT + - Removed NAN_WEAK_CALLBACK_DATA + - Introduce NanNew, replaces NanNewLocal, NanPersistentToLocal, adds many overloaded typed versions + - Introduce NanUndefined, NanNull, NanTrue and NanFalse + - Introduce NanEscapableScope and NanEscapeScope + - Introduce NanMakeWeakPersistent (requires a special callback to work on both old and new node) + - Introduce NanMakeCallback for node::MakeCallback + - Introduce NanSetTemplate + - Introduce NanGetCurrentContext + - Introduce NanCompileScript and NanRunScript + - Introduce NanAdjustExternalMemory + - Introduce NanAddGCEpilogueCallback, NanAddGCPrologueCallback, NanRemoveGCEpilogueCallback, NanRemoveGCPrologueCallback + - Introduce NanGetHeapStatistics + - Rename NanAsyncWorker#SavePersistent() to SaveToPersistent() + +**0.8.0 Jan 9 2014** + + - NanDispose -> NanDisposePersistent, deprecate NanDispose + - Extract _NAN_*_RETURN_TYPE, pull up NAN_*() + +**0.7.1 Jan 9 2014** + + - Fixes to work against debug builds of Node + - Safer NanPersistentToLocal (avoid reinterpret_cast) + - Speed up common NanRawString case by only extracting flattened string when necessary + +**0.7.0 Dec 17 2013** + + - New no-arg form of NanCallback() constructor. + - NanCallback#Call takes Handle rather than Local + - Removed deprecated NanCallback#Run method, use NanCallback#Call instead + - Split off _NAN_*_ARGS_TYPE from _NAN_*_ARGS + - Restore (unofficial) Node 0.6 compatibility at NanCallback#Call() + - Introduce NanRawString() for char* (or appropriate void*) from v8::String + (replacement for NanFromV8String) + - Introduce NanCString() for null-terminated char* from v8::String + +**0.6.0 Nov 21 2013** + + - Introduce NanNewLocal(v8::Handle value) for use in place of + v8::Local::New(...) since v8 started requiring isolate in Node 0.11.9 + +**0.5.2 Nov 16 2013** + + - Convert SavePersistent and GetFromPersistent in NanAsyncWorker from protected and public + +**0.5.1 Nov 12 2013** + + - Use node::MakeCallback() instead of direct v8::Function::Call() + +**0.5.0 Nov 11 2013** + + - Added @TooTallNate as collaborator + - New, much simpler, "include_dirs" for binding.gyp + - Added full range of NAN_INDEX_* macros to match NAN_PROPERTY_* macros + +**0.4.4 Nov 2 2013** + + - Isolate argument from v8::Persistent::MakeWeak removed for 0.11.8+ + +**0.4.3 Nov 2 2013** + + - Include node_object_wrap.h, removed from node.h for Node 0.11.8. + +**0.4.2 Nov 2 2013** + + - Handle deprecation of v8::Persistent::Dispose(v8::Isolate* isolate)) for + Node 0.11.8 release. + +**0.4.1 Sep 16 2013** + + - Added explicit `#include ` as it was removed from node.h for v0.11.8 + +**0.4.0 Sep 2 2013** + + - Added NAN_INLINE and NAN_DEPRECATED and made use of them + - Added NanError, NanTypeError and NanRangeError + - Cleaned up code + +**0.3.2 Aug 30 2013** + + - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent + in NanAsyncWorker + +**0.3.1 Aug 20 2013** + + - fix "not all control paths return a value" compile warning on some platforms + +**0.3.0 Aug 19 2013** + + - Made NAN work with NPM + - Lots of fixes to NanFromV8String, pulling in features from new Node core + - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API + - Added optional error number argument for NanThrowError() + - Added NanInitPersistent() + - Added NanReturnNull() and NanReturnEmptyString() + - Added NanLocker and NanUnlocker + - Added missing scopes + - Made sure to clear disposed Persistent handles + - Changed NanAsyncWorker to allocate error messages on the heap + - Changed NanThrowError(Local) to NanThrowError(Handle) + - Fixed leak in NanAsyncWorker when errmsg is used + +**0.2.2 Aug 5 2013** + + - Fixed usage of undefined variable with node::BASE64 in NanFromV8String() + +**0.2.1 Aug 5 2013** + + - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for + NanFromV8String() + +**0.2.0 Aug 5 2013** + + - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR, + NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY + - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS, + _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS, + _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS, + _NAN_PROPERTY_QUERY_ARGS + - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer + - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT, + NAN_WEAK_CALLBACK_DATA, NanMakeWeak + - Renamed THROW_ERROR to _NAN_THROW_ERROR + - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*) + - Added NanBufferUse(char*, uint32_t) + - Added NanNewContextHandle(v8::ExtensionConfiguration*, + v8::Handle, v8::Handle) + - Fixed broken NanCallback#GetFunction() + - Added optional encoding and size arguments to NanFromV8String() + - Added NanGetPointerSafe() and NanSetPointerSafe() + - Added initial test suite (to be expanded) + - Allow NanUInt32OptionValue to convert any Number object + +**0.1.0 Jul 21 2013** + + - Added `NAN_GETTER`, `NAN_SETTER` + - Added `NanThrowError` with single Local argument + - Added `NanNewBufferHandle` with single uint32_t argument + - Added `NanHasInstance(Persistent&, Handle)` + - Added `Local NanCallback#GetFunction()` + - Added `NanCallback#Call(int, Local[])` + - Deprecated `NanCallback#Run(int, Local[])` in favour of Call diff --git a/node_modules/pg/node_modules/nan/LICENSE b/node_modules/pg/node_modules/nan/LICENSE new file mode 100644 index 0000000..d502e18 --- /dev/null +++ b/node_modules/pg/node_modules/nan/LICENSE @@ -0,0 +1,46 @@ +Copyright 2013, NAN contributors: + - Rod Vagg + - Benjamin Byholm + - Trevor Norris + - Nathan Rajlich + - Brett Lawson + - Ben Noordhuis +(the "Original Author") +All rights reserved. + +MIT +no-false-attribs License + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +Distributions of all or part of the Software intended to be used +by the recipients as they would use the unmodified Software, +containing modifications that substantially alter, remove, or +disable functionality of the Software, outside of the documented +configuration mechanisms provided by the Software, shall be +modified such that the Original Author's bug reporting email +addresses and urls are either replaced with the contact information +of the parties responsible for the changes, or removed entirely. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + + +Except where noted, this license applies to any and all software +programs and associated documentation files created by the +Original Author, when distributed with the Software. diff --git a/node_modules/pg/node_modules/nan/README.md b/node_modules/pg/node_modules/nan/README.md new file mode 100644 index 0000000..2904a38 --- /dev/null +++ b/node_modules/pg/node_modules/nan/README.md @@ -0,0 +1,1054 @@ +Native Abstractions for Node.js +=============================== + +**A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.** + +***Current version: 1.3.0*** + +*(See [nan.h](https://github.com/rvagg/nan/blob/master/CHANGELOG.md) for complete ChangeLog)* + +[![NPM](https://nodei.co/npm/nan.png?downloads=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/) + +[![Build Status](https://secure.travis-ci.org/rvagg/nan.png)](http://travis-ci.org/rvagg/nan) +[![Build status](https://ci.appveyor.com/api/projects/status/kh73pbm9dsju7fgh)](https://ci.appveyor.com/project/RodVagg/nan) + +Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle. + +This project also contains some helper utilities that make addon development a bit more pleasant. + + * **[News & Updates](#news)** + * **[Usage](#usage)** + * **[Example](#example)** + * **[API](#api)** + + +## News & Updates + +### Aug-2014: 1.3.0 release + +* `NanCString()` and `NanRawString()` have been deprecated in favour of new NanAsciiString, NanUtf8String and NanUcs2String. These classes manage the underlying memory for you in a safer way than just handing off an allocated array. You should now `*NanAsciiString(handle)` to access the raw `char` data, you can also allocate on the heap if you need to keep a reference. +* Two more NanMakeCallback overloads have been added to for parity with Node core. +* You can now `NanNew(std::string)` (use `NanNew(std::string&)` to pass by reference) +* NanSetTemplate, NanSetPrototypeTemplate and NanSetInstanceTemplate have been added. + +### May-2014: 1.1.0 release + +* We've deprecated `NanSymbol()`, you should just use `NanNew()` now. +* `NanNull()`, `NanUndefined()`, `NanTrue()`, `NanFalse()` all return `Local`s now. +* `nan_isolate` is gone, it was intended to be internal-only but if you were using it then you should switch to `v8::Isolate::GetCurrent()`. +* `NanNew()` has received some additional overload-love so you should be able to give it many kinds of values without specifying the ``. +* Lots of small fixes and additions to expand the V8 API coverage, *use the source, Luke*. + + +### May-2014: Major changes for V8 3.25 / Node 0.11.13 + +Node 0.11.11 and 0.11.12 were both broken releases for native add-ons, you simply can't properly compile against either of them for different reasons. But we now have a 0.11.13 release that jumps a couple of versions of V8 ahead and includes some more, major (traumatic) API changes. + +Because we are now nearing Node 0.12 and estimate that the version of V8 we are using in Node 0.11.13 will be close to the API we get for 0.12, we have taken the opportunity to not only *fix* NAN for 0.11.13 but make some major changes to improve the NAN API. + +We have **removed support for Node 0.11 versions prior to 0.11.13**. As usual, our tests are run against (and pass) the last 5 versions of Node 0.8 and Node 0.10. We also include Node 0.11.13 obviously. + +The major change is something that [Benjamin Byholm](kkoopa) has put many hours in to. We now have a fantastic new `NanNew(args)` interface for creating new `Local`s, this replaces `NanNewLocal()` and much more. If you look in [./nan.h](nan.h) you'll see a large number of overloaded versions of this method. In general you should be able to `NanNew(arguments)` for any type you want to make a `Local` from. This includes `Persistent` types, so we now have a `Local NanNew(const Persistent arg)` to replace `NanPersistentToLocal()`. + +We also now have `NanUndefined()`, `NanNull()`, `NanTrue()` and `NanFalse()`. Mainly because of the new requirement for an `Isolate` argument for each of the native V8 versions of this. + +V8 has now introduced an `EscapableHandleScope` from which you `scope.Escape(Local value)` to *return* a value from a one scope to another. This replaces the standard `HandleScope` and `scope.Close(Local value)`, although `HandleScope` still exists for when you don't need to return a handle to the caller. For NAN we are exposing it as `NanEscapableScope()` and `NanEscapeScope()`, while `NanScope()` is still how you create a new scope that doesn't need to return handles. For older versions of Node/V8, it'll still map to the older `HandleScope` functionality. + +`NanFromV8String()` was deprecated and has now been removed. You should use `NanCString()` or `NanRawString()` instead. + +Because `node::MakeCallback()` now takes an `Isolate`, and because it doesn't exist in older versions of Node, we've introduced `NanMakeCallback()`. You should *always* use this when calling a JavaScript function from C++. + +There's lots more, check out the Changelog in nan.h or look through [#86](https://github.com/rvagg/nan/pull/86) for all the gory details. + +### Dec-2013: NanCString and NanRawString + +Two new functions have been introduced to replace the functionality that's been provided by `NanFromV8String` until now. NanCString has sensible defaults so it's super easy to fetch a null-terminated c-style string out of a `v8::String`. `NanFromV8String` is still around and has defaults that allow you to pass a single handle to fetch a `char*` while `NanRawString` requires a little more attention to arguments. + +### Nov-2013: Node 0.11.9+ breaking V8 change + +The version of V8 that's shipping with Node 0.11.9+ has changed the signature for new `Local`s to: `v8::Local::New(isolate, value)`, i.e. introducing the `isolate` argument and therefore breaking all new `Local` declarations for previous versions. NAN 0.6+ now includes a `NanNewLocal(value)` that can be used in place to work around this incompatibility and maintain compatibility with 0.8->0.11.9+ (minus a few early 0.11 releases). + +For example, if you wanted to return a `null` on a callback you will have to change the argument from `v8::Local::New(v8::Null())` to `NanNewLocal(v8::Null())`. + +### Nov-2013: Change to binding.gyp `"include_dirs"` for NAN + +Inclusion of NAN in a project's binding.gyp is now greatly simplified. You can now just use `" +## Usage + +Simply add **NAN** as a dependency in the *package.json* of your Node addon: + +``` bash +$ npm install --save nan +``` + +Pull in the path to **NAN** in your *binding.gyp* so that you can use `#include ` in your *.cpp* files: + +``` python +"include_dirs" : [ + "` when compiling your addon. + + +## Example + +See **[LevelDOWN](https://github.com/rvagg/node-leveldown/pull/48)** for a full example of **NAN** in use. + +For a simpler example, see the **[async pi estimation example](https://github.com/rvagg/nan/tree/master/examples/async_pi_estimate)** in the examples directory for full code and an explanation of what this Monte Carlo Pi estimation example does. Below are just some parts of the full example that illustrate the use of **NAN**. + +Compare to the current 0.10 version of this example, found in the [node-addon-examples](https://github.com/rvagg/node-addon-examples/tree/master/9_async_work) repository and also a 0.11 version of the same found [here](https://github.com/kkoopa/node-addon-examples/tree/5c01f58fc993377a567812597e54a83af69686d7/9_async_work). + +Note that there is no embedded version sniffing going on here and also the async work is made much simpler, see below for details on the `NanAsyncWorker` class. + +```c++ +// addon.cc +#include +#include +// ... + +using v8::FunctionTemplate; +using v8::Handle; +using v8::Object; +using v8::String; + +void InitAll(Handle exports) { + exports->Set(NanNew("calculateSync"), + NanNew(CalculateSync)->GetFunction()); + + exports->Set(NanNew("calculateAsync"), + NanNew(CalculateAsync)->GetFunction()); +} + +NODE_MODULE(addon, InitAll) +``` + +```c++ +// sync.h +#include +#include + +NAN_METHOD(CalculateSync); +``` + +```c++ +// sync.cc +#include +#include +#include "./sync.h" +// ... + +using v8::Number; + +// Simple synchronous access to the `Estimate()` function +NAN_METHOD(CalculateSync) { + NanScope(); + + // expect a number as the first argument + int points = args[0]->Uint32Value(); + double est = Estimate(points); + + NanReturnValue(NanNew(est)); +} +``` + +```c++ +// async.h +#include +#include + +NAN_METHOD(CalculateAsync); +``` + +```c++ +// async.cc +#include +#include +#include "./async.h" + +// ... + +using v8::Function; +using v8::Local; +using v8::Null; +using v8::Number; +using v8::Value; + +class PiWorker : public NanAsyncWorker { + public: + PiWorker(NanCallback *callback, int points) + : NanAsyncWorker(callback), points(points) {} + ~PiWorker() {} + + // Executed inside the worker-thread. + // It is not safe to access V8, or V8 data structures + // here, so everything we need for input and output + // should go on `this`. + void Execute () { + estimate = Estimate(points); + } + + // Executed when the async work is complete + // this function will be run inside the main event loop + // so it is safe to use V8 again + void HandleOKCallback () { + NanScope(); + + Local argv[] = { + NanNull() + , NanNew(estimate) + }; + + callback->Call(2, argv); + }; + + private: + int points; + double estimate; +}; + +// Asynchronous access to the `Estimate()` function +NAN_METHOD(CalculateAsync) { + NanScope(); + + int points = args[0]->Uint32Value(); + NanCallback *callback = new NanCallback(args[1].As()); + + NanAsyncQueueWorker(new PiWorker(callback, points)); + NanReturnUndefined(); +} +``` + + +## API + + * NAN_METHOD + * NAN_GETTER + * NAN_SETTER + * NAN_PROPERTY_GETTER + * NAN_PROPERTY_SETTER + * NAN_PROPERTY_ENUMERATOR + * NAN_PROPERTY_DELETER + * NAN_PROPERTY_QUERY + * NAN_INDEX_GETTER + * NAN_INDEX_SETTER + * NAN_INDEX_ENUMERATOR + * NAN_INDEX_DELETER + * NAN_INDEX_QUERY + * NAN_WEAK_CALLBACK + * NAN_DEPRECATED + * NAN_INLINE + * NanNew + * NanUndefined + * NanNull + * NanTrue + * NanFalse + * NanReturnValue + * NanReturnUndefined + * NanReturnNull + * NanReturnEmptyString + * NanScope + * NanEscapableScope + * NanEscapeScope + * NanLocker + * NanUnlocker + * NanGetInternalFieldPointer + * NanSetInternalFieldPointer + * NanObjectWrapHandle + * NanSymbol + * NanGetPointerSafe + * NanSetPointerSafe + * NanRawString + * NanCString + * NanAsciiString + * NanUtf8String + * NanUcs2String + * NanBooleanOptionValue + * NanUInt32OptionValue + * NanError, NanTypeError, NanRangeError + * NanThrowError, NanThrowTypeError, NanThrowRangeError, NanThrowError(Handle), NanThrowError(Handle, int) + * NanNewBufferHandle(char *, size_t, FreeCallback, void *), NanNewBufferHandle(char *, uint32_t), NanNewBufferHandle(uint32_t) + * NanBufferUse(char *, uint32_t) + * NanNewContextHandle + * NanGetCurrentContext + * NanHasInstance + * NanDisposePersistent + * NanAssignPersistent + * NanMakeWeakPersistent + * NanSetTemplate + * NanSetPrototypeTemplate + * NanSetInstanceTemplate + * NanMakeCallback + * NanCompileScript + * NanRunScript + * NanAdjustExternalMemory + * NanAddGCEpilogueCallback + * NanAddGCPrologueCallback + * NanRemoveGCEpilogueCallback + * NanRemoveGCPrologueCallback + * NanGetHeapStatistics + * NanCallback + * NanAsyncWorker + * NanAsyncQueueWorker + + +### NAN_METHOD(methodname) + +Use `NAN_METHOD` to define your V8 accessible methods: + +```c++ +// .h: +class Foo : public node::ObjectWrap { + ... + + static NAN_METHOD(Bar); + static NAN_METHOD(Baz); +} + + +// .cc: +NAN_METHOD(Foo::Bar) { + ... +} + +NAN_METHOD(Foo::Baz) { + ... +} +``` + +The reason for this macro is because of the method signature change in 0.11: + +```c++ +// 0.10 and below: +Handle name(const Arguments& args) + +// 0.11 and above +void name(const FunctionCallbackInfo& args) +``` + +The introduction of `FunctionCallbackInfo` brings additional complications: + + +### NAN_GETTER(methodname) + +Use `NAN_GETTER` to declare your V8 accessible getters. You get a `Local` `property` and an appropriately typed `args` object that can act like the `args` argument to a `NAN_METHOD` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_GETTER`. + + +### NAN_SETTER(methodname) + +Use `NAN_SETTER` to declare your V8 accessible setters. Same as `NAN_GETTER` but you also get a `Local` `value` object to work with. + + +### NAN_PROPERTY_GETTER(cbname) +Use `NAN_PROPERTY_GETTER` to declare your V8 accessible property getters. You get a `Local` `property` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_GETTER`. + + +### NAN_PROPERTY_SETTER(cbname) +Use `NAN_PROPERTY_SETTER` to declare your V8 accessible property setters. Same as `NAN_PROPERTY_GETTER` but you also get a `Local` `value` object to work with. + + +### NAN_PROPERTY_ENUMERATOR(cbname) +Use `NAN_PROPERTY_ENUMERATOR` to declare your V8 accessible property enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_PROPERTY_GETTER` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_ENUMERATOR`. + + +### NAN_PROPERTY_DELETER(cbname) +Use `NAN_PROPERTY_DELETER` to declare your V8 accessible property deleters. Same as `NAN_PROPERTY_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_DELETER`. + + +### NAN_PROPERTY_QUERY(cbname) +Use `NAN_PROPERTY_QUERY` to declare your V8 accessible property queries. Same as `NAN_PROPERTY_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_QUERY`. + + +### NAN_INDEX_GETTER(cbname) +Use `NAN_INDEX_GETTER` to declare your V8 accessible index getters. You get a `uint32_t` `index` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_GETTER`. + + +### NAN_INDEX_SETTER(cbname) +Use `NAN_INDEX_SETTER` to declare your V8 accessible index setters. Same as `NAN_INDEX_GETTER` but you also get a `Local` `value` object to work with. + + +### NAN_INDEX_ENUMERATOR(cbname) +Use `NAN_INDEX_ENUMERATOR` to declare your V8 accessible index enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_INDEX_GETTER` call. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_ENUMERATOR`. + + +### NAN_INDEX_DELETER(cbname) +Use `NAN_INDEX_DELETER` to declare your V8 accessible index deleters. Same as `NAN_INDEX_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_DELETER`. + + +### NAN_INDEX_QUERY(cbname) +Use `NAN_INDEX_QUERY` to declare your V8 accessible index queries. Same as `NAN_INDEX_GETTER`. + +You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_QUERY`. + + +### NAN_WEAK_CALLBACK(cbname) + +Use `NAN_WEAK_CALLBACK` to define your V8 WeakReference callbacks. There is an argument object `const _NanWeakCallbackData &data` allowing access to the weak object and the supplied parameter through its `GetValue` and `GetParameter` methods. You can even access the weak callback info object through the `GetCallbackInfo()`method, but you probably should not. `Revive()` keeps the weak object alive until the next GC round. + +```c++ +NAN_WEAK_CALLBACK(weakCallback) { + int *parameter = data.GetParameter(); + NanMakeCallback(NanGetCurrentContext()->Global(), data.GetValue(), 0, NULL); + if ((*parameter)++ == 0) { + data.Revive(); + } else { + delete parameter; + } +} +``` + + +### NAN_DEPRECATED +Declares a function as deprecated. + +```c++ +static NAN_DEPRECATED NAN_METHOD(foo) { + ... +} +``` + + +### NAN_INLINE +Inlines a function. + +```c++ +NAN_INLINE int foo(int bar) { + ... +} +``` + + +### Local<T> NanNew<T>( ... ) + +Use `NanNew` to construct almost all v8 objects and make new local handles. + +Note: Using NanNew with an std::string is possible, however, you should ensure +to use the overload version (`NanNew(stdString)`) rather than the template +version (`NanNew(stdString)`) as there is an unnecessary +performance penalty to using the template version because of the inability for +compilers to appropriately deduce to reference types on template specialization. + +```c++ +Local s = NanNew("value"); + +... + +Persistent o; + +... + +Local lo = NanNew(o); + +``` + + +### Local<Primitive> NanUndefined() + +Use instead of `Undefined()` + + +### Local<Primitive> NanNull() + +Use instead of `Null()` + + +### Local<Boolean> NanTrue() + +Use instead of `True()` + + +### Local<Boolean> NanFalse() + +Use instead of `False()` + + +### NanReturnValue(Handle<Value>) + +Use `NanReturnValue` when you want to return a value from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Bar) { + ... + + NanReturnValue(NanNew("FooBar!")); +} +``` + +No `return` statement required. + + +### NanReturnUndefined() + +Use `NanReturnUndefined` when you don't want to return anything from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnUndefined(); +} +``` + + +### NanReturnNull() + +Use `NanReturnNull` when you want to return `Null` from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnNull(); +} +``` + + +### NanReturnEmptyString() + +Use `NanReturnEmptyString` when you want to return an empty `String` from your V8 accessible method: + +```c++ +NAN_METHOD(Foo::Baz) { + ... + + NanReturnEmptyString(); +} +``` + + +### NanScope() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanScope()` necessary, use it in place of `HandleScope scope` when you do not wish to return handles (`Handle` or `Local`) to the surrounding scope (or in functions directly exposed to V8, as they do not return values in the normal sense): + +```c++ +NAN_METHOD(Foo::Bar) { + NanScope(); + + NanReturnValue(NanNew("FooBar!")); +} +``` + +This method is not directly exposed to V8, nor does it return a handle, so it uses an unescapable scope: + +```c++ +bool Foo::Bar() { + NanScope(); + + Local val = NanFalse(); + ... + return val->Value(); +} +``` + + +### NanEscapableScope() + +The separation of handle scopes into escapable and inescapable scopes makes `NanEscapableScope()` necessary, use it in place of `HandleScope scope` when you later wish to return a handle (`Handle` or `Local`) from the scope, this is for internal functions not directly exposed to V8: + +```c++ +Handle Foo::Bar() { + NanEscapableScope(); + + return NanEscapeScope(NanNew("FooBar!")); +} +``` + + +### Local<T> NanEscapeScope(Handle<T> value); +Use together with `NanEscapableScope` to escape the scope. Corresponds to `HandleScope::Close` or `EscapableHandleScope::Escape`. + + +### NanLocker() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanLocker()` necessary, use it in place of `Locker locker`: + +```c++ +NAN_METHOD(Foo::Bar) { + NanLocker(); + ... + NanUnlocker(); +} +``` + + +### NanUnlocker() + +The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanUnlocker()` necessary, use it in place of `Unlocker unlocker`: + +```c++ +NAN_METHOD(Foo::Bar) { + NanLocker(); + ... + NanUnlocker(); +} +``` + + +### void * NanGetInternalFieldPointer(Handle<Object>, int) + +Gets a pointer to the internal field with at `index` from a V8 `Object` handle. + +```c++ +Local obj; +... +NanGetInternalFieldPointer(obj, 0); +``` + +### void NanSetInternalFieldPointer(Handle<Object>, int, void *) + +Sets the value of the internal field at `index` on a V8 `Object` handle. + +```c++ +static Persistent dataWrapperCtor; +... +Local wrapper = NanNew(dataWrapperCtor)->NewInstance(); +NanSetInternalFieldPointer(wrapper, 0, this); +``` + + +### Local<Object> NanObjectWrapHandle(Object) + +When you want to fetch the V8 object handle from a native object you've wrapped with Node's `ObjectWrap`, you should use `NanObjectWrapHandle`: + +```c++ +NanObjectWrapHandle(iterator)->Get(NanNew("end")) +``` + + +### Local<String> NanSymbol(const char *) + +Deprecated. Use `NanNew` instead. +Use to create string symbol objects (i.e. `v8::String::NewSymbol(x)`), for getting and setting object properties, or names of objects. + +```c++ +bool foo = false; +if (obj->Has(NanNew("foo"))) + foo = optionsObj->Get(NanNew("foo"))->BooleanValue() +``` + + +### Type NanGetPointerSafe(Type *[, Type]) + +A helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to. + +```c++ +char *plugh(uint32_t *optional) { + char res[] = "xyzzy"; + uint32_t param = NanGetPointerSafe(optional, 0x1337); + switch (param) { + ... + } + NanSetPointerSafe(optional, 0xDEADBEEF); +} +``` + + +### bool NanSetPointerSafe(Type *, Type) + +A helper for setting optional argument pointers. If the pointer is `NULL`, the function simply returns `false`. Otherwise, the value is assigned to the variable the pointer points to. + +```c++ +const char *plugh(size_t *outputsize) { + char res[] = "xyzzy"; + if !(NanSetPointerSafe(outputsize, strlen(res) + 1)) { + ... + } + + ... +} +``` + + +### void* NanRawString(Handle<Value>, enum Nan::Encoding, size_t *, void *, size_t, int) + +Deprecated. Use something else. + +When you want to convert a V8 `String` to a `char*` buffer, use `NanRawString`. You have to supply an encoding as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows setting `String::WriteOptions`. +Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer: + +```c++ +size_t count; +void* decoded = NanRawString(args[1], Nan::BASE64, &count, NULL, 0, String::HINT_MANY_WRITES_EXPECTED); +... +delete[] reinterpret_cast(decoded); +``` + + +### char* NanCString(Handle<Value>, size_t *[, char *, size_t, int]) + +Deprecated. Use `NanUtf8String` instead. + +When you want to convert a V8 `String` to a null-terminated C `char*` use `NanCString`. The resulting `char*` will be UTF-8-encoded, and you need to supply a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `v8::String::NO_OPTIONS`. +Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer: + +```c++ +size_t count; +char* name = NanCString(args[0], &count); +... +delete[] name; +``` + + +### NanAsciiString + +Convert a `String` to zero-terminated, Ascii-encoded `char *`. + +```c++ +NAN_METHOD(foo) { + NanScope(); + NanReturnValue(NanNew(*NanAsciiString(arg[0]))); +} +``` + + +### NanUtf8String + +Convert a `String` to zero-terminated, Utf8-encoded `char *`. + +```c++ +NAN_METHOD(foo) { + NanScope(); + NanReturnValue(NanNew(*NanUtf8String(arg[0]))); +} +``` + + +### NanUcs2String + +Convert a `String` to zero-terminated, Ucs2-encoded `uint16_t *`. + +```c++ +NAN_METHOD(foo) { + NanScope(); + NanReturnValue(NanNew(*NanUcs2String(arg[0]))); +} +``` + + +### bool NanBooleanOptionValue(Handle<Value>, Handle<String>[, bool]) + +When you have an "options" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`. + +The optional last parameter is the *default* value, which is `false` if left off: + +```c++ +// `foo` is false unless the user supplies a truthy value for it +bool foo = NanBooleanOptionValue(optionsObj, NanNew("foo")); +// `bar` is true unless the user supplies a falsy value for it +bool bar = NanBooleanOptionValueDefTrue(optionsObj, NanNew("bar"), true); +``` + + +### uint32_t NanUInt32OptionValue(Handle<Value>, Handle<String>, uint32_t) + +Similar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer. + +Requires all 3 arguments as a default is not optional: + +```c++ +uint32_t count = NanUInt32OptionValue(optionsObj, NanNew("count"), 1024); +``` + + +### NanError(message), NanTypeError(message), NanRangeError(message) + +For making `Error`, `TypeError` and `RangeError` objects. + +```c++ +Local res = NanError("you must supply a callback argument"); +``` + + +### NanThrowError(message), NanThrowTypeError(message), NanThrowRangeError(message), NanThrowError(Local<Value>), NanThrowError(Local<Value>, int) + +For throwing `Error`, `TypeError` and `RangeError` objects. + +```c++ +NanThrowError("you must supply a callback argument"); +``` + +Can also handle any custom object you may want to throw. If used with the error code argument, it will add the supplied error code to the error object as a property called `code`. + + +### Local<Object> NanNewBufferHandle(char *, uint32_t), Local<Object> NanNewBufferHandle(uint32_t) + +The `Buffer` API has changed a little in Node 0.11, this helper provides consistent access to `Buffer` creation: + +```c++ +NanNewBufferHandle((char*)value.data(), value.size()); +``` + +Can also be used to initialize a `Buffer` with just a `size` argument. + +Can also be supplied with a `NanFreeCallback` and a hint for the garbage collector. + + +### Local<Object> NanBufferUse(char*, uint32_t) + +`Buffer::New(char*, uint32_t)` prior to 0.11 would make a copy of the data. +While it was possible to get around this, it required a shim by passing a +callback. So the new API `Buffer::Use(char*, uint32_t)` was introduced to remove +needing to use this shim. + +`NanBufferUse` uses the `char*` passed as the backing data, and will free the +memory automatically when the weak callback is called. Keep this in mind, as +careless use can lead to "double free or corruption" and other cryptic failures. + + +### bool NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>) + +Can be used to check the type of an object to determine it is of a particular class you have already defined and have a `Persistent` handle for. + + +### Local<Context> NanNewContextHandle([ExtensionConfiguration*, Handle<ObjectTemplate>, Handle<Value>]) +Creates a new `Local` handle. + +```c++ +Local ftmpl = NanNew(); +Local otmpl = ftmpl->InstanceTemplate(); +Local ctx = NanNewContextHandle(NULL, otmpl); +``` + + +### Local<Context> NanGetCurrentContext() + +Gets the current context. + +```c++ +Local ctx = NanGetCurrentContext(); +``` + + +### void NanDisposePersistent(Persistent<T> &) + +Use `NanDisposePersistent` to dispose a `Persistent` handle. + +```c++ +NanDisposePersistent(persistentHandle); +``` + + +### NanAssignPersistent(handle, object) + +Use `NanAssignPersistent` to assign a non-`Persistent` handle to a `Persistent` one. You can no longer just declare a `Persistent` handle and assign directly to it later, you have to `Reset` it in Node 0.11, so this makes it easier. + +In general it is now better to place anything you want to protect from V8's garbage collector as properties of a generic `Object` and then assign that to a `Persistent`. This works in older versions of Node also if you use `NanAssignPersistent`: + +```c++ +Persistent persistentHandle; + +... + +Local obj = NanNew(); +obj->Set(NanNew("key"), keyHandle); // where keyHandle might be a Local +NanAssignPersistent(persistentHandle, obj) +``` + + +### _NanWeakCallbackInfo<T, P>* NanMakeWeakPersistent(Handle<T>, P*, _NanWeakCallbackInfo<T, P>::Callback) + +Creates a weak persistent handle with the supplied parameter and `NAN_WEAK_CALLBACK`. + +```c++ +NAN_WEAK_CALLBACK(weakCallback) { + +... + +} + +Local func; + +... + +int *parameter = new int(0); +NanMakeWeakPersistent(func, parameter, &weakCallback); +``` + + +### NanSetTemplate(templ, name, value [, attributes]) + +Use to add properties on object and function templates. + + +### NanSetPrototypeTemplate(templ, name, value [, attributes]) + +Use to add prototype properties on function templates. + + +### NanSetInstanceTemplate(templ, name, value [, attributes]) + +Use to add instance properties on function templates. + + +### NanMakeCallback(target, func, argc, argv) + +Use instead of `node::MakeCallback` to call javascript functions. This is the only proper way of calling functions. + + +### NanCompileScript(Handle s [, const ScriptOrigin& origin]) + +Use to create new scripts bound to the current context. + + +### NanRunScript(script) + +Use to run both bound and unbound scripts. + + +### NanAdjustExternalMemory(int change_in_bytes) + +Simply does `AdjustAmountOfExternalAllocatedMemory`, note that the argument and returned value have type `int`. + + +### NanAddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type_filter=kGCTypeAll) + +Simply does `AddGCEpilogueCallback` + + +### NanAddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type_filter=kGCTypeAll) + +Simply does `AddGCPrologueCallback` + + +### NanRemoveGCEpilogueCallback(GCEpilogueCallback callback) + +Simply does `RemoveGCEpilogueCallback` + + +### NanRemoveGCPrologueCallback(GCPrologueCallback callback) + +Simply does `RemoveGCPrologueCallback` + + +### NanGetHeapStatistics(HeapStatistics *heap_statistics) + +Simply does `GetHeapStatistics` + + +### NanCallback + +Because of the difficulties imposed by the changes to `Persistent` handles in V8 in Node 0.11, creating `Persistent` versions of your `Handle` is annoyingly tricky. `NanCallback` makes it easier by taking your handle, making it persistent until the `NanCallback` is deleted and even providing a handy `Call()` method to fetch and execute the callback `Function`. + +```c++ +Local callbackHandle = args[0].As(); +NanCallback *callback = new NanCallback(callbackHandle); +// pass `callback` around and it's safe from GC until you: +delete callback; +``` + +You can execute the callback like so: + +```c++ +// no arguments: +callback->Call(0, NULL); + +// an error argument: +Handle argv[] = { + NanError(NanNew("fail!")) +}; +callback->Call(1, argv); + +// a success argument: +Handle argv[] = { + NanNull(), + NanNew("w00t!") +}; +callback->Call(2, argv); +``` + +`NanCallback` also has a `Local GetCallback()` method that you can use +to fetch a local handle to the underlying callback function, as well as a +`void SetFunction(Handle)` for setting the callback on the +`NanCallback`. You can check if a `NanCallback` is empty with the `bool IsEmpty()` method. Additionally a generic constructor is available for using +`NanCallback` without performing heap allocations. + + +### NanAsyncWorker + +`NanAsyncWorker` is an abstract class that you can subclass to have much of the annoying async queuing and handling taken care of for you. It can even store arbitrary V8 objects for you and have them persist while the async work is in progress. + +See a rough outline of the implementation: + +```c++ +class NanAsyncWorker { +public: + NanAsyncWorker (NanCallback *callback); + + // Clean up persistent handles and delete the *callback + virtual ~NanAsyncWorker (); + + // Check the `ErrorMessage()` and call HandleOKCallback() + // or HandleErrorCallback depending on whether it has been set or not + virtual void WorkComplete (); + + // You must implement this to do some async work. If there is an + // error then use `SetErrorMessage()` to set an error message and the callback will + // be passed that string in an Error object + virtual void Execute (); + + // Save a V8 object in a Persistent handle to protect it from GC + void SaveToPersistent(const char *key, Local &obj); + + // Fetch a stored V8 object (don't call from within `Execute()`) + Local GetFromPersistent(const char *key); + + // Get the error message (or NULL) + const char *ErrorMessage(); + + // Set an error message + void SetErrorMessage(const char *msg); + +protected: + // Default implementation calls the callback function with no arguments. + // Override this to return meaningful data + virtual void HandleOKCallback (); + + // Default implementation calls the callback function with an Error object + // wrapping the `errmsg` string + virtual void HandleErrorCallback (); +}; +``` + + +### NanAsyncQueueWorker(NanAsyncWorker *) + +`NanAsyncQueueWorker` will run a `NanAsyncWorker` asynchronously via libuv. Both the *execute* and *after_work* steps are taken care of for you—most of the logic for this is embedded in `NanAsyncWorker`. + +### Contributors + +NAN is only possible due to the excellent work of the following contributors: + + + + + + + + +
Rod VaggGitHub/rvaggTwitter/@rvagg
Benjamin ByholmGitHub/kkoopa-
Trevor NorrisGitHub/trevnorrisTwitter/@trevnorris
Nathan RajlichGitHub/TooTallNateTwitter/@TooTallNate
Brett LawsonGitHub/brett19Twitter/@brett19x
Ben NoordhuisGitHub/bnoordhuisTwitter/@bnoordhuis
+ +Licence & copyright +----------------------- + +Copyright (c) 2014 NAN contributors (listed above). + +Native Abstractions for Node.js is licensed under an MIT +no-false-attribs license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/node_modules/pg/node_modules/nan/appveyor.yml b/node_modules/pg/node_modules/nan/appveyor.yml new file mode 100644 index 0000000..657eed6 --- /dev/null +++ b/node_modules/pg/node_modules/nan/appveyor.yml @@ -0,0 +1,32 @@ +# http://www.appveyor.com/docs/appveyor-yml + +# Test against these versions of Node.js. +environment: + matrix: + - nodejs_version: "0.8" + - nodejs_version: "0.10" + - nodejs_version: "0.11" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node 0.STABLE.latest + - npm install npm + - move node_modules npm + - ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version) + # Typical npm stuff. + - npm/.bin/npm install + - npm/.bin/npm run rebuild-tests + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - npm --version + - cmd: npm test + +# Don't actually build. +build: off + +# Set build version format here instead of in the admin panel. +version: "{build}" + diff --git a/node_modules/pg/node_modules/nan/include_dirs.js b/node_modules/pg/node_modules/nan/include_dirs.js new file mode 100644 index 0000000..4f1dfb4 --- /dev/null +++ b/node_modules/pg/node_modules/nan/include_dirs.js @@ -0,0 +1 @@ +console.log(require('path').relative('.', __dirname)); diff --git a/node_modules/pg/node_modules/nan/nan.h b/node_modules/pg/node_modules/nan/nan.h new file mode 100644 index 0000000..063de4e --- /dev/null +++ b/node_modules/pg/node_modules/nan/nan.h @@ -0,0 +1,2331 @@ +/********************************************************************************** + * NAN - Native Abstractions for Node.js + * + * Copyright (c) 2014 NAN contributors: + * - Rod Vagg + * - Benjamin Byholm + * - Trevor Norris + * - Nathan Rajlich + * - Brett Lawson + * - Ben Noordhuis + * + * MIT +no-false-attribs License + * + * Version 1.3.0: current Node unstable: 0.11.13, Node stable: 0.10.30 + * + * See https://github.com/rvagg/nan for the latest update to this file + **********************************************************************************/ + +#ifndef NAN_H_ +#define NAN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && !defined(DEBUG) +# define NAN_INLINE inline __attribute__((always_inline)) +#elif defined(_MSC_VER) && !defined(DEBUG) +# define NAN_INLINE __forceinline +#else +# define NAN_INLINE inline +#endif + +#if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS +# define NAN_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS +# define NAN_DEPRECATED __declspec(deprecated) +#else +# define NAN_DEPRECATED +#endif + +// some generic helpers + +template NAN_INLINE bool NanSetPointerSafe( + T *var + , T val +) { + if (var) { + *var = val; + return true; + } else { + return false; + } +} + +template NAN_INLINE T NanGetPointerSafe( + T *var + , T fallback = reinterpret_cast(0) +) { + if (var) { + return *var; + } else { + return fallback; + } +} + +NAN_INLINE bool NanBooleanOptionValue( + v8::Local optionsObj + , v8::Handle opt, bool def +) { + if (def) { + return optionsObj.IsEmpty() + || !optionsObj->Has(opt) + || optionsObj->Get(opt)->BooleanValue(); + } else { + return !optionsObj.IsEmpty() + && optionsObj->Has(opt) + && optionsObj->Get(opt)->BooleanValue(); + } +} + +NAN_INLINE bool NanBooleanOptionValue( + v8::Local optionsObj + , v8::Handle opt +) { + return NanBooleanOptionValue(optionsObj, opt, false); +} + +NAN_INLINE uint32_t NanUInt32OptionValue( + v8::Local optionsObj + , v8::Handle opt + , uint32_t def +) { + return !optionsObj.IsEmpty() + && optionsObj->Has(opt) + && optionsObj->Get(opt)->IsNumber() + ? optionsObj->Get(opt)->Uint32Value() + : def; +} + +#if (NODE_MODULE_VERSION > 0x000B) +// Node 0.11+ (0.11.3 and below won't compile with these) + +# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo& +# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args +# define _NAN_METHOD_RETURN_TYPE void + +# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo& +# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args +# define _NAN_GETTER_RETURN_TYPE void + +# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo& +# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args +# define _NAN_SETTER_RETURN_TYPE void + +# define _NAN_PROPERTY_GETTER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args +# define _NAN_PROPERTY_GETTER_RETURN_TYPE void + +# define _NAN_PROPERTY_SETTER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args +# define _NAN_PROPERTY_SETTER_RETURN_TYPE void + +# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args +# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void + +# define _NAN_PROPERTY_DELETER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_PROPERTY_DELETER_ARGS \ + _NAN_PROPERTY_DELETER_ARGS_TYPE args +# define _NAN_PROPERTY_DELETER_RETURN_TYPE void + +# define _NAN_PROPERTY_QUERY_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args +# define _NAN_PROPERTY_QUERY_RETURN_TYPE void + +# define _NAN_INDEX_GETTER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args +# define _NAN_INDEX_GETTER_RETURN_TYPE void + +# define _NAN_INDEX_SETTER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args +# define _NAN_INDEX_SETTER_RETURN_TYPE void + +# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args +# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void + +# define _NAN_INDEX_DELETER_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args +# define _NAN_INDEX_DELETER_RETURN_TYPE void + +# define _NAN_INDEX_QUERY_ARGS_TYPE \ + const v8::PropertyCallbackInfo& +# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args +# define _NAN_INDEX_QUERY_RETURN_TYPE void + + typedef v8::FunctionCallback NanFunctionCallback; + + template + NAN_INLINE v8::Local NanNew() { + return T::New(v8::Isolate::GetCurrent()); + } + + template + NAN_INLINE v8::Local NanNew(P arg1) { + return T::New(v8::Isolate::GetCurrent(), arg1); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle receiver + , int argc + , v8::Handle argv[] = 0) { + return v8::Signature::New(v8::Isolate::GetCurrent(), receiver, argc, argv); + } + + template + NAN_INLINE v8::Local NanNew( + NanFunctionCallback callback + , v8::Handle data = v8::Handle() + , v8::Handle signature = v8::Handle()) { + return T::New(v8::Isolate::GetCurrent(), callback, data, signature); + } + + template + NAN_INLINE v8::Local NanNew(v8::Handle arg1) { + return v8::Local::New(v8::Isolate::GetCurrent(), arg1); + } + + template + NAN_INLINE v8::Local NanNew(const v8::Persistent &arg1) { + return v8::Local::New(v8::Isolate::GetCurrent(), arg1); + } + + template + NAN_INLINE v8::Local NanNew(P arg1, int arg2) { + return T::New(v8::Isolate::GetCurrent(), arg1, arg2); + } + + template<> + NAN_INLINE v8::Local NanNew() { + return v8::Array::New(v8::Isolate::GetCurrent()); + } + + template<> + NAN_INLINE v8::Local NanNew(int length) { + return v8::Array::New(v8::Isolate::GetCurrent(), length); + } + + template<> + NAN_INLINE v8::Local NanNew(double time) { + return v8::Date::New(v8::Isolate::GetCurrent(), time).As(); + } + + template<> + NAN_INLINE v8::Local NanNew(int time) { + return v8::Date::New(v8::Isolate::GetCurrent(), time).As(); + } + + typedef v8::UnboundScript NanUnboundScript; + typedef v8::Script NanBoundScript; + + template + NAN_INLINE v8::Local NanNew( + P s + , const v8::ScriptOrigin& origin + ) { + v8::ScriptCompiler::Source source(s, origin); + return v8::ScriptCompiler::CompileUnbound( + v8::Isolate::GetCurrent(), &source); + } + + template<> + NAN_INLINE v8::Local NanNew( + v8::Local s + ) { + v8::ScriptCompiler::Source source(s); + return v8::ScriptCompiler::CompileUnbound( + v8::Isolate::GetCurrent(), &source); + } + + template<> + NAN_INLINE v8::Local NanNew(bool value) { + return v8::BooleanObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local + NanNew >( + v8::Local value) { + return v8::StringObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local + NanNew >( + v8::Handle value) { + return v8::StringObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local NanNew(double val) { + return v8::NumberObject::New( + v8::Isolate::GetCurrent(), val).As(); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Local pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Local pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template<> + NAN_INLINE v8::Local NanNew(int32_t val) { + return v8::Uint32::NewFromUnsigned( + v8::Isolate::GetCurrent(), val)->ToUint32(); + } + + template<> + NAN_INLINE v8::Local NanNew(uint32_t val) { + return v8::Uint32::NewFromUnsigned( + v8::Isolate::GetCurrent(), val)->ToUint32(); + } + + template<> + NAN_INLINE v8::Local NanNew(int32_t val) { + return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); + } + + template<> + NAN_INLINE v8::Local NanNew(uint32_t val) { + return v8::Int32::New(v8::Isolate::GetCurrent(), val)->ToInt32(); + } + + template<> + NAN_INLINE v8::Local NanNew( + char *arg + , int length) { + return v8::String::NewFromUtf8( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + + template<> + NAN_INLINE v8::Local NanNew( + const char *arg + , int length) { + return v8::String::NewFromUtf8( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + + template<> + NAN_INLINE v8::Local NanNew(char *arg) { + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + const char *arg) { + return v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + uint8_t *arg + , int length) { + return v8::String::NewFromOneByte( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint8_t *arg + , int length) { + return v8::String::NewFromOneByte( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + + template<> + NAN_INLINE v8::Local NanNew(uint8_t *arg) { + return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint8_t *arg) { + return v8::String::NewFromOneByte(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + uint16_t *arg + , int length) { + return v8::String::NewFromTwoByte( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint16_t *arg + , int length) { + return v8::String::NewFromTwoByte( + v8::Isolate::GetCurrent() + , arg + , v8::String::kNormalString + , length); + } + template<> + NAN_INLINE v8::Local NanNew( + uint16_t *arg) { + return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint16_t *arg) { + return v8::String::NewFromTwoByte(v8::Isolate::GetCurrent(), arg); + } + + template<> + NAN_INLINE v8::Local NanNew( + std::string arg) { + return NanNew(arg.c_str(), arg.size()); + } + + template<> + NAN_INLINE v8::Local NanNew() { + return v8::String::Empty(v8::Isolate::GetCurrent()); + } + + NAN_INLINE v8::Local NanNew(const char* arg, int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + const uint8_t* arg + , int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + const uint16_t* arg + , int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + const std::string& arg) { + return NanNew(arg.c_str(), arg.size()); + } + + NAN_INLINE v8::Local NanNew(double val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(int val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(unsigned int val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(bool val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew( + v8::String::ExternalStringResource *resource) { + return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource); + } + + NAN_INLINE v8::Local NanNew( + v8::String::ExternalAsciiStringResource *resource) { + return v8::String::NewExternal(v8::Isolate::GetCurrent(), resource); + } + +# define NanScope() v8::HandleScope scope(v8::Isolate::GetCurrent()) +# define NanEscapableScope() \ + v8::EscapableHandleScope scope(v8::Isolate::GetCurrent()) + + template + NAN_INLINE v8::Local _NanEscapeScopeHelper(v8::Handle val) { + return NanNew(val); + } + + template + NAN_INLINE v8::Local _NanEscapeScopeHelper(v8::Local val) { + return val; + } + +# define NanEscapeScope(val) scope.Escape(_NanEscapeScopeHelper(val)) +# define NanLocker() v8::Locker locker(v8::Isolate::GetCurrent()) +# define NanUnlocker() v8::Unlocker unlocker(v8::Isolate::GetCurrent()) +# define NanReturnValue(value) return args.GetReturnValue().Set(value) +# define NanReturnUndefined() return +# define NanReturnNull() return args.GetReturnValue().SetNull() +# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString() + +# define NanObjectWrapHandle(obj) obj->handle() + + NAN_INLINE v8::Local NanUndefined() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::Undefined(v8::Isolate::GetCurrent()))); + } + + NAN_INLINE v8::Local NanNull() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::Null(v8::Isolate::GetCurrent()))); + } + + NAN_INLINE v8::Local NanTrue() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::True(v8::Isolate::GetCurrent()))); + } + + NAN_INLINE v8::Local NanFalse() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::False(v8::Isolate::GetCurrent()))); + } + + NAN_INLINE int NanAdjustExternalMemory(int bc) { + return static_cast( + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(bc)); + } + + NAN_INLINE void NanSetTemplate( + v8::Handle templ + , const char *name + , v8::Handle value) { + templ->Set(v8::Isolate::GetCurrent(), name, value); + } + + NAN_INLINE void NanSetTemplate( + v8::Handle templ + , v8::Handle name + , v8::Handle value + , v8::PropertyAttribute attributes) { + templ->Set(name, value, attributes); + } + + NAN_INLINE v8::Local NanGetCurrentContext() { + return v8::Isolate::GetCurrent()->GetCurrentContext(); + } + + NAN_INLINE void* NanGetInternalFieldPointer( + v8::Handle object + , int index) { + return object->GetAlignedPointerFromInternalField(index); + } + + NAN_INLINE void NanSetInternalFieldPointer( + v8::Handle object + , int index + , void* value) { + object->SetAlignedPointerInInternalField(index, value); + } + + NAN_INLINE void NanAddGCEpilogueCallback( + v8::Isolate::GCEpilogueCallback callback + , v8::GCType gc_type_filter = v8::kGCTypeAll) { + v8::Isolate::GetCurrent()->AddGCEpilogueCallback(callback, gc_type_filter); + } + + NAN_INLINE void NanRemoveGCEpilogueCallback( + v8::Isolate::GCEpilogueCallback callback) { + v8::Isolate::GetCurrent()->RemoveGCEpilogueCallback(callback); + } + + NAN_INLINE void NanAddGCPrologueCallback( + v8::Isolate::GCPrologueCallback callback + , v8::GCType gc_type_filter = v8::kGCTypeAll) { + v8::Isolate::GetCurrent()->AddGCPrologueCallback(callback, gc_type_filter); + } + + NAN_INLINE void NanRemoveGCPrologueCallback( + v8::Isolate::GCPrologueCallback callback) { + v8::Isolate::GetCurrent()->RemoveGCPrologueCallback(callback); + } + + NAN_INLINE void NanGetHeapStatistics( + v8::HeapStatistics *heap_statistics) { + v8::Isolate::GetCurrent()->GetHeapStatistics(heap_statistics); + } + + NAN_DEPRECATED NAN_INLINE v8::Local NanSymbol( + const char* data, int length = -1) { + return NanNew(data, length); + } + + template + NAN_INLINE void NanAssignPersistent( + v8::Persistent& handle + , v8::Handle obj) { + handle.Reset(v8::Isolate::GetCurrent(), obj); + } + + template + NAN_INLINE void NanAssignPersistent( + v8::Persistent& handle + , const v8::Persistent& obj) { + handle.Reset(v8::Isolate::GetCurrent(), obj); + } + + template + class _NanWeakCallbackData; + + template + struct _NanWeakCallbackInfo { + typedef void (*Callback)(const _NanWeakCallbackData& data); + NAN_INLINE _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) + : parameter(param), callback(cb) { + NanAssignPersistent(persistent, handle); + } + + NAN_INLINE ~_NanWeakCallbackInfo() { + persistent.Reset(); + } + + P* const parameter; + Callback const callback; + v8::Persistent persistent; + }; + + template + class _NanWeakCallbackData { + public: + NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo *info) + : info_(info) { } + + NAN_INLINE v8::Local GetValue() const { + return NanNew(info_->persistent); + } + + NAN_INLINE P* GetParameter() const { return info_->parameter; } + + NAN_INLINE bool IsNearDeath() const { + return info_->persistent.IsNearDeath(); + } + + NAN_INLINE void Revive() const; + + NAN_INLINE _NanWeakCallbackInfo* GetCallbackInfo() const { + return info_; + } + + NAN_DEPRECATED NAN_INLINE void Dispose() const { + } + + private: + _NanWeakCallbackInfo* info_; + }; + + template + static void _NanWeakCallbackDispatcher( + const v8::WeakCallbackData > &data) { + _NanWeakCallbackInfo *info = data.GetParameter(); + _NanWeakCallbackData wcbd(info); + info->callback(wcbd); + if (wcbd.IsNearDeath()) { + delete wcbd.GetCallbackInfo(); + } + } + + template + NAN_INLINE void _NanWeakCallbackData::Revive() const { + info_->persistent.SetWeak(info_, &_NanWeakCallbackDispatcher); + } + +template +NAN_INLINE _NanWeakCallbackInfo* NanMakeWeakPersistent( + v8::Handle handle + , P* parameter + , typename _NanWeakCallbackInfo::Callback callback) { + _NanWeakCallbackInfo *cbinfo = + new _NanWeakCallbackInfo(handle, parameter, callback); + cbinfo->persistent.SetWeak(cbinfo, &_NanWeakCallbackDispatcher); + return cbinfo; +} + +# define NAN_WEAK_CALLBACK(name) \ + template \ + static void name(const _NanWeakCallbackData &data) + +# define _NAN_ERROR(fun, errmsg) fun(NanNew(errmsg)) + +# define _NAN_THROW_ERROR(fun, errmsg) \ + do { \ + NanScope(); \ + v8::Isolate::GetCurrent()->ThrowException(_NAN_ERROR(fun, errmsg)); \ + } while (0); + + NAN_INLINE v8::Local NanError(const char* errmsg) { + return _NAN_ERROR(v8::Exception::Error, errmsg); + } + + NAN_INLINE void NanThrowError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::Error, errmsg); + } + + NAN_INLINE void NanThrowError(v8::Handle error) { + NanScope(); + v8::Isolate::GetCurrent()->ThrowException(error); + } + + NAN_INLINE v8::Local NanError( + const char *msg + , const int errorNumber + ) { + v8::Local err = v8::Exception::Error(NanNew(msg)); + v8::Local obj = err.As(); + obj->Set(NanNew("code"), NanNew(errorNumber)); + return err; + } + + NAN_INLINE void NanThrowError( + const char *msg + , const int errorNumber + ) { + NanThrowError(NanError(msg, errorNumber)); + } + + NAN_INLINE v8::Local NanTypeError(const char* errmsg) { + return _NAN_ERROR(v8::Exception::TypeError, errmsg); + } + + NAN_INLINE void NanThrowTypeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); + } + + NAN_INLINE v8::Local NanRangeError(const char* errmsg) { + return _NAN_ERROR(v8::Exception::RangeError, errmsg); + } + + NAN_INLINE void NanThrowRangeError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); + } + + template NAN_INLINE void NanDisposePersistent( + v8::Persistent &handle + ) { + handle.Reset(); + } + + NAN_INLINE v8::Local NanNewBufferHandle ( + char *data + , size_t length + , node::smalloc::FreeCallback callback + , void *hint + ) { + return node::Buffer::New( + v8::Isolate::GetCurrent(), data, length, callback, hint); + } + + NAN_INLINE v8::Local NanNewBufferHandle ( + const char *data + , uint32_t size + ) { + return node::Buffer::New(v8::Isolate::GetCurrent(), data, size); + } + + NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { + return node::Buffer::New(v8::Isolate::GetCurrent(), size); + } + + NAN_INLINE v8::Local NanBufferUse( + char* data + , uint32_t size + ) { + return node::Buffer::Use(v8::Isolate::GetCurrent(), data, size); + } + + NAN_INLINE bool NanHasInstance( + v8::Persistent& function_template + , v8::Handle value + ) { + return NanNew(function_template)->HasInstance(value); + } + + NAN_INLINE v8::Local NanNewContextHandle( + v8::ExtensionConfiguration* extensions = NULL + , v8::Handle tmpl = v8::Handle() + , v8::Handle obj = v8::Handle() + ) { + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + return v8::Local::New( + isolate + , v8::Context::New(isolate, extensions, tmpl, obj) + ); + } + + NAN_INLINE v8::Local NanCompileScript( + v8::Local s + , const v8::ScriptOrigin& origin + ) { + v8::ScriptCompiler::Source source(s, origin); + return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); + } + + NAN_INLINE v8::Local NanCompileScript( + v8::Local s + ) { + v8::ScriptCompiler::Source source(s); + return v8::ScriptCompiler::Compile(v8::Isolate::GetCurrent(), &source); + } + + NAN_INLINE v8::Local NanRunScript( + v8::Handle script + ) { + return script->BindToCurrentContext()->Run(); + } + + NAN_INLINE v8::Local NanRunScript( + v8::Handle script + ) { + return script->Run(); + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , v8::Handle func + , int argc + , v8::Handle* argv) { + return NanNew(node::MakeCallback( + v8::Isolate::GetCurrent(), target, func, argc, argv)); + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , v8::Handle symbol + , int argc + , v8::Handle* argv) { + return NanNew(node::MakeCallback( + v8::Isolate::GetCurrent(), target, symbol, argc, argv)); + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , const char* method + , int argc + , v8::Handle* argv) { + return NanNew(node::MakeCallback( + v8::Isolate::GetCurrent(), target, method, argc, argv)); + } + + template + NAN_INLINE void NanSetIsolateData( + v8::Isolate *isolate + , T *data + ) { + isolate->SetData(0, data); + } + + template + NAN_INLINE T *NanGetIsolateData( + v8::Isolate *isolate + ) { + return static_cast(isolate->GetData(0)); + } + + class NanAsciiString { + public: + NAN_INLINE explicit NanAsciiString(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Length() + 1; + buf = new char[buf_size]; + size = toStr->WriteOneByte( + reinterpret_cast(buf), 0, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE char* operator*() { return buf; } + + NAN_INLINE ~NanAsciiString() { + delete[] buf; + } + + private: + char *buf; + int size; + }; + + class NanUtf8String { + public: + NAN_INLINE explicit NanUtf8String(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Utf8Length() + 1; + buf = new char[buf_size]; + size = toStr->WriteUtf8(buf, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE char* operator*() { return buf; } + + NAN_INLINE ~NanUtf8String() { + delete[] buf; + } + + private: + char *buf; + int size; + }; + + class NanUcs2String { + public: + NAN_INLINE explicit NanUcs2String(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Length() + 1; + buf = new uint16_t[buf_size]; + size = toStr->Write(buf, 0, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE uint16_t* operator*() { return buf; } + + NAN_INLINE ~NanUcs2String() { + delete[] buf; + } + + private: + uint16_t *buf; + int size; + }; + +#else +// Node 0.8 and 0.10 + +# define _NAN_METHOD_ARGS_TYPE const v8::Arguments& +# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args +# define _NAN_METHOD_RETURN_TYPE v8::Handle + +# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo & +# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args +# define _NAN_GETTER_RETURN_TYPE v8::Handle + +# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo & +# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args +# define _NAN_SETTER_RETURN_TYPE void + +# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args +# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle + +# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args +# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle + +# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args +# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle + +# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args +# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle + +# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args +# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle + +# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args +# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle + +# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args +# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle + +# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args +# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle + +# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args +# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle + +# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo& +# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args +# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle + + typedef v8::InvocationCallback NanFunctionCallback; + + NAN_DEPRECATED NAN_INLINE v8::Local NanSymbol( + const char* data, int length = -1) { + return v8::String::NewSymbol(data, length); + } + + template + NAN_INLINE v8::Local NanNew() { + return v8::Local::New(T::New()); + } + + template + NAN_INLINE v8::Local NanNew(v8::Handle arg) { + return v8::Local::New(arg); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle receiver + , int argc + , v8::Handle argv[] = 0) { + return v8::Signature::New(receiver, argc, argv); + } + + template + NAN_INLINE v8::Local NanNew( + NanFunctionCallback callback + , v8::Handle data = v8::Handle() + , v8::Handle signature = v8::Handle()) { + return T::New(callback, data, signature); + } + + template + NAN_INLINE v8::Local NanNew(const v8::Persistent &arg) { + return v8::Local::New(arg); + } + + template + NAN_INLINE v8::Local NanNew(P arg) { + return v8::Local::New(T::New(arg)); + } + + template + NAN_INLINE v8::Local NanNew(P arg, int length) { + return v8::Local::New(T::New(arg, length)); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Local pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Handle pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template + NAN_INLINE v8::Local NanNew( + v8::Local pattern, v8::RegExp::Flags flags) { + return v8::RegExp::New(pattern, flags); + } + + template<> + NAN_INLINE v8::Local NanNew() { + return v8::Array::New(); + } + + template<> + NAN_INLINE v8::Local NanNew(int length) { + return v8::Array::New(length); + } + + template<> + NAN_INLINE v8::Local NanNew(double time) { + return v8::Date::New(time).As(); + } + + template<> + NAN_INLINE v8::Local NanNew(int time) { + return v8::Date::New(time).As(); + } + + typedef v8::Script NanUnboundScript; + typedef v8::Script NanBoundScript; + + template + NAN_INLINE v8::Local NanNew( + P s + , const v8::ScriptOrigin& origin + ) { + return v8::Script::New(s, const_cast(&origin)); + } + + template<> + NAN_INLINE v8::Local NanNew( + v8::Local s + ) { + return v8::Script::New(s); + } + + template<> + NAN_INLINE v8::Local NanNew(bool value) { + return v8::BooleanObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local + NanNew >( + v8::Local value) { + return v8::StringObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local + NanNew >( + v8::Handle value) { + return v8::StringObject::New(value).As(); + } + + template<> + NAN_INLINE v8::Local NanNew(double val) { + return v8::NumberObject::New(val).As(); + } + + template<> + NAN_INLINE v8::Local NanNew(int32_t val) { + return v8::Uint32::NewFromUnsigned(val)->ToUint32(); + } + + template<> + NAN_INLINE v8::Local NanNew(uint32_t val) { + return v8::Uint32::NewFromUnsigned(val)->ToUint32(); + } + + template<> + NAN_INLINE v8::Local NanNew(int32_t val) { + return v8::Int32::New(val)->ToInt32(); + } + + template<> + NAN_INLINE v8::Local NanNew(uint32_t val) { + return v8::Int32::New(val)->ToInt32(); + } + + template<> + NAN_INLINE v8::Local NanNew( + uint8_t *arg + , int length) { + int len = length; + if (len < 0) { + size_t temp = strlen(reinterpret_cast(arg)); + assert(temp <= INT_MAX && "too long string"); + len = static_cast(temp); + } + uint16_t *warg = new uint16_t[len]; + for (int i = 0; i < len; i++) { + warg[i] = arg[i]; + } + v8::Local retval = v8::String::New(warg, len); + delete[] warg; + return retval; + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint8_t *arg + , int length) { + int len = length; + if (len < 0) { + size_t temp = strlen(reinterpret_cast(arg)); + assert(temp <= INT_MAX && "too long string"); + len = static_cast(temp); + } + uint16_t *warg = new uint16_t[len]; + for (int i = 0; i < len; i++) { + warg[i] = arg[i]; + } + v8::Local retval = v8::String::New(warg, len); + delete[] warg; + return retval; + } + + template<> + NAN_INLINE v8::Local NanNew(uint8_t *arg) { + size_t temp = strlen(reinterpret_cast(arg)); + assert(temp <= INT_MAX && "too long string"); + int length = static_cast(temp); + uint16_t *warg = new uint16_t[length]; + for (int i = 0; i < length; i++) { + warg[i] = arg[i]; + } + + v8::Local retval = v8::String::New(warg, length); + delete[] warg; + return retval; + } + + template<> + NAN_INLINE v8::Local NanNew( + const uint8_t *arg) { + size_t temp = strlen(reinterpret_cast(arg)); + assert(temp <= INT_MAX && "too long string"); + int length = static_cast(temp); + uint16_t *warg = new uint16_t[length]; + for (int i = 0; i < length; i++) { + warg[i] = arg[i]; + } + v8::Local retval = v8::String::New(warg, length); + delete[] warg; + return retval; + } + + template<> + NAN_INLINE v8::Local NanNew( + std::string arg) { + return NanNew(arg.c_str(), arg.size()); + } + + template<> + NAN_INLINE v8::Local NanNew() { + return v8::String::Empty(); + } + + NAN_INLINE v8::Local NanNew(const char* arg, int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + const uint8_t* arg + , int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + const uint16_t* arg + , int length = -1) { + return NanNew(arg, length); + } + + NAN_INLINE v8::Local NanNew( + std::string& arg) { + return NanNew(arg.c_str(), arg.size()); + } + + NAN_INLINE v8::Local NanNew(double val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(int val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(unsigned int val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew(bool val) { + return NanNew(val); + } + + NAN_INLINE v8::Local NanNew( + v8::String::ExternalStringResource *resource) { + return v8::String::NewExternal(resource); + } + + NAN_INLINE v8::Local NanNew( + v8::String::ExternalAsciiStringResource *resource) { + return v8::String::NewExternal(resource); + } + +# define NanScope() v8::HandleScope scope +# define NanEscapableScope() v8::HandleScope scope +# define NanEscapeScope(val) scope.Close(val) +# define NanLocker() v8::Locker locker +# define NanUnlocker() v8::Unlocker unlocker +# define NanReturnValue(value) return scope.Close(value) +# define NanReturnUndefined() return v8::Undefined() +# define NanReturnNull() return v8::Null() +# define NanReturnEmptyString() return v8::String::Empty() +# define NanObjectWrapHandle(obj) v8::Local::New(obj->handle_) + + NAN_INLINE v8::Local NanUndefined() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::Undefined())); + } + + NAN_INLINE v8::Local NanNull() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::Null())); + } + + NAN_INLINE v8::Local NanTrue() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::True())); + } + + NAN_INLINE v8::Local NanFalse() { + NanEscapableScope(); + return NanEscapeScope(NanNew(v8::False())); + } + + NAN_INLINE int NanAdjustExternalMemory(int bc) { + return static_cast(v8::V8::AdjustAmountOfExternalAllocatedMemory(bc)); + } + + NAN_INLINE void NanSetTemplate( + v8::Handle templ + , const char *name + , v8::Handle value) { + templ->Set(name, value); + } + + NAN_INLINE void NanSetTemplate( + v8::Handle templ + , v8::Handle name + , v8::Handle value + , v8::PropertyAttribute attributes) { + templ->Set(name, value, attributes); + } + + NAN_INLINE v8::Local NanGetCurrentContext() { + return v8::Context::GetCurrent(); + } + + NAN_INLINE void* NanGetInternalFieldPointer( + v8::Handle object + , int index) { + return object->GetPointerFromInternalField(index); + } + + NAN_INLINE void NanSetInternalFieldPointer( + v8::Handle object + , int index + , void* value) { + object->SetPointerInInternalField(index, value); + } + + NAN_INLINE void NanAddGCEpilogueCallback( + v8::GCEpilogueCallback callback + , v8::GCType gc_type_filter = v8::kGCTypeAll) { + v8::V8::AddGCEpilogueCallback(callback, gc_type_filter); + } + NAN_INLINE void NanRemoveGCEpilogueCallback( + v8::GCEpilogueCallback callback) { + v8::V8::RemoveGCEpilogueCallback(callback); + } + NAN_INLINE void NanAddGCPrologueCallback( + v8::GCPrologueCallback callback + , v8::GCType gc_type_filter = v8::kGCTypeAll) { + v8::V8::AddGCPrologueCallback(callback, gc_type_filter); + } + NAN_INLINE void NanRemoveGCPrologueCallback( + v8::GCPrologueCallback callback) { + v8::V8::RemoveGCPrologueCallback(callback); + } + NAN_INLINE void NanGetHeapStatistics( + v8::HeapStatistics *heap_statistics) { + v8::V8::GetHeapStatistics(heap_statistics); + } + + template + NAN_INLINE void NanAssignPersistent( + v8::Persistent& handle + , v8::Handle obj) { + handle.Dispose(); + handle = v8::Persistent::New(obj); + } + + template + class _NanWeakCallbackData; + + template + struct _NanWeakCallbackInfo { + typedef void (*Callback)(const _NanWeakCallbackData &data); + NAN_INLINE _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) + : parameter(param) + , callback(cb) + , persistent(v8::Persistent::New(handle)) { } + + NAN_INLINE ~_NanWeakCallbackInfo() { + persistent.Dispose(); + persistent.Clear(); + } + + P* const parameter; + Callback const callback; + v8::Persistent persistent; + }; + + template + class _NanWeakCallbackData { + public: + NAN_INLINE _NanWeakCallbackData(_NanWeakCallbackInfo *info) + : info_(info) { } + + NAN_INLINE v8::Local GetValue() const { + return NanNew(info_->persistent); + } + + NAN_INLINE P* GetParameter() const { return info_->parameter; } + + NAN_INLINE bool IsNearDeath() const { + return info_->persistent.IsNearDeath(); + } + + NAN_INLINE void Revive() const; + + NAN_INLINE _NanWeakCallbackInfo* GetCallbackInfo() const { + return info_; + } + + NAN_DEPRECATED NAN_INLINE void Dispose() const { + } + + private: + _NanWeakCallbackInfo* info_; + }; + + template + static void _NanWeakPersistentDispatcher( + v8::Persistent object, void *data) { + _NanWeakCallbackInfo* info = + static_cast<_NanWeakCallbackInfo*>(data); + _NanWeakCallbackData wcbd(info); + info->callback(wcbd); + if (wcbd.IsNearDeath()) { + delete wcbd.GetCallbackInfo(); + } + } + + template + NAN_INLINE void _NanWeakCallbackData::Revive() const { + info_->persistent.MakeWeak( + info_ + , &_NanWeakPersistentDispatcher); + } + + template + NAN_INLINE _NanWeakCallbackInfo* NanMakeWeakPersistent( + v8::Handle handle + , P* parameter + , typename _NanWeakCallbackInfo::Callback callback) { + _NanWeakCallbackInfo *cbinfo = + new _NanWeakCallbackInfo(handle, parameter, callback); + cbinfo->persistent.MakeWeak( + cbinfo + , &_NanWeakPersistentDispatcher); + return cbinfo; + } + +# define NAN_WEAK_CALLBACK(name) \ + template \ + static void name(const _NanWeakCallbackData &data) + +# define _NAN_ERROR(fun, errmsg) \ + fun(v8::String::New(errmsg)) + +# define _NAN_THROW_ERROR(fun, errmsg) \ + do { \ + NanScope(); \ + return v8::Local::New( \ + v8::ThrowException(_NAN_ERROR(fun, errmsg))); \ + } while (0); + + NAN_INLINE v8::Local NanError(const char* errmsg) { + return _NAN_ERROR(v8::Exception::Error, errmsg); + } + + NAN_INLINE v8::Local NanThrowError(const char* errmsg) { + _NAN_THROW_ERROR(v8::Exception::Error, errmsg); + } + + NAN_INLINE v8::Local NanThrowError( + v8::Handle error + ) { + NanScope(); + return v8::Local::New(v8::ThrowException(error)); + } + + NAN_INLINE v8::Local NanError( + const char *msg + , const int errorNumber + ) { + v8::Local err = v8::Exception::Error(v8::String::New(msg)); + v8::Local obj = err.As(); + obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); + return err; + } + + NAN_INLINE v8::Local NanThrowError( + const char *msg + , const int errorNumber + ) { + return NanThrowError(NanError(msg, errorNumber)); + } + + NAN_INLINE v8::Local NanTypeError(const char* errmsg) { + return _NAN_ERROR(v8::Exception::TypeError, errmsg); + } + + NAN_INLINE v8::Local NanThrowTypeError( + const char* errmsg + ) { + _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); + } + + NAN_INLINE v8::Local NanRangeError( + const char* errmsg + ) { + return _NAN_ERROR(v8::Exception::RangeError, errmsg); + } + + NAN_INLINE v8::Local NanThrowRangeError( + const char* errmsg + ) { + _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); + } + + template + NAN_INLINE void NanDisposePersistent( + v8::Persistent &handle) { // NOLINT(runtime/references) + handle.Dispose(); + handle.Clear(); + } + + NAN_INLINE v8::Local NanNewBufferHandle ( + char *data + , size_t length + , node::Buffer::free_callback callback + , void *hint + ) { + return NanNew( + node::Buffer::New(data, length, callback, hint)->handle_); + } + + NAN_INLINE v8::Local NanNewBufferHandle ( + const char *data + , uint32_t size + ) { +#if NODE_MODULE_VERSION >= 0x000B + return NanNew(node::Buffer::New(data, size)->handle_); +#else + return NanNew( + node::Buffer::New(const_cast(data), size)->handle_); +#endif + } + + NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { + return NanNew(node::Buffer::New(size)->handle_); + } + + NAN_INLINE void FreeData(char *data, void *hint) { + delete[] data; + } + + NAN_INLINE v8::Local NanBufferUse( + char* data + , uint32_t size + ) { + return NanNew( + node::Buffer::New(data, size, FreeData, NULL)->handle_); + } + + NAN_INLINE bool NanHasInstance( + v8::Persistent& function_template + , v8::Handle value + ) { + return function_template->HasInstance(value); + } + + NAN_INLINE v8::Local NanNewContextHandle( + v8::ExtensionConfiguration* extensions = NULL + , v8::Handle tmpl = v8::Handle() + , v8::Handle obj = v8::Handle() + ) { + v8::Persistent ctx = v8::Context::New(extensions, tmpl, obj); + v8::Local lctx = NanNew(ctx); + ctx.Dispose(); + return lctx; + } + + NAN_INLINE v8::Local NanCompileScript( + v8::Local s + , const v8::ScriptOrigin& origin + ) { + return v8::Script::Compile(s, const_cast(&origin)); + } + + NAN_INLINE v8::Local NanCompileScript( + v8::Local s + ) { + return v8::Script::Compile(s); + } + + NAN_INLINE v8::Local NanRunScript(v8::Handle script) { + return script->Run(); + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , v8::Handle func + , int argc + , v8::Handle* argv) { +# if NODE_VERSION_AT_LEAST(0, 8, 0) + return NanNew(node::MakeCallback(target, func, argc, argv)); +# else + v8::TryCatch try_catch; + v8::Local result = NanNew(func->Call(target, argc, argv)); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + return result; +# endif + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , v8::Handle symbol + , int argc + , v8::Handle* argv) { +# if NODE_VERSION_AT_LEAST(0, 8, 0) + return NanNew(node::MakeCallback(target, symbol, argc, argv)); +# else + v8::Local callback = target->Get(symbol).As(); + return NanMakeCallback(target, callback, argc, argv); +# endif + } + + NAN_INLINE v8::Local NanMakeCallback( + v8::Handle target + , const char* method + , int argc + , v8::Handle* argv) { +# if NODE_VERSION_AT_LEAST(0, 8, 0) + return NanNew(node::MakeCallback(target, method, argc, argv)); +# else + return NanMakeCallback(target, NanNew(method), argc, argv); +# endif + } + + template + NAN_INLINE void NanSetIsolateData( + v8::Isolate *isolate + , T *data + ) { + isolate->SetData(data); + } + + template + NAN_INLINE T *NanGetIsolateData( + v8::Isolate *isolate + ) { + return static_cast(isolate->GetData()); + } + + class NanAsciiString { + public: + NAN_INLINE explicit NanAsciiString(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Length() + 1; + buf = new char[buf_size]; + size = toStr->WriteAscii(buf, 0, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE char* operator*() { return buf; } + + NAN_INLINE ~NanAsciiString() { + delete[] buf; + } + + private: + char *buf; + int size; + }; + + class NanUtf8String { + public: + NAN_INLINE explicit NanUtf8String(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Utf8Length() + 1; + buf = new char[buf_size]; + size = toStr->WriteUtf8(buf, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE char* operator*() { return buf; } + + NAN_INLINE ~NanUtf8String() { + delete[] buf; + } + + private: + char *buf; + int size; + }; + + class NanUcs2String { + public: + NAN_INLINE explicit NanUcs2String(v8::Handle from) { + v8::Local toStr = from->ToString(); + int buf_size = toStr->Length() + 1; + buf = new uint16_t[buf_size]; + size = toStr->Write(buf, 0, buf_size); + } + + NAN_INLINE int Size() const { + return size; + } + + NAN_INLINE uint16_t* operator*() { return buf; } + + NAN_INLINE ~NanUcs2String() { + delete[] buf; + } + + private: + uint16_t *buf; + int size; + }; + +#endif // NODE_MODULE_VERSION + +typedef void (*NanFreeCallback)(char *data, void *hint); + +#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS) +#define NAN_GETTER(name) \ + _NAN_GETTER_RETURN_TYPE name( \ + v8::Local property \ + , _NAN_GETTER_ARGS) +#define NAN_SETTER(name) \ + _NAN_SETTER_RETURN_TYPE name( \ + v8::Local property \ + , v8::Local value \ + , _NAN_SETTER_ARGS) +#define NAN_PROPERTY_GETTER(name) \ + _NAN_PROPERTY_GETTER_RETURN_TYPE name( \ + v8::Local property \ + , _NAN_PROPERTY_GETTER_ARGS) +#define NAN_PROPERTY_SETTER(name) \ + _NAN_PROPERTY_SETTER_RETURN_TYPE name( \ + v8::Local property \ + , v8::Local value \ + , _NAN_PROPERTY_SETTER_ARGS) +#define NAN_PROPERTY_ENUMERATOR(name) \ + _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS) +#define NAN_PROPERTY_DELETER(name) \ + _NAN_PROPERTY_DELETER_RETURN_TYPE name( \ + v8::Local property \ + , _NAN_PROPERTY_DELETER_ARGS) +#define NAN_PROPERTY_QUERY(name) \ + _NAN_PROPERTY_QUERY_RETURN_TYPE name( \ + v8::Local property \ + , _NAN_PROPERTY_QUERY_ARGS) +# define NAN_INDEX_GETTER(name) \ + _NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS) +#define NAN_INDEX_SETTER(name) \ + _NAN_INDEX_SETTER_RETURN_TYPE name( \ + uint32_t index \ + , v8::Local value \ + , _NAN_INDEX_SETTER_ARGS) +#define NAN_INDEX_ENUMERATOR(name) \ + _NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS) +#define NAN_INDEX_DELETER(name) \ + _NAN_INDEX_DELETER_RETURN_TYPE name( \ + uint32_t index \ + , _NAN_INDEX_DELETER_ARGS) +#define NAN_INDEX_QUERY(name) \ + _NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS) + +class NanCallback { + public: + NanCallback() { + NanScope(); + v8::Local obj = NanNew(); + NanAssignPersistent(handle, obj); + } + + explicit NanCallback(const v8::Handle &fn) { + NanScope(); + v8::Local obj = NanNew(); + NanAssignPersistent(handle, obj); + SetFunction(fn); + } + + ~NanCallback() { + if (handle.IsEmpty()) return; + NanDisposePersistent(handle); + } + + NAN_INLINE void SetFunction(const v8::Handle &fn) { + NanScope(); + NanNew(handle)->Set(kCallbackIndex, fn); + } + + NAN_INLINE v8::Local GetFunction() const { + NanEscapableScope(); + return NanEscapeScope(NanNew(handle)->Get(kCallbackIndex) + .As()); + } + + NAN_INLINE bool IsEmpty() const { + NanScope(); + return NanNew(handle)->Get(kCallbackIndex)->IsUndefined(); + } + + v8::Handle Call(int argc, v8::Handle argv[]) const { + NanEscapableScope(); +#if (NODE_MODULE_VERSION > 0x000B) // 0.11.12+ + v8::Isolate* isolate = v8::Isolate::GetCurrent(); + v8::Local callback = NanNew(handle)-> + Get(kCallbackIndex).As(); + return NanEscapeScope(node::MakeCallback( + isolate + , isolate->GetCurrentContext()->Global() + , callback + , argc + , argv + )); +#else +#if NODE_VERSION_AT_LEAST(0, 8, 0) + v8::Local callback = handle-> + Get(kCallbackIndex).As(); + return NanEscapeScope(node::MakeCallback( + v8::Context::GetCurrent()->Global() + , callback + , argc + , argv + )); +#else + v8::Local callback = handle-> + Get(kCallbackIndex).As(); + return NanEscapeScope(NanMakeCallback( + v8::Context::GetCurrent()->Global(), callback, argc, argv)); +#endif +#endif + } + + private: + v8::Persistent handle; + static const uint32_t kCallbackIndex = 0; +}; + +/* abstract */ class NanAsyncWorker { + public: + explicit NanAsyncWorker(NanCallback *callback) + : callback(callback), errmsg_(NULL) { + request.data = this; + + NanScope(); + v8::Local obj = NanNew(); + NanAssignPersistent(persistentHandle, obj); + } + + virtual ~NanAsyncWorker() { + NanScope(); + + if (!persistentHandle.IsEmpty()) + NanDisposePersistent(persistentHandle); + if (callback) + delete callback; + if (errmsg_) + delete[] errmsg_; + } + + virtual void WorkComplete() { + NanScope(); + + if (errmsg_ == NULL) + HandleOKCallback(); + else + HandleErrorCallback(); + delete callback; + callback = NULL; + } + + NAN_INLINE void SaveToPersistent( + const char *key, const v8::Local &obj) { + v8::Local handle = NanNew(persistentHandle); + handle->Set(NanNew(key), obj); + } + + v8::Local GetFromPersistent(const char *key) const { + NanEscapableScope(); + v8::Local handle = NanNew(persistentHandle); + return NanEscapeScope(handle->Get(NanNew(key)).As()); + } + + virtual void Execute() = 0; + + uv_work_t request; + + protected: + v8::Persistent persistentHandle; + NanCallback *callback; + + virtual void HandleOKCallback() { + NanScope(); + + callback->Call(0, NULL); + } + + virtual void HandleErrorCallback() { + NanScope(); + + v8::Local argv[] = { + v8::Exception::Error(NanNew(ErrorMessage())) + }; + callback->Call(1, argv); + } + + void SetErrorMessage(const char *msg) { + if (errmsg_) { + delete[] errmsg_; + } + + size_t size = strlen(msg) + 1; + errmsg_ = new char[size]; + memcpy(errmsg_, msg, size); + } + + const char* ErrorMessage() const { + return errmsg_; + } + + private: + char *errmsg_; +}; + +NAN_INLINE void NanAsyncExecute (uv_work_t* req) { + NanAsyncWorker *worker = static_cast(req->data); + worker->Execute(); +} + +NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) { + NanAsyncWorker* worker = static_cast(req->data); + worker->WorkComplete(); + delete worker; +} + +NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) { + uv_queue_work( + uv_default_loop() + , &worker->request + , NanAsyncExecute + , (uv_after_work_cb)NanAsyncExecuteComplete + ); +} + +//// Base 64 //// + +#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4) + +// Doesn't check for padding at the end. Can be 1-2 bytes over. +NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) { + size_t remainder = size % 4; + + size = (size / 4) * 3; + if (remainder) { + if (size == 0 && remainder == 1) { + // special case: 1-byte input cannot be decoded + size = 0; + } else { + // non-padded input, add 1 or 2 extra bytes + size += 1 + (remainder == 3); + } + } + + return size; +} + +template +NAN_INLINE size_t _nan_base64_decoded_size( + const T* src + , size_t size +) { + if (size == 0) + return 0; + + if (src[size - 1] == '=') + size--; + if (size > 0 && src[size - 1] == '=') + size--; + + return _nan_base64_decoded_size_fast(size); +} + +// supports regular and URL-safe base64 +static const int _nan_unbase64_table[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63 + , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1 + , -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + , 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63 + , -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 + , 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)] + +template static size_t _nan_base64_decode( + char* buf + , size_t len + , const T* src + , const size_t srcLen +) { + char* dst = buf; + char* dstEnd = buf + len; + const T* srcEnd = src + srcLen; + + while (src < srcEnd && dst < dstEnd) { + ptrdiff_t remaining = srcEnd - src; + char a, b, c, d; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining == 0 || *src == '=') break; + a = _nan_unbase64(*src++); + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 1 || *src == '=') break; + b = _nan_unbase64(*src++); + + *dst++ = (a << 2) | ((b & 0x30) >> 4); + if (dst == dstEnd) break; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 2 || *src == '=') break; + c = _nan_unbase64(*src++); + + *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2); + if (dst == dstEnd) break; + + while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; + if (remaining <= 3 || *src == '=') break; + d = _nan_unbase64(*src++); + + *dst++ = ((c & 0x03) << 6) | (d & 0x3F); + } + + return dst - buf; +} + +//// HEX //// + +template unsigned _nan_hex2bin(T c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); + if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); + return static_cast(-1); +} + +template static size_t _nan_hex_decode( + char* buf + , size_t len + , const T* src + , const size_t srcLen +) { + size_t i; + for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) { + unsigned a = _nan_hex2bin(src[i * 2 + 0]); + unsigned b = _nan_hex2bin(src[i * 2 + 1]); + if (!~a || !~b) return i; + buf[i] = a * 16 + b; + } + + return i; +} + +static bool _NanGetExternalParts( + v8::Handle val + , const char** data + , size_t* len +) { + if (node::Buffer::HasInstance(val)) { + *data = node::Buffer::Data(val.As()); + *len = node::Buffer::Length(val.As()); + return true; + } + + assert(val->IsString()); + v8::Local str = NanNew(val.As()); + + if (str->IsExternalAscii()) { + const v8::String::ExternalAsciiStringResource* ext; + ext = str->GetExternalAsciiStringResource(); + *data = ext->data(); + *len = ext->length(); + return true; + + } else if (str->IsExternal()) { + const v8::String::ExternalStringResource* ext; + ext = str->GetExternalStringResource(); + *data = reinterpret_cast(ext->data()); + *len = ext->length(); + return true; + } + + return false; +} + +namespace Nan { + enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; +} + +/* NAN_DEPRECATED */ NAN_INLINE void* _NanRawString( + v8::Handle from + , enum Nan::Encoding encoding + , size_t *datalen + , void *buf + , size_t buflen + , int flags +) { + NanScope(); + + size_t sz_; + size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION); + char *data = NULL; + size_t len; + bool is_extern = _NanGetExternalParts( + from + , const_cast(&data) + , &len); + + if (is_extern && !term_len) { + NanSetPointerSafe(datalen, len); + return data; + } + + v8::Local toStr = from->ToString(); + + char *to = static_cast(buf); + + switch (encoding) { + case Nan::ASCII: +#if NODE_MODULE_VERSION < 0x000C + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } + NanSetPointerSafe( + datalen + , toStr->WriteAscii(to, 0, static_cast(sz_ + term_len), flags)); + return to; +#endif + case Nan::BINARY: + case Nan::BUFFER: + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } +#if NODE_MODULE_VERSION < 0x000C + { + uint16_t* twobytebuf = new uint16_t[sz_ + term_len]; + + size_t len = toStr->Write(twobytebuf, 0, + static_cast(sz_ + term_len), flags); + + for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) { + unsigned char *b = reinterpret_cast(&twobytebuf[i]); + to[i] = *b; + } + + NanSetPointerSafe(datalen, len); + + delete[] twobytebuf; + return to; + } +#else + NanSetPointerSafe( + datalen, + toStr->WriteOneByte( + reinterpret_cast(to) + , 0 + , static_cast(sz_ + term_len) + , flags)); + return to; +#endif + case Nan::UTF8: + sz_ = toStr->Utf8Length(); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len && "too small buffer"); + } + NanSetPointerSafe( + datalen + , toStr->WriteUtf8(to, static_cast(sz_ + term_len) + , NULL, flags) + - term_len); + return to; + case Nan::BASE64: + { + v8::String::Value value(toStr); + sz_ = _nan_base64_decoded_size(*value, value.length()); + if (to == NULL) { + to = new char[sz_ + term_len]; + } else { + assert(buflen >= sz_ + term_len); + } + NanSetPointerSafe( + datalen + , _nan_base64_decode(to, sz_, *value, value.length())); + if (term_len) { + to[sz_] = '\0'; + } + return to; + } + case Nan::UCS2: + { + sz_ = toStr->Length(); + if (to == NULL) { + to = new char[(sz_ + term_len) * 2]; + } else { + assert(buflen >= (sz_ + term_len) * 2 && "too small buffer"); + } + + int bc = 2 * toStr->Write( + reinterpret_cast(to) + , 0 + , static_cast(sz_ + term_len) + , flags); + NanSetPointerSafe(datalen, bc); + return to; + } + case Nan::HEX: + { + v8::String::Value value(toStr); + sz_ = value.length(); + assert(!(sz_ & 1) && "bad hex data"); + if (to == NULL) { + to = new char[sz_ / 2 + term_len]; + } else { + assert(buflen >= sz_ / 2 + term_len && "too small buffer"); + } + NanSetPointerSafe( + datalen + , _nan_hex_decode(to, sz_ / 2, *value, value.length())); + } + if (term_len) { + to[sz_ / 2] = '\0'; + } + return to; + default: + assert(0 && "unknown encoding"); + } + return to; +} + +NAN_DEPRECATED NAN_INLINE void* NanRawString( + v8::Handle from + , enum Nan::Encoding encoding + , size_t *datalen + , void *buf + , size_t buflen + , int flags +) { + return _NanRawString(from, encoding, datalen, buf, buflen, flags); +} + + +NAN_DEPRECATED NAN_INLINE char* NanCString( + v8::Handle from + , size_t *datalen + , char *buf = NULL + , size_t buflen = 0 + , int flags = v8::String::NO_OPTIONS +) { + return static_cast( + _NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags) + ); +} + +NAN_INLINE void NanSetPrototypeTemplate( + v8::Local templ + , const char *name + , v8::Handle value +) { + NanSetTemplate(templ->PrototypeTemplate(), name, value); +} + +NAN_INLINE void NanSetPrototypeTemplate( + v8::Local templ + , v8::Handle name + , v8::Handle value + , v8::PropertyAttribute attributes +) { + NanSetTemplate(templ->PrototypeTemplate(), name, value, attributes); +} + +NAN_INLINE void NanSetInstanceTemplate( + v8::Local templ + , const char *name + , v8::Handle value +) { + NanSetTemplate(templ->InstanceTemplate(), name, value); +} + +NAN_INLINE void NanSetInstanceTemplate( + v8::Local templ + , v8::Handle name + , v8::Handle value + , v8::PropertyAttribute attributes +) { + NanSetTemplate(templ->InstanceTemplate(), name, value, attributes); +} + +#endif // NAN_H_ diff --git a/node_modules/pg/node_modules/nan/package.json b/node_modules/pg/node_modules/nan/package.json new file mode 100644 index 0000000..af046a9 --- /dev/null +++ b/node_modules/pg/node_modules/nan/package.json @@ -0,0 +1,78 @@ +{ + "name": "nan", + "version": "1.3.0", + "description": "Native Abstractions for Node.js: C++ header for Node 0.8->0.12 compatibility", + "main": "include_dirs.js", + "repository": { + "type": "git", + "url": "git://github.com/rvagg/nan.git" + }, + "scripts": { + "test": "tap --gc test/js/*-test.js", + "rebuild-tests": "node-gyp rebuild --directory test" + }, + "contributors": [ + { + "name": "Rod Vagg", + "email": "r@va.gg", + "url": "https://github.com/rvagg" + }, + { + "name": "Benjamin Byholm", + "email": "bbyholm@abo.fi", + "url": "https://github.com/kkoopa/" + }, + { + "name": "Trevor Norris", + "email": "trev.norris@gmail.com", + "url": "https://github.com/trevnorris" + }, + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net", + "url": "https://github.com/TooTallNate" + }, + { + "name": "Brett Lawson", + "email": "brett19@gmail.com", + "url": "https://github.com/brett19" + }, + { + "name": "Ben Noordhuis", + "email": "info@bnoordhuis.nl", + "url": "https://github.com/bnoordhuis" + } + ], + "devDependencies": { + "bindings": "~1.2.1", + "node-gyp": "~1.0.1", + "tap": "~0.4.12", + "xtend": "~4.0.0" + }, + "license": "MIT", + "gitHead": "e482fbe142e58373d5a24f4e5a60c61e22a13f83", + "bugs": { + "url": "https://github.com/rvagg/nan/issues" + }, + "homepage": "https://github.com/rvagg/nan", + "_id": "nan@1.3.0", + "_shasum": "9a5b8d5ef97a10df3050e59b2c362d3baf779742", + "_from": "nan@1.3.0", + "_npmVersion": "1.4.21", + "_npmUser": { + "name": "rvagg", + "email": "rod@vagg.org" + }, + "maintainers": [ + { + "name": "rvagg", + "email": "rod@vagg.org" + } + ], + "dist": { + "shasum": "9a5b8d5ef97a10df3050e59b2c362d3baf779742", + "tarball": "http://registry.npmjs.org/nan/-/nan-1.3.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/nan/-/nan-1.3.0.tgz" +} diff --git a/node_modules/pg/node_modules/packet-reader/.npmignore b/node_modules/pg/node_modules/packet-reader/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/pg/node_modules/packet-reader/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/pg/node_modules/packet-reader/index.js b/node_modules/pg/node_modules/packet-reader/index.js new file mode 100644 index 0000000..68f91ef --- /dev/null +++ b/node_modules/pg/node_modules/packet-reader/index.js @@ -0,0 +1,57 @@ +var assert = require('assert') + +var Reader = module.exports = function(options) { + //TODO - remove for version 1.0 + if(typeof options == 'number') { + options = { headerSize: options } + } + options = options || {} + this.offset = 0 + this.lastChunk = false + this.chunk = null + this.headerSize = options.headerSize || 0 + this.lengthPadding = options.lengthPadding || 0 + this.header = null + assert(this.headerSize < 2, 'pre-length header of more than 1 byte length not currently supported') +} + +Reader.prototype.addChunk = function(chunk) { + this.offset = 0 + this.chunk = chunk + if(this.lastChunk) { + this.chunk = Buffer.concat([this.lastChunk, this.chunk]) + this.lastChunk = false + } +} + +Reader.prototype._save = function() { + //save any unread chunks for next read + if(this.offset < this.chunk.length) { + this.lastChunk = this.chunk.slice(this.offset) + } + return false +} + +Reader.prototype.read = function() { + if(this.chunk.length < (this.headerSize + 4 + this.offset)) { + return this._save() + } + + if(this.headerSize) { + this.header = this.chunk[this.offset] + } + + //read length of next item + var length = this.chunk.readUInt32BE(this.offset + this.headerSize) + this.lengthPadding + + //next item spans more chunks than we have + var remaining = this.chunk.length - (this.offset + 4 + this.headerSize) + if(length > remaining) { + return this._save() + } + + this.offset += (this.headerSize + 4) + var result = this.chunk.slice(this.offset, this.offset + length) + this.offset += length + return result +} diff --git a/node_modules/pg/node_modules/packet-reader/package.json b/node_modules/pg/node_modules/packet-reader/package.json new file mode 100644 index 0000000..4c443fb --- /dev/null +++ b/node_modules/pg/node_modules/packet-reader/package.json @@ -0,0 +1,46 @@ +{ + "name": "packet-reader", + "version": "0.2.0", + "description": "Read binary packets...", + "main": "index.js", + "directories": { + "test": "test" + }, + "scripts": { + "test": "mocha" + }, + "repository": { + "type": "git", + "url": "git://github.com/brianc/node-packet-parser.git" + }, + "author": { + "name": "Brian M. Carlson" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/brianc/node-packet-parser/issues" + }, + "homepage": "https://github.com/brianc/node-packet-parser", + "devDependencies": { + "mocha": "~1.16.2" + }, + "_id": "packet-reader@0.2.0", + "dist": { + "shasum": "819df4d010b82d5ea5671f8a1a3acf039bcd7700", + "tarball": "http://registry.npmjs.org/packet-reader/-/packet-reader-0.2.0.tgz" + }, + "_from": "packet-reader@0.2.0", + "_npmVersion": "1.4.3", + "_npmUser": { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + }, + "maintainers": [ + { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + } + ], + "_shasum": "819df4d010b82d5ea5671f8a1a3acf039bcd7700", + "_resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.2.0.tgz" +} diff --git a/node_modules/pg/node_modules/packet-reader/test/index.js b/node_modules/pg/node_modules/packet-reader/test/index.js new file mode 100644 index 0000000..4be99d2 --- /dev/null +++ b/node_modules/pg/node_modules/packet-reader/test/index.js @@ -0,0 +1,135 @@ +var assert = require('assert') +var Reader = require('../') +describe('packet-reader', function() { + beforeEach(function() { + this.reader = new Reader(1) + }) + + it('reads perfect 1 length buffer', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 1, 1])) + var result = this.reader.read() + assert.equal(result.length, 1) + assert.equal(result[0], 1) + assert.strictEqual(false, this.reader.read()) + }) + + it('reads perfect longer buffer', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 4, 1, 2, 3, 4])) + var result = this.reader.read() + assert.equal(result.length, 4) + assert.strictEqual(false, this.reader.read()) + }) + + it('reads two parts', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 1])) + var result = this.reader.read() + assert.strictEqual(false, result) + this.reader.addChunk(Buffer([2])) + var result = this.reader.read() + assert.equal(result.length, 1, 'should return 1 length buffer') + assert.equal(result[0], 2) + assert.strictEqual(this.reader.read(), false) + }) + + it('reads multi-part', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 16])) + assert.equal(false, this.reader.read()) + this.reader.addChunk(Buffer([1, 2, 3, 4, 5, 6, 7, 8])) + assert.equal(false, this.reader.read()) + this.reader.addChunk(Buffer([9, 10, 11, 12, 13, 14, 15, 16])) + var result = this.reader.read() + assert.equal(result.length, 16) + }) + + it('reads multiple messages from single chunk', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2, 1, 2])) + var result = this.reader.read() + assert.equal(result.length, 1, 'should have 1 length buffer') + assert.equal(result[0], 1) + var result = this.reader.read() + assert.equal(result.length, 2, 'should have 2 length buffer but was ' + result.length) + assert.equal(result[0], 1) + assert.equal(result[1], 2) + assert.strictEqual(false, this.reader.read()) + }) + + it('reads 1 and a split', function() { + this.reader.addChunk(Buffer([0, 0, 0, 0, 1, 1, 0, 0]))//, 0, 0, 2, 1, 2])) + var result = this.reader.read() + assert.equal(result.length, 1, 'should have 1 length buffer') + assert.equal(result[0], 1) + var result = this.reader.read() + assert.strictEqual(result, false) + + this.reader.addChunk(Buffer([0, 0, 2, 1, 2])) + var result = this.reader.read() + assert.equal(result.length, 2, 'should have 2 length buffer but was ' + result.length) + assert.equal(result[0], 1) + assert.equal(result[1], 2) + assert.strictEqual(false, this.reader.read()) + }) +}) + +describe('variable length header', function() { + beforeEach(function() { + this.reader = new Reader() + }) + + it('reads double message buffers', function() { + this.reader.addChunk(Buffer([ + 0, 0, 0, 1, 1, + 0, 0, 0, 2, 1, 2])) + var result = this.reader.read() + assert(result) + assert.equal(result.length, 1) + assert.equal(result[0], 1) + result = this.reader.read() + assert(result) + assert.equal(result.length, 2) + assert.equal(result[0], 1) + assert.equal(result[1], 2) + assert.strictEqual(this.reader.read(), false) + }) +}) + +describe('1 length code', function() { + beforeEach(function() { + this.reader = new Reader(1) + }) + + it('reads code', function() { + this.reader.addChunk(Buffer([9, 0, 0, 0, 1, 1])) + var result = this.reader.read() + assert(result) + assert.equal(this.reader.header, 9) + assert.equal(result.length, 1) + assert.equal(result[0], 1) + }) + + it('is set on uncompleted read', function() { + assert.equal(this.reader.header, null) + this.reader.addChunk(Buffer([2, 0, 0, 0, 1])) + assert.strictEqual(this.reader.read(), false) + assert.equal(this.reader.header, 2) + }) +}) + +describe('postgres style packet', function() { + beforeEach(function() { + this.reader = new Reader({ + headerSize: 1, + lengthPadding: -4 + }) + }) + + it('reads with padded length', function() { + this.reader.addChunk(Buffer([1, 0, 0, 0, 8, 0, 0, 2, 0])) + var result = this.reader.read() + assert(result) + assert.equal(result.length, 4) + assert.equal(result[0], 0) + assert.equal(result[1], 0) + assert.equal(result[2], 2) + assert.equal(result[3], 0) + }) +}) diff --git a/node_modules/pg/node_modules/pg-connection-string/.npmignore b/node_modules/pg/node_modules/pg-connection-string/.npmignore new file mode 100644 index 0000000..da23d0d --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/.npmignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Deployed apps should consider commenting this line out: +# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git +node_modules diff --git a/node_modules/pg/node_modules/pg-connection-string/.travis.yml b/node_modules/pg/node_modules/pg-connection-string/.travis.yml new file mode 100644 index 0000000..244b7e8 --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - '0.10' diff --git a/node_modules/pg/node_modules/pg-connection-string/LICENSE b/node_modules/pg/node_modules/pg-connection-string/LICENSE new file mode 100644 index 0000000..b068a6c --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Iced Development + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/node_modules/pg/node_modules/pg-connection-string/README.md b/node_modules/pg/node_modules/pg-connection-string/README.md new file mode 100644 index 0000000..4986270 --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/README.md @@ -0,0 +1,18 @@ +pg-connection-string +==================== + +[![Build Status](https://travis-ci.org/iceddev/pg-connection-string.svg?branch=master)](https://travis-ci.org/iceddev/pg-connection-string) + +Functions for dealing with a PostgresSQL connection string + +`parse` method taken from [node-postgres](https://github.com/brianc/node-postgres.git) +Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) +MIT License + +## Usage + +```js +var parse = require('pg-connection-string').parse; + +var config = parse('postgres://someuser:somepassword@somehost:381/sometable') +``` diff --git a/node_modules/pg/node_modules/pg-connection-string/index.js b/node_modules/pg/node_modules/pg-connection-string/index.js new file mode 100644 index 0000000..ac2fd64 --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/index.js @@ -0,0 +1,62 @@ +'use strict'; + +var url = require('url'); + +//Parse method copied from https://github.com/brianc/node-postgres +//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) +//MIT License + +//parses a connection string +function parse(str) { + var config; + //unix socket + if(str.charAt(0) === '/') { + config = str.split(' '); + return { host: config[0], database: config[1] }; + } + // url parse expects spaces encoded as %20 + if(/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) { + str = encodeURI(str).replace(/\%25(\d\d)/g, "%$1"); + } + var result = url.parse(str, true); + config = {}; + + if (result.query.application_name) { + config.application_name = result.query.application_name; + } + if (result.query.fallback_application_name) { + config.fallback_application_name = result.query.fallback_application_name; + } + + config.port = result.port; + if(result.protocol == 'socket:') { + config.host = decodeURI(result.pathname); + config.database = result.query.db; + config.client_encoding = result.query.encoding; + return config; + } + config.host = result.hostname; + + // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) + // only strip the slash if it is present. + var pathname = result.pathname; + if (pathname && pathname.charAt(0) === '/') { + pathname = result.pathname.slice(1) || null; + } + config.database = pathname && decodeURI(pathname); + + var auth = (result.auth || ':').split(':'); + config.user = auth[0]; + config.password = auth.splice(1).join(':'); + + var ssl = result.query.ssl; + if (ssl === 'true' || ssl === '1') { + config.ssl = true; + } + + return config; +} + +module.exports = { + parse: parse +}; diff --git a/node_modules/pg/node_modules/pg-connection-string/package.json b/node_modules/pg/node_modules/pg-connection-string/package.json new file mode 100644 index 0000000..0ecf60b --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/package.json @@ -0,0 +1,54 @@ +{ + "name": "pg-connection-string", + "version": "0.1.3", + "description": "Functions for dealing with a PostgresSQL connection string", + "main": "index.js", + "scripts": { + "test": "tap ./test" + }, + "repository": { + "type": "git", + "url": "https://github.com/iceddev/pg-connection-string" + }, + "keywords": [ + "pg", + "connection", + "string", + "parse" + ], + "author": { + "name": "Blaine Bublitz", + "email": "blaine@iceddev.com", + "url": "http://iceddev.com/" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/iceddev/pg-connection-string/issues" + }, + "homepage": "https://github.com/iceddev/pg-connection-string", + "dependencies": {}, + "devDependencies": { + "tap": "^0.4.11" + }, + "gitHead": "4c151b9403420c1c9a9682facef1fcdbb9b79b3b", + "_id": "pg-connection-string@0.1.3", + "_shasum": "da1847b20940e42ee1492beaf65d49d91b245df7", + "_from": "pg-connection-string@0.1.3", + "_npmVersion": "1.4.28", + "_npmUser": { + "name": "phated", + "email": "blaine@iceddev.com" + }, + "maintainers": [ + { + "name": "phated", + "email": "blaine@iceddev.com" + } + ], + "dist": { + "shasum": "da1847b20940e42ee1492beaf65d49d91b245df7", + "tarball": "http://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz" +} diff --git a/node_modules/pg/node_modules/pg-connection-string/test/parse.js b/node_modules/pg/node_modules/pg-connection-string/test/parse.js new file mode 100644 index 0000000..c1494c3 --- /dev/null +++ b/node_modules/pg/node_modules/pg-connection-string/test/parse.js @@ -0,0 +1,126 @@ +'use strict'; + +var test = require('tap').test; + +var parse = require('../').parse; + +test('using connection string in client constructor', function(t){ + var subject = parse('postgres://brian:pw@boom:381/lala'); + t.equal(subject.user,'brian'); + t.equal(subject.password, 'pw'); + t.equal(subject.host, 'boom'); + t.equal(subject.port, '381'); + t.equal(subject.database, 'lala'); + t.end(); +}); + +test('escape spaces if present', function(t){ + var subject = parse('postgres://localhost/post gres'); + t.equal(subject.database, 'post gres'); + t.end(); +}); + +test('do not double escape spaces', function(t){ + var subject = parse('postgres://localhost/post%20gres'); + t.equal(subject.database, 'post gres'); + t.end(); +}); + +test('initializing with unix domain socket', function(t){ + var subject = parse('/var/run/'); + t.equal(subject.host, '/var/run/'); + t.end(); +}); + +test('initializing with unix domain socket and a specific database, the simple way', function(t){ + var subject = parse('/var/run/ mydb'); + t.equal(subject.host, '/var/run/'); + t.equal(subject.database, 'mydb'); + t.end(); +}); + +test('initializing with unix domain socket, the health way', function(t){ + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8'); + t.equal(subject.host, '/some path/'); + t.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); + t.equal(subject.client_encoding, 'utf8'); + t.end(); +}); + +test('initializing with unix domain socket, the escaped health way', function(t){ + var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); + t.equal(subject.host, '/some path/'); + t.equal(subject.database, 'my+db'); + t.equal(subject.client_encoding, 'utf8'); + t.end(); +}); + +test('password contains < and/or > characters', function(t){ + var sourceConfig = { + user:'brian', + password: 'helloe', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + t.equal(subject.password, sourceConfig.password); + t.end(); +}); + +test('password contains colons', function(t){ + var sourceConfig = { + user:'brian', + password: 'hello:pass:world', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + t.equal(subject.password, sourceConfig.password); + t.end(); +}); + +test('username or password contains weird characters', function(t){ + var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; + var subject = parse(strang); + t.equal(subject.user, 'my f%irst name'); + t.equal(subject.password, 'is&%awesome!'); + t.equal(subject.host, 'localhost'); + t.end(); +}); + +test('url is properly encoded', function(t){ + var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'; + var subject = parse(encoded); + t.equal(subject.user, 'bi%na%%ry '); + t.equal(subject.password, 's@f#'); + t.equal(subject.host, 'localhost'); + t.equal(subject.database, ' u%20rl'); + t.end(); +}); + +test('relative url sets database', function(t){ + var relative = 'different_db_on_default_host'; + var subject = parse(relative); + t.equal(subject.database, 'different_db_on_default_host'); + t.end(); +}); + +test('no pathname returns null database', function (t) { + var subject = parse('pg://myhost'); + t.equal(subject.host, 'myhost'); + t.type(subject.database, 'null'); + + t.end(); +}); + +test('pathname of "/" returns null database', function (t) { + var subject = parse('pg://myhost/'); + t.equal(subject.host, 'myhost'); + t.type(subject.database, 'null'); + + t.end(); +}); diff --git a/node_modules/pg/node_modules/pg-types/.npmignore b/node_modules/pg/node_modules/pg-types/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/pg/node_modules/pg-types/.travis.yml b/node_modules/pg/node_modules/pg-types/.travis.yml new file mode 100644 index 0000000..061e3d1 --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "0.10" + - "0.11" +env: + - PGUSER=postgres diff --git a/node_modules/pg/node_modules/pg-types/Makefile b/node_modules/pg/node_modules/pg-types/Makefile new file mode 100644 index 0000000..d7ec83d --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/Makefile @@ -0,0 +1,14 @@ +.PHONY: publish-patch test + +test: + npm test + +patch: test + npm version patch -m "Bump version" + git push origin master --tags + npm publish + +minor: test + npm version minor -m "Bump version" + git push origin master --tags + npm publish diff --git a/node_modules/pg/node_modules/pg-types/README.md b/node_modules/pg/node_modules/pg-types/README.md new file mode 100644 index 0000000..8f8512b --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/README.md @@ -0,0 +1,72 @@ +# pg-types + +This is the code that turns all the raw text from postgres into JavaScript types for [node-postgres](https://github.com/brianc/node-postgres.git) + +## use + +This module is consumed and exported from the root `pg` object of node-postgres. To access it, do the following: + +```js +var types = require('pg').types +``` + +Generally what you'll want to do is override how a specific data-type is parsed and turned into a JavaScript type. By default the PostgreSQL backend server returns everything as strings. Every data type corresponds to a unique `OID` within the server, and these `OIDs` are sent back with the query response. So, you need to match a particluar `OID` to a function you'd like to use to take the raw text input and produce a valid JavaScript object as a result. + +Let's do something I commonly like to do on projects: return 64-bit integers `(int8)` as JavaScript integers. Because JavaScript doesn't have support for 64-bit integers node-postgres cannot confidently parse `int8` data type results as numbers because if you have a _huge_ number it will overflow and the result you'd get back from node-postgres would not be the result in the datbase. That would be a __very bad thing__ so node-postgres just returns `int8` results as strings and leaves the parsing up to you. Let's say that you know you don't and wont ever have numbers greater than `int4` in your database, but you're tired of recieving results from the `COUNT(*)` function as strings (because that function returns `int8`). You would do this: + +```js +var types = require('pg').types +types.setTypeParser(20, function(val) { + //remember: all values returned from the server are either NULL or a string + return val === null ? null : parseInt(val) +}) +``` + +__boom__: now you get numbers instead of strings. + +Just as another example -- not saying this is a good idea -- let's say you want to return all dates from your database as [moment](http://momentjs.com/docs/) objects. Okay, do this: + +```js +var types = require('pg').types +var moment = require('moment') +var TIMESTAMPTZ_OID = 1114 +var TIMESTAMP_OID = 1184 +var parseFn = function(val) { + return val === null ? null : moment(val) +} +types.setTypeParser(TIMESTAMPTZ_OID, parseFn) +types.setTypeParser(TIMESTAMP_OID, parseFn) +``` +_note: I've never done that with my dates, and I'm not 100% sure moment can parse all the date strings returned from postgres. It's just an example!_ + +If you're thinking "gee, this seems pretty handy, but how can I get a list of all the OIDs in the database and what the correspond to?!?!?!" worry not: + +```bash +$ psql -c "select oid, typname from pg_type where typtype = 'b' order by oid" +``` + +:smile: + +## license + +The MIT License (MIT) + +Copyright (c) 2014 Brian M. Carlson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/pg/node_modules/pg-types/index.js b/node_modules/pg/node_modules/pg-types/index.js new file mode 100644 index 0000000..41a0ca5 --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/index.js @@ -0,0 +1,47 @@ +var textParsers = require('./lib/textParsers'); +var binaryParsers = require('./lib/binaryParsers'); +var arrayParser = require('./lib/arrayParser'); + +var typeParsers = { + text: {}, + binary: {} +}; + +//the empty parse function +var noParse = function(val) { + return String(val); +}; + +//returns a function used to convert a specific type (specified by +//oid) into a result javascript type +//note: the oid can be obtained via the following sql query: +//SELECT oid FROM pg_type WHERE typname = 'TYPE_NAME_HERE'; +var getTypeParser = function(oid, format) { + format = format || 'text'; + if (!typeParsers[format]) { + return noParse; + } + return typeParsers[format][oid] || noParse; +}; + +var setTypeParser = function(oid, format, parseFn) { + if(typeof format == 'function') { + parseFn = format; + format = 'text'; + } + typeParsers[format][oid] = parseFn; +}; + +textParsers.init(function(oid, converter) { + typeParsers.text[oid] = converter; +}); + +binaryParsers.init(function(oid, converter) { + typeParsers.binary[oid] = converter; +}); + +module.exports = { + getTypeParser: getTypeParser, + setTypeParser: setTypeParser, + arrayParser: arrayParser +}; diff --git a/node_modules/pg/node_modules/pg-types/lib/arrayParser.js b/node_modules/pg/node_modules/pg-types/lib/arrayParser.js new file mode 100644 index 0000000..96a37b9 --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/lib/arrayParser.js @@ -0,0 +1,97 @@ +function ArrayParser(source, converter) { + this.source = source; + this.converter = converter; + this.pos = 0; + this.entries = []; + this.recorded = []; + this.dimension = 0; + if (!this.converter) { + this.converter = function(entry) { + return entry; + }; + } +} + +ArrayParser.prototype.eof = function() { + return this.pos >= this.source.length; +}; + +ArrayParser.prototype.nextChar = function() { + var c; + if ((c = this.source[this.pos++]) === "\\") { + return { + char: this.source[this.pos++], + escaped: true + }; + } else { + return { + char: c, + escaped: false + }; + } +}; + +ArrayParser.prototype.record = function(c) { + return this.recorded.push(c); +}; + +ArrayParser.prototype.newEntry = function(includeEmpty) { + var entry; + if (this.recorded.length > 0 || includeEmpty) { + entry = this.recorded.join(""); + if (entry === "NULL" && !includeEmpty) { + entry = null; + } + if (entry !== null) { + entry = this.converter(entry); + } + this.entries.push(entry); + this.recorded = []; + } +}; + +ArrayParser.prototype.parse = function(nested) { + var c, p, quote; + if (nested === null) { + nested = false; + } + quote = false; + while (!this.eof()) { + c = this.nextChar(); + if (c.char === "{" && !quote) { + this.dimension++; + if (this.dimension > 1) { + p = new ArrayParser(this.source.substr(this.pos - 1), this.converter); + this.entries.push(p.parse(true)); + this.pos += p.pos - 2; + } + } else if (c.char === "}" && !quote) { + this.dimension--; + if (this.dimension === 0) { + this.newEntry(); + if (nested) { + return this.entries; + } + } + } else if (c.char === '"' && !c.escaped) { + if (quote) { + this.newEntry(true); + } + quote = !quote; + } else if (c.char === ',' && !quote) { + this.newEntry(); + } else { + this.record(c.char); + } + } + if (this.dimension !== 0) { + throw "array dimension not balanced"; + } + return this.entries; +}; + +module.exports = { + create: function(source, converter){ + return new ArrayParser(source, converter); + } +}; diff --git a/node_modules/pg/node_modules/pg-types/lib/binaryParsers.js b/node_modules/pg/node_modules/pg-types/lib/binaryParsers.js new file mode 100644 index 0000000..8d33e19 --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/lib/binaryParsers.js @@ -0,0 +1,254 @@ +var parseBits = function(data, bits, offset, invert, callback) { + offset = offset || 0; + invert = invert || false; + callback = callback || function(lastValue, newValue, bits) { return (lastValue * Math.pow(2, bits)) + newValue; }; + var offsetBytes = offset >> 3; + + var inv = function(value) { + if (invert) { + return ~value & 0xff; + } + + return value; + }; + + // read first (maybe partial) byte + var mask = 0xff; + var firstBits = 8 - (offset % 8); + if (bits < firstBits) { + mask = (0xff << (8 - bits)) & 0xff; + firstBits = bits; + } + + if (offset) { + mask = mask >> (offset % 8); + } + + var result = 0; + if ((offset % 8) + bits >= 8) { + result = callback(0, inv(data[offsetBytes]) & mask, firstBits); + } + + // read bytes + var bytes = (bits + offset) >> 3; + for (var i = offsetBytes + 1; i < bytes; i++) { + result = callback(result, inv(data[i]), 8); + } + + // bits to read, that are not a complete byte + var lastBits = (bits + offset) % 8; + if (lastBits > 0) { + result = callback(result, inv(data[bytes]) >> (8 - lastBits), lastBits); + } + + return result; +}; + +var parseFloatFromBits = function(data, precisionBits, exponentBits) { + var bias = Math.pow(2, exponentBits - 1) - 1; + var sign = parseBits(data, 1); + var exponent = parseBits(data, exponentBits, 1); + + if (exponent === 0) { + return 0; + } + + // parse mantissa + var precisionBitsCounter = 1; + var parsePrecisionBits = function(lastValue, newValue, bits) { + if (lastValue === 0) { + lastValue = 1; + } + + for (var i = 1; i <= bits; i++) { + precisionBitsCounter /= 2; + if ((newValue & (0x1 << (bits - i))) > 0) { + lastValue += precisionBitsCounter; + } + } + + return lastValue; + }; + + var mantissa = parseBits(data, precisionBits, exponentBits + 1, false, parsePrecisionBits); + + // special cases + if (exponent == (Math.pow(2, exponentBits + 1) - 1)) { + if (mantissa === 0) { + return (sign === 0) ? Infinity : -Infinity; + } + + return NaN; + } + + // normale number + return ((sign === 0) ? 1 : -1) * Math.pow(2, exponent - bias) * mantissa; +}; + +var parseInt16 = function(value) { + if (parseBits(value, 1) == 1) { + return -1 * (parseBits(value, 15, 1, true) + 1); + } + + return parseBits(value, 15, 1); +}; + +var parseInt32 = function(value) { + if (parseBits(value, 1) == 1) { + return -1 * (parseBits(value, 31, 1, true) + 1); + } + + return parseBits(value, 31, 1); +}; + +var parseFloat32 = function(value) { + return parseFloatFromBits(value, 23, 8); +}; + +var parseFloat64 = function(value) { + return parseFloatFromBits(value, 52, 11); +}; + +var parseNumeric = function(value) { + var sign = parseBits(value, 16, 32); + if (sign == 0xc000) { + return NaN; + } + + var weight = Math.pow(10000, parseBits(value, 16, 16)); + var result = 0; + + var digits = []; + var ndigits = parseBits(value, 16); + for (var i = 0; i < ndigits; i++) { + result += parseBits(value, 16, 64 + (16 * i)) * weight; + weight /= 10000; + } + + var scale = Math.pow(10, parseBits(value, 16, 48)); + return ((sign === 0) ? 1 : -1) * Math.round(result * scale) / scale; +}; + +var parseDate = function(isUTC, value) { + var sign = parseBits(value, 1); + var rawValue = parseBits(value, 63, 1); + + // discard usecs and shift from 2000 to 1970 + var result = new Date((((sign === 0) ? 1 : -1) * rawValue / 1000) + 946684800000); + + if (!isUTC) { + result.setTime(result.getTime() + result.getTimezoneOffset() * 60000); + } + + // add microseconds to the date + result.usec = rawValue % 1000; + result.getMicroSeconds = function() { + return this.usec; + }; + result.setMicroSeconds = function(value) { + this.usec = value; + }; + result.getUTCMicroSeconds = function() { + return this.usec; + }; + + return result; +}; + +var parseArray = function(value) { + var dim = parseBits(value, 32); + + var flags = parseBits(value, 32, 32); + var elementType = parseBits(value, 32, 64); + + var offset = 96; + var dims = []; + for (var i = 0; i < dim; i++) { + // parse dimension + dims[i] = parseBits(value, 32, offset); + offset += 32; + + // ignore lower bounds + offset += 32; + } + + var parseElement = function(elementType) { + // parse content length + var length = parseBits(value, 32, offset); + offset += 32; + + // parse null values + if (length == 0xffffffff) { + return null; + } + + var result; + if ((elementType == 0x17) || (elementType == 0x14)) { + // int/bigint + result = parseBits(value, length * 8, offset); + offset += length * 8; + return result; + } + else if (elementType == 0x19) { + // string + result = value.toString(this.encoding, offset >> 3, (offset += (length << 3)) >> 3); + return result; + } + else { + console.log("ERROR: ElementType not implemented: " + elementType); + } + }; + + var parse = function(dimension, elementType) { + var array = []; + var i; + + if (dimension.length > 1) { + var count = dimension.shift(); + for (i = 0; i < count; i++) { + array[i] = parse(dimension, elementType); + } + dimension.unshift(count); + } + else { + for (i = 0; i < dimension[0]; i++) { + array[i] = parseElement(elementType); + } + } + + return array; + }; + + return parse(dims, elementType); +}; + +var parseText = function(value) { + return value.toString('utf8'); +}; + +var parseBool = function(value) { + if(value === null) return null; + return (parseBits(value, 8) > 0); +}; + +var init = function(register) { + register(21, parseInt16); + register(23, parseInt32); + register(26, parseInt32); + register(1700, parseNumeric); + register(700, parseFloat32); + register(701, parseFloat64); + register(16, parseBool); + register(1114, parseDate.bind(null, false)); + register(1184, parseDate.bind(null, true)); + register(1000, parseArray); + register(1007, parseArray); + register(1016, parseArray); + register(1008, parseArray); + register(1009, parseArray); + register(25, parseText); +}; + +module.exports = { + init: init +}; diff --git a/node_modules/pg/node_modules/pg-types/lib/textParsers.js b/node_modules/pg/node_modules/pg-types/lib/textParsers.js new file mode 100644 index 0000000..7294e1b --- /dev/null +++ b/node_modules/pg/node_modules/pg-types/lib/textParsers.js @@ -0,0 +1,272 @@ +var arrayParser = require(__dirname + "/arrayParser.js"); + +//parses PostgreSQL server formatted date strings into javascript date objects +var parseDate = function(isoDate) { + //TODO this could do w/ a refactor + var dateMatcher = /(\d{1,})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(\.\d{1,})?/; + + var match = dateMatcher.exec(isoDate); + //could not parse date + if(!match) { + dateMatcher = /^(\d{1,})-(\d{2})-(\d{2})$/; + match = dateMatcher.test(isoDate); + if(!match) { + return null; + } else { + //it is a date in YYYY-MM-DD format + //add time portion to force js to parse as local time + return new Date(isoDate + ' 00:00:00'); + } + } + var isBC = /BC$/.test(isoDate); + var _year = parseInt(match[1], 10); + var isFirstCentury = (_year > 0) && (_year < 100); + var year = (isBC ? "-" : "") + match[1]; + + var month = parseInt(match[2],10)-1; + var day = match[3]; + var hour = parseInt(match[4],10); + var min = parseInt(match[5],10); + var seconds = parseInt(match[6], 10); + + var miliString = match[7]; + var mili = 0; + if(miliString) { + mili = 1000 * parseFloat(miliString); + } + + //match timezones like the following: + //Z (UTC) + //-05 + //+06:30 + var tZone = /([Z|+\-])(\d{2})?:?(\d{2})?:?(\d{2})?/.exec(isoDate.split(' ')[1]); + //minutes to adjust for timezone + var tzAdjust = 0; + var tzSign = 1; + var date; + if(tZone) { + var type = tZone[1]; + switch(type) { + case 'Z': + break; + case '-': + tzSign = -1; + case '+': + tzAdjust = tzSign * ( + (parseInt(tZone[2], 10) * 3600) + + (parseInt(tZone[3] || 0, 10) * 60) + + (parseInt(tZone[4] || 0, 10)) + ); + break; + default: + throw new Error("Unidentifed tZone part " + type); + } + + var utcOffset = Date.UTC(year, month, day, hour, min, seconds, mili); + + date = new Date(utcOffset - (tzAdjust * 1000)); + } + //no timezone information + else { + date = new Date(year, month, day, hour, min, seconds, mili); + } + + if (isFirstCentury) { + date.setUTCFullYear(year); + } + + return date; +}; + +var parseBool = function(val) { + if(val === null) return val; + return val === 't'; +}; + +var parseBoolArray = function(val) { + if(!val) { return null; } + var p = arrayParser.create(val, function(entry){ + if(entry !== null) { + entry = parseBool(entry); + } + return entry; + }); + + return p.parse(); +}; + +var parseIntegerArray = function(val) { + if(!val) { return null; } + var p = arrayParser.create(val, function(entry){ + if(entry !== null) { + entry = parseInt(entry, 10); + } + return entry; + }); + + return p.parse(); +}; + +var parseBigIntegerArray = function(val) { + if(!val) { return null; } + var p = arrayParser.create(val, function(entry){ + if(entry !== null) { + entry = parseBigInteger(entry).trim(); + } + return entry; + }); + + return p.parse(); +}; + +var parseFloatArray = function(val) { + if(!val) { return null; } + var p = arrayParser.create(val, function(entry) { + if(entry !== null) { + entry = parseFloat(entry); + } + return entry; + }); + + return p.parse(); +}; + +var parseStringArray = function(val) { + if(!val) { return null; } + + var p = arrayParser.create(val); + return p.parse(); +}; + +var parseDateArray = function(val) { + if (!val) { return null; } + + var p = arrayParser.create(val, function(entry) { + if (entry !== null) { + entry = parseDate(entry); + } + return entry; + }); + + return p.parse(); +}; + +var NUM = '([+-]?\\d+)'; +var YEAR = NUM + '\\s+years?'; +var MON = NUM + '\\s+mons?'; +var DAY = NUM + '\\s+days?'; +var TIME = '([+-])?(\\d\\d):(\\d\\d):(\\d\\d)'; +var INTERVAL = [YEAR,MON,DAY,TIME].map(function(p){ + return "("+p+")?"; +}).join('\\s*'); + +var parseInterval = function(val) { + if (!val) { return {}; } + var m = new RegExp(INTERVAL).exec(val); + var i = {}; + if (m[2]) { i.years = parseInt(m[2], 10); } + if (m[4]) { i.months = parseInt(m[4], 10); } + if (m[6]) { i.days = parseInt(m[6], 10); } + if (m[9]) { i.hours = parseInt(m[9], 10); } + if (m[10]) { i.minutes = parseInt(m[10], 10); } + if (m[11]) { i.seconds = parseInt(m[11], 10); } + if (m[8] == '-'){ + if (i.hours) { i.hours *= -1; } + if (i.minutes) { i.minutes *= -1; } + if (i.seconds) { i.seconds *= -1; } + } + for (var field in i){ + if (i[field] === 0) { + delete i[field]; + } + } + return i; +}; + +var parseByteA = function(val) { + if(/^\\x/.test(val)){ + // new 'hex' style response (pg >9.0) + return new Buffer(val.substr(2), 'hex'); + }else{ + var out = ""; + var i = 0; + while(i < val.length){ + if(val[i] != "\\"){ + out += val[i]; + ++i; + }else{ + if(val.substr(i+1,3).match(/[0-7]{3}/)){ + out += String.fromCharCode(parseInt(val.substr(i+1,3),8)); + i += 4; + }else{ + backslashes = 1; + while(i+backslashes < val.length && val[i+backslashes] == "\\") + backslashes++; + for(k=0; k'; + + if (! isRegFile(stats.mode)) { + warn('WARNING: password file "%s" is not a plain file', fname); + return false; + } + + if (stats.mode & (S_IRWXG | S_IRWXO)) { + /* If password file is insecure, alert the user and ignore it. */ + warn('WARNING: password file "%s" has group or world access; permissions should be u=rw (0600) or less', fname); + return false; + } + + return true; +}; + + +var matcher = module.exports.match = function(connInfo, entry) { + return fieldNames.slice(0, -1).reduce(function(prev, field, idx){ + if (idx == 1) { + // the port + if ( Number( connInfo[field] || defaultPort ) === Number( entry[field] ) ) { + return prev && true; + } + } + return prev && ( + entry[field] === '*' || + entry[field] === connInfo[field] + ); + }, true); +}; + + +module.exports.getPassword = function(connInfo, stream, cb) { + var pass; + var lineStream = stream.pipe(new Split()); + + function onLine(line) { + var entry = parseLine(line); + if (entry && isValidEntry(entry) && matcher(connInfo, entry)) { + pass = entry[passKey]; + lineStream.end(); // -> calls onEnd(), but pass is set now + } + } + + var onEnd = function() { + cb(pass); + }; + + var onErr = function(err) { + warn('WARNING: error on reading file: %s', err); + cb(undefined); + }; + + stream.on('error', onErr); + lineStream + .on('data', onLine) + .on('end', onEnd) + .on('error', onErr) + ; + +}; + + +var parseLine = module.exports.parseLine = function(line) { + if (line.length < 11 || line.match(/^\s+#/)) { + return null; + } + + var curChar = ''; + var prevChar = ''; + var fieldIdx = 0; + var startIdx = 0; + var endIdx = 0; + var obj = {}; + var isLastField = false; + var addToObj = function(idx, i0, i1) { + var field = line.substring(i0, i1); + + if (! Object.hasOwnProperty.call(process.env, 'PGPASS_NO_DEESCAPE')) { + field = field.replace(/\\([:\\])/g, '$1'); + } + + obj[ fieldNames[idx] ] = field; + }; + + for (var i = 0 ; i < line.length-1 ; i += 1) { + curChar = line.charAt(i+1); + prevChar = line.charAt(i); + + isLastField = (fieldIdx == nrOfFields-1); + + if (isLastField) { + addToObj(fieldIdx, startIdx); + break; + } + + if (i >= 0 && curChar == ':' && prevChar !== '\\') { + addToObj(fieldIdx, startIdx, i+1); + + startIdx = i+2; + fieldIdx += 1; + } + } + + obj = ( Object.keys(obj).length === nrOfFields ) ? obj : null; + + return obj; +}; + + +var isValidEntry = module.exports.isValidEntry = function(entry){ + var rules = { + // host + 0 : function(x){ + return x.length > 0; + } , + // port + 1 : function(x){ + if (x === '*') { + return true; + } + x = Number(x); + return ( + isFinite(x) && + x > 0 && + x < 9007199254740992 && + Math.floor(x) === x + ); + } , + // database + 2 : function(x){ + return x.length > 0; + } , + // username + 3 : function(x){ + return x.length > 0; + } , + // password + 4 : function(x){ + return x.length > 0; + } + }; + + for (var idx = 0 ; idx < fieldNames.length ; idx += 1) { + var rule = rules[idx]; + var value = entry[ fieldNames[idx] ] || ''; + + var res = rule(value); + if (!res) { + return false; + } + } + + return true; +}; + diff --git a/node_modules/pg/node_modules/pgpass/lib/index.js b/node_modules/pg/node_modules/pgpass/lib/index.js new file mode 100644 index 0000000..5458948 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/lib/index.js @@ -0,0 +1,23 @@ +'use strict'; + +var path = require('path') + , fs = require('fs') + , helper = require( path.join(__dirname, 'helper.js') ) +; + + +module.exports.warnTo = helper.warnTo; + +module.exports = function(connInfo, cb) { + var file = helper.getFileName(); + + fs.stat(file, function(err, stat){ + if (err || !helper.usePgPass(stat, file)) { + return cb(undefined); + } + + var st = fs.createReadStream(file); + + helper.getPassword(connInfo, st, cb); + }); +}; \ No newline at end of file diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/.npmignore b/node_modules/pg/node_modules/pgpass/node_modules/split/.npmignore new file mode 100644 index 0000000..13abef4 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/.npmignore @@ -0,0 +1,3 @@ +node_modules +node_modules/* +npm_debug.log diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/.travis.yml b/node_modules/pg/node_modules/pgpass/node_modules/split/.travis.yml new file mode 100644 index 0000000..dad2273 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.8 + - "0.10" diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/LICENCE b/node_modules/pg/node_modules/pgpass/node_modules/split/LICENCE new file mode 100644 index 0000000..171dd97 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/LICENCE @@ -0,0 +1,22 @@ +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/examples/pretty.js b/node_modules/pg/node_modules/pgpass/node_modules/split/examples/pretty.js new file mode 100644 index 0000000..2e89131 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/examples/pretty.js @@ -0,0 +1,26 @@ + +var inspect = require('util').inspect +var es = require('event-stream') //load event-stream +var split = require('../') + +if(!module.parent) { + es.pipe( //pipe joins streams together + process.openStdin(), //open stdin + split(), //split stream to break on newlines + es.map(function (data, callback) {//turn this async function into a stream + var j + try { + j = JSON.parse(data) //try to parse input into json + } catch (err) { + return callback(null, data) //if it fails just pass it anyway + } + callback(null, inspect(j)) //render it nicely + }), + process.stdout // pipe it to stdout ! + ) + } + +// run this +// +// curl -sS registry.npmjs.org/event-stream | node pretty.js +// diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/index.js b/node_modules/pg/node_modules/pgpass/node_modules/split/index.js new file mode 100644 index 0000000..e63fbbc --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/index.js @@ -0,0 +1,63 @@ +//filter will reemit the data if cb(err,pass) pass is truthy + +// reduce is more tricky +// maybe we want to group the reductions or emit progress updates occasionally +// the most basic reduce just emits one 'data' event after it has recieved 'end' + + +var through = require('through') +var Decoder = require('string_decoder').StringDecoder + +module.exports = split + +//TODO pass in a function to map across the lines. + +function split (matcher, mapper, options) { + var decoder = new Decoder() + var soFar = '' + var maxLength = options && options.maxLength; + if('function' === typeof matcher) + mapper = matcher, matcher = null + if (!matcher) + matcher = /\r?\n/ + + function emit(stream, piece) { + if(mapper) { + try { + piece = mapper(piece) + } + catch (err) { + return stream.emit('error', err) + } + if('undefined' !== typeof piece) + stream.queue(piece) + } + else + stream.queue(piece) + } + + function next (stream, buffer) { + var pieces = (soFar + buffer).split(matcher) + soFar = pieces.pop() + + if (maxLength && soFar.length > maxLength) + stream.emit('error', new Error('maximum buffer reached')) + + for (var i = 0; i < pieces.length; i++) { + var piece = pieces[i] + emit(stream, piece) + } + } + + return through(function (b) { + next(this, decoder.write(b)) + }, + function () { + if(decoder.end) + next(this, decoder.end()) + if(soFar != null) + emit(this, soFar) + this.queue(null) + }) +} + diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/.travis.yml b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/.travis.yml new file mode 100644 index 0000000..c693a93 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 + - 0.8 + - "0.10" diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.APACHE2 b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.APACHE2 new file mode 100644 index 0000000..6366c04 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.APACHE2 @@ -0,0 +1,15 @@ +Apache License, Version 2.0 + +Copyright (c) 2011 Dominic Tarr + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.MIT b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.MIT new file mode 100644 index 0000000..6eafbd7 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/LICENSE.MIT @@ -0,0 +1,24 @@ +The MIT License + +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/index.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/index.js new file mode 100644 index 0000000..7b935bf --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/index.js @@ -0,0 +1,108 @@ +var Stream = require('stream') + +// through +// +// a stream that does nothing but re-emit the input. +// useful for aggregating a series of changing but not ending streams into one stream) + +exports = module.exports = through +through.through = through + +//create a readable writable stream. + +function through (write, end, opts) { + write = write || function (data) { this.queue(data) } + end = end || function () { this.queue(null) } + + var ended = false, destroyed = false, buffer = [], _ended = false + var stream = new Stream() + stream.readable = stream.writable = true + stream.paused = false + +// stream.autoPause = !(opts && opts.autoPause === false) + stream.autoDestroy = !(opts && opts.autoDestroy === false) + + stream.write = function (data) { + write.call(this, data) + return !stream.paused + } + + function drain() { + while(buffer.length && !stream.paused) { + var data = buffer.shift() + if(null === data) + return stream.emit('end') + else + stream.emit('data', data) + } + } + + stream.queue = stream.push = function (data) { +// console.error(ended) + if(_ended) return stream + if(data == null) _ended = true + buffer.push(data) + drain() + return stream + } + + //this will be registered as the first 'end' listener + //must call destroy next tick, to make sure we're after any + //stream piped from here. + //this is only a problem if end is not emitted synchronously. + //a nicer way to do this is to make sure this is the last listener for 'end' + + stream.on('end', function () { + stream.readable = false + if(!stream.writable && stream.autoDestroy) + process.nextTick(function () { + stream.destroy() + }) + }) + + function _end () { + stream.writable = false + end.call(stream) + if(!stream.readable && stream.autoDestroy) + stream.destroy() + } + + stream.end = function (data) { + if(ended) return + ended = true + if(arguments.length) stream.write(data) + _end() // will emit or queue + return stream + } + + stream.destroy = function () { + if(destroyed) return + destroyed = true + ended = true + buffer.length = 0 + stream.writable = stream.readable = false + stream.emit('close') + return stream + } + + stream.pause = function () { + if(stream.paused) return + stream.paused = true + return stream + } + + stream.resume = function () { + if(stream.paused) { + stream.paused = false + stream.emit('resume') + } + drain() + //may have become paused again, + //as drain emits 'data'. + if(!stream.paused) + stream.emit('drain') + return stream + } + return stream +} + diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/package.json b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/package.json new file mode 100644 index 0000000..ef54fa3 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/package.json @@ -0,0 +1,64 @@ +{ + "name": "through", + "version": "2.3.6", + "description": "simplified stream construction", + "main": "index.js", + "scripts": { + "test": "set -e; for t in test/*.js; do node $t; done" + }, + "devDependencies": { + "stream-spec": "~0.3.5", + "tape": "~2.3.2", + "from": "~0.1.3" + }, + "keywords": [ + "stream", + "streams", + "user-streams", + "pipe" + ], + "author": { + "name": "Dominic Tarr", + "email": "dominic.tarr@gmail.com", + "url": "dominictarr.com" + }, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/dominictarr/through.git" + }, + "homepage": "http://github.com/dominictarr/through", + "testling": { + "browsers": [ + "ie/8..latest", + "ff/15..latest", + "chrome/20..latest", + "safari/5.1..latest" + ], + "files": "test/*.js" + }, + "gitHead": "19ed9b7e84efe7c3e3c8be80f29390b1620e13c0", + "bugs": { + "url": "https://github.com/dominictarr/through/issues" + }, + "_id": "through@2.3.6", + "_shasum": "26681c0f524671021d4e29df7c36bce2d0ecf2e8", + "_from": "through@>=2.0.0 <3.0.0", + "_npmVersion": "1.4.26", + "_npmUser": { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + }, + "maintainers": [ + { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + } + ], + "dist": { + "shasum": "26681c0f524671021d4e29df7c36bce2d0ecf2e8", + "tarball": "http://registry.npmjs.org/through/-/through-2.3.6.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/through/-/through-2.3.6.tgz" +} diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/readme.markdown b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/readme.markdown new file mode 100644 index 0000000..cb34c81 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/readme.markdown @@ -0,0 +1,64 @@ +#through + +[![build status](https://secure.travis-ci.org/dominictarr/through.png)](http://travis-ci.org/dominictarr/through) +[![testling badge](https://ci.testling.com/dominictarr/through.png)](https://ci.testling.com/dominictarr/through) + +Easy way to create a `Stream` that is both `readable` and `writable`. + +* Pass in optional `write` and `end` methods. +* `through` takes care of pause/resume logic if you use `this.queue(data)` instead of `this.emit('data', data)`. +* Use `this.pause()` and `this.resume()` to manage flow. +* Check `this.paused` to see current flow state. (`write` always returns `!this.paused`). + +This function is the basis for most of the synchronous streams in +[event-stream](http://github.com/dominictarr/event-stream). + +``` js +var through = require('through') + +through(function write(data) { + this.queue(data) //data *must* not be null + }, + function end () { //optional + this.queue(null) + }) +``` + +Or, can also be used _without_ buffering on pause, use `this.emit('data', data)`, +and this.emit('end') + +``` js +var through = require('through') + +through(function write(data) { + this.emit('data', data) + //this.pause() + }, + function end () { //optional + this.emit('end') + }) +``` + +## Extended Options + +You will probably not need these 99% of the time. + +### autoDestroy=false + +By default, `through` emits close when the writable +and readable side of the stream has ended. +If that is not desired, set `autoDestroy=false`. + +``` js +var through = require('through') + +//like this +var ts = through(write, end, {autoDestroy: false}) +//or like this +var ts = through(write, end) +ts.autoDestroy = false +``` + +## License + +MIT / Apache2 diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/async.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/async.js new file mode 100644 index 0000000..46bdbae --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/async.js @@ -0,0 +1,28 @@ +var from = require('from') +var through = require('../') + +var tape = require('tape') + +tape('simple async example', function (t) { + + var n = 0, expected = [1,2,3,4,5], actual = [] + from(expected) + .pipe(through(function(data) { + this.pause() + n ++ + setTimeout(function(){ + console.log('pushing data', data) + this.push(data) + this.resume() + }.bind(this), 300) + })).pipe(through(function(data) { + console.log('pushing data second time', data); + this.push(data) + })).on('data', function (d) { + actual.push(d) + }).on('end', function() { + t.deepEqual(actual, expected) + t.end() + }) + +}) diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/auto-destroy.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/auto-destroy.js new file mode 100644 index 0000000..9a8fd00 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/auto-destroy.js @@ -0,0 +1,30 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('end before close', function (assert) { + var ts = through() + ts.autoDestroy = false + var ended = false, closed = false + + ts.on('end', function () { + assert.ok(!closed) + ended = true + }) + ts.on('close', function () { + assert.ok(ended) + closed = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.ok(ended) + assert.notOk(closed) + ts.destroy() + assert.ok(closed) + assert.end() +}) + diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/buffering.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/buffering.js new file mode 100644 index 0000000..b0084bf --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/buffering.js @@ -0,0 +1,71 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('buffering', function(assert) { + var ts = through(function (data) { + this.queue(data) + }, function () { + this.queue(null) + }) + + var ended = false, actual = [] + + ts.on('data', actual.push.bind(actual)) + ts.on('end', function () { + ended = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + assert.deepEqual(actual, [1, 2, 3]) + ts.pause() + ts.write(4) + ts.write(5) + ts.write(6) + assert.deepEqual(actual, [1, 2, 3]) + ts.resume() + assert.deepEqual(actual, [1, 2, 3, 4, 5, 6]) + ts.pause() + ts.end() + assert.ok(!ended) + ts.resume() + assert.ok(ended) + assert.end() +}) + +test('buffering has data in queue, when ends', function (assert) { + + /* + * If stream ends while paused with data in the queue, + * stream should still emit end after all data is written + * on resume. + */ + + var ts = through(function (data) { + this.queue(data) + }, function () { + this.queue(null) + }) + + var ended = false, actual = [] + + ts.on('data', actual.push.bind(actual)) + ts.on('end', function () { + ended = true + }) + + ts.pause() + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.deepEqual(actual, [], 'no data written yet, still paused') + assert.ok(!ended, 'end not emitted yet, still paused') + ts.resume() + assert.deepEqual(actual, [1, 2, 3], 'resumed, all data should be delivered') + assert.ok(ended, 'end should be emitted once all data was delivered') + assert.end(); +}) diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/end.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/end.js new file mode 100644 index 0000000..fa113f5 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/end.js @@ -0,0 +1,45 @@ +var test = require('tape') +var through = require('../') + +// must emit end before close. + +test('end before close', function (assert) { + var ts = through() + var ended = false, closed = false + + ts.on('end', function () { + assert.ok(!closed) + ended = true + }) + ts.on('close', function () { + assert.ok(ended) + closed = true + }) + + ts.write(1) + ts.write(2) + ts.write(3) + ts.end() + assert.ok(ended) + assert.ok(closed) + assert.end() +}) + +test('end only once', function (t) { + + var ts = through() + var ended = false, closed = false + + ts.on('end', function () { + t.equal(ended, false) + ended = true + }) + + ts.queue(null) + ts.queue(null) + ts.queue(null) + + ts.resume() + + t.end() +}) diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/index.js b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/index.js new file mode 100644 index 0000000..8d1517e --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/node_modules/through/test/index.js @@ -0,0 +1,117 @@ + +var test = require('tape') +var spec = require('stream-spec') +var through = require('../') + +/* + I'm using these two functions, and not streams and pipe + so there is less to break. if this test fails it must be + the implementation of _through_ +*/ + +function write(array, stream) { + array = array.slice() + function next() { + while(array.length) + if(stream.write(array.shift()) === false) + return stream.once('drain', next) + + stream.end() + } + + next() +} + +function read(stream, callback) { + var actual = [] + stream.on('data', function (data) { + actual.push(data) + }) + stream.once('end', function () { + callback(null, actual) + }) + stream.once('error', function (err) { + callback(err) + }) +} + +test('simple defaults', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = through() + var s = spec(t).through().pausable() + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected) + assert.end() + }) + + t.on('close', s.validate) + + write(expected, t) +}); + +test('simple functions', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l * Math.random()) + + var t = through(function (data) { + this.emit('data', data*2) + }) + var s = spec(t).through().pausable() + + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected.map(function (data) { + return data*2 + })) + assert.end() + }) + + t.on('close', s.validate) + + write(expected, t) +}) + +test('pauses', function(assert) { + + var l = 1000 + , expected = [] + + while(l--) expected.push(l) //Math.random()) + + var t = through() + + var s = spec(t) + .through() + .pausable() + + t.on('data', function () { + if(Math.random() > 0.1) return + t.pause() + process.nextTick(function () { + t.resume() + }) + }) + + read(t, function (err, actual) { + assert.ifError(err) + assert.deepEqual(actual, expected) + }) + + t.on('close', function () { + s.validate() + assert.end() + }) + + write(expected, t) +}) diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/package.json b/node_modules/pg/node_modules/pgpass/node_modules/split/package.json new file mode 100644 index 0000000..a487cdb --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/package.json @@ -0,0 +1,55 @@ +{ + "name": "split", + "version": "0.3.0", + "description": "split a Text Stream into a Line Stream", + "homepage": "http://github.com/dominictarr/split", + "repository": { + "type": "git", + "url": "git://github.com/dominictarr/split.git" + }, + "dependencies": { + "through": "2" + }, + "devDependencies": { + "asynct": "*", + "it-is": "1", + "ubelt": "~2.9", + "stream-spec": "~0.2", + "event-stream": "~3.0.2" + }, + "scripts": { + "test": "asynct test/" + }, + "author": { + "name": "Dominic Tarr", + "email": "dominic.tarr@gmail.com", + "url": "http://bit.ly/dominictarr" + }, + "optionalDependencies": {}, + "engines": { + "node": "*" + }, + "bugs": { + "url": "https://github.com/dominictarr/split/issues" + }, + "_id": "split@0.3.0", + "dist": { + "shasum": "02958c9fb7adb35907ac7068629aa28c91814f1b", + "tarball": "http://registry.npmjs.org/split/-/split-0.3.0.tgz" + }, + "_from": "split@>=0.3.0 <0.4.0", + "_npmVersion": "1.3.21", + "_npmUser": { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + }, + "maintainers": [ + { + "name": "dominictarr", + "email": "dominic.tarr@gmail.com" + } + ], + "directories": {}, + "_shasum": "02958c9fb7adb35907ac7068629aa28c91814f1b", + "_resolved": "https://registry.npmjs.org/split/-/split-0.3.0.tgz" +} diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/readme.markdown b/node_modules/pg/node_modules/pgpass/node_modules/split/readme.markdown new file mode 100644 index 0000000..7a77c17 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/readme.markdown @@ -0,0 +1,54 @@ +# Split (matcher) + +[![build status](https://secure.travis-ci.org/dominictarr/split.png)](http://travis-ci.org/dominictarr/split) + +Break up a stream and reassemble it so that each line is a chunk. matcher may be a `String`, or a `RegExp` + +Example, read every line in a file ... + +``` js + fs.createReadStream(file) + .pipe(split()) + .on('data', function (line) { + //each chunk now is a seperate line! + }) + +``` + +`split` takes the same arguments as `string.split` except it defaults to '/\r?\n/' instead of ',', and the optional `limit` paremeter is ignored. +[String#split](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/split) + +`split` takes an optional options object on it's third argument. + +``` js + split(matcher, mapper, options) +``` + +Valid options: + +* maxLength - The maximum buffer length without seeing a newline or `matcher`, + if a single line exceeds this, the split stream will emit an error. + +``` js + split(JSON.parse, null, { maxLength: 2}) +``` + +# NDJ - Newline Delimited Json + +`split` accepts a function which transforms each line. + +``` js +fs.createReadStream(file) + .pipe(split(JSON.parse)) + .on('data', function (obj) { + //each chunk now is a a js object + }) + .on('error', function (err) { + //syntax errors will land here + //note, this ends the stream. + }) +``` + +# License + +MIT diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/test/options.asynct.js b/node_modules/pg/node_modules/pgpass/node_modules/split/test/options.asynct.js new file mode 100644 index 0000000..6d34d87 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/test/options.asynct.js @@ -0,0 +1,23 @@ +var it = require('it-is').style('colour') + , split = require('..') + +exports ['maximum buffer limit'] = function (test) { + var s = split(JSON.parse, null, { + maxLength: 2 + }) + , caughtError = false + , rows = [] + + s.on('error', function (err) { + caughtError = true + }) + + s.on('data', function (row) { rows.push(row) }) + + s.write('{"a":1}\n{"') + s.write('{ "') + it(caughtError).equal(true) + + s.end() + test.done() +} diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/test/partitioned_unicode.js b/node_modules/pg/node_modules/pgpass/node_modules/split/test/partitioned_unicode.js new file mode 100644 index 0000000..aff3d5d --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/test/partitioned_unicode.js @@ -0,0 +1,34 @@ +var it = require('it-is').style('colour') + , split = require('..') + +exports ['split data with partitioned unicode character'] = function (test) { + var s = split(/,/g) + , caughtError = false + , rows = [] + + s.on('error', function (err) { + caughtError = true + }) + + s.on('data', function (row) { rows.push(row) }) + + var x = 'テスト試験今日とても,よい天気で' + unicodeData = new Buffer(x); + + // partition of 日 + piece1 = unicodeData.slice(0, 20); + piece2 = unicodeData.slice(20, unicodeData.length); + + s.write(piece1); + s.write(piece2); + + s.end() + + it(caughtError).equal(false) + + it(rows).deepEqual(['テスト試験今日とても', 'よい天気で']); + + it(rows).deepEqual(x.split(',')) + + test.done() +} diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/test/split.asynct.js b/node_modules/pg/node_modules/pgpass/node_modules/split/test/split.asynct.js new file mode 100644 index 0000000..fb15b28 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/test/split.asynct.js @@ -0,0 +1,85 @@ +var es = require('event-stream') + , it = require('it-is').style('colour') + , d = require('ubelt') + , split = require('..') + , join = require('path').join + , fs = require('fs') + , Stream = require('stream').Stream + , spec = require('stream-spec') + +exports ['split() works like String#split'] = function (test) { + var readme = join(__filename) + , expected = fs.readFileSync(readme, 'utf-8').split('\n') + , cs = split() + , actual = [] + , ended = false + , x = spec(cs).through() + + var a = new Stream () + + a.write = function (l) { + actual.push(l.trim()) + } + a.end = function () { + + ended = true + expected.forEach(function (v,k) { + //String.split will append an empty string '' + //if the string ends in a split pattern. + //es.split doesn't which was breaking this test. + //clearly, appending the empty string is correct. + //tests are passing though. which is the current job. + if(v) + it(actual[k]).like(v) + }) + //give the stream time to close + process.nextTick(function () { + test.done() + x.validate() + }) + } + a.writable = true + + fs.createReadStream(readme, {flags: 'r'}).pipe(cs) + cs.pipe(a) + +} + +exports ['split() takes mapper function'] = function (test) { + var readme = join(__filename) + , expected = fs.readFileSync(readme, 'utf-8').split('\n') + , cs = split(function (line) { return line.toUpperCase() }) + , actual = [] + , ended = false + , x = spec(cs).through() + + var a = new Stream () + + a.write = function (l) { + actual.push(l.trim()) + } + a.end = function () { + + ended = true + expected.forEach(function (v,k) { + //String.split will append an empty string '' + //if the string ends in a split pattern. + //es.split doesn't which was breaking this test. + //clearly, appending the empty string is correct. + //tests are passing though. which is the current job. + if(v) + it(actual[k]).equal(v.trim().toUpperCase()) + }) + //give the stream time to close + process.nextTick(function () { + test.done() + x.validate() + }) + } + a.writable = true + + fs.createReadStream(readme, {flags: 'r'}).pipe(cs) + cs.pipe(a) + +} + diff --git a/node_modules/pg/node_modules/pgpass/node_modules/split/test/try_catch.asynct.js b/node_modules/pg/node_modules/pgpass/node_modules/split/test/try_catch.asynct.js new file mode 100644 index 0000000..39e49f7 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/node_modules/split/test/try_catch.asynct.js @@ -0,0 +1,51 @@ +var it = require('it-is').style('colour') + , split = require('..') + +exports ['emit mapper exceptions as error events'] = function (test) { + var s = split(JSON.parse) + , caughtError = false + , rows = [] + + s.on('error', function (err) { + caughtError = true + }) + + s.on('data', function (row) { rows.push(row) }) + + s.write('{"a":1}\n{"') + it(caughtError).equal(false) + it(rows).deepEqual([ { a: 1 } ]) + + s.write('b":2}\n{"c":}\n') + it(caughtError).equal(true) + it(rows).deepEqual([ { a: 1 }, { b: 2 } ]) + + s.end() + test.done() +} + +exports ['mapper error events on trailing chunks'] = function (test) { + var s = split(JSON.parse) + , caughtError = false + , rows = [] + + s.on('error', function (err) { + caughtError = true + }) + + s.on('data', function (row) { rows.push(row) }) + + s.write('{"a":1}\n{"') + it(caughtError).equal(false) + it(rows).deepEqual([ { a: 1 } ]) + + s.write('b":2}\n{"c":}') + it(caughtError).equal(false) + it(rows).deepEqual([ { a: 1 }, { b: 2 } ]) + + s.end() + it(caughtError).equal(true) + it(rows).deepEqual([ { a: 1 }, { b: 2 } ]) + + test.done() +} diff --git a/node_modules/pg/node_modules/pgpass/package.json b/node_modules/pg/node_modules/pgpass/package.json new file mode 100644 index 0000000..ca7ff2c --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/package.json @@ -0,0 +1,64 @@ +{ + "name": "pgpass", + "version": "0.0.3", + "description": "Module for reading .pgpass", + "main": "lib/index", + "scripts": { + "pretest": "chmod 600 ./test/_pgpass", + "test": "npm run hint && mocha --recursive -R list && npm run coverage", + "coverage": "rm -rf -- lib-cov ; jscoverage lib lib-cov && mocha --recursive -R html-cov > coverage.html", + "hint": "jshint --verbose lib test" + }, + "author": { + "name": "Hannes Hörl", + "email": "hannes.hoerl+pgpass@snowreporter.com" + }, + "license": "BSD-2-Clause", + "dependencies": { + "split": "~0.3" + }, + "devDependencies": { + "mocha": "~1.14.0", + "resumer": "0.0.0", + "jscoverage": "~0.3.8", + "jshint": "~2.3.0", + "pg": "~2.11.1", + "pg-escape": "0.0.2", + "tmp": "0.0.23" + }, + "keywords": [ + "postgres", + "pg", + "pgpass", + "password", + "postgresql" + ], + "bugs": { + "url": "https://github.com/hoegaarden/pgpass/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/hoegaarden/pgpass.git" + }, + "homepage": "https://github.com/hoegaarden/pgpass", + "_id": "pgpass@0.0.3", + "dist": { + "shasum": "12e67e343b3189c2f31206ebc9cc0befffcf9140", + "tarball": "http://registry.npmjs.org/pgpass/-/pgpass-0.0.3.tgz" + }, + "_from": "pgpass@0.0.3", + "_npmVersion": "1.4.4", + "_npmUser": { + "name": "hoegaarden", + "email": "hannes.hoerl+npm@snowreporter.com" + }, + "maintainers": [ + { + "name": "hoegaarden", + "email": "hannes.hoerl+npm@snowreporter.com" + } + ], + "directories": {}, + "_shasum": "12e67e343b3189c2f31206ebc9cc0befffcf9140", + "_resolved": "https://registry.npmjs.org/pgpass/-/pgpass-0.0.3.tgz" +} diff --git a/node_modules/pg/node_modules/pgpass/test/#1 de-escaping.js b/node_modules/pg/node_modules/pgpass/test/#1 de-escaping.js new file mode 100644 index 0000000..d700c78 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/#1 de-escaping.js @@ -0,0 +1,42 @@ +'use strict'; + +/* global describe: false */ +/* global it: false */ +/* global after: false */ +/* global before: false */ + +/* jshint -W106 */ +var COV = process.env.npm_lifecycle_event === 'coverage'; +/* jshint +W106 */ + +var assert = require('assert') + , path = require('path') + , pgPass = require( path.join('..', COV ? 'lib-cov' : 'lib' , 'index') ) +; + + +var conn = { + 'host' : 'host5' , + 'database' : 'database5' , + 'user' : 'dummy\\:user' +}; + +describe('#1', function(){ + before(function(){ + process.env.PGPASS_NO_DEESCAPE = true; + process.env.PGPASSFILE = path.join(__dirname, '_pgpass'); + }); + after(function(){ + delete process.env.PGPASS_NO_DEESCAPE; + delete process.env.PGPASSFILE; + }); + + it('should not de-escape NODE_PG_NO_DESCAPE is set', function(done){ + process.env.PGPASSFILE = path.join(__dirname, '_pgpass'); + + pgPass(conn, function(res){ + assert.strictEqual('some:password', res); + done(); + }); + }); +}); diff --git a/node_modules/pg/node_modules/pgpass/test/#1 escaping.js b/node_modules/pg/node_modules/pgpass/test/#1 escaping.js new file mode 100644 index 0000000..d7ea111 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/#1 escaping.js @@ -0,0 +1,31 @@ +'use strict'; + +/* global describe: false */ +/* global it: false */ + +/* jshint -W106 */ +var COV = process.env.npm_lifecycle_event === 'coverage'; +/* jshint +W106 */ + +var assert = require('assert') + , path = require('path') + , pgPass = require( path.join('..', COV ? 'lib-cov' : 'lib' , 'index') ) +; + + +var conn = { + 'host' : 'host4' , + 'port' : 100 , + 'database' : 'database4' , + 'user' : 'user4' +}; + +describe('#1', function(){ + it('should handle escaping right', function(done){ + process.env.PGPASSFILE = path.join(__dirname, '_pgpass'); + pgPass(conn, function(res){ + assert.strictEqual('some:wired:password', res); + done(); + }); + }); +}); diff --git a/node_modules/pg/node_modules/pgpass/test/_pgpass b/node_modules/pg/node_modules/pgpass/test/_pgpass new file mode 100644 index 0000000..0717605 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/_pgpass @@ -0,0 +1,10 @@ +# comments?? +host1:1:database1:user1:pass1 +*:*:*:user2:pass2 +host3:3:database3:user3:pass3 + +host4:*:database4:user4:some\:wired\:password + +host5:*:database5:dummy\:user:some:password + + diff --git a/node_modules/pg/node_modules/pgpass/test/helper.js b/node_modules/pg/node_modules/pgpass/test/helper.js new file mode 100644 index 0000000..1c7b0c5 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/helper.js @@ -0,0 +1,285 @@ +'use strict'; + +/* global describe: false */ +/* global it: false */ +/* global after: false */ +/* global before: false */ + +/* jshint -W106 */ +var COV = process.env.npm_lifecycle_event === 'coverage'; +/* jshint +W106 */ + +var assert = require('assert') + , path = require('path') + , helper = require( path.join('..', COV ? 'lib-cov' : 'lib', 'helper') ) + , util = require('util') + , Stream = require('resumer') +; + + +describe('#warnTo()', function(){ + it('should be process.stderr by default', function(){ + var stdErr = process.stderr; + var org = helper.warnTo( stdErr ); + assert(org === stdErr); + }); + + it('should not cause problems to give a non-stream', function(){ + var orgStream = helper.warnTo(null); + assert( false === helper.usePgPass({mode:6}) ); + helper.warnTo(orgStream); + }); + + it('should write warnings to our writable stream', function(done){ + var stream = new Stream(); + + var orgStream = helper.warnTo(stream); + var orgIsWin = helper.isWin; + helper.isWin = false; + + assert( process.stderr === orgStream ); + assert( false === helper.usePgPass({mode:6}) ); + + stream.on('data', function(d){ + assert( + 0 === d.indexOf('WARNING: password file "" is not a plain file') + ); + + helper.orgisWin = orgIsWin; + helper.warnTo(orgStream); + stream.end(); + + done(); + }); + }); +}); + + +describe('#getFileName()', function(){ + it('should return the default pgpass file', function(){ + var env = { + HOME : '/tmp' , + APPDATA : 'C:\\tmp' + }; + assert.equal( + helper.getFileName(env) , + process.platform === 'win32' ? 'C:\\tmp\\postgresql\\pgpass.conf' : '/tmp/.pgpass' + ); + }); + + it('should return the the path to PGPASSFILE if set', function(){ + var env = {}; + var something = env.PGPASSFILE = 'xxx'; + assert.equal( helper.getFileName(env), something ); + }); +}); + + +describe('#isWin', function(){ + it('should represent the platform and can be changed', function(){ + var orgIsWin = helper.isWin; + var test = 'something'; + var isWin = process.platform === 'win32'; + + assert.equal(isWin, helper.isWin); + + helper.isWin = test; + assert.equal(test, helper.isWin); + + helper.isWin = orgIsWin; + assert.equal(isWin, helper.isWin); + }); +}); + + +describe('#usePgPass()', function(){ + // http://lxr.free-electrons.com/source/include/uapi/linux/stat.h + var testResults = { + '0100660' : false , + '0100606' : false , + '0100100' : true , + '0100600' : true , + '0040600' : false , // is a directory + '0060600' : false // is a blockdevice + }; + + var org = helper.isWin; // pretend we are UNIXish for permission tests + helper.isWin = true; + Object.keys(testResults).forEach(function(octPerm){ + var decPerm = Number(parseInt(octPerm, 8)); + var res = testResults[octPerm]; + var msg = util.format( + 'should consider permission %s %s', + octPerm, res ? 'secure' : 'not secure' + ); + + it(msg, function(){ + assert.equal( helper.usePgPass({ mode : decPerm }) === res , true ); + }); + }); + helper.isWin = org; + + it('should always return false if PGPASSWORD is set', function(){ + process.env.PGPASSWORD = 'some'; + assert( false === helper.usePgPass() ); + delete process.env.PGPASSWORD; + }); + + it('should always return true on windows', function(){ + var org = helper.isWin; + helper.isWin = true; + assert( helper.usePgPass() ); + helper.isWin = org; + }); +}); + + +describe('#parseLine()', function(){ + + it('should parse a simple line', function(){ + var res = helper.parseLine( 'host:port:dbase:user:pass' ); + + assert.deepEqual(res, { + 'host' : 'host' , + 'port' : 'port' , + 'database' : 'dbase' , + 'user' : 'user' , + 'password' : 'pass' + }); + }); + + it('should handle comments', function(){ + var res = helper.parseLine( ' # some random comment' ); + assert.equal(res, null); + }); + + it('should handle escaped \':\' and \'\\\' right', function(){ + /* jshint -W044 */ + var res = helper.parseLine('some\\:host:port:some\\\\database:some\;user:somepass'); + /* jshint +W044 */ + assert.deepEqual(res, { + 'host' : 'some:host' , + 'port' : 'port' , + 'database' : 'some\\database' , + /* jshint -W044 */ + 'user' : 'some\;user' , + /* jshint +W044 */ + 'password' : 'somepass' + }); + }); + + it('should ignore too short lines', function(){ + var tests = [ + '::::' , + 'host:port' , + 'host:port:database' , + 'host:port:database:' + ]; + + tests.forEach(function(line){ + var res = helper.parseLine(line); + assert.equal(null, res); + }); + }); + +}); + + +describe('#isValidEntry()', function(){ + it('shouldn\'t report valid entries', function(){ + assert(helper.isValidEntry({ + 'host' : 'some:host' , + 'port' : 100 , + 'database' : 'some\\database' , + /* jshint -W044 */ + 'user' : 'some\;user' , + /* jshint +W044 */ + 'password' : 'somepass' + })); + assert(helper.isValidEntry({ + 'host' : '*' , + 'port' : '*' , + 'database' : '*' , + 'user' : '*' , + 'password' : 'somepass' + })); + }); + + it('should find invalid entries', function(){ + assert(!helper.isValidEntry({ + 'host' : '' + })); + assert(!helper.isValidEntry({ + 'host' : 'host' , + 'port' : '100' , + 'database' : 'database' , + 'user' : 'user' + })); + assert(!helper.isValidEntry({ + 'host' : 'host' , + 'port' : -100 , + 'database' : 'database' , + 'user' : 'user' , + 'password' : '232323' + })); + }); +}); + + + + +describe('#getPassword()', function(){ + var creds = + 'host1:100:database1:user1:thepassword1' + '\n' + + '*:*:database2:*:thepassword2' + '\n' + ; + + var conn1 = { + 'host' : 'host1' , + 'port' : 100 , + 'database' : 'database1' , + 'user' : 'user1' + }; + var conn3 = { + 'host' : 'host3' , + 'database' : 'database3' , + 'user' : 'user3' + }; + + + it('should not get password for non-matching conn_info', function(done){ + var st = new Stream(); + + helper.getPassword(conn3, st, function(pass){ + assert.deepEqual(pass, undefined); + done(); + }); + + st.write(creds); + st.end(); + }); + + it('should get password for matching conn_info', function(done){ + var st = new Stream(); + + helper.getPassword(conn1, st, function(pass){ + assert.notDeepEqual(pass, undefined); + done(); + }); + + st.write(creds); + st.end(); + }); + + it('should ignore no password on any error', function(done){ + var st = new Stream(); + + helper.getPassword({}, st, function(pass){ + assert.deepEqual(pass, undefined); + done(); + }); + + st.emit('error', new Error('just some error')); + st.end(); + }); +}); \ No newline at end of file diff --git a/node_modules/pg/node_modules/pgpass/test/index.js b/node_modules/pg/node_modules/pgpass/test/index.js new file mode 100644 index 0000000..467d9c5 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/index.js @@ -0,0 +1,52 @@ +'use strict'; + +/* global describe: false */ +/* global it: false */ + +/* jshint -W106 */ +var COV = process.env.npm_lifecycle_event === 'coverage'; +/* jshint +W106 */ + +var assert = require('assert') + , path = require('path') + , pgPass = require( path.join('..', COV ? 'lib-cov' : 'lib' , 'index') ) +; + + +var conn = { + 'host' : 'host1' , + 'port' : 100 , + 'database' : 'somedb' , + 'user' : 'user2' +}; + +describe('MAIN', function(){ + it('should ignore non existent file', function(done){ + process.env.PGPASSFILE = path.join(__dirname, '_no_such_file_'); + pgPass(conn, function(res){ + assert(undefined === res); + done(); + }); + }); + + + it('should read .pgpass', function(done){ + process.env.PGPASSFILE = path.join(__dirname, '_pgpass'); + pgPass(conn, function(res){ + assert.strictEqual('pass2', res); + done(); + }); + }); + + + it('should not read .pgpass because of PGPASSWORD', function(done){ + process.env.PGPASSFILE = path.join(__dirname, '_pgpass'); + process.env.PGPASSWORD = 'something'; + pgPass(conn, function(res){ + assert(undefined === res); + delete process.env.PGPASSWORD; + done(); + }); + }); + +}); diff --git a/node_modules/pg/node_modules/pgpass/test/integration/#1 escaping.js b/node_modules/pg/node_modules/pgpass/test/integration/#1 escaping.js new file mode 100644 index 0000000..c888155 --- /dev/null +++ b/node_modules/pg/node_modules/pgpass/test/integration/#1 escaping.js @@ -0,0 +1,178 @@ +'use strict'; + +/* global describe: false */ +/* global it: false */ +/* global before: false */ +/* global after: false */ + +/* jshint -W106 */ +var COV = process.env.npm_lifecycle_event === 'coverage'; +/* jshint +W106 */ + +var RND = Math.random(); +var USER = 'pgpass-test-some:user:'.concat(RND); +var PASS = 'pgpass-test-some:pass:'.concat(RND); +var TEST_QUERY = 'SELECT CURRENT_USER AS me'; + +var path = require('path'); +var pgPass = require( path.join('..', '..', COV ? 'lib-cov' : 'lib') ); +var assert = require('assert'); +var spawn = require('child_process').spawn; +var fs = require('fs'); +var esc = require('pg-escape'); +var tmp = require('tmp'); + +// cleanup temp file +tmp.setGracefulCleanup(); + +/** + * Run connection test with + * - natvie clien + * - JS client + * - psql + */ +describe('using same password file', function(){ + before(pre); + after(delUser); + + // load the module after setting up PGPASSFILE + var pg = require('pg'); + var pgNative = pg.native; + + var config = { + user : USER , + database : 'postgres' + }; + + it('the JS client can connect', function(done){ + pg.connect(config, checkConnection.bind(null, done)); + }); + + it('the native client can connect', function(done){ + pgNative.connect(config, checkConnection.bind(null, done)); + }); + + it('the psql client can connect', function(done){ + runPsqlCmd(TEST_QUERY, function(err, res){ + checkQueryRes(err, res.replace(/\n$/, '')); + done(); + }, USER); + }); +}); + + + +/** + * Did running the query return an error and is the result as expected? + */ +function checkQueryRes(err, res) { + assert.ifError(err); + assert.strictEqual(USER, res); +} + +/** + * Check the connection with node-postgres + */ +function checkConnection(testDone, err, client, pgDone) { + assert.ifError(err); + + client.query(TEST_QUERY, function(err, res){ + checkQueryRes(err, res.rows[0].me); + pgDone(); + testDone(); + }); +} + +/** + * Run test setup tasks + */ +function pre(cb) { + genUser(function(err){ + if (err) { + delUser(function(){ + throw err; + }); + } else { + setupPassFile(cb); + } + }); +} + +/** + * Escape ':' and '\' before writing the password file + */ +function pgEsc(str) { + return str.replace(/([:\\])/g, '\\$1'); +} + +/** + * Write the temp. password file and setup the env var + */ +function setupPassFile(cb) { + // 384 == 0600 + tmp.file({ mode: 384 }, function (err, path, fd) { + if (err) { + return cb(err); + } + + var str = '*:*:*:__USER__:__PASS__' + .replace('__USER__', pgEsc(USER)) + .replace('__PASS__', pgEsc(PASS)) + ; + var buf = new Buffer(str); + + fs.write(fd, buf, 0, buf.length, 0, function(err){ + if (err) { + return cb(err); + } + + process.env.PGPASSFILE = path; + cb(); + }); + }); +} + +/** + * generate a new user with password using psql + */ +function genUser(cb) { + var cmd = esc('CREATE USER %I WITH PASSWORD %L', USER, PASS); + runPsqlCmd(cmd, cb); +} + +/** + * delete the user using psql + */ +function delUser(cb) { + var cmd = esc('DROP USER %I', USER); + runPsqlCmd(cmd, cb); +} + +/** + * run a SQL command with psql + */ +function runPsqlCmd(cmd, cb, user) { + // the user running the tests needs to be able to connect to + // postgres as user 'postgres' without a password + var psql = spawn('psql', [ + '-A', '-t', + '-h', '127.0.0.1', + '-d', 'postgres', + '-U', user || 'postgres', + '-c', cmd + ]); + + var out = ''; + + psql.stdout.on('data', function(data){ + out += data.toString(); + }); + + psql.on('exit', function(code){ + cb(code === 0 ? null : code, out); + }); + + psql.stderr.on('data', function(err){ + console.log('ERR:', err.toString()); + }); +} diff --git a/node_modules/pg/package.json b/node_modules/pg/package.json new file mode 100644 index 0000000..1dd2fee --- /dev/null +++ b/node_modules/pg/package.json @@ -0,0 +1,69 @@ +{ + "name": "pg", + "version": "3.6.2", + "description": "PostgreSQL client - pure javascript & libpq with the same API", + "keywords": [ + "postgres", + "pg", + "libpq", + "postgre", + "database", + "rdbms" + ], + "homepage": "http://github.com/brianc/node-postgres", + "repository": { + "type": "git", + "url": "git://github.com/brianc/node-postgres.git" + }, + "author": { + "name": "Brian Carlson", + "email": "brian.m.carlson@gmail.com" + }, + "main": "./lib", + "dependencies": { + "bindings": "1.2.1", + "buffer-writer": "1.0.0", + "generic-pool": "2.1.1", + "nan": "1.3.0", + "packet-reader": "0.2.0", + "pg-connection-string": "0.1.3", + "pg-types": "1.6.0", + "pgpass": "0.0.3" + }, + "devDependencies": { + "jshint": "2.5.2", + "semver": "~3.0.1", + "async": "0.9.0" + }, + "scripts": { + "changelog": "npm i github-changes && ./node_modules/.bin/github-changes -o brianc -r node-postgres -d pulls -a -v", + "test": "make test-travis connectionString=postgres://postgres@localhost:5432/postgres", + "install": "node-gyp rebuild || (exit 0)" + }, + "engines": { + "node": ">= 0.8.0" + }, + "bugs": { + "url": "https://github.com/brianc/node-postgres/issues" + }, + "_id": "pg@3.6.2", + "_shasum": "8802affe61a1bf597be29734bcd301a8e7a85351", + "_from": "pg@*", + "_npmVersion": "1.4.9", + "_npmUser": { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + }, + "maintainers": [ + { + "name": "brianc", + "email": "brian.m.carlson@gmail.com" + } + ], + "dist": { + "shasum": "8802affe61a1bf597be29734bcd301a8e7a85351", + "tarball": "http://registry.npmjs.org/pg/-/pg-3.6.2.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/pg/-/pg-3.6.2.tgz" +} diff --git a/node_modules/pg/script/create-test-tables.js b/node_modules/pg/script/create-test-tables.js new file mode 100644 index 0000000..c3aa44a --- /dev/null +++ b/node_modules/pg/script/create-test-tables.js @@ -0,0 +1,60 @@ +var args = require(__dirname + '/../test/cli'); +var pg = require(__dirname + '/../lib'); + +var people = [ + {name: 'Aaron', age: 10}, + {name: 'Brian', age: 20}, + {name: 'Chris', age: 30}, + {name: 'David', age: 40}, + {name: 'Elvis', age: 50}, + {name: 'Frank', age: 60}, + {name: 'Grace', age: 70}, + {name: 'Haley', age: 80}, + {name: 'Irma', age: 90}, + {name: 'Jenny', age: 100}, + {name: 'Kevin', age: 110}, + {name: 'Larry', age: 120}, + {name: 'Michelle', age: 130}, + {name: 'Nancy', age: 140}, + {name: 'Olivia', age: 150}, + {name: 'Peter', age: 160}, + {name: 'Quinn', age: 170}, + {name: 'Ronda', age: 180}, + {name: 'Shelley', age: 190}, + {name: 'Tobias', age: 200}, + {name: 'Uma', age: 210}, + {name: 'Veena', age: 220}, + {name: 'Wanda', age: 230}, + {name: 'Xavier', age: 240}, + {name: 'Yoyo', age: 250}, + {name: 'Zanzabar', age: 260} +] + +var con = new pg.Client({ + host: args.host, + port: args.port, + user: args.user, + password: args.password, + database: args.database +}); +con.connect(); +if(args.down) { + console.log("Dropping table 'person'") + var query = con.query("drop table if exists person"); + query.on('end', function() { + console.log("Dropped!"); + con.end(); + }); +} else { + console.log("Creating table 'person'"); + con.query("create table person(id serial, name varchar(10), age integer)").on('end', function(){ + console.log("Created!"); + console.log("Filling it with people"); + });; + people.map(function(person) { + return con.query("insert into person(name, age) values('"+person.name + "', '" + person.age + "')"); + }).pop().on('end', function(){ + console.log("Inserted 26 people"); + con.end(); + }); +} diff --git a/node_modules/pg/script/dump-db-types.js b/node_modules/pg/script/dump-db-types.js new file mode 100644 index 0000000..aa23825 --- /dev/null +++ b/node_modules/pg/script/dump-db-types.js @@ -0,0 +1,23 @@ +var pg = require(__dirname + '/../lib'); +var args = require(__dirname + '/../test/cli'); + +var queries = [ + "select CURRENT_TIMESTAMP", + "select interval '1 day' + interval '1 hour'", + "select TIMESTAMP 'today'"]; + +queries.forEach(function(query) { + + var client = new pg.Client({ + user: args.user, + database: args.database, + password: args.password + }); + client.connect(); + client + .query(query) + .on('row', function(row) { + console.log(row); + client.end(); + }); +}); diff --git a/node_modules/pg/script/list-db-types.js b/node_modules/pg/script/list-db-types.js new file mode 100644 index 0000000..748d32f --- /dev/null +++ b/node_modules/pg/script/list-db-types.js @@ -0,0 +1,6 @@ +var helper = require(__dirname + "/../test/integration/test-helper"); +var pg = helper.pg; +pg.connect(helper.config, assert.success(function(client) { + var query = client.query('select oid, typname from pg_type where typtype = \'b\' order by oid'); + query.on('row', console.log); +})) diff --git a/node_modules/pg/script/test-connection.js b/node_modules/pg/script/test-connection.js new file mode 100644 index 0000000..a70ada3 --- /dev/null +++ b/node_modules/pg/script/test-connection.js @@ -0,0 +1,24 @@ +var helper = require(__dirname + '/../test/test-helper'); + +console.log(); +console.log("testing ability to connect to '%j'", helper.config); +var pg = require(__dirname + '/../lib'); +pg.connect(helper.config, function(err, client, done) { + if(err !== null) { + console.error("Recieved connection error when attempting to contact PostgreSQL:"); + console.error(err); + process.exit(255); + } + console.log("Checking for existance of required test table 'person'") + client.query("SELECT COUNT(name) FROM person", function(err, callback) { + if(err != null) { + console.error("Recieved error when executing query 'SELECT COUNT(name) FROM person'") + console.error("It is possible you have not yet run the table create script under script/create-test-tables") + console.error("Consult the postgres-node wiki under the 'Testing' section for more information") + console.error(err); + process.exit(255); + } + done(); + pg.end(); + }) +}) diff --git a/node_modules/pg/script/travis-pg-9.2-install.sh b/node_modules/pg/script/travis-pg-9.2-install.sh new file mode 100755 index 0000000..82ad58d --- /dev/null +++ b/node_modules/pg/script/travis-pg-9.2-install.sh @@ -0,0 +1,20 @@ +#! /usr/bin/env bash +#sudo cat /etc/postgresql/9.1/main/pg_hba.conf +#sudo cat /etc/postgresql/9.1/main/pg_ident.conf +#sudo cat /etc/postgresql/9.1/main/postgresql.conf +sudo /etc/init.d/postgresql stop +sudo apt-get -y --purge remove postgresql +echo "yes" | sudo add-apt-repository ppa:pitti/postgresql +sudo apt-get update -qq +sudo apt-get -q -y -o Dpkg::Options::=--force-confdef install postgresql-9.2 postgresql-contrib-9.2 +sudo chmod 777 /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "local all postgres trust" > /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "local all all trust" >> /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "host all all 127.0.0.1/32 trust" >> /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "host all all ::1/128 trust" >> /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "host all all 0.0.0.0/0 trust" >> /etc/postgresql/9.2/main/pg_hba.conf +sudo echo "host all all 0.0.0.0 255.255.255.255 trust" >> /etc/postgresql/9.2/main/pg_hba.conf +sudo /etc/init.d/postgresql restart +# for some reason both postgres 9.1 and 9.2 are started +# 9.2 is running on port 5433 +node script/create-test-tables.js postgres://postgres@localhost:5433/postgres diff --git a/node_modules/pg/src/binding.cc b/node_modules/pg/src/binding.cc new file mode 100644 index 0000000..c1c93ed --- /dev/null +++ b/node_modules/pg/src/binding.cc @@ -0,0 +1,953 @@ +#include +#include +#include +#include +#include +#include + +#define LOG(msg) printf("%s\n",msg); +#define TRACE(msg) //printf("%s\n", msg); + +#if PG_VERSION_NUM >= 90000 +#define ESCAPE_SUPPORTED +#endif + +#if PG_VERSION_NUM >= 90200 +#define SINGLE_ROW_SUPPORTED +#endif + +#define THROW(msg) NanThrowError(msg); NanReturnUndefined(); + +using namespace v8; +using namespace node; + +class Connection : public ObjectWrap { + +public: + + //creates the V8 objects & attaches them to the module (target) + static void + Init (Handle target) + { + NanScope(); + Local t = NanNew(New); + + t->InstanceTemplate()->SetInternalFieldCount(1); + t->SetClassName(NanNew("Connection")); + + NanSetPrototypeTemplate(t, "connect", NanNew(Connect)); +#ifdef ESCAPE_SUPPORTED + NanSetPrototypeTemplate(t, "escapeIdentifier", NanNew(EscapeIdentifier)); + NanSetPrototypeTemplate(t, "escapeLiteral", NanNew(EscapeLiteral)); +#endif + NanSetPrototypeTemplate(t, "_sendQuery", NanNew(SendQuery)); + NanSetPrototypeTemplate(t, "_sendQueryWithParams", NanNew(SendQueryWithParams)); + NanSetPrototypeTemplate(t, "_sendPrepare", NanNew(SendPrepare)); + NanSetPrototypeTemplate(t, "_sendQueryPrepared", NanNew(SendQueryPrepared)); + NanSetPrototypeTemplate(t, "cancel", NanNew(Cancel)); + NanSetPrototypeTemplate(t, "end", NanNew(End)); + NanSetPrototypeTemplate(t, "_sendCopyFromChunk", NanNew(SendCopyFromChunk)); + NanSetPrototypeTemplate(t, "_endCopyFrom", NanNew(EndCopyFrom)); + target->Set(NanNew("Connection"), t->GetFunction()); + TRACE("created class"); + } + + //static function called by libuv as callback entrypoint + static void + io_event(uv_poll_t* w, int status, int revents) + { + + TRACE("Received IO event"); + + if(status == -1) { + TRACE("Connection error. -1 status from lib_uv_poll"); + } + + Connection *connection = static_cast(w->data); + connection->HandleIOEvent(revents); + } + + //v8 entry point into Connection#connect + static NAN_METHOD(Connect) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + if(args.Length() == 0 || !args[0]->IsString()) { + THROW("Must include connection string as only argument to connect"); + } + + String::Utf8Value conninfo(args[0]->ToString()); + bool success = self->Connect(*conninfo); + if(!success) { + self -> EmitLastError(); + self -> DestroyConnection(); + } + + NanReturnUndefined(); + } + + //v8 entry point into Connection#cancel + static NAN_METHOD(Cancel) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + + bool success = self->Cancel(); + if(!success) { + self -> EmitLastError(); + self -> DestroyConnection(); + } + + NanReturnUndefined(); + } + +#ifdef ESCAPE_SUPPORTED + //v8 entry point into Connection#escapeIdentifier + static NAN_METHOD(EscapeIdentifier) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + + char* inputStr = MallocCString(args[0]); + + if(!inputStr) { + THROW("Unable to allocate memory for a string in EscapeIdentifier.") + } + + char* escapedStr = self->EscapeIdentifier(inputStr); + free(inputStr); + + if(escapedStr == NULL) { + THROW(self->GetLastError()); + } + + Local jsStr = NanNew(escapedStr, strlen(escapedStr)); + PQfreemem(escapedStr); + + NanReturnValue(jsStr); + } + + //v8 entry point into Connection#escapeLiteral + static NAN_METHOD(EscapeLiteral) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + + char* inputStr = MallocCString(args[0]); + + if(!inputStr) { + THROW("Unable to allocate memory for a string in EscapeIdentifier.") + } + + char* escapedStr = self->EscapeLiteral(inputStr); + free(inputStr); + + if(escapedStr == NULL) { + THROW(self->GetLastError()); + } + + Local jsStr = NanNew(escapedStr, strlen(escapedStr)); + PQfreemem(escapedStr); + + NanReturnValue(jsStr); + } +#endif + + //v8 entry point into Connection#_sendQuery + static NAN_METHOD(SendQuery) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + const char *lastErrorMessage; + if(!args[0]->IsString()) { + THROW("First parameter must be a string query"); + } + + char* queryText = MallocCString(args[0]); + bool singleRowMode = (bool)args[1]->Int32Value(); + + int result = self->Send(queryText, singleRowMode); + free(queryText); + if(result == 0) { + lastErrorMessage = self->GetLastError(); + THROW(lastErrorMessage); + } + //TODO should we flush before throw? + self->Flush(); + NanReturnUndefined(); + } + + //v8 entry point into Connection#_sendQueryWithParams + static NAN_METHOD(SendQueryWithParams) + { + NanScope(); + //dispatch non-prepared parameterized query + DispatchParameterizedQuery(args, false); + NanReturnUndefined(); + } + + //v8 entry point into Connection#_sendPrepare(string queryName, string queryText, int nParams) + static NAN_METHOD(SendPrepare) + { + NanScope(); + + Connection *self = ObjectWrap::Unwrap(args.This()); + String::Utf8Value queryName(args[0]); + String::Utf8Value queryText(args[1]); + int length = args[2]->Int32Value(); + bool singleRowMode = (bool)args[3]->Int32Value(); + self->SendPrepare(*queryName, *queryText, length, singleRowMode); + + NanReturnUndefined(); + } + + //v8 entry point into Connection#_sendQueryPrepared(string queryName, string[] paramValues) + static NAN_METHOD(SendQueryPrepared) + { + NanScope(); + //dispatch prepared parameterized query + DispatchParameterizedQuery(args, true); + NanReturnUndefined(); + } + + static void DispatchParameterizedQuery(_NAN_METHOD_ARGS, bool isPrepared) + { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + + String::Utf8Value queryName(args[0]); + //TODO this is much copy/pasta code + if(!args[0]->IsString()) { + NanThrowError("First parameter must be a string"); + return; + } + + if(!args[1]->IsArray()) { + NanThrowError("Values must be an array"); + return; + } + + Local jsParams = Local::Cast(args[1]); + int len = jsParams->Length(); + + + char** paramValues = ArgToCStringArray(jsParams); + if(!paramValues) { + NanThrowError("Unable to allocate char **paramValues from Local of v8 params"); + return; + } + + char* queryText = MallocCString(args[0]); + bool singleRowMode = (bool)args[2]->Int32Value(); + + int result = 0; + if(isPrepared) { + result = self->SendPreparedQuery(queryText, len, paramValues, singleRowMode); + } else { + result = self->SendQueryParams(queryText, len, paramValues, singleRowMode); + } + + free(queryText); + ReleaseCStringArray(paramValues, len); + if(result == 1) { + return; + } + self->EmitLastError(); + NanThrowError("Postgres returned non-1 result from query dispatch."); + } + + //v8 entry point into Connection#end + static NAN_METHOD(End) + { + NanScope(); + + Connection *self = ObjectWrap::Unwrap(args.This()); + + self->End(); + NanReturnUndefined(); + } + + uv_poll_t read_watcher_; + uv_poll_t write_watcher_; + PGconn *connection_; + bool connecting_; + bool ioInitialized_; + bool copyOutMode_; + bool copyInMode_; + bool reading_; + bool writing_; + bool ended_; + Connection () : ObjectWrap () + { + connection_ = NULL; + connecting_ = false; + ioInitialized_ = false; + copyOutMode_ = false; + copyInMode_ = false; + reading_ = false; + writing_ = false; + ended_ = false; + TRACE("Initializing ev watchers"); + read_watcher_.data = this; + write_watcher_.data = this; + } + + ~Connection () + { + } + + static NAN_METHOD(SendCopyFromChunk) { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + //TODO handle errors in some way + if (args.Length() < 1 && !Buffer::HasInstance(args[0])) { + THROW("SendCopyFromChunk requires 1 Buffer argument"); + } + self->SendCopyFromChunk(args[0]->ToObject()); + NanReturnUndefined(); + } + static NAN_METHOD(EndCopyFrom) { + NanScope(); + Connection *self = ObjectWrap::Unwrap(args.This()); + char * error_msg = NULL; + if (args[0]->IsString()) { + error_msg = MallocCString(args[0]); + } + //TODO handle errors in some way + self->EndCopyFrom(error_msg); + free(error_msg); + NanReturnUndefined(); + } + +protected: + //v8 entry point to constructor + static NAN_METHOD(New) + { + NanScope(); + Connection *connection = new Connection(); + connection->Wrap(args.This()); + + NanReturnValue(args.This()); + } + +#ifdef ESCAPE_SUPPORTED + char * EscapeIdentifier(const char *str) + { + TRACE("js::EscapeIdentifier") + return PQescapeIdentifier(connection_, str, strlen(str)); + } + + char * EscapeLiteral(const char *str) + { + TRACE("js::EscapeLiteral") + return PQescapeLiteral(connection_, str, strlen(str)); + } +#endif + + void enableSingleRowMode(bool enable) + { +#ifdef SINGLE_ROW_SUPPORTED + if(enable == true) { + int mode = PQsetSingleRowMode(connection_); + if(mode == 1) { + TRACE("PQsetSingleRowMode enabled") + } else { + TRACE("PQsetSingleRowMode disabled") + } + } else { + TRACE("PQsetSingleRowMode disabled") + } +#endif + } + + int Send(const char *queryText, bool singleRowMode) + { + TRACE("js::Send") + int rv = PQsendQuery(connection_, queryText); + enableSingleRowMode(singleRowMode); + StartWrite(); + return rv; + } + + int SendQueryParams(const char *command, const int nParams, const char * const *paramValues, bool singleRowMode) + { + TRACE("js::SendQueryParams") + int rv = PQsendQueryParams(connection_, command, nParams, NULL, paramValues, NULL, NULL, 0); + enableSingleRowMode(singleRowMode); + StartWrite(); + return rv; + } + + int SendPrepare(const char *name, const char *command, const int nParams, bool singleRowMode) + { + TRACE("js::SendPrepare") + int rv = PQsendPrepare(connection_, name, command, nParams, NULL); + enableSingleRowMode(singleRowMode); + StartWrite(); + return rv; + } + + int SendPreparedQuery(const char *name, int nParams, const char * const *paramValues, bool singleRowMode) + { + int rv = PQsendQueryPrepared(connection_, name, nParams, paramValues, NULL, NULL, 0); + enableSingleRowMode(singleRowMode); + StartWrite(); + return rv; + } + + bool Cancel() + { + PGcancel* pgCancel = PQgetCancel(connection_); + char errbuf[256]; + int result = PQcancel(pgCancel, errbuf, 256); + StartWrite(); + PQfreeCancel(pgCancel); + return result; + } + + //flushes socket + void Flush() + { + if(PQflush(connection_) == 1) { + TRACE("Flushing"); + uv_poll_start(&write_watcher_, UV_WRITABLE, io_event); + } + } + + //safely destroys the connection at most 1 time + void DestroyConnection() + { + if(connection_ != NULL) { + PQfinish(connection_); + connection_ = NULL; + } + } + + //initializes initial async connection to postgres via libpq + //and hands off control to libev + bool Connect(const char* conninfo) + { + if(ended_) return true; + connection_ = PQconnectStart(conninfo); + + if (!connection_) { + LOG("Connection couldn't be created"); + } + + ConnStatusType status = PQstatus(connection_); + + if(CONNECTION_BAD == status) { + return false; + } + + if (PQsetnonblocking(connection_, 1) == -1) { + LOG("Unable to set connection to non-blocking"); + return false; + } + + int fd = PQsocket(connection_); + if(fd < 0) { + LOG("socket fd was negative. error"); + return false; + } + + assert(PQisnonblocking(connection_)); + + PQsetNoticeProcessor(connection_, NoticeReceiver, this); + + TRACE("Setting watchers to socket"); + uv_poll_init(uv_default_loop(), &read_watcher_, fd); + uv_poll_init(uv_default_loop(), &write_watcher_, fd); + + ioInitialized_ = true; + + connecting_ = true; + StartWrite(); + + Ref(); + return true; + } + + static void NoticeReceiver(void *arg, const char *message) + { + Connection *self = (Connection*)arg; + self->HandleNotice(message); + } + + void HandleNotice(const char *message) + { + NanScope(); + Handle notice = NanNew(message); + Emit("notice", ¬ice); + } + + //called to process io_events from libuv + void HandleIOEvent(int revents) + { + + if(connecting_) { + TRACE("Processing connecting_ io"); + HandleConnectionIO(); + return; + } + + if(revents & UV_READABLE) { + TRACE("revents & UV_READABLE"); + TRACE("about to consume input"); + if(PQconsumeInput(connection_) == 0) { + TRACE("could not read, terminating"); + End(); + EmitLastError(); + //LOG("Something happened, consume input is 0"); + return; + } + TRACE("Consumed"); + + //declare handlescope as this method is entered via a libuv callback + //and not part of the public v8 interface + NanScope(); + if (this->copyOutMode_) { + this->HandleCopyOut(); + } + if (!this->copyInMode_ && !this->copyOutMode_ && PQisBusy(connection_) == 0) { + PGresult *result; + bool didHandleResult = false; + TRACE("PQgetResult"); + while ((result = PQgetResult(connection_))) { + TRACE("HandleResult"); + didHandleResult = HandleResult(result); + TRACE("PQClear"); + PQclear(result); + if(!didHandleResult) { + //this means that we are in copy in or copy out mode + //in this situation PQgetResult will return same + //result untill all data will be read (copy out) or + //until data end notification (copy in) + //and because of this, we need to break cycle + break; + } + } + //might have fired from notification + if(didHandleResult) { + Emit("_readyForQuery"); + } + } + + PGnotify *notify; + TRACE("PQnotifies"); + while ((notify = PQnotifies(connection_))) { + Local result = NanNew(); + result->Set(NanNew("channel"), NanNew(notify->relname)); + result->Set(NanNew("payload"), NanNew(notify->extra)); + Handle res = (Handle)result; + Emit("notification", &res); + PQfreemem(notify); + } + + } + + if(revents & UV_WRITABLE) { + TRACE("revents & UV_WRITABLE"); + if (PQflush(connection_) == 0) { + //nothing left to write, poll the socket for more to read + StartRead(); + } + } + } + bool HandleCopyOut () { + char * buffer = NULL; + int copied; + copied = PQgetCopyData(connection_, &buffer, 1); + while (copied > 0) { + Local node_chunk = NanNewBufferHandle(buffer, copied); + Emit("copyData", &node_chunk); + PQfreemem(buffer); + copied = PQgetCopyData(connection_, &buffer, 1); + } + if (copied == 0) { + //wait for next read ready + //result was not handled completely + return false; + } else if (copied == -1) { + this->copyOutMode_ = false; + return true; + } else if (copied == -2) { + this->copyOutMode_ = false; + return true; + } + return false; + } + + //maps the postgres tuple results to v8 objects + //and emits row events + //TODO look at emitting fewer events because the back & forth between + //javascript & c++ might introduce overhead (requires benchmarking) + void EmitRowDescription(const PGresult* result) + { + NanScope(); + Local row = NanNew(); + int fieldCount = PQnfields(result); + for(int fieldNumber = 0; fieldNumber < fieldCount; fieldNumber++) { + Local field = NanNew(); + //name of field + char* fieldName = PQfname(result, fieldNumber); + field->Set(NanNew("name"), NanNew(fieldName)); + + //oid of type of field + int fieldType = PQftype(result, fieldNumber); + field->Set(NanNew("dataTypeID"), NanNew(fieldType)); + + row->Set(NanNew(fieldNumber), field); + } + + Handle e = (Handle)row; + Emit("_rowDescription", &e); + } + + bool HandleResult(PGresult* result) + { + TRACE("PQresultStatus"); + ExecStatusType status = PQresultStatus(result); + switch(status) { + case PGRES_TUPLES_OK: +#ifdef SINGLE_ROW_SUPPORTED + case PGRES_SINGLE_TUPLE: +#endif + { + EmitRowDescription(result); + HandleTuplesResult(result); + EmitCommandMetaData(result); + return true; + } + break; + case PGRES_FATAL_ERROR: + { + TRACE("HandleErrorResult"); + HandleErrorResult(result); + return true; + } + break; + case PGRES_COMMAND_OK: + case PGRES_EMPTY_QUERY: + { + EmitCommandMetaData(result); + return true; + } + break; + case PGRES_COPY_IN: + { + this->copyInMode_ = true; + Emit("copyInResponse"); + return false; + } + break; + case PGRES_COPY_OUT: + { + this->copyOutMode_ = true; + Emit("copyOutResponse"); + return this->HandleCopyOut(); + } + break; + default: + printf("YOU SHOULD NEVER SEE THIS! PLEASE OPEN AN ISSUE ON GITHUB! Unrecogized query status: %s\n", PQresStatus(status)); + break; + } + return true; + } + + void EmitCommandMetaData(PGresult* result) + { + NanScope(); + Local info = NanNew(); + info->Set(NanNew("command"), NanNew(PQcmdStatus(result))); + info->Set(NanNew("value"), NanNew(PQcmdTuples(result))); + Handle e = (Handle)info; + Emit("_cmdStatus", &e); + } + + //maps the postgres tuple results to v8 objects + //and emits row events + //TODO look at emitting fewer events because the back & forth between + //javascript & c++ might introduce overhead (requires benchmarking) + void HandleTuplesResult(const PGresult* result) + { + NanScope(); + int rowCount = PQntuples(result); + for(int rowNumber = 0; rowNumber < rowCount; rowNumber++) { + //create result object for this row + Local row = NanNew(); + int fieldCount = PQnfields(result); + for(int fieldNumber = 0; fieldNumber < fieldCount; fieldNumber++) { + + //value of field + if(PQgetisnull(result, rowNumber, fieldNumber)) { + row->Set(NanNew(fieldNumber), NanNull()); + } else { + char* fieldValue = PQgetvalue(result, rowNumber, fieldNumber); + row->Set(NanNew(fieldNumber), NanNew(fieldValue)); + } + } + + Handle e = (Handle)row; + Emit("_row", &e); + } + } + + void HandleErrorResult(const PGresult* result) + { + NanScope(); + //instantiate the return object as an Error with the summary Postgres message + TRACE("ReadResultField"); + const char* errorMessage = PQresultErrorField(result, PG_DIAG_MESSAGE_PRIMARY); + if(!errorMessage) { + //there is no error, it has already been consumed in the last + //read-loop callback + return; + } + Local msg = Local::Cast(NanError(errorMessage)); + TRACE("AttachErrorFields"); + //add the other information returned by Postgres to the error object + AttachErrorField(result, msg, NanNew("severity"), PG_DIAG_SEVERITY); + AttachErrorField(result, msg, NanNew("code"), PG_DIAG_SQLSTATE); + AttachErrorField(result, msg, NanNew("detail"), PG_DIAG_MESSAGE_DETAIL); + AttachErrorField(result, msg, NanNew("hint"), PG_DIAG_MESSAGE_HINT); + AttachErrorField(result, msg, NanNew("position"), PG_DIAG_STATEMENT_POSITION); + AttachErrorField(result, msg, NanNew("internalPosition"), PG_DIAG_INTERNAL_POSITION); + AttachErrorField(result, msg, NanNew("internalQuery"), PG_DIAG_INTERNAL_QUERY); + AttachErrorField(result, msg, NanNew("where"), PG_DIAG_CONTEXT); + AttachErrorField(result, msg, NanNew("file"), PG_DIAG_SOURCE_FILE); + AttachErrorField(result, msg, NanNew("line"), PG_DIAG_SOURCE_LINE); + AttachErrorField(result, msg, NanNew("routine"), PG_DIAG_SOURCE_FUNCTION); + Handle m = msg; + TRACE("EmitError"); + Emit("_error", &m); + } + + void AttachErrorField(const PGresult *result, const Local msg, const Local symbol, int fieldcode) + { + NanScope(); + char *val = PQresultErrorField(result, fieldcode); + if(val) { + msg->Set(symbol, NanNew(val)); + } + } + + void End() + { + TRACE("stopping read & write"); + StopRead(); + StopWrite(); + DestroyConnection(); + Emit("_end"); + ended_ = true; + } + +private: + //EventEmitter was removed from c++ in node v0.5.x + void Emit(const char* message) { + NanScope(); + Handle args[1] = { NanNew(message) }; + Emit(1, args); + } + + void Emit(const char* message, Handle* arg) { + NanScope(); + Handle args[2] = { NanNew(message), *arg }; + Emit(2, args); + } + + void Emit(int length, Handle *args) { + NanScope(); + + Local emit_v = NanObjectWrapHandle(this)->Get(NanNew("emit")); + assert(emit_v->IsFunction()); + Local emit_f = emit_v.As(); + + TryCatch tc; + emit_f->Call(NanObjectWrapHandle(this), length, args); + if(tc.HasCaught()) { + FatalException(tc); + } + } + + void HandleConnectionIO() + { + PostgresPollingStatusType status = PQconnectPoll(connection_); + switch(status) { + case PGRES_POLLING_READING: + TRACE("Polled: PGRES_POLLING_READING"); + StartRead(); + break; + case PGRES_POLLING_WRITING: + TRACE("Polled: PGRES_POLLING_WRITING"); + StartWrite(); + break; + case PGRES_POLLING_FAILED: + StopRead(); + StopWrite(); + TRACE("Polled: PGRES_POLLING_FAILED"); + EmitLastError(); + break; + case PGRES_POLLING_OK: + TRACE("Polled: PGRES_POLLING_OK"); + connecting_ = false; + StartRead(); + Emit("connect"); + default: + //printf("Unknown polling status: %d\n", status); + break; + } + } + + void EmitError(const char *message) + { + NanScope(); + Local exception = NanError(message); + Emit("_error", &exception); + } + + void EmitLastError() + { + EmitError(PQerrorMessage(connection_)); + } + + const char *GetLastError() + { + return PQerrorMessage(connection_); + } + + void StopWrite() + { + TRACE("write STOP"); + if(ioInitialized_ && writing_) { + uv_poll_stop(&write_watcher_); + writing_ = false; + } + } + + void StartWrite() + { + TRACE("write START"); + if(reading_) { + TRACE("stop READ to start WRITE"); + StopRead(); + } + uv_poll_start(&write_watcher_, UV_WRITABLE, io_event); + writing_ = true; + } + + void StopRead() + { + TRACE("read STOP"); + if(ioInitialized_ && reading_) { + uv_poll_stop(&read_watcher_); + reading_ = false; + } + } + + void StartRead() + { + TRACE("read START"); + if(writing_) { + TRACE("stop WRITE to start READ"); + StopWrite(); + } + uv_poll_start(&read_watcher_, UV_READABLE, io_event); + reading_ = true; + } + //Converts a v8 array to an array of cstrings + //the result char** array must be free() when it is no longer needed + //if for any reason the array cannot be created, returns 0 + static char** ArgToCStringArray(Local params) + { + int len = params->Length(); + char** paramValues = new char*[len]; + for(int i = 0; i < len; i++) { + Handle val = params->Get(i); + if(val->IsString()) { + char* cString = MallocCString(val); + //will be 0 if could not malloc + if(!cString) { + LOG("ArgToCStringArray: OUT OF MEMORY OR SOMETHING BAD!"); + ReleaseCStringArray(paramValues, i-1); + return 0; + } + paramValues[i] = cString; + } else if(val->IsNull()) { + paramValues[i] = NULL; + } else if(val->IsObject() && Buffer::HasInstance(val)) { + char *cHexString = MallocCHexString(val->ToObject()); + if(!cHexString) { + LOG("ArgToCStringArray: OUT OF MEMORY OR SOMETHING BAD!"); + ReleaseCStringArray(paramValues, i-1); + return 0; + } + paramValues[i] = cHexString; + } else { + //a paramter was not a string + LOG("Parameter not a string or buffer"); + ReleaseCStringArray(paramValues, i-1); + return 0; + } + } + return paramValues; + } + + //helper function to release cString arrays + static void ReleaseCStringArray(char **strArray, int len) + { + for(int i = 0; i < len; i++) { + free(strArray[i]); + } + delete [] strArray; + } + + //helper function to malloc new string from v8string + static char* MallocCString(v8::Handle v8String) + { + String::Utf8Value utf8String(v8String->ToString()); + char *cString = (char *) malloc(strlen(*utf8String) + 1); + if(!cString) { + return cString; + } + strcpy(cString, *utf8String); + return cString; + } + + //helper function to Malloc a Bytea encoded Hex string from a buffer + static char* MallocCHexString(v8::Handle buf) + { + char* bufferData = Buffer::Data(buf); + size_t hexStringLen = Buffer::Length(buf)*2 + 3; + char *cHexString = (char *) malloc(hexStringLen); + if(!cHexString) { + return cHexString; + } + strcpy(cHexString, "\\x"); + for (uint32_t i = 0, k = 2; k < hexStringLen; i += 1, k += 2) { + static const char hex[] = "0123456789abcdef"; + uint8_t val = static_cast(bufferData[i]); + cHexString[k + 0] = hex[val >> 4]; + cHexString[k + 1] = hex[val & 15]; + } + cHexString[hexStringLen-1] = 0; + return cHexString; + } + + void SendCopyFromChunk(Handle chunk) { + PQputCopyData(connection_, Buffer::Data(chunk), Buffer::Length(chunk)); + } + void EndCopyFrom(char * error_msg) { + PQputCopyEnd(connection_, error_msg); + this->copyInMode_ = false; + } + +}; + + +extern "C" void init (Handle target) +{ + NanScope(); + Connection::Init(target); +} +NODE_MODULE(binding, init) diff --git a/node_modules/pg/test/buffer-list.js b/node_modules/pg/test/buffer-list.js new file mode 100644 index 0000000..3aa2455 --- /dev/null +++ b/node_modules/pg/test/buffer-list.js @@ -0,0 +1,69 @@ +BufferList = function() { + this.buffers = []; +}; +var p = BufferList.prototype; + +p.add = function(buffer, front) { + this.buffers[front ? "unshift" : "push"](buffer); + return this; +}; + +p.addInt16 = function(val, front) { + return this.add(Buffer([(val >>> 8),(val >>> 0)]),front); +}; + +p.getByteLength = function(initial) { + return this.buffers.reduce(function(previous, current){ + return previous + current.length; + },initial || 0); +}; + +p.addInt32 = function(val, first) { + return this.add(Buffer([ + (val >>> 24 & 0xFF), + (val >>> 16 & 0xFF), + (val >>> 8 & 0xFF), + (val >>> 0 & 0xFF) + ]),first); +}; + +p.addCString = function(val, front) { + var len = Buffer.byteLength(val); + var buffer = new Buffer(len+1); + buffer.write(val); + buffer[len] = 0; + return this.add(buffer, front); +}; + +p.addChar = function(char, first) { + return this.add(Buffer(char,'utf8'), first); +}; + +p.join = function(appendLength, char) { + var length = this.getByteLength(); + if(appendLength) { + this.addInt32(length+4, true); + return this.join(false, char); + } + if(char) { + this.addChar(char, true); + length++; + } + var result = Buffer(length); + var index = 0; + this.buffers.forEach(function(buffer) { + buffer.copy(result, index, 0); + index += buffer.length; + }); + return result; +}; + +BufferList.concat = function() { + var total = new BufferList(); + for(var i = 0; i < arguments.length; i++) { + total.add(arguments[i]); + } + return total.join(); +}; + +module.exports = BufferList; diff --git a/node_modules/pg/test/cli.js b/node_modules/pg/test/cli.js new file mode 100644 index 0000000..93482c9 --- /dev/null +++ b/node_modules/pg/test/cli.js @@ -0,0 +1,20 @@ +var ConnectionParameters = require(__dirname + '/../lib/connection-parameters'); +var config = new ConnectionParameters(process.argv[2]); + +for(var i = 0; i < process.argv.length; i++) { + switch(process.argv[i].toLowerCase()) { + case 'native': + config.native = true; + break; + case 'binary': + config.binary = true; + break; + case 'down': + config.down = true; + break; + default: + break; + } +} + +module.exports = config; diff --git a/node_modules/pg/test/integration/client/api-tests.js b/node_modules/pg/test/integration/client/api-tests.js new file mode 100644 index 0000000..c3baca8 --- /dev/null +++ b/node_modules/pg/test/integration/client/api-tests.js @@ -0,0 +1,167 @@ +var helper = require(__dirname + '/../test-helper'); +var pg = helper.pg; + +var log = function() { + //console.log.apply(console, arguments); +} + +var sink = new helper.Sink(5, 10000, function() { + log("ending connection pool: %j", helper.config); + pg.end(helper.config); +}); + +test('api', function() { + log("connecting to %j", helper.config) + //test weird callback behavior with node-pool + pg.connect(helper.config, function(err) { + assert.isNull(err); + arguments[1].emit('drain'); + arguments[2](); + }); + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.equal(err, null, "Failed to connect: " + helper.sys.inspect(err)); + + client.query('CREATE TEMP TABLE band(name varchar(100))'); + + ['the flaming lips', 'wolf parade', 'radiohead', 'bright eyes', 'the beach boys', 'dead black hearts'].forEach(function(bandName) { + var query = client.query("INSERT INTO band (name) VALUES ('"+ bandName +"')") + }); + + + test('simple query execution',assert.calls( function() { + log("executing simple query") + client.query("SELECT * FROM band WHERE name = 'the beach boys'", assert.calls(function(err, result) { + assert.lengthIs(result.rows, 1) + assert.equal(result.rows.pop().name, 'the beach boys') + log("simple query executed") + })); + + })) + + test('prepared statement execution',assert.calls( function() { + log("executing prepared statement 1") + client.query('SELECT * FROM band WHERE name = $1', ['dead black hearts'],assert.calls( function(err, result) { + log("Prepared statement 1 finished") + assert.lengthIs(result.rows, 1); + assert.equal(result.rows.pop().name, 'dead black hearts'); + })) + + log("executing prepared statement two") + client.query('SELECT * FROM band WHERE name LIKE $1 ORDER BY name', ['the %'], assert.calls(function(err, result) { + log("prepared statement two finished") + assert.lengthIs(result.rows, 2); + assert.equal(result.rows.pop().name, 'the flaming lips'); + assert.equal(result.rows.pop().name, 'the beach boys'); + sink.add(); + done(); + })) + })) + })) +}) + +test('executing nested queries', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + log("connected for nested queriese") + client.query('select now as now from NOW()', assert.calls(function(err, result) { + assert.equal(new Date().getYear(), result.rows[0].now.getYear()) + client.query('select now as now_again FROM NOW()', assert.calls(function() { + client.query('select * FROM NOW()', assert.calls(function() { + log('all nested queries recieved') + assert.ok('all queries hit') + sink.add(); + done(); + })) + })) + })) + })) +}) + +test('raises error if cannot connect', function() { + var connectionString = "pg://sfalsdkf:asdf@localhost/ieieie"; + log("trying to connect to invalid place for error") + pg.connect(connectionString, assert.calls(function(err, client, done) { + assert.ok(err, 'should have raised an error') + log("invalid connection supplied error to callback") + sink.add(); + done(); + })) +}) + +test("query errors are handled and do not bubble if callback is provded", function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err) + log("checking for query error") + client.query("SELECT OISDJF FROM LEIWLISEJLSE", assert.calls(function(err, result) { + assert.ok(err); + log("query error supplied error to callback") + sink.add(); + done(); + })) + })) +}) + +test('callback is fired once and only once', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query("CREATE TEMP TABLE boom(name varchar(10))"); + var callCount = 0; + client.query([ + "INSERT INTO boom(name) VALUES('hai')", + "INSERT INTO boom(name) VALUES('boom')", + "INSERT INTO boom(name) VALUES('zoom')", + ].join(";"), function(err, callback) { + assert.equal(callCount++, 0, "Call count should be 0. More means this callback fired more than once."); + sink.add(); + done(); + }) + })) +}) + +test('can provide callback and config object', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query({ + name: 'boom', + text: 'select NOW()' + }, assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].now.getYear(), new Date().getYear()) + done(); + })) + })) +}) + +test('can provide callback and config and parameters', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + var config = { + text: 'select $1::text as val' + }; + client.query(config, ['hi'], assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows.length, 1); + assert.equal(result.rows[0].val, 'hi'); + done(); + })) + })) +}) + +test('null and undefined are both inserted as NULL', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query("CREATE TEMP TABLE my_nulls(a varchar(1), b varchar(1), c integer, d integer, e date, f date)"); + client.query("INSERT INTO my_nulls(a,b,c,d,e,f) VALUES ($1,$2,$3,$4,$5,$6)", [ null, undefined, null, undefined, null, undefined ]); + client.query("SELECT * FROM my_nulls", assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows.length, 1); + assert.isNull(result.rows[0].a); + assert.isNull(result.rows[0].b); + assert.isNull(result.rows[0].c); + assert.isNull(result.rows[0].d); + assert.isNull(result.rows[0].e); + assert.isNull(result.rows[0].f); + done(); + })) + })) +}) diff --git a/node_modules/pg/test/integration/client/appname-tests.js b/node_modules/pg/test/integration/client/appname-tests.js new file mode 100644 index 0000000..2735368 --- /dev/null +++ b/node_modules/pg/test/integration/client/appname-tests.js @@ -0,0 +1,95 @@ +var helper = require('./test-helper'); +var Client = helper.Client; + +var conInfo = helper.config; + +function getConInfo(override) { + var newConInfo = {}; + Object.keys(conInfo).forEach(function(k){ + newConInfo[k] = conInfo[k]; + }); + Object.keys(override || {}).forEach(function(k){ + newConInfo[k] = override[k]; + }); + return newConInfo; +} + +function getAppName(conf, cb) { + var client = new Client(conf); + client.connect(assert.success(function(){ + client.query('SHOW application_name', assert.success(function(res){ + var appName = res.rows[0].application_name; + cb(appName); + client.end(); + })); + })); +} + +test('No default appliation_name ', function(){ + var conf = getConInfo(); + getAppName(conf, function(res){ + assert.strictEqual(res, ''); + }); +}); + +test('fallback_application_name is used', function(){ + var fbAppName = 'this is my app'; + var conf = getConInfo({ + 'fallback_application_name' : fbAppName + }); + getAppName(conf, function(res){ + assert.strictEqual(res, fbAppName); + }); +}); + +test('application_name is used', function(){ + var appName = 'some wired !@#$% application_name'; + var conf = getConInfo({ + 'application_name' : appName + }); + getAppName(conf, function(res){ + assert.strictEqual(res, appName); + }); +}); + +test('application_name has precedence over fallback_application_name', function(){ + var appName = 'some wired !@#$% application_name'; + var fbAppName = 'some other strange $$test$$ appname'; + var conf = getConInfo({ + 'application_name' : appName , + 'fallback_application_name' : fbAppName + }); + getAppName(conf, function(res){ + assert.strictEqual(res, appName); + }); +}); + +test('application_name from connection string', function(){ + var appName = 'my app'; + var conParams = require(__dirname + '/../../../lib/connection-parameters'); + var conf; + if (process.argv[2]) { + conf = new conParams(process.argv[2]+'?application_name='+appName); + } else { + conf = 'postgres://?application_name='+appName; + } + getAppName(conf, function(res){ + assert.strictEqual(res, appName); + }); +}); + + + +// TODO: make the test work for native client too +if (!helper.args.native) { + test('application_name is read from the env', function(){ + var appName = process.env.PGAPPNAME = 'testest'; + var conf = getConInfo({ + 'just some bla' : 'to fool the pool' + }); + getAppName(conf, function(res){ + delete process.env.PGAPPNAME; + assert.strictEqual(res, appName); + }); + }); +} \ No newline at end of file diff --git a/node_modules/pg/test/integration/client/array-tests.js b/node_modules/pg/test/integration/client/array-tests.js new file mode 100644 index 0000000..e01a252 --- /dev/null +++ b/node_modules/pg/test/integration/client/array-tests.js @@ -0,0 +1,136 @@ +var helper = require(__dirname + "/test-helper"); +var pg = helper.pg; + +test('parsing array results', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query("CREATE TEMP TABLE why(names text[], numbors integer[])"); + client.query('INSERT INTO why(names, numbors) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\')').on('error', console.log); + test('numbers', function() { + // client.connection.on('message', console.log) + client.query('SELECT numbors FROM why', assert.success(function(result) { + assert.lengthIs(result.rows[0].numbors, 3); + assert.equal(result.rows[0].numbors[0], 1); + assert.equal(result.rows[0].numbors[1], 2); + assert.equal(result.rows[0].numbors[2], 3); + })) + }) + + test('parses string arrays', function() { + client.query('SELECT names FROM why', assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 3); + assert.equal(names[0], 'aaron'); + assert.equal(names[1], 'brian'); + assert.equal(names[2], "a b c"); + })) + }) + + test('empty array', function(){ + client.query("SELECT '{}'::text[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 0); + })) + }) + + test('element containing comma', function(){ + client.query("SELECT '{\"joe,bob\",jim}'::text[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 2); + assert.equal(names[0], 'joe,bob'); + assert.equal(names[1], 'jim'); + })) + }) + + test('bracket in quotes', function(){ + client.query("SELECT '{\"{\",\"}\"}'::text[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 2); + assert.equal(names[0], '{'); + assert.equal(names[1], '}'); + })) + }) + + test('null value', function(){ + client.query("SELECT '{joe,null,bob,\"NULL\"}'::text[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 4); + assert.equal(names[0], 'joe'); + assert.equal(names[1], null); + assert.equal(names[2], 'bob'); + assert.equal(names[3], 'NULL'); + })) + }) + + test('element containing quote char', function(){ + client.query("SELECT ARRAY['joe''', 'jim', 'bob\"'] AS names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 3); + assert.equal(names[0], 'joe\''); + assert.equal(names[1], 'jim'); + assert.equal(names[2], 'bob"'); + })) + }) + + test('nested array', function(){ + client.query("SELECT '{{1,joe},{2,bob}}'::text[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 2); + + assert.lengthIs(names[0], 2); + assert.equal(names[0][0], '1'); + assert.equal(names[0][1], 'joe'); + + assert.lengthIs(names[1], 2); + assert.equal(names[1][0], '2'); + assert.equal(names[1][1], 'bob'); + + })) + }) + + test('integer array', function(){ + client.query("SELECT '{1,2,3}'::integer[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 3); + assert.equal(names[0], 1); + assert.equal(names[1], 2); + assert.equal(names[2], 3); + })) + }) + + test('integer nested array', function(){ + client.query("SELECT '{{1,100},{2,100},{3,100}}'::integer[] as names", assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 3); + assert.equal(names[0][0], 1); + assert.equal(names[0][1], 100); + + assert.equal(names[1][0], 2); + assert.equal(names[1][1], 100); + + assert.equal(names[2][0], 3); + assert.equal(names[2][1], 100); + })) + }) + + test('JS array parameter', function(){ + client.query("SELECT $1::integer[] as names", [[[1,100],[2,100],[3,100]]], assert.success(function(result) { + var names = result.rows[0].names; + assert.lengthIs(names, 3); + assert.equal(names[0][0], 1); + assert.equal(names[0][1], 100); + + assert.equal(names[1][0], 2); + assert.equal(names[1][1], 100); + + assert.equal(names[2][0], 3); + assert.equal(names[2][1], 100); + done(); + pg.end(); + })) + }) + + })) +}) + + diff --git a/node_modules/pg/test/integration/client/big-simple-query-tests.js b/node_modules/pg/test/integration/client/big-simple-query-tests.js new file mode 100644 index 0000000..cf6cdbf --- /dev/null +++ b/node_modules/pg/test/integration/client/big-simple-query-tests.js @@ -0,0 +1,79 @@ +var helper = require(__dirname+"/test-helper"); + +/* + Test to trigger a bug. + + I really dont know what's wrong but it seams that its triggered by multable big queryies with supplied values. + The test bellow can trigger the bug. +*/ + +// Big query with a where clouse from supplied value +var big_query_rows_1 = []; +var big_query_rows_2 = []; +var big_query_rows_3 = []; + +// Works +test('big simple query 1',function() { + var client = helper.client(); + client.query("select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' as bla from person where name = '' or 1 = 1") + .on('row', function(row) { big_query_rows_1.push(row); }) + .on('error', function(error) { console.log("big simple query 1 error"); console.log(error); }); + client.on('drain', client.end.bind(client)); +}); + +// Works +test('big simple query 2',function() { + var client = helper.client(); + client.query("select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' as bla from person where name = $1 or 1 = 1",['']) + .on('row', function(row) { big_query_rows_2.push(row); }) + .on('error', function(error) { console.log("big simple query 2 error"); console.log(error); }); + client.on('drain', client.end.bind(client)); +}); + +// Fails most of the time with 'invalid byte sequence for encoding "UTF8": 0xb9' or 'insufficient data left in message' +// If test 1 and 2 are commented out it works +test('big simple query 3',function() { + var client = helper.client(); + client.query("select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' as bla from person where name = $1 or 1 = 1",['']) + .on('row', function(row) { big_query_rows_3.push(row); }) + .on('error', function(error) { console.log("big simple query 3 error"); console.log(error); }); + client.on('drain', client.end.bind(client)); +}); + +process.on('exit', function() { + assert.equal(big_query_rows_1.length, 26,'big simple query 1 should return 26 rows'); + assert.equal(big_query_rows_2.length, 26,'big simple query 2 should return 26 rows'); + assert.equal(big_query_rows_3.length, 26,'big simple query 3 should return 26 rows'); +}); + + +var runBigQuery = function(client) { + var rows = []; + var q = client.query("select 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' as bla from person where name = $1 or 1 = 1",[''], function(err, result) { + if(err != null) { + console.log(err); + throw Err; + } + assert.lengthIs(result.rows, 26); + }); + q.on('row', function(row) { + rows.push(row); + }) + assert.emits(q, 'end', function() { + //query ended + assert.lengthIs(rows, 26); + }) +} + +test('many times', function() { + var client = helper.client(); + for(var i = 0; i < 20; i++) { + runBigQuery(client); + } + client.on('drain', function() { + client.end(); + setTimeout(function() { + //let client disconnect fully + }, 100) + }); +}) diff --git a/node_modules/pg/test/integration/client/cancel-query-tests.js b/node_modules/pg/test/integration/client/cancel-query-tests.js new file mode 100644 index 0000000..80b05b2 --- /dev/null +++ b/node_modules/pg/test/integration/client/cancel-query-tests.js @@ -0,0 +1,46 @@ +var helper = require(__dirname+"/test-helper"); + +//before running this test make sure you run the script create-test-tables +test("cancellation of a query", function() { + + var client = helper.client(); + + var qry = "select name from person order by name"; + + client.on('drain', client.end.bind(client)); + + var rows1 = 0, rows2 = 0, rows3 = 0, rows4 = 0; + + var query1 = client.query(qry); + query1.on('row', function(row) { + rows1++; + }); + var query2 = client.query(qry); + query2.on('row', function(row) { + rows2++; + }); + var query3 = client.query(qry); + query3.on('row', function(row) { + rows3++; + }); + var query4 = client.query(qry); + query4.on('row', function(row) { + rows4++; + }); + + helper.pg.cancel(helper.config, client, query1); + helper.pg.cancel(helper.config, client, query2); + helper.pg.cancel(helper.config, client, query4); + + setTimeout(function() { + assert.equal(rows1, 0); + assert.equal(rows2, 0); + assert.equal(rows4, 0); + }, 2000); + + assert.emits(query3, 'end', function() { + test("returned right number of rows", function() { + assert.equal(rows3, 26); + }); + }); +}); diff --git a/node_modules/pg/test/integration/client/configuration-tests.js b/node_modules/pg/test/integration/client/configuration-tests.js new file mode 100644 index 0000000..e922a4e --- /dev/null +++ b/node_modules/pg/test/integration/client/configuration-tests.js @@ -0,0 +1,58 @@ +var helper = require(__dirname + '/test-helper'); +var pg = helper.pg; + +//clear process.env +var realEnv = {}; +for(var key in process.env) { + realEnv[key] = process.env[key]; + if(!key.indexOf('PG')) delete process.env[key]; +} + +test('default values', function() { + assert.same(pg.defaults,{ + user: process.env.USER, + database: process.env.USER, + password: null, + port: 5432, + rows: 0, + poolSize: 10 + }) + test('are used in new clients', function() { + var client = new pg.Client(); + assert.same(client,{ + user: process.env.USER, + database: process.env.USER, + password: null, + port: 5432 + }) + }) +}) + +if(!helper.args.native) { + test('modified values', function() { + pg.defaults.user = 'boom' + pg.defaults.password = 'zap' + pg.defaults.database = 'pow' + pg.defaults.port = 1234 + pg.defaults.host = 'blam' + pg.defaults.rows = 10 + pg.defaults.poolSize = 0 + + test('are passed into created clients', function() { + var client = new Client(); + assert.same(client,{ + user: 'boom', + password: 'zap', + database: 'pow', + port: 1234, + host: 'blam' + }) + }) + }) +} + + +//restore process.env +for(var key in realEnv) { + process.env[key] = realEnv[key]; +} diff --git a/node_modules/pg/test/integration/client/copy-tests.js b/node_modules/pg/test/integration/client/copy-tests.js new file mode 100644 index 0000000..de06b0d --- /dev/null +++ b/node_modules/pg/test/integration/client/copy-tests.js @@ -0,0 +1,168 @@ +var helper = require(__dirname + '/../test-helper'); +var pg = require(__dirname + '/../../../lib'); +if(helper.args.native) { + pg = require(__dirname + '/../../../lib').native; +} +var ROWS_TO_INSERT = 1000; +var prepareTable = function (client, callback) { + client.query( + 'CREATE TEMP TABLE copy_test (id SERIAL, name CHARACTER VARYING(10), age INT)', + assert.calls(function (err, result) { + assert.equal(err, null, + err && err.message ? "create table query should not fail: " + err.message : null); + callback(); + }) + ); +}; +test('COPY FROM', function () { + pg.connect(helper.config, function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + prepareTable(client, function () { + var stream = client.copyFrom("COPY copy_test (name, age) FROM stdin WITH CSV"); + stream.on('error', function (error) { + assert.ok(false, "COPY FROM stream should not emit errors" + helper.sys.inspect(error)); + }); + for (var i = 0; i < ROWS_TO_INSERT; i++) { + stream.write( String(Date.now() + Math.random()).slice(0,10) + ',' + i + '\n'); + } + assert.emits(stream, 'close', function () { + client.query("SELECT count(*), sum(age) from copy_test", function (err, result) { + assert.equal(err, null, "Query should not fail"); + assert.lengthIs(result.rows, 1) + assert.equal(result.rows[0].sum, ROWS_TO_INSERT * (0 + ROWS_TO_INSERT -1)/2); + assert.equal(result.rows[0].count, ROWS_TO_INSERT); + done(); + }); + }, "COPY FROM stream should emit close after query end"); + stream.end(); + }); + }); +}); +test('COPY TO', function () { + pg.connect(helper.config, function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + prepareTable(client, function () { + var stream = client.copyTo("COPY person (id, name, age) TO stdin WITH CSV"); + var buf = new Buffer(0); + stream.on('error', function (error) { + assert.ok(false, "COPY TO stream should not emit errors" + helper.sys.inspect(error)); + }); + assert.emits(stream, 'data', function (chunk) { + buf = Buffer.concat([buf, chunk]); + }, "COPY IN stream should emit data event for each row"); + assert.emits(stream, 'end', function () { + var lines = buf.toString().split('\n'); + assert.equal(lines.length >= 0, true, "copy in should return rows saved by copy from"); + assert.equal(lines[0].split(',').length, 3, "each line should consists of 3 fields"); + done(); + }, "COPY IN stream should emit end event after all rows"); + }); + }); +}); + +test('COPY TO, queue queries', function () { + if(helper.config.native) return false; + pg.connect(helper.config, assert.calls(function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + prepareTable(client, function () { + var query1Done = false, + copyQueryDone = false, + query2Done = false; + client.query("SELECT count(*) from person", function () { + query1Done = true; + assert.ok(!copyQueryDone && ! query2Done, "first query has to be executed before others"); + }); + var stream = client.copyTo("COPY person (id, name, age) TO stdin WITH CSV"); + //imitate long query, to make impossible, + //that copy query end callback runs after + //second query callback + client.query("SELECT pg_sleep(1)", function () { + query2Done = true; + assert.ok(copyQueryDone && query2Done, "second query has to be executed after others"); + }); + var buf = new Buffer(0); + stream.on('error', function (error) { + assert.ok(false, "COPY TO stream should not emit errors" + helper.sys.inspect(error)); + }); + assert.emits(stream, 'data', function (chunk) { + buf = Buffer.concat([buf, chunk]); + }, "COPY IN stream should emit data event for each row"); + assert.emits(stream, 'end', function () { + copyQueryDone = true; + assert.ok(query1Done && ! query2Done, "copy query has to be executed before second query and after first"); + var lines = buf.toString().split('\n'); + assert.equal(lines.length >= 0, true, "copy in should return rows saved by copy from"); + assert.equal(lines[0].split(',').length, 3, "each line should consists of 3 fields"); + done(); + }, "COPY IN stream should emit end event after all rows"); + }); + })); +}); + +test("COPY TO incorrect usage with large data", function () { + if(helper.config.native) return false; + //when many data is loaded from database (and it takes a lot of time) + //there are chance, that query will be canceled before it ends + //but if there are not so much data, cancel message may be + //send after copy query ends + //so we need to test both situations + pg.connect(helper.config, assert.calls(function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + //intentionally incorrect usage of copy. + //this has to report error in standart way, instead of just throwing exception + client.query( + "COPY (SELECT GENERATE_SERIES(1, 10000000)) TO STDOUT WITH CSV", + assert.calls(function (error) { + assert.ok(error, "error should be reported when sending copy to query with query method"); + client.query("SELECT 1", assert.calls(function (error, result) { + assert.isNull(error, "incorrect copy usage should not break connection"); + assert.ok(result, "incorrect copy usage should not break connection"); + done(); + })); + }) + ); + })); +}); + +test("COPY TO incorrect usage with small data", function () { + if(helper.config.native) return false; + pg.connect(helper.config, assert.calls(function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + //intentionally incorrect usage of copy. + //this has to report error in standart way, instead of just throwing exception + client.query( + "COPY (SELECT GENERATE_SERIES(1, 1)) TO STDOUT WITH CSV", + assert.calls(function (error) { + assert.ok(error, "error should be reported when sending copy to query with query method"); + client.query("SELECT 1", assert.calls(function (error, result) { + assert.isNull(error, "incorrect copy usage should not break connection: " + error); + assert.ok(result, "incorrect copy usage should not break connection"); + done(); + })); + }) + ); + })); +}); + +test("COPY FROM incorrect usage", function () { + pg.connect(helper.config, function (error, client, done) { + assert.equal(error, null, "Failed to connect: " + helper.sys.inspect(error)); + prepareTable(client, function () { + //intentionally incorrect usage of copy. + //this has to report error in standart way, instead of just throwing exception + client.query( + "COPY copy_test from STDIN WITH CSV", + assert.calls(function (error) { + assert.ok(error, "error should be reported when sending copy to query with query method"); + client.query("SELECT 1", assert.calls(function (error, result) { + assert.isNull(error, "incorrect copy usage should not break connection: " + error); + assert.ok(result, "incorrect copy usage should not break connection"); + done(); + pg.end(helper.config); + })); + }) + ); + }); + }); +}); + diff --git a/node_modules/pg/test/integration/client/empty-query-tests.js b/node_modules/pg/test/integration/client/empty-query-tests.js new file mode 100644 index 0000000..6f0d574 --- /dev/null +++ b/node_modules/pg/test/integration/client/empty-query-tests.js @@ -0,0 +1,17 @@ +var helper = require(__dirname+'/test-helper'); +var client = helper.client(); + +test("empty query message handling", function() { + assert.emits(client, 'drain', function() { + client.end(); + }); + client.query({text: ""}); +}); + +test('callback supported', assert.calls(function() { + client.query("", function(err, result) { + assert.isNull(err); + assert.empty(result.rows); + }) +})) + diff --git a/node_modules/pg/test/integration/client/error-handling-tests.js b/node_modules/pg/test/integration/client/error-handling-tests.js new file mode 100644 index 0000000..616493b --- /dev/null +++ b/node_modules/pg/test/integration/client/error-handling-tests.js @@ -0,0 +1,181 @@ +var helper = require(__dirname + '/test-helper'); +var util = require('util'); + +var createErorrClient = function() { + var client = helper.client(); + client.on('error', function(err) { + assert.ok(false, "client should not throw query error: " + util.inspect(err)); + }); + client.on('drain', client.end.bind(client)); + return client; +}; + +test('error handling', function(){ + test('within a simple query', function() { + + var client = createErorrClient(); + + var query = client.query("select omfg from yodas_dsflsd where pixistix = 'zoiks!!!'"); + + assert.emits(query, 'error', function(error) { + test('error is a psql error', function() { + assert.equal(error.severity, "ERROR"); + }); + }); + + }); + + test('within a prepared statement', function() { + + var client = createErorrClient(); + + var q = client.query({text: "CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);", binary: false}); + + test("when query is parsing", function() { + + //this query wont parse since there ain't no table named bang + + var ensureFuture = function(testClient) { + test("client can issue more queries successfully", function() { + var goodQuery = testClient.query("select age from boom"); + assert.emits(goodQuery, 'row', function(row) { + assert.equal(row.age, 28); + }); + }); + }; + + var query = client.query({ + text: "select * from bang where name = $1", + values: ['0'] + }); + + test("query emits the error", function() { + assert.emits(query, 'error', function(err) { + ensureFuture(client); + }); + }); + + test("when a query is binding", function() { + + var query = client.query({ + text: 'select * from boom where age = $1', + values: ['asldkfjasdf'] + }); + + test("query emits the error", function() { + + assert.emits(query, 'error', function(err) { + test('error has right severity', function() { + assert.equal(err.severity, "ERROR"); + }) + + ensureFuture(client); + }); + }); + + //TODO how to test for errors during execution? + }); + }); + }); + + test('non-query error', function() { + + var client = new Client({ + user:'asldkfjsadlfkj' + }); + assert.emits(client, 'error'); + client.connect(); + }); + + test('non-query error with callback', function() { + var client = new Client({ + user:'asldkfjsadlfkj' + }); + client.connect(assert.calls(function(error, client) { + assert.ok(error); + })); + }); + +}); + +test('non-error calls supplied callback', function() { + var client = new Client({ + user: helper.args.user, + password: helper.args.password, + host: helper.args.host, + port: helper.args.port, + database: helper.args.database + }); + + client.connect(assert.calls(function(err) { + assert.isNull(err); + client.end(); + })) +}); + +test('when connecting to invalid host', function() { + //this test fails about 30% on travis and only on travis... + //I'm not sure what the cause could be + if(process.env.TRAVIS) return false; + + var client = new Client({ + user: 'aslkdjfsdf', + password: '1234', + host: 'asldkfjasdf!!#1308140.com' + }); + var delay = 5000; + var tid = setTimeout(function() { + assert(false, "When connecting to an invalid host the error event should be emitted but it has been " + delay + " and still no error event."); + }, delay); + client.on('error', function() { + clearTimeout(tid); + }) + client.connect(); +}); + +test('when connecting to invalid host with callback', function() { + var client = new Client({ + user: 'brian', + password: '1234', + host: 'asldkfjasdf!!#1308140.com' + }); + client.connect(function(error, client) { + assert.ok(error); + }); +}); + +test('multiple connection errors (gh#31)', function() { + return false; + test('with single client', function() { + //don't run yet...this test fails...need to think of fix + var client = new Client({ + user: 'blaksdjf', + password: 'omfsadfas', + host: helper.args.host, + port: helper.args.port, + database: helper.args.database + }); + client.connect(); + assert.emits(client, 'error', function(e) { + client.connect(); + assert.emits(client, 'error'); + }); + }); + + test('with callback method', function() { + var badConString = "postgres://aslkdfj:oi14081@"+helper.args.host+":"+helper.args.port+"/"+helper.args.database; + return false; + }); +}); + +test('query receives error on client shutdown', function() { + var client = new Client(helper.config); + client.connect(assert.calls(function() { + client.query('SELECT pg_sleep(5)', assert.calls(function(err, res) { + assert(err); + })); + client.end(); + assert.emits(client, 'end'); + })); +}); + diff --git a/node_modules/pg/test/integration/client/force-native-with-envvar-tests.js b/node_modules/pg/test/integration/client/force-native-with-envvar-tests.js new file mode 100644 index 0000000..e41587d --- /dev/null +++ b/node_modules/pg/test/integration/client/force-native-with-envvar-tests.js @@ -0,0 +1,38 @@ +/** + * helper needs to be loaded for the asserts but it alos proloads + * client which we don't want here + * + */ +var helper = require(__dirname+"/test-helper") + , path = require('path') +; + +var paths = { + 'pg' : path.join(__dirname, '..', '..', '..', 'lib', 'index.js') , + 'query_js' : path.join(__dirname, '..', '..', '..', 'lib', 'query.js') , + 'query_native' : path.join(__dirname, '..', '..', '..', 'lib', 'native', 'query.js') , +}; + +/** + * delete the modules we are concerned about from the + * module cache, so they get loaded cleanly and the env + * var can kick in ... + */ +function emptyCache(){ + Object.keys(require.cache).forEach(function(key){ + delete require.cache[key]; + }); +}; + +emptyCache(); +process.env.NODE_PG_FORCE_NATIVE = '1'; + +var pg = require( paths.pg ); +var query_native = require( paths.query_native ); +var query_js = require( paths.query_js ); + +assert.deepEqual(pg.Client.Query, query_native); +assert.notDeepEqual(pg.Client.Query, query_js); + +emptyCache(); +delete process.env.NODE_PG_FORCE_NATIVE diff --git a/node_modules/pg/test/integration/client/heroku-pgpass-tests.js b/node_modules/pg/test/integration/client/heroku-pgpass-tests.js new file mode 100644 index 0000000..578342f --- /dev/null +++ b/node_modules/pg/test/integration/client/heroku-pgpass-tests.js @@ -0,0 +1,39 @@ +var helper = require(__dirname + '/../test-helper'); + +// Path to the password file +var passfile = __dirname + '/heroku.pgpass'; + +// Export the path to the password file +process.env.PGPASSFILE = passfile; + +// Do a chmod 660, because git doesn't track those permissions +require('fs').chmodSync(passfile, 384); + +var pg = helper.pg; + +var host = 'ec2-107-20-224-218.compute-1.amazonaws.com'; +var database = 'db6kfntl5qhp2'; +var user = 'kwdzdnqpdiilfs'; + +var config = { + host: host, + database: database, + user: user, + ssl: true +}; + +test('uses password file when PGPASSFILE env variable is set', function() { + // connect & disconnect from heroku + pg.connect(config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query('SELECT NOW() as time', assert.success(function(res) { + assert(res.rows[0].time.getTime()); + + // cleanup ... remove the env variable + delete process.env.PGPASSFILE; + + done(); + pg.end(); + })) + })); +}); diff --git a/node_modules/pg/test/integration/client/heroku-ssl-tests.js b/node_modules/pg/test/integration/client/heroku-ssl-tests.js new file mode 100644 index 0000000..f0f7007 --- /dev/null +++ b/node_modules/pg/test/integration/client/heroku-ssl-tests.js @@ -0,0 +1,28 @@ +var helper = require(__dirname + '/../test-helper'); +var pg = helper.pg; + +var host = 'ec2-107-20-224-218.compute-1.amazonaws.com'; +var database = 'db6kfntl5qhp2'; +var user = 'kwdzdnqpdiilfs'; +var port = 5432; + +var config = { + host: host, + port: port, + database: database, + user: user, + password: 'uaZoSSHgi7mVM7kYaROtusClKu', + ssl: true +}; + +test('connection with config ssl = true', function() { + //connect & disconnect from heroku + pg.connect(config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query('SELECT NOW() as time', assert.success(function(res) { + assert(res.rows[0].time.getTime()); + done(); + pg.end(); + })) + })); +}); \ No newline at end of file diff --git a/node_modules/pg/test/integration/client/heroku.pgpass b/node_modules/pg/test/integration/client/heroku.pgpass new file mode 100644 index 0000000..39bba52 --- /dev/null +++ b/node_modules/pg/test/integration/client/heroku.pgpass @@ -0,0 +1 @@ +ec2-107-20-224-218.compute-1.amazonaws.com:5432:db6kfntl5qhp2:kwdzdnqpdiilfs:uaZoSSHgi7mVM7kYaROtusClKu diff --git a/node_modules/pg/test/integration/client/huge-numeric-tests.js b/node_modules/pg/test/integration/client/huge-numeric-tests.js new file mode 100644 index 0000000..8db3f29 --- /dev/null +++ b/node_modules/pg/test/integration/client/huge-numeric-tests.js @@ -0,0 +1,22 @@ +var helper = require(__dirname + '/test-helper'); + +helper.pg.connect(helper.config, assert.success(function(client, done) { + var types = require('pg-types'); + //1231 = numericOID + types.setTypeParser(1700, function(){ + return 'yes'; + }) + types.setTypeParser(1700, 'binary', function(){ + return 'yes'; + }) + var bignum = '294733346389144765940638005275322203805'; + client.query('CREATE TEMP TABLE bignumz(id numeric)'); + client.query('INSERT INTO bignumz(id) VALUES ($1)', [bignum]); + client.query('SELECT * FROM bignumz', assert.success(function(result) { + assert.equal(result.rows[0].id, 'yes') + helper.pg.end(); + done(); + })) +})); + +//custom type converter diff --git a/node_modules/pg/test/integration/client/json-type-parsing-tests.js b/node_modules/pg/test/integration/client/json-type-parsing-tests.js new file mode 100644 index 0000000..1c0759b --- /dev/null +++ b/node_modules/pg/test/integration/client/json-type-parsing-tests.js @@ -0,0 +1,38 @@ +var helper = require(__dirname + '/test-helper'); +var assert = require('assert'); +//if you want binary support, pull request me! +if (helper.config.binary) { + console.log('binary mode does not support JSON right now'); + return; +} + +test('can read and write json', function() { + helper.pg.connect(helper.config, function(err, client, done) { + assert.ifError(err); + helper.versionGTE(client, '9.2.0', assert.success(function(jsonSupported) { + if(!jsonSupported) { + console.log('skip json test on older versions of postgres'); + done(); + return helper.pg.end(); + } + client.query('CREATE TEMP TABLE stuff(id SERIAL PRIMARY KEY, data JSON)'); + var value ={name: 'Brian', age: 250, alive: true, now: new Date()}; + client.query('INSERT INTO stuff (data) VALUES ($1)', [value]); + client.query('SELECT * FROM stuff', assert.success(function(result) { + assert.equal(result.rows.length, 1); + assert.equal(typeof result.rows[0].data, 'object'); + var row = result.rows[0].data; + assert.strictEqual(row.name, value.name); + assert.strictEqual(row.age, value.age); + assert.strictEqual(row.alive, value.alive); + test('row should have "now" as a date', function() { + return false; + assert(row.now instanceof Date, 'row.now should be a date instance but is ' + typeof row.now); + }); + assert.equal(JSON.stringify(row.now), JSON.stringify(value.now)); + done(); + helper.pg.end(); + })); + })); + }); +}); diff --git a/node_modules/pg/test/integration/client/no-data-tests.js b/node_modules/pg/test/integration/client/no-data-tests.js new file mode 100644 index 0000000..341d728 --- /dev/null +++ b/node_modules/pg/test/integration/client/no-data-tests.js @@ -0,0 +1,41 @@ +var helper = require(__dirname + '/test-helper'); + +test("noData message handling", function() { + + var client = helper.client(); + + var q = client.query({ + name: 'boom', + text: 'create temp table boom(id serial, size integer)' + }); + + client.query({ + name: 'insert', + text: 'insert into boom(size) values($1)', + values: [100] + }, function(err, result) { + if(err) { + console.log(err); + throw err; + } + }); + + client.query({ + name: 'insert', + text: 'insert into boom(size) values($1)', + values: [101] + }); + + var query = client.query({ + name: 'fetch', + text: 'select size from boom where size < $1', + values: [101] + }); + + assert.emits(query, 'row', function(row) { + assert.strictEqual(row.size,100) + }); + + client.on('drain', client.end.bind(client)); + +}); diff --git a/node_modules/pg/test/integration/client/no-row-result-tests.js b/node_modules/pg/test/integration/client/no-row-result-tests.js new file mode 100644 index 0000000..5555ff6 --- /dev/null +++ b/node_modules/pg/test/integration/client/no-row-result-tests.js @@ -0,0 +1,23 @@ +var helper = require(__dirname + '/test-helper'); +var pg = helper.pg; +var config = helper.config; + +test('can access results when no rows are returned', function() { + if(config.native) return false; + var checkResult = function(result) { + assert(result.fields, 'should have fields definition'); + assert.equal(result.fields.length, 1); + assert.equal(result.fields[0].name, 'val'); + assert.equal(result.fields[0].dataTypeID, 25); + pg.end(); + }; + + pg.connect(config, assert.success(function(client, done) { + var query = client.query('select $1::text as val limit 0', ['hi'], assert.success(function(result) { + checkResult(result); + done(); + })); + + assert.emits(query, 'end', checkResult); + })); +}); diff --git a/node_modules/pg/test/integration/client/notice-tests.js b/node_modules/pg/test/integration/client/notice-tests.js new file mode 100644 index 0000000..4c6920a --- /dev/null +++ b/node_modules/pg/test/integration/client/notice-tests.js @@ -0,0 +1,44 @@ +var helper = require(__dirname + '/test-helper'); +test('emits notice message', function() { + //TODO this doesn't work on all versions of postgres + return false; + var client = helper.client(); + client.query('create temp table boom(id serial, size integer)'); + assert.emits(client, 'notice', function(notice) { + assert.ok(notice != null); + //TODO ending connection after notice generates weird errors + process.nextTick(function() { + client.end(); + }) + }); +}) + +test('emits notify message', function() { + var client = helper.client(); + client.query('LISTEN boom', assert.calls(function() { + var otherClient = helper.client(); + otherClient.query('LISTEN boom', assert.calls(function() { + assert.emits(client, 'notification', function(msg) { + //make sure PQfreemem doesn't invalidate string pointers + setTimeout(function() { + assert.equal(msg.channel, 'boom'); + assert.ok(msg.payload == 'omg!' /*9.x*/ || msg.payload == '' /*8.x*/, "expected blank payload or correct payload but got " + msg.message) + client.end() + }, 100) + + }); + assert.emits(otherClient, 'notification', function(msg) { + assert.equal(msg.channel, 'boom'); + otherClient.end(); + }); + + client.query("NOTIFY boom, 'omg!'", function(err, q) { + if(err) { + //notify not supported with payload on 8.x + client.query("NOTIFY boom") + } + }); + })); + })); +}) + diff --git a/node_modules/pg/test/integration/client/parse-int-8-tests.js b/node_modules/pg/test/integration/client/parse-int-8-tests.js new file mode 100644 index 0000000..7028e90 --- /dev/null +++ b/node_modules/pg/test/integration/client/parse-int-8-tests.js @@ -0,0 +1,18 @@ + +var helper = require(__dirname + '/../test-helper'); +var pg = helper.pg; +test('ability to turn on and off parser', function() { + if(helper.args.binary) return false; + pg.connect(helper.config, assert.success(function(client, done) { + pg.defaults.parseInt8 = true; + client.query('CREATE TEMP TABLE asdf(id SERIAL PRIMARY KEY)'); + client.query('SELECT COUNT(*) as "count" FROM asdf', assert.success(function(res) { + pg.defaults.parseInt8 = false; + client.query('SELECT COUNT(*) as "count" FROM asdf', assert.success(function(res) { + done(); + assert.strictEqual("0", res.rows[0].count); + pg.end(); + })); + })); + })); +}); diff --git a/node_modules/pg/test/integration/client/prepared-statement-tests.js b/node_modules/pg/test/integration/client/prepared-statement-tests.js new file mode 100644 index 0000000..34e5f9b --- /dev/null +++ b/node_modules/pg/test/integration/client/prepared-statement-tests.js @@ -0,0 +1,187 @@ +var helper = require(__dirname +'/test-helper'); + +test("simple, unnamed prepared statement", function(){ + var client = helper.client(); + + var query = client.query({ + text: 'select age from person where name = $1', + values: ['Brian'] + }); + + assert.emits(query, 'row', function(row) { + assert.equal(row.age, 20); + }); + + assert.emits(query, 'end', function() { + client.end(); + }); +}); + +test("named prepared statement", function() { + + var client = helper.client(); + client.on('drain', client.end.bind(client)); + + var queryName = "user by age and like name"; + var parseCount = 0; + + test("first named prepared statement",function() { + var query = client.query({ + text: 'select name from person where age <= $1 and name LIKE $2', + values: [20, 'Bri%'], + name: queryName + }); + + assert.emits(query, 'row', function(row) { + assert.equal(row.name, 'Brian'); + }); + + assert.emits(query, 'end', function() { + }); + }); + + test("second named prepared statement with same name & text", function() { + var cachedQuery = client.query({ + text: 'select name from person where age <= $1 and name LIKE $2', + name: queryName, + values: [10, 'A%'] + }); + + assert.emits(cachedQuery, 'row', function(row) { + assert.equal(row.name, 'Aaron'); + }); + + assert.emits(cachedQuery, 'end', function() { + }); + }); + + test("with same name, but the query text not even there batman!", function() { + var q = client.query({ + name: queryName, + values: [30, '%n%'] + }); + + test("gets first row", function() { + assert.emits(q, 'row', function(row) { + assert.equal(row.name, "Aaron"); + + test("gets second row", function() { + assert.emits(q, 'row', function(row) { + assert.equal(row.name, "Brian"); + }); + }); + + }); + }); + + assert.emits(q, 'end', function() { + + }); + }); +}); + +test("prepared statements on different clients", function() { + var statementName = "differ"; + var statement1 = "select count(*)::int4 as count from person"; + var statement2 = "select count(*)::int4 as count from person where age < $1"; + + var client1Finished = false; + var client2Finished = false; + + var client1 = helper.client(); + + var client2 = helper.client(); + + test("client 1 execution", function() { + + var query = client1.query({ + name: statementName, + text: statement1 + }); + test('gets right data back', function() { + assert.emits(query, 'row', function(row) { + assert.equal(row.count, 26); + }); + }); + + assert.emits(query, 'end', function() { + if(client2Finished) { + client1.end(); + client2.end(); + } else { + client1Finished = true; + } + }); + + }); + + test('client 2 execution', function() { + var query = client2.query({ + name: statementName, + text: statement2, + values: [11] + }); + + test('gets right data', function() { + assert.emits(query, 'row', function(row) { + assert.equal(row.count, 1); + }); + }); + + assert.emits(query, 'end', function() { + if(client1Finished) { + client1.end(); + client2.end(); + } else { + client2Finished = true; + } + }); + }); + +}); + +test('prepared statement', function() { + var client = helper.client(); + client.on('drain', client.end.bind(client)); + client.query('CREATE TEMP TABLE zoom(name varchar(100));'); + client.query("INSERT INTO zoom (name) VALUES ('zed')"); + client.query("INSERT INTO zoom (name) VALUES ('postgres')"); + client.query("INSERT INTO zoom (name) VALUES ('node postgres')"); + + var checkForResults = function(q) { + test('row callback fires for each result', function() { + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'node postgres'); + + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'postgres'); + + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'zed'); + }) + }); + }) + }) + }; + + test('with small row count', function() { + var query = client.query({ + name: 'get names', + text: "SELECT name FROM zoom ORDER BY name", + rows: 1 + }); + + checkForResults(query); + + }) + + test('with large row count', function() { + var query = client.query({ + name: 'get names', + text: 'SELECT name FROM zoom ORDER BY name', + rows: 1000 + }) + checkForResults(query); + }) + +}) diff --git a/node_modules/pg/test/integration/client/query-callback-error-tests.js b/node_modules/pg/test/integration/client/query-callback-error-tests.js new file mode 100644 index 0000000..bd80153 --- /dev/null +++ b/node_modules/pg/test/integration/client/query-callback-error-tests.js @@ -0,0 +1,33 @@ +var helper = require(__dirname + '/test-helper'); +var util = require('util'); + +var withQuery = function(text, resultLength, cb) { + test('error during query execution', function() { + var client = new Client(helper.args); + process.removeAllListeners('uncaughtException'); + assert.emits(process, 'uncaughtException', function() { + assert.equal(client.activeQuery, null, 'should remove active query even if error happens in callback'); + client.query('SELECT * FROM blah', assert.success(function(result) { + assert.equal(result.rows.length, resultLength); + client.end(); + cb(); + })); + }); + client.connect(assert.success(function() { + client.query('CREATE TEMP TABLE "blah"(data text)', assert.success(function() { + var q = client.query(text, ['yo'], assert.calls(function() { + assert.emits(client, 'drain'); + throw new Error('WHOOOAAAHH!!'); + })); + })); + })); + }); +} + +//test with good query so our callback is called +//as a successful callback +withQuery('INSERT INTO blah(data) VALUES($1)', 1, function() { + //test with an error query so our callback is called with an error + withQuery('INSERT INTO asldkfjlaskfj eoooeoriiri', 0, function() { + }); +}); diff --git a/node_modules/pg/test/integration/client/query-error-handling-prepared-statement-tests.js b/node_modules/pg/test/integration/client/query-error-handling-prepared-statement-tests.js new file mode 100644 index 0000000..7d25a7d --- /dev/null +++ b/node_modules/pg/test/integration/client/query-error-handling-prepared-statement-tests.js @@ -0,0 +1,83 @@ +var helper = require(__dirname + '/test-helper'); +var util = require('util'); + +function killIdleQuery(targetQuery) { + var client2 = new Client(helper.args); + var pidColName = 'procpid' + var queryColName = 'current_query'; + client2.connect(assert.success(function() { + helper.versionGTE(client2, '9.2.0', assert.success(function(isGreater) { + if(isGreater) { + pidColName = 'pid'; + queryColName = 'query'; + } + var killIdleQuery = "SELECT " + pidColName + ", (SELECT pg_terminate_backend(" + pidColName + ")) AS killed FROM pg_stat_activity WHERE " + queryColName + " = $1"; + client2.query(killIdleQuery, [targetQuery], assert.calls(function(err, res) { + assert.ifError(err); + assert.equal(res.rows.length, 1); + client2.end(); + assert.emits(client2, 'end'); + })); + })); + })); +} + +test('query killed during query execution of prepared statement', function() { + if(helper.args.native) { + return false; + } + var client = new Client(helper.args); + client.connect(assert.success(function() { + var sleepQuery = 'select pg_sleep($1)'; + var query1 = client.query({ + name: 'sleep query', + text: sleepQuery, + values: [5] }, + assert.calls(function(err, result) { + assert.equal(err.message, 'terminating connection due to administrator command'); + })); + + query1.on('error', function(err) { + assert.fail('Prepared statement should not emit error'); + }); + + query1.on('row', function(row) { + assert.fail('Prepared statement should not emit row'); + }); + + query1.on('end', function(err) { + assert.fail('Prepared statement when executed should not return before being killed'); + }); + + killIdleQuery(sleepQuery); + })); +}); + + +test('client end during query execution of prepared statement', function() { + var client = new Client(helper.args); + client.connect(assert.success(function() { + var sleepQuery = 'select pg_sleep($1)'; + var query1 = client.query({ + name: 'sleep query', + text: sleepQuery, + values: [5] }, + assert.calls(function(err, result) { + assert.equal(err.message, 'Connection was ended during query'); + })); + + query1.on('error', function(err) { + assert.fail('Prepared statement should not emit error'); + }); + + query1.on('row', function(row) { + assert.fail('Prepared statement should not emit row'); + }); + + query1.on('end', function(err) { + assert.fail('Prepared statement when executed should not return before being killed'); + }); + + client.end(); + })); +}); diff --git a/node_modules/pg/test/integration/client/query-error-handling-tests.js b/node_modules/pg/test/integration/client/query-error-handling-tests.js new file mode 100644 index 0000000..2b708b8 --- /dev/null +++ b/node_modules/pg/test/integration/client/query-error-handling-tests.js @@ -0,0 +1,37 @@ +var helper = require(__dirname + '/test-helper'); +var util = require('util'); + +test('error during query execution', function() { + var client = new Client(helper.args); + client.connect(assert.success(function() { + var sleepQuery = 'select pg_sleep(5)'; + var pidColName = 'procpid' + var queryColName = 'current_query'; + helper.versionGTE(client, '9.2.0', assert.success(function(isGreater) { + if(isGreater) { + pidColName = 'pid'; + queryColName = 'query'; + } + var query1 = client.query(sleepQuery, assert.calls(function(err, result) { + assert(err); + client.end(); + })); + //ensure query1 does not emit an 'end' event + //because it was killed and received an error + //https://github.com/brianc/node-postgres/issues/547 + query1.on('end', function() { + assert.fail('Query with an error should not emit "end" event') + }) + var client2 = new Client(helper.args); + client2.connect(assert.success(function() { + var killIdleQuery = "SELECT " + pidColName + ", (SELECT pg_terminate_backend(" + pidColName + ")) AS killed FROM pg_stat_activity WHERE " + queryColName + " = $1"; + client2.query(killIdleQuery, [sleepQuery], assert.calls(function(err, res) { + assert.ifError(err); + assert.equal(res.rows.length, 1); + client2.end(); + assert.emits(client2, 'end'); + })); + })); + })); + })); +}); diff --git a/node_modules/pg/test/integration/client/quick-disconnect-tests.js b/node_modules/pg/test/integration/client/quick-disconnect-tests.js new file mode 100644 index 0000000..a1b6bab --- /dev/null +++ b/node_modules/pg/test/integration/client/quick-disconnect-tests.js @@ -0,0 +1,7 @@ +//test for issue #320 +// +var helper = require('./test-helper'); + +var client = new helper.pg.Client(helper.config); +client.connect(); +client.end(); diff --git a/node_modules/pg/test/integration/client/result-metadata-tests.js b/node_modules/pg/test/integration/client/result-metadata-tests.js new file mode 100644 index 0000000..8f66fe1 --- /dev/null +++ b/node_modules/pg/test/integration/client/result-metadata-tests.js @@ -0,0 +1,35 @@ +var helper = require(__dirname + "/test-helper"); +var pg = helper.pg; + +test('should return insert metadata', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + + helper.versionGTE(client, '9.0.0', assert.success(function(hasRowCount) { + client.query("CREATE TEMP TABLE zugzug(name varchar(10))", assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.oid, null); + assert.equal(result.command, 'CREATE'); + + var q = client.query("INSERT INTO zugzug(name) VALUES('more work?')", assert.calls(function(err, result) { + assert.equal(result.command, "INSERT"); + assert.equal(result.rowCount, 1); + + client.query('SELECT * FROM zugzug', assert.calls(function(err, result) { + assert.isNull(err); + if(hasRowCount) assert.equal(result.rowCount, 1); + assert.equal(result.command, 'SELECT'); + process.nextTick(pg.end.bind(pg)); + })); + })); + + assert.emits(q, 'end', function(result) { + assert.equal(result.command, "INSERT"); + if(hasRowCount) assert.equal(result.rowCount, 1); + done(); + }); + + })); + })); + })); +}); diff --git a/node_modules/pg/test/integration/client/results-as-array-tests.js b/node_modules/pg/test/integration/client/results-as-array-tests.js new file mode 100644 index 0000000..ef11a89 --- /dev/null +++ b/node_modules/pg/test/integration/client/results-as-array-tests.js @@ -0,0 +1,33 @@ +var util = require('util'); +var helper = require('./test-helper'); + +var Client = helper.Client; + +var conInfo = helper.config; + +test('returns results as array', function() { + var client = new Client(conInfo); + var checkRow = function(row) { + assert(util.isArray(row), 'row should be an array'); + assert.equal(row.length, 4); + assert.equal(row[0].getFullYear(), new Date().getFullYear()); + assert.strictEqual(row[1], 1); + assert.strictEqual(row[2], 'hai'); + assert.strictEqual(row[3], null); + } + client.connect(assert.success(function() { + var config = { + text: 'SELECT NOW(), 1::int, $1::text, null', + values: ['hai'], + rowMode: 'array' + }; + var query = client.query(config, assert.success(function(result) { + assert.equal(result.rows.length, 1); + checkRow(result.rows[0]); + client.end(); + })); + assert.emits(query, 'row', function(row) { + checkRow(row); + }); + })); +}); diff --git a/node_modules/pg/test/integration/client/row-description-on-results-tests.js b/node_modules/pg/test/integration/client/row-description-on-results-tests.js new file mode 100644 index 0000000..22c9296 --- /dev/null +++ b/node_modules/pg/test/integration/client/row-description-on-results-tests.js @@ -0,0 +1,37 @@ +var helper = require('./test-helper'); + +var Client = helper.Client; + +var conInfo = helper.config; + +var checkResult = function(result) { + assert(result.fields); + assert.equal(result.fields.length, 3); + var fields = result.fields; + assert.equal(fields[0].name, 'now'); + assert.equal(fields[1].name, 'num'); + assert.equal(fields[2].name, 'texty'); + assert.equal(fields[0].dataTypeID, 1184); + assert.equal(fields[1].dataTypeID, 23); + assert.equal(fields[2].dataTypeID, 25); +}; + +test('row descriptions on result object', function() { + var client = new Client(conInfo); + client.connect(assert.success(function() { + client.query('SELECT NOW() as now, 1::int as num, $1::text as texty', ["hello"], assert.success(function(result) { + checkResult(result); + client.end(); + })); + })); +}); + +test('row description on no rows', function() { + var client = new Client(conInfo); + client.connect(assert.success(function() { + client.query('SELECT NOW() as now, 1::int as num, $1::text as texty LIMIT 0', ["hello"], assert.success(function(result) { + checkResult(result); + client.end(); + })); + })); +}); diff --git a/node_modules/pg/test/integration/client/simple-query-tests.js b/node_modules/pg/test/integration/client/simple-query-tests.js new file mode 100644 index 0000000..f8ef1ad --- /dev/null +++ b/node_modules/pg/test/integration/client/simple-query-tests.js @@ -0,0 +1,65 @@ +var helper = require(__dirname+"/test-helper"); +//before running this test make sure you run the script create-test-tables +test("simple query interface", function() { + + var client = helper.client(); + + var query = client.query("select name from person order by name"); + + client.on('drain', client.end.bind(client)); + + var rows = []; + query.on('row', function(row, result) { + assert.ok(result); + rows.push(row['name']); + }); + query.once('row', function(row) { + test('Can iterate through columns', function () { + var columnCount = 0; + for (column in row) { + columnCount++; + } + if ('length' in row) { + assert.lengthIs(row, columnCount, 'Iterating through the columns gives a different length from calling .length.'); + } + }); + }); + + assert.emits(query, 'end', function() { + test("returned right number of rows", function() { + assert.lengthIs(rows, 26); + }); + test("row ordering", function(){ + assert.equal(rows[0], "Aaron"); + assert.equal(rows[25], "Zanzabar"); + }); + }); +}); + +test("multiple simple queries", function() { + var client = helper.client(); + client.query({ text: "create temp table bang(id serial, name varchar(5));insert into bang(name) VALUES('boom');"}) + client.query("insert into bang(name) VALUES ('yes');"); + var query = client.query("select name from bang"); + assert.emits(query, 'row', function(row) { + assert.equal(row['name'], 'boom'); + assert.emits(query, 'row', function(row) { + assert.equal(row['name'],'yes'); + }); + }); + client.on('drain', client.end.bind(client)); +}); + +test("multiple select statements", function() { + var client = helper.client(); + client.query("create temp table boom(age integer); insert into boom(age) values(1); insert into boom(age) values(2); insert into boom(age) values(3)"); + client.query({text: "create temp table bang(name varchar(5)); insert into bang(name) values('zoom');"}); + var result = client.query({text: "select age from boom where age < 2; select name from bang"}); + assert.emits(result, 'row', function(row) { + assert.strictEqual(row['age'], 1); + assert.emits(result, 'row', function(row) { + assert.strictEqual(row['name'], 'zoom'); + }); + }); + client.on('drain', client.end.bind(client)); +}); diff --git a/node_modules/pg/test/integration/client/ssl-tests.js b/node_modules/pg/test/integration/client/ssl-tests.js new file mode 100644 index 0000000..0458d6b --- /dev/null +++ b/node_modules/pg/test/integration/client/ssl-tests.js @@ -0,0 +1,14 @@ +var pg = require(__dirname + '/../../../lib'); +var config = require(__dirname + '/test-helper').config; +test('can connect with ssl', function() { + return false; + config.ssl = { + rejectUnauthorized: false + }; + pg.connect(config, assert.success(function(client) { + return false; + client.query('SELECT NOW()', assert.success(function() { + pg.end(); + })); + })); +}); diff --git a/node_modules/pg/test/integration/client/test-helper.js b/node_modules/pg/test/integration/client/test-helper.js new file mode 100644 index 0000000..24cddf6 --- /dev/null +++ b/node_modules/pg/test/integration/client/test-helper.js @@ -0,0 +1,3 @@ +var helper = require(__dirname+'/../test-helper'); + +module.exports = helper; diff --git a/node_modules/pg/test/integration/client/timezone-tests.js b/node_modules/pg/test/integration/client/timezone-tests.js new file mode 100644 index 0000000..b355550 --- /dev/null +++ b/node_modules/pg/test/integration/client/timezone-tests.js @@ -0,0 +1,29 @@ +var helper = require(__dirname + '/../test-helper'); +var exec = require('child_process').exec; + +var oldTz = process.env.TZ; +process.env.TZ = 'Europe/Berlin'; + +var date = new Date(); + +helper.pg.connect(helper.config, function(err, client, done) { + assert.isNull(err); + + test('timestamp without time zone', function() { + client.query("SELECT CAST($1 AS TIMESTAMP WITHOUT TIME ZONE) AS \"val\"", [ date ], function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].val.getTime(), date.getTime()); + + test('timestamp with time zone', function() { + client.query("SELECT CAST($1 AS TIMESTAMP WITH TIME ZONE) AS \"val\"", [ date ], function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].val.getTime(), date.getTime()); + + done(); + helper.pg.end(); + process.env.TZ = oldTz; + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/node_modules/pg/test/integration/client/transaction-tests.js b/node_modules/pg/test/integration/client/transaction-tests.js new file mode 100644 index 0000000..85ee7e5 --- /dev/null +++ b/node_modules/pg/test/integration/client/transaction-tests.js @@ -0,0 +1,72 @@ +var helper = require(__dirname + '/test-helper'); + +var sink = new helper.Sink(2, function() { + helper.pg.end(); +}); + +test('a single connection transaction', function() { + helper.pg.connect(helper.config, assert.success(function(client, done) { + + client.query('begin'); + + var getZed = { + text: 'SELECT * FROM person WHERE name = $1', + values: ['Zed'] + }; + + test('Zed should not exist in the database', function() { + client.query(getZed, assert.calls(function(err, result) { + assert.isNull(err); + assert.empty(result.rows); + })) + }) + + client.query("INSERT INTO person(name, age) VALUES($1, $2)", ['Zed', 270], assert.calls(function(err, result) { + assert.isNull(err) + })); + + test('Zed should exist in the database', function() { + client.query(getZed, assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].name, 'Zed'); + })) + }) + + client.query('rollback'); + + test('Zed should not exist in the database', function() { + client.query(getZed, assert.calls(function(err, result) { + assert.isNull(err); + assert.empty(result.rows); + done(); + sink.add(); + })) + }) + })) +}) + +test('gh#36', function() { + helper.pg.connect(helper.config, assert.success(function(client, done) { + client.query("BEGIN"); + client.query({ + name: 'X', + text: "SELECT $1::INTEGER", + values: [0] + }, assert.calls(function(err, result) { + if(err) throw err; + assert.equal(result.rows.length, 1); + })) + client.query({ + name: 'X', + text: "SELECT $1::INTEGER", + values: [0] + }, assert.calls(function(err, result) { + if(err) throw err; + assert.equal(result.rows.length, 1); + })) + client.query("COMMIT", function() { + sink.add(); + done(); + }) + })); +}) diff --git a/node_modules/pg/test/integration/client/type-coercion-tests.js b/node_modules/pg/test/integration/client/type-coercion-tests.js new file mode 100644 index 0000000..05dda98 --- /dev/null +++ b/node_modules/pg/test/integration/client/type-coercion-tests.js @@ -0,0 +1,216 @@ +var helper = require(__dirname + '/test-helper'); +var sink; + +var testForTypeCoercion = function(type){ + helper.pg.connect(helper.config, function(err, client, done) { + assert.isNull(err); + client.query("create temp table test_type(col " + type.name + ")", assert.calls(function(err, result) { + assert.isNull(err); + test("Coerces " + type.name, function() { + type.values.forEach(function(val) { + + var insertQuery = client.query('insert into test_type(col) VALUES($1)',[val],assert.calls(function(err, result) { + assert.isNull(err); + })); + + var query = client.query({ + name: 'get type ' + type.name , + text: 'select col from test_type' + }); + query.on('error', function(err) { + console.log(err); + throw err; + }); + + assert.emits(query, 'row', function(row) { + var expected = val + " (" + typeof val + ")"; + var returned = row.col + " (" + typeof row.col + ")"; + assert.strictEqual(row.col, val, "expected " + type.name + " of " + expected + " but got " + returned); + }, "row should have been called for " + type.name + " of " + val); + + client.query('delete from test_type'); + }); + + client.query('drop table test_type', function() { + sink.add(); + done(); + }); + }) + })); + }) +}; + +var types = [{ + name: 'integer', + values: [-2147483648, -1, 0, 1, 2147483647, null] +},{ + name: 'smallint', + values: [-32768, -1, 0, 1, 32767, null] +},{ + name: 'bigint', + values: [ + '-9223372036854775808', + '-9007199254740992', + '0', + '9007199254740992', + '72057594037928030', + '9223372036854775807', + null + ] +},{ + name: 'varchar(5)', + values: ['yo', '', 'zomg!', null] +},{ + name: 'oid', + values: [0, 204410, null] +},{ + name: 'bool', + values: [true, false, null] +},{ + name: 'numeric', + values: [ + '-12.34', + '0', + '12.34', + '-3141592653589793238462643383279502.1618033988749894848204586834365638', + '3141592653589793238462643383279502.1618033988749894848204586834365638', + null + ] +},{ + name: 'real', + values: [-101.3, -1.2, 0, 1.2, 101.1, null] +},{ + name: 'double precision', + values: [-101.3, -1.2, 0, 1.2, 101.1, null] +},{ + name: 'timestamptz', + values: [null] +},{ + name: 'timestamp', + values: [null] +},{ + name: 'timetz', + values: ['13:11:12.1234-05:30',null] +},{ + name: 'time', + values: ['13:12:12.321', null] +}]; + +// ignore some tests in binary mode +if (helper.config.binary) { + types = types.filter(function(type) { + return !(type.name in {'real': 1, 'timetz':1, 'time':1, 'numeric': 1, 'bigint': 1}); + }); +} + +var valueCount = 0; +types.forEach(function(type) { + valueCount += type.values.length; +}) +sink = new helper.Sink(types.length + 1, function() { + helper.pg.end(); +}) + +types.forEach(function(type) { + testForTypeCoercion(type) +}); + +test("timestampz round trip", function() { + var now = new Date(); + var client = helper.client(); + client.on('error', function(err) { + console.log(err); + client.end(); + }); + client.query("create temp table date_tests(name varchar(10), tstz timestamptz(3))"); + client.query({ + text: "insert into date_tests(name, tstz)VALUES($1, $2)", + name: 'add date', + values: ['now', now] + }); + var result = client.query({ + name: 'get date', + text: 'select * from date_tests where name = $1', + values: ['now'] + }); + + assert.emits(result, 'row', function(row) { + var date = row.tstz; + assert.equal(date.getYear(),now.getYear()); + assert.equal(date.getMonth(), now.getMonth()); + assert.equal(date.getDate(), now.getDate()); + assert.equal(date.getHours(), now.getHours()); + assert.equal(date.getMinutes(), now.getMinutes()); + assert.equal(date.getSeconds(), now.getSeconds()); + test("milliseconds are equal", function() { + assert.equal(date.getMilliseconds(), now.getMilliseconds()); + }); + }); + + client.on('drain', client.end.bind(client)); +}); + +if(!helper.config.binary) { + test('date range extremes', function() { + var client = helper.client(); + client.on('error', function(err) { + console.log(err); + client.end(); + }); + + // Set teh server timeszone to the same as used for the test, + // otherwise (if server's timezone is ahead of GMT) in + // textParsers.js::parseDate() the timezone offest is added to the date; + // in the case of "275760-09-13 00:00:00 GMT" the timevalue overflows. + client.query('SET TIMEZONE TO GMT', [], assert.success(function(res){ + + // PostgreSQL supports date range of 4713 BCE to 294276 CE + // http://www.postgresql.org/docs/9.2/static/datatype-datetime.html + // ECMAScript supports date range of Apr 20 271821 BCE to Sep 13 275760 CE + // http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1 + client.query('SELECT $1::TIMESTAMPTZ as when', ["275760-09-13 00:00:00 GMT"], assert.success(function(res) { + assert.equal(res.rows[0].when.getFullYear(), 275760); + })); + + client.query('SELECT $1::TIMESTAMPTZ as when', ["4713-12-31 12:31:59 BC GMT"], assert.success(function(res) { + assert.equal(res.rows[0].when.getFullYear(), -4713); + })); + + client.query('SELECT $1::TIMESTAMPTZ as when', ["275760-09-13 00:00:00 -15:00"], assert.success(function(res) { + assert( isNaN(res.rows[0].when.getTime()) ); + })); + + client.on('drain', client.end.bind(client)); + })); + }); +} + +helper.pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query('select null as res;', assert.calls(function(err, res) { + assert.isNull(err); + assert.strictEqual(res.rows[0].res, null) + })) + client.query('select 7 <> $1 as res;',[null], function(err, res) { + assert.isNull(err); + assert.strictEqual(res.rows[0].res, null); + sink.add(); + done(); + }) +})) + +if(!helper.config.binary) { + test("postgres date type", function() { + var client = helper.client(); + var testDate = new Date (2010, 9, 31); + client.on('error', function(err) { + console.log(err); + client.end(); + }); + client.query("SELECT $1::date", [testDate], assert.calls(function(err, result){ + assert.isNull(err); + assert.strictEqual(result.rows[0].date.toString(), testDate.toString()); + })); + client.on('drain', client.end.bind(client)); + }); +} diff --git a/node_modules/pg/test/integration/connection-pool/double-connection-tests.js b/node_modules/pg/test/integration/connection-pool/double-connection-tests.js new file mode 100644 index 0000000..ae7eb31 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/double-connection-tests.js @@ -0,0 +1,2 @@ +var helper = require(__dirname + "/test-helper") +helper.testPoolSize(2); diff --git a/node_modules/pg/test/integration/connection-pool/ending-empty-pool-tests.js b/node_modules/pg/test/integration/connection-pool/ending-empty-pool-tests.js new file mode 100644 index 0000000..4f5dd80 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/ending-empty-pool-tests.js @@ -0,0 +1,15 @@ +var helper = require(__dirname + '/test-helper') + +var called = false; +test('disconnects', function() { + called = true; + var eventSink = new helper.Sink(1, function() {}); + helper.pg.on('end', function() { + eventSink.add(); + }); + + //this should exit the process + helper.pg.end(); +}) + + diff --git a/node_modules/pg/test/integration/connection-pool/ending-pool-tests.js b/node_modules/pg/test/integration/connection-pool/ending-pool-tests.js new file mode 100644 index 0000000..83f4b1b --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/ending-pool-tests.js @@ -0,0 +1,29 @@ +var helper = require(__dirname + '/test-helper') + +var called = false; +test('disconnects', function() { + var sink = new helper.Sink(4, function() { + called = true; + var eventSink = new helper.Sink(1, function() {}); + helper.pg.on('end', function() { + eventSink.add(); + }); + + //this should exit the process, killing each connection pool + helper.pg.end(); + }); + [helper.config, helper.config, helper.config, helper.config].forEach(function(config) { + helper.pg.connect(config, function(err, client, done) { + assert.isNull(err); + client.query("SELECT * FROM NOW()", function(err, result) { + setTimeout(function() { + assert.equal(called, false, "Should not have disconnected yet") + sink.add(); + done(); + }, 0) + }) + }) + }) +}) + + diff --git a/node_modules/pg/test/integration/connection-pool/error-tests.js b/node_modules/pg/test/integration/connection-pool/error-tests.js new file mode 100644 index 0000000..c286d56 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/error-tests.js @@ -0,0 +1,40 @@ +var helper = require(__dirname + "/../test-helper"); +var pg = require(__dirname + "/../../../lib"); +pg = pg; + +//first make pool hold 2 clients +pg.defaults.poolSize = 2; + + +//get first client +pg.connect(helper.config, assert.success(function(client, done) { + client.id = 1; + pg.connect(helper.config, assert.success(function(client2, done2) { + client2.id = 2; + var pidColName = 'procpid' + helper.versionGTE(client2, '9.2.0', assert.success(function(isGreater) { + console.log(isGreater) + var killIdleQuery = 'SELECT pid, (SELECT pg_terminate_backend(pid)) AS killed FROM pg_stat_activity WHERE state = $1'; + var params = ['idle']; + if(!isGreater) { + killIdleQuery = 'SELECT procpid, (SELECT pg_terminate_backend(procpid)) AS killed FROM pg_stat_activity WHERE current_query LIKE $1'; + params = ['%IDLE%'] + } + + //subscribe to the pg error event + assert.emits(pg, 'error', function(error, brokenClient) { + assert.ok(error); + assert.ok(brokenClient); + assert.equal(client.id, brokenClient.id); + }); + + //kill the connection from client + client2.query(killIdleQuery, params, assert.success(function(res) { + //check to make sure client connection actually was killed + //return client2 to the pool + done2(); + pg.end(); + })); + })); + })); +})); diff --git a/node_modules/pg/test/integration/connection-pool/idle-timeout-tests.js b/node_modules/pg/test/integration/connection-pool/idle-timeout-tests.js new file mode 100644 index 0000000..34a403f --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/idle-timeout-tests.js @@ -0,0 +1,13 @@ +var helper = require(__dirname + '/test-helper'); + +helper.pg.defaults.poolIdleTimeout = 200; + +test('idle timeout', function() { + helper.pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query('SELECT NOW()'); + //just let this one time out + //test will hang if pool doesn't timeout + done(); + })); +}); diff --git a/node_modules/pg/test/integration/connection-pool/max-connection-tests.js b/node_modules/pg/test/integration/connection-pool/max-connection-tests.js new file mode 100644 index 0000000..61755a0 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/max-connection-tests.js @@ -0,0 +1,3 @@ +var helper = require(__dirname + "/test-helper") +helper.testPoolSize(10); +helper.testPoolSize(11); diff --git a/node_modules/pg/test/integration/connection-pool/optional-config-tests.js b/node_modules/pg/test/integration/connection-pool/optional-config-tests.js new file mode 100644 index 0000000..716d315 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/optional-config-tests.js @@ -0,0 +1,21 @@ +var helper = require(__dirname + '/test-helper'); + +//setup defaults +helper.pg.defaults.user = helper.args.user; +helper.pg.defaults.password = helper.args.password; +helper.pg.defaults.host = helper.args.host; +helper.pg.defaults.port = helper.args.port; +helper.pg.defaults.database = helper.args.database; +helper.pg.defaults.poolSize = 1; + +helper.pg.connect(assert.calls(function(err, client, done) { + assert.isNull(err); + client.query('SELECT NOW()'); + client.once('drain', function() { + setTimeout(function() { + helper.pg.end(); + done(); + + }, 10); + }); +})); diff --git a/node_modules/pg/test/integration/connection-pool/single-connection-tests.js b/node_modules/pg/test/integration/connection-pool/single-connection-tests.js new file mode 100644 index 0000000..5ca0a88 --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/single-connection-tests.js @@ -0,0 +1,2 @@ +var helper = require(__dirname + "/test-helper") +helper.testPoolSize(1); diff --git a/node_modules/pg/test/integration/connection-pool/test-helper.js b/node_modules/pg/test/integration/connection-pool/test-helper.js new file mode 100644 index 0000000..199407c --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/test-helper.js @@ -0,0 +1,32 @@ +var helper = require(__dirname + "/../test-helper"); + +helper.testPoolSize = function(max) { + var sink = new helper.Sink(max, function() { + helper.pg.end(); + }); + + test("can pool " + max + " times", function() { + for(var i = 0; i < max; i++) { + helper.pg.poolSize = 10; + test("connection #" + i + " executes", function() { + helper.pg.connect(helper.config, function(err, client, done) { + assert.isNull(err); + client.query("select * from person", function(err, result) { + assert.lengthIs(result.rows, 26) + }) + client.query("select count(*) as c from person", function(err, result) { + assert.equal(result.rows[0].c, 26) + }) + var query = client.query("SELECT * FROM NOW()") + query.on('end',function() { + sink.add(); + done(); + }) + }) + }) + } + }) +} + +module.exports = helper; + diff --git a/node_modules/pg/test/integration/connection-pool/waiting-connection-tests.js b/node_modules/pg/test/integration/connection-pool/waiting-connection-tests.js new file mode 100644 index 0000000..f2519ec --- /dev/null +++ b/node_modules/pg/test/integration/connection-pool/waiting-connection-tests.js @@ -0,0 +1,2 @@ +var helper = require(__dirname + "/test-helper") +helper.testPoolSize(200); diff --git a/node_modules/pg/test/integration/connection/bound-command-tests.js b/node_modules/pg/test/integration/connection/bound-command-tests.js new file mode 100644 index 0000000..9d40e5b --- /dev/null +++ b/node_modules/pg/test/integration/connection/bound-command-tests.js @@ -0,0 +1,60 @@ +var helper = require(__dirname + '/test-helper'); +//http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY + +test('flushing once', function() { + helper.connect(function(con) { + con.parse({ + text: 'select * from ids' + }); + + con.bind(); + con.execute(); + con.flush(); + + assert.emits(con, 'parseComplete'); + assert.emits(con, 'bindComplete'); + assert.emits(con, 'dataRow'); + assert.emits(con, 'commandComplete', function(){ + con.sync(); + }); + assert.emits(con, 'readyForQuery', function(){ + con.end(); + }); + + }); +}); + +test("sending many flushes", function() { + helper.connect(function(con) { + + assert.emits(con, 'parseComplete', function(){ + con.bind(); + con.flush(); + }); + + assert.emits(con, 'bindComplete', function(){ + con.execute(); + con.flush(); + }); + + assert.emits(con, 'dataRow', function(msg){ + assert.equal(msg.fields[0], 1); + assert.emits(con, 'dataRow', function(msg){ + assert.equal(msg.fields[0], 2); + assert.emits(con, 'commandComplete', function(){ + con.sync(); + }); + assert.emits(con, 'readyForQuery', function(){ + con.end(); + }); + }); + }); + + con.parse({ + text: "select * from ids order by id" + }); + + con.flush(); + + }); +}); diff --git a/node_modules/pg/test/integration/connection/copy-tests.js b/node_modules/pg/test/integration/connection/copy-tests.js new file mode 100644 index 0000000..ee4a71c --- /dev/null +++ b/node_modules/pg/test/integration/connection/copy-tests.js @@ -0,0 +1,44 @@ +var helper = require(__dirname+"/test-helper"); +var assert = require('assert'); + +test('COPY FROM events check', function () { + helper.connect(function (con) { + var stdinStream = con.query('COPY person FROM STDIN'); + con.on('copyInResponse', function () { + con.endCopyFrom(); + }); + assert.emits(con, 'copyInResponse', + function () { + con.endCopyFrom(); + }, + "backend should emit copyInResponse after COPY FROM query" + ); + assert.emits(con, 'commandComplete', + function () { + con.end(); + }, + "backend should emit commandComplete after COPY FROM stream ends" + ) + }); +}); +test('COPY TO events check', function () { + helper.connect(function (con) { + var stdoutStream = con.query('COPY person TO STDOUT'); + assert.emits(con, 'copyOutResponse', + function () { + }, + "backend should emit copyOutResponse after COPY TO query" + ); + assert.emits(con, 'copyData', + function () { + }, + "backend should emit copyData on every data row" + ); + assert.emits(con, 'copyDone', + function () { + con.end(); + }, + "backend should emit copyDone after all data rows" + ); + }); +}); diff --git a/node_modules/pg/test/integration/connection/notification-tests.js b/node_modules/pg/test/integration/connection/notification-tests.js new file mode 100644 index 0000000..e0cf138 --- /dev/null +++ b/node_modules/pg/test/integration/connection/notification-tests.js @@ -0,0 +1,15 @@ +var helper = require(__dirname + '/test-helper'); +//http://www.postgresql.org/docs/8.3/static/libpq-notify.html +test('recieves notification from same connection with no payload', function() { + helper.connect(function(con) { + con.query('LISTEN boom'); + assert.emits(con, 'readyForQuery', function() { + con.query("NOTIFY boom"); + assert.emits(con, 'notification', function(msg) { + assert.equal(msg.payload, ""); + assert.equal(msg.channel, 'boom') + con.end(); + }); + }); + }); +}); diff --git a/node_modules/pg/test/integration/connection/query-tests.js b/node_modules/pg/test/integration/connection/query-tests.js new file mode 100644 index 0000000..f308546 --- /dev/null +++ b/node_modules/pg/test/integration/connection/query-tests.js @@ -0,0 +1,25 @@ +var helper = require(__dirname+"/test-helper"); +var assert = require('assert'); + +var rows = []; +//testing the low level 1-1 mapping api of client to postgres messages +//it's cumbersome to use the api this way +test('simple query', function() { + helper.connect(function(con) { + con.query('select * from ids'); + assert.emits(con, 'dataRow'); + con.on('dataRow', function(msg) { + rows.push(msg.fields); + }); + assert.emits(con, 'readyForQuery', function() { + con.end(); + }); + }); +}); + +process.on('exit', function() { + assert.equal(rows.length, 2); + assert.equal(rows[0].length, 1); + assert.strictEqual(String(rows[0] [0]), '1'); + assert.strictEqual(String(rows[1] [0]), '2'); +}); diff --git a/node_modules/pg/test/integration/connection/test-helper.js b/node_modules/pg/test/integration/connection/test-helper.js new file mode 100644 index 0000000..0bc6504 --- /dev/null +++ b/node_modules/pg/test/integration/connection/test-helper.js @@ -0,0 +1,42 @@ +var net = require('net'); +var helper = require(__dirname+'/../test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); +var connect = function(callback) { + var username = helper.args.user; + var database = helper.args.database; + var con = new Connection({stream: new net.Stream()}); + con.on('error', function(error){ + console.log(error); + throw new Error("Connection error"); + }); + con.connect(helper.args.port || '5432', helper.args.host || 'localhost'); + con.once('connect', function() { + con.startup({ + user: username, + database: database + }); + con.once('authenticationCleartextPassword', function(){ + con.password(helper.args.password); + }); + con.once('authenticationMD5Password', function(msg){ + //need js client even if native client is included + var client = require(__dirname +"/../../../lib/client"); + var inner = client.md5(helper.args.password+helper.args.user); + var outer = client.md5(inner + msg.salt.toString('binary')); + con.password("md5"+outer); + }); + con.once('readyForQuery', function() { + con.query('create temp table ids(id integer)'); + con.once('readyForQuery', function() { + con.query('insert into ids(id) values(1); insert into ids(id) values(2);'); + con.once('readyForQuery', function() { + callback(con); + }); + }); + }); + }); +}; + +module.exports = { + connect: connect +}; diff --git a/node_modules/pg/test/integration/domain-tests.js b/node_modules/pg/test/integration/domain-tests.js new file mode 100644 index 0000000..a51f13d --- /dev/null +++ b/node_modules/pg/test/integration/domain-tests.js @@ -0,0 +1,58 @@ +var helper = require('./test-helper') +var async = require('async') + +var testWithoutDomain = function(cb) { + test('no domain', function() { + assert(!process.domain) + helper.pg.connect(helper.config, assert.success(function(client, done) { + assert(!process.domain) + done() + cb() + })) + }) +} + +var testWithDomain = function(cb) { + test('with domain', function() { + assert(!process.domain) + var domain = require('domain').create() + domain.run(function() { + var startingDomain = process.domain + assert(startingDomain) + helper.pg.connect(helper.config, assert.success(function(client, done) { + assert(process.domain, 'no domain exists in connect callback') + assert.equal(startingDomain, process.domain, 'domain was lost when checking out a client') + var query = client.query('SELECT NOW()', assert.success(function() { + assert(process.domain, 'no domain exists in query callback') + assert.equal(startingDomain, process.domain, 'domain was lost when checking out a client') + done(true) + process.domain.exit() + cb() + })) + })) + }) + }) +} + +var testErrorWithDomain = function(cb) { + test('error on domain', function() { + var domain = require('domain').create() + domain.on('error', function() { + cb() + }) + domain.run(function() { + helper.pg.connect(helper.config, assert.success(function(client, done) { + client.query('SELECT SLDKJFLSKDJF') + client.on('drain', done) + })) + }) + }) +} + +async.series([ + testWithoutDomain, + testWithDomain, + testErrorWithDomain +], function() { + helper.pg.end() +}) diff --git a/node_modules/pg/test/integration/gh-issues/130-tests.js b/node_modules/pg/test/integration/gh-issues/130-tests.js new file mode 100644 index 0000000..34670a6 --- /dev/null +++ b/node_modules/pg/test/integration/gh-issues/130-tests.js @@ -0,0 +1,17 @@ +var helper = require(__dirname + '/../test-helper'); +var exec = require('child_process').exec; + +helper.pg.defaults.poolIdleTimeout = 1000; + +helper.pg.connect(helper.config, function(err,client) { + client.query("SELECT pg_backend_pid()", function(err, result) { + var pid = result.rows[0].pg_backend_pid; + exec('psql -c "select pg_terminate_backend('+pid+')" template1', assert.calls(function (error, stdout, stderr) { + assert.isNull(error); + })); + }); +}); + +helper.pg.on('error', function(err, client) { + //swallow errors +}); diff --git a/node_modules/pg/test/integration/gh-issues/131-tests.js b/node_modules/pg/test/integration/gh-issues/131-tests.js new file mode 100644 index 0000000..eee5086 --- /dev/null +++ b/node_modules/pg/test/integration/gh-issues/131-tests.js @@ -0,0 +1,20 @@ +var helper = require(__dirname + "/../test-helper"); +var pg = helper.pg; + +test('parsing array results', function() { + pg.connect(helper.config, assert.calls(function(err, client, done) { + assert.isNull(err); + client.query("CREATE TEMP TABLE why(names text[], numbors integer[], decimals double precision[])"); + client.query('INSERT INTO why(names, numbors, decimals) VALUES(\'{"aaron", "brian","a b c" }\', \'{1, 2, 3}\', \'{.1, 0.05, 3.654}\')').on('error', console.log); + test('decimals', function() { + client.query('SELECT decimals FROM why', assert.success(function(result) { + assert.lengthIs(result.rows[0].decimals, 3); + assert.equal(result.rows[0].decimals[0], 0.1); + assert.equal(result.rows[0].decimals[1], 0.05); + assert.equal(result.rows[0].decimals[2], 3.654); + done() + pg.end(); + })) + }) + })) +}) diff --git a/node_modules/pg/test/integration/gh-issues/199-tests.js b/node_modules/pg/test/integration/gh-issues/199-tests.js new file mode 100644 index 0000000..b60477f --- /dev/null +++ b/node_modules/pg/test/integration/gh-issues/199-tests.js @@ -0,0 +1,21 @@ +var helper = require('../test-helper'); +var client = helper.client(); + +client.query('CREATE TEMP TABLE arrtest (n integer, s varchar)'); +client.query("INSERT INTO arrtest VALUES (4, 'foo'), (5, 'bar'), (6, 'baz');"); + +var qText = "SELECT \ +ARRAY[1, 2, 3] AS b,\ +ARRAY['xx', 'yy', 'zz'] AS c,\ +ARRAY(SELECT n FROM arrtest) AS d,\ +ARRAY(SELECT s FROM arrtest) AS e;"; + +client.query(qText, function(err, result) { + if(err) throw err; + var row = result.rows[0]; + for(var key in row) { + assert.equal(typeof row[key], 'object'); + assert.equal(row[key].length, 3); + } + client.end(); +}); diff --git a/node_modules/pg/test/integration/gh-issues/507-tests.js b/node_modules/pg/test/integration/gh-issues/507-tests.js new file mode 100644 index 0000000..ef75eff --- /dev/null +++ b/node_modules/pg/test/integration/gh-issues/507-tests.js @@ -0,0 +1,15 @@ +var helper = require(__dirname + "/../test-helper"); +var pg = helper.pg; + +test('parsing array results', function() { + pg.connect(helper.config, assert.success(function(client, done) { + client.query('CREATE TEMP TABLE test_table(bar integer, "baz\'s" integer)') + client.query('INSERT INTO test_table(bar, "baz\'s") VALUES(1, 1), (2, 2)') + client.query('SELECT * FROM test_table', function(err, res) { + assert.equal(res.rows[0]["baz's"], 1) + assert.equal(res.rows[1]["baz's"], 2) + done() + pg.end() + }) + })) +}) diff --git a/node_modules/pg/test/integration/gh-issues/600-tests.js b/node_modules/pg/test/integration/gh-issues/600-tests.js new file mode 100644 index 0000000..0476d42 --- /dev/null +++ b/node_modules/pg/test/integration/gh-issues/600-tests.js @@ -0,0 +1,77 @@ +var async = require('async'); +var helper = require('../test-helper'); + +var db = helper.client(); + +function createTableFoo(callback){ + db.query("create temp table foo(column1 int, column2 int)", callback); +} + +function createTableBar(callback){ + db.query("create temp table bar(column1 text, column2 text)", callback); +} + +function insertDataFoo(callback){ + db.query({ + name: 'insertFoo', + text: 'insert into foo values($1,$2)', + values:['one','two'] + }, callback ); +} + +function insertDataBar(callback){ + db.query({ + name: 'insertBar', + text: 'insert into bar values($1,$2)', + values:['one','two'] + }, callback ); +} + +function startTransaction(callback) { + db.query('BEGIN', callback); +} +function endTransaction(callback) { + db.query('COMMIT', callback); +} + +function doTransaction(callback) { + // The transaction runs startTransaction, then all queries, then endTransaction, + // no matter if there has been an error in a query in the middle. + startTransaction(function() { + insertDataFoo(function() { + insertDataBar(function() { + endTransaction( callback ); + }); + }); + }); +} + +var steps = [ + createTableFoo, + createTableBar, + doTransaction, + insertDataBar +] + +test('test if query fails', function() { + async.series(steps, assert.success(function() { + db.end() + })) +}) + +test('test if prepare works but bind fails', function() { + var client = helper.client(); + var q = { + text: 'SELECT $1::int as name', + values: ['brian'], + name: 'test' + }; + client.query(q, assert.calls(function(err, res) { + q.values = [1]; + client.query(q, assert.calls(function(err, res) { + assert.ifError(err); + client.end(); + })); + })); +}); + diff --git a/node_modules/pg/test/integration/test-helper.js b/node_modules/pg/test/integration/test-helper.js new file mode 100644 index 0000000..7905d15 --- /dev/null +++ b/node_modules/pg/test/integration/test-helper.js @@ -0,0 +1,27 @@ +var helper = require(__dirname + '/../test-helper'); + +if(helper.args.native) { + Client = require(__dirname + '/../../lib/native'); + helper.Client = Client; + helper.pg = helper.pg.native; +} + +//creates a client from cli parameters +helper.client = function() { + var client = new Client(helper.config); + client.connect(); + return client; +}; + +var semver = require('semver'); +helper.versionGTE = function(client, versionString, callback) { + client.query('SELECT version()', assert.calls(function(err, result) { + if(err) return callback(err); + var version = result.rows[0].version.split(' ')[1]; + return callback(null, semver.gte(version, versionString)); + })); +}; + +//export parent helper stuffs +module.exports = helper; + diff --git a/node_modules/pg/test/native/callback-api-tests.js b/node_modules/pg/test/native/callback-api-tests.js new file mode 100644 index 0000000..0b71357 --- /dev/null +++ b/node_modules/pg/test/native/callback-api-tests.js @@ -0,0 +1,31 @@ +var domain = require('domain'); +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); + +test('fires callback with results', function() { + var client = new Client(helper.config); + client.connect(); + client.query('SELECT 1 as num', assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].num, 1); + client.query('SELECT * FROM person WHERE name = $1', ['Brian'], assert.calls(function(err, result) { + assert.isNull(err); + assert.equal(result.rows[0].name, 'Brian'); + client.end(); + })) + })); +}) + +test('preserves domain', function() { + var dom = domain.create(); + + dom.run(function() { + var client = new Client(helper.config); + assert.ok(dom === require('domain').active, 'domain is active'); + client.connect() + client.query('select 1', function() { + assert.ok(dom === require('domain').active, 'domain is still active'); + client.end(); + }); + }); +}) diff --git a/node_modules/pg/test/native/connection-tests.js b/node_modules/pg/test/native/connection-tests.js new file mode 100644 index 0000000..be84be6 --- /dev/null +++ b/node_modules/pg/test/native/connection-tests.js @@ -0,0 +1,36 @@ +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); +var domain = require('domain'); + +test('connecting with wrong parameters', function() { + var con = new Client("user=asldfkj hostaddr=127.0.0.1 port=5432 dbname=asldkfj"); + assert.emits(con, 'error', function(error) { + assert.ok(error != null, "error should not be null"); + con.end(); + }); + + con.connect(); +}); + +test('connects', function() { + var con = new Client(helper.config); + con.connect(); + assert.emits(con, 'connect', function() { + test('disconnects', function() { + con.end(); + }) + }) +}) + +test('preserves domain', function() { + var dom = domain.create(); + + dom.run(function() { + var con = new Client(helper.config); + assert.ok(dom === require('domain').active, 'domain is active'); + con.connect(function() { + assert.ok(dom === require('domain').active, 'domain is still active'); + con.end(); + }); + }); +}) diff --git a/node_modules/pg/test/native/copy-events-tests.js b/node_modules/pg/test/native/copy-events-tests.js new file mode 100644 index 0000000..76f7e29 --- /dev/null +++ b/node_modules/pg/test/native/copy-events-tests.js @@ -0,0 +1,40 @@ +var helper = require(__dirname+"/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); +test('COPY FROM events check', function () { + var con = new Client(helper.config), + stdinStream = con.copyFrom('COPY person FROM STDIN'); + assert.emits(con, 'copyInResponse', + function () { + stdinStream.end(); + }, + "backend should emit copyInResponse after COPY FROM query" + ); + assert.emits(con, '_readyForQuery', + function () { + con.end(); + }, + "backend should emit _readyForQuery after data will be coped to stdin stream" + ); + con.connect(); +}); +test('COPY TO events check', function () { + var con = new Client(helper.config), + stdoutStream = con.copyTo('COPY person TO STDOUT'); + assert.emits(con, 'copyOutResponse', + function () {}, + "backend should emit copyOutResponse on copyOutResponse message from server" + ); + assert.emits(con, 'copyData', + function () { + }, + "backend should emit copyData on every data row" + ); + assert.emits(con, '_readyForQuery', + function () { + con.end(); + }, + "backend should emit _readyForQuery after data will be coped to stdout stream" + ); + con.connect(); +}); + diff --git a/node_modules/pg/test/native/copyto-largedata-tests.js b/node_modules/pg/test/native/copyto-largedata-tests.js new file mode 100644 index 0000000..8c87948 --- /dev/null +++ b/node_modules/pg/test/native/copyto-largedata-tests.js @@ -0,0 +1,23 @@ +var helper = require(__dirname+"/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); +test("COPY TO large amount of data from postgres", function () { + //there were a bug in native implementation of COPY TO: + //if there were too much data (if we face situation + //when data is not ready while calling PQgetCopyData); + //while loop in Connection::HandleIOEvent becomes infinite + //in such way hanging node, consumes 100% cpu, and making connection unusable + var con = new Client(helper.config), + rowCount = 100000, + stdoutStream = con.copyTo('COPY (select generate_series(1, ' + rowCount + ')) TO STDOUT'); + stdoutStream.on('data', function () { + rowCount--; + }); + stdoutStream.on('end', function () { + assert.equal(rowCount, 0, "copy to should load exactly requested number of rows"); + con.query("SELECT 1", assert.calls(function (error, result) { + assert.ok(!error && result, "loading large amount of data by copy to should not break connection"); + con.end(); + })); + }); + con.connect(); +}); diff --git a/node_modules/pg/test/native/error-tests.js b/node_modules/pg/test/native/error-tests.js new file mode 100644 index 0000000..3a93270 --- /dev/null +++ b/node_modules/pg/test/native/error-tests.js @@ -0,0 +1,68 @@ +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); + +test('query with non-text as first parameter throws error', function() { + var client = new Client(helper.config); + client.connect(); + assert.emits(client, 'connect', function() { + client.end(); + assert.emits(client, 'end', function() { + assert.throws(function() { + client.query({text:{fail: true}}); + }); + }); + }); +}); + +test('parameterized query with non-text as first parameter throws error', function() { + var client = new Client(helper.config); + client.connect(); + assert.emits(client, 'connect', function() { + client.end(); + assert.emits(client, 'end', function() { + assert.throws(function() { + client.query({ + text: {fail: true}, + values: [1, 2] + }) + }); + }); + }); +}); + +var connect = function(callback) { + var client = new Client(helper.config); + client.connect(); + assert.emits(client, 'connect', function() { + callback(client); + }) +} + +test('parameterized query with non-array for second value', function() { + test('inline', function() { + connect(function(client) { + client.end(); + assert.emits(client, 'end', function() { + assert.throws(function() { + client.query("SELECT *", "LKSDJF") + }); + }); + }); + }); + + test('config', function() { + connect(function(client) { + client.end(); + assert.emits(client, 'end', function() { + assert.throws(function() { + client.query({ + text: "SELECT *", + values: "ALSDKFJ" + }); + }); + }); + }); + }); +}); + + diff --git a/node_modules/pg/test/native/evented-api-tests.js b/node_modules/pg/test/native/evented-api-tests.js new file mode 100644 index 0000000..db93f5b --- /dev/null +++ b/node_modules/pg/test/native/evented-api-tests.js @@ -0,0 +1,114 @@ +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); + +var setupClient = function() { + var client = new Client(helper.config); + client.connect(); + client.query("CREATE TEMP TABLE boom(name varchar(10), age integer)"); + client.query("INSERT INTO boom(name, age) VALUES('Aaron', 26)"); + client.query("INSERT INTO boom(name, age) VALUES('Brian', 28)"); + return client; +} + +test('connects', function() { + var client = new Client(helper.config); + client.connect(); + test('good query', function() { + var query = client.query("SELECT 1 as num, 'HELLO' as str"); + assert.emits(query, 'row', function(row) { + test('has integer data type', function() { + assert.strictEqual(row.num, 1); + }) + test('has string data type', function() { + assert.strictEqual(row.str, "HELLO") + }) + test('emits end AFTER row event', function() { + assert.emits(query, 'end'); + test('error query', function() { + var query = client.query("LSKDJF"); + assert.emits(query, 'error', function(err) { + assert.ok(err != null, "Should not have emitted null error"); + client.end(); + }) + }) + }) + }) + }) +}) + +test('multiple results', function() { + test('queued queries', function() { + var client = setupClient(); + var q = client.query("SELECT name FROM BOOM"); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Aaron'); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, "Brian"); + }) + }) + assert.emits(q, 'end', function() { + test('query with config', function() { + var q = client.query({text:'SELECT 1 as num'}); + assert.emits(q, 'row', function(row) { + assert.strictEqual(row.num, 1); + assert.emits(q, 'end', function() { + client.end(); + }) + }) + }) + }) + }) +}) + +test('parameterized queries', function() { + test('with a single string param', function() { + var client = setupClient(); + var q = client.query("SELECT * FROM boom WHERE name = $1", ['Aaron']); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Aaron'); + }) + assert.emits(q, 'end', function() { + client.end(); + }); + }) + + test('with object config for query', function() { + var client = setupClient(); + var q = client.query({ + text: "SELECT name FROM boom WHERE name = $1", + values: ['Brian'] + }); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Brian'); + }) + assert.emits(q, 'end', function() { + client.end(); + }) + }) + + test('multiple parameters', function() { + var client = setupClient(); + var q = client.query('SELECT name FROM boom WHERE name = $1 or name = $2 ORDER BY name', ['Aaron', 'Brian']); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Aaron'); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Brian'); + assert.emits(q, 'end', function() { + client.end(); + }) + }) + }) + }) + + test('integer parameters', function() { + var client = setupClient(); + var q = client.query('SELECT * FROM boom WHERE age > $1', [27]); + assert.emits(q, 'row', function(row) { + assert.equal(row.name, 'Brian'); + assert.equal(row.age, 28); + }); + assert.emits(q, 'end', function() { + client.end(); + }) + }) +}) diff --git a/node_modules/pg/test/native/stress-tests.js b/node_modules/pg/test/native/stress-tests.js new file mode 100644 index 0000000..cac03d0 --- /dev/null +++ b/node_modules/pg/test/native/stress-tests.js @@ -0,0 +1,49 @@ +var helper = require(__dirname + "/../test-helper"); +var Client = require(__dirname + "/../../lib/native"); + +test('many rows', function() { + var client = new Client(helper.config); + client.connect(); + var q = client.query("SELECT * FROM person"); + var rows = []; + q.on('row', function(row) { + rows.push(row) + }); + assert.emits(q, 'end', function() { + client.end(); + assert.lengthIs(rows, 26); + }) +}); + +test('many queries', function() { + var client = new Client(helper.config); + client.connect(); + var count = 0; + var expected = 100; + for(var i = 0; i < expected; i++) { + var q = client.query("SELECT * FROM person"); + assert.emits(q, 'end', function() { + count++; + }) + } + assert.emits(client, 'drain', function() { + client.end(); + assert.equal(count, expected); + }) +}) + +test('many clients', function() { + var clients = []; + for(var i = 0; i < 10; i++) { + clients.push(new Client(helper.config)); + } + clients.forEach(function(client) { + client.connect(); + for(var i = 0; i < 20; i++) { + client.query('SELECT * FROM person'); + } + assert.emits(client, 'drain', function() { + client.end(); + }) + }) +}) diff --git a/node_modules/pg/test/test-buffers.js b/node_modules/pg/test/test-buffers.js new file mode 100644 index 0000000..ddb6ba6 --- /dev/null +++ b/node_modules/pg/test/test-buffers.js @@ -0,0 +1,124 @@ +require(__dirname+'/test-helper'); +//http://developer.postgresql.org/pgdocs/postgres/protocol-message-formats.html + +var buffers = {}; +buffers.readyForQuery = function() { + return new BufferList() + .add(Buffer('I')) + .join(true,'Z'); +}; + +buffers.authenticationOk = function() { + return new BufferList() + .addInt32(0) + .join(true, 'R'); +}; + +buffers.authenticationCleartextPassword = function() { + return new BufferList() + .addInt32(3) + .join(true, 'R'); +}; + +buffers.authenticationMD5Password = function() { + return new BufferList() + .addInt32(5) + .add(Buffer([1,2,3,4])) + .join(true, 'R'); +}; + +buffers.parameterStatus = function(name, value) { + return new BufferList() + .addCString(name) + .addCString(value) + .join(true, 'S'); +}; + +buffers.backendKeyData = function(processID, secretKey) { + return new BufferList() + .addInt32(processID) + .addInt32(secretKey) + .join(true, 'K'); +}; + +buffers.commandComplete = function(string) { + return new BufferList() + .addCString(string) + .join(true, 'C'); +}; + +buffers.rowDescription = function(fields) { + fields = fields || []; + var buf = new BufferList(); + buf.addInt16(fields.length); + fields.forEach(function(field) { + buf.addCString(field.name) + .addInt32(field.tableID || 0) + .addInt16(field.attributeNumber || 0) + .addInt32(field.dataTypeID || 0) + .addInt16(field.dataTypeSize || 0) + .addInt32(field.typeModifier || 0) + .addInt16(field.formatCode || 0) + }); + return buf.join(true, 'T'); +}; + +buffers.dataRow = function(columns) { + columns = columns || []; + var buf = new BufferList(); + buf.addInt16(columns.length); + columns.forEach(function(col) { + if(col == null) { + buf.addInt32(-1); + } else { + var strBuf = new Buffer(col, 'utf8'); + buf.addInt32(strBuf.length); + buf.add(strBuf); + } + }); + return buf.join(true, 'D'); +}; + +buffers.error = function(fields) { + return errorOrNotice(fields).join(true, 'E'); +}; + +buffers.notice = function(fields) { + return errorOrNotice(fields).join(true, 'N'); +}; + +var errorOrNotice = function(fields) { + fields = fields || []; + var buf = new BufferList(); + fields.forEach(function(field) { + buf.addChar(field.type); + buf.addCString(field.value); + }); + return buf.add(Buffer([0]));//terminator +} + +buffers.parseComplete = function() { + return new BufferList().join(true, '1'); +}; + +buffers.bindComplete = function() { + return new BufferList().join(true, '2'); +}; + +buffers.notification = function(id, channel, payload) { + return new BufferList() + .addInt32(id) + .addCString(channel) + .addCString(payload) + .join(true, 'A') +}; + +buffers.emptyQuery = function() { + return new BufferList().join(true, 'I'); +}; + +buffers.portalSuspended = function() { + return new BufferList().join(true, 's'); +}; + +module.exports = buffers; diff --git a/node_modules/pg/test/test-helper.js b/node_modules/pg/test/test-helper.js new file mode 100644 index 0000000..cb7e606 --- /dev/null +++ b/node_modules/pg/test/test-helper.js @@ -0,0 +1,251 @@ +//make assert a global... +assert = require('assert'); + +var EventEmitter = require('events').EventEmitter; +var sys = require('util'); +var BufferList = require(__dirname+'/buffer-list') + +var Connection = require(__dirname + '/../lib/connection'); + +Client = require(__dirname + '/../lib').Client; + +process.on('uncaughtException', function(d) { + if ('stack' in d && 'message' in d) { + console.log("Message: " + d.message); + console.log(d.stack); + } else { + console.log(d); + } +}); + +assert.same = function(actual, expected) { + for(var key in expected) { + assert.equal(actual[key], expected[key]); + } +}; + + +assert.emits = function(item, eventName, callback, message) { + var called = false; + var id = setTimeout(function() { + test("Should have called '" + eventName + "' event", function() { + assert.ok(called, message || "Expected '" + eventName + "' to be called.") + }); + },5000); + + item.once(eventName, function() { + if (eventName === 'error') { + // belt and braces test to ensure all error events return an error + assert.ok(arguments[0] instanceof Error, + "Expected error events to throw instances of Error but found: " + sys.inspect(arguments[0])); + } + called = true; + clearTimeout(id); + assert.ok(true); + if(callback) { + callback.apply(item, arguments); + } + }); +}; + +assert.UTCDate = function(actual, year, month, day, hours, min, sec, milisecond) { + var actualYear = actual.getUTCFullYear(); + assert.equal(actualYear, year, "expected year " + year + " but got " + actualYear); + + var actualMonth = actual.getUTCMonth(); + assert.equal(actualMonth, month, "expected month " + month + " but got " + actualMonth); + + var actualDate = actual.getUTCDate(); + assert.equal(actualDate, day, "expected day " + day + " but got " + actualDate); + + var actualHours = actual.getUTCHours(); + assert.equal(actualHours, hours, "expected hours " + hours + " but got " + actualHours); + + var actualMin = actual.getUTCMinutes(); + assert.equal(actualMin, min, "expected min " + min + " but got " + actualMin); + + var actualSec = actual.getUTCSeconds(); + assert.equal(actualSec, sec, "expected sec " + sec + " but got " + actualSec); + + var actualMili = actual.getUTCMilliseconds(); + assert.equal(actualMili, milisecond, "expected milisecond " + milisecond + " but got " + actualMili); +}; + +var spit = function(actual, expected) { + console.log(""); + console.log("actual " + sys.inspect(actual)); + console.log("expect " + sys.inspect(expected)); + console.log(""); +} + +assert.equalBuffers = function(actual, expected) { + if(actual.length != expected.length) { + spit(actual, expected) + assert.equal(actual.length, expected.length); + } + for(var i = 0; i < actual.length; i++) { + if(actual[i] != expected[i]) { + spit(actual, expected) + } + assert.equal(actual[i],expected[i]); + } +}; + +assert.empty = function(actual) { + assert.lengthIs(actual, 0); +}; + +assert.success = function(callback) { + if(callback.length === 1 || callback.length === 0) { + return assert.calls(function(err, arg) { + if(err) { + console.log(err); + } + assert(!err); + callback(arg); + }); + } else if (callback.length === 2) { + return assert.calls(function(err, arg1, arg2) { + if(err) { + console.log(err); + } + assert(!err); + callback(arg1, arg2); + }); + } else { + throw new Error('need to preserve arrity of wrapped function'); + } +} + +assert.throws = function(offender) { + try { + offender(); + } catch (e) { + assert.ok(e instanceof Error, "Expected " + offender + " to throw instances of Error"); + return; + } + assert.ok(false, "Expected " + offender + " to throw exception"); +} + +assert.lengthIs = function(actual, expectedLength) { + assert.equal(actual.length, expectedLength); +}; + +var expect = function(callback, timeout) { + var executed = false; + timeout = timeout || parseInt(process.env.TEST_TIMEOUT) || 5000; + var id = setTimeout(function() { + assert.ok(executed, + "Expected execution of function to be fired within " + timeout + + " milliseconds " + + + " (hint: export TEST_TIMEOUT=" + + " to change timeout globally)"); + }, timeout) + + if(callback.length < 3) { + return function(err, queryResult) { + clearTimeout(id); + if (err) { + assert.ok(err instanceof Error, "Expected errors to be instances of Error: " + sys.inspect(err)); + } + callback.apply(this, arguments) + } + } else if(callback.length == 3) { + return function(err, arg1, arg2) { + clearTimeout(id); + if (err) { + assert.ok(err instanceof Error, "Expected errors to be instances of Error: " + sys.inspect(err)); + } + callback.apply(this, arguments) + } + } else { + throw new Error("Unsupported arrity " + callback.length); + } + +} +assert.calls = expect; + +assert.isNull = function(item, message) { + message = message || "expected " + item + " to be null"; + assert.ok(item === null, message); +}; + +test = function(name, action) { + test.testCount ++; + test[name] = action; + var result = test[name](); + if(result === false) { + process.stdout.write('?'); + }else{ + process.stdout.write('.'); + } +}; + +//print out the filename +process.stdout.write(require('path').basename(process.argv[1])); +var args = require(__dirname + '/cli'); +if(args.binary) process.stdout.write(' (binary)'); +if(args.native) process.stdout.write(' (native)'); + +process.on('exit', function() { + console.log('') +}) + +process.on('uncaughtException', function(err) { + console.error("\n %s", err.stack || err.toString()) + //causes xargs to abort right away + process.exit(255); +}); + +var count = 0; + +var Sink = function(expected, timeout, callback) { + var defaultTimeout = 5000; + if(typeof timeout == 'function') { + callback = timeout; + timeout = defaultTimeout; + } + timeout = timeout || defaultTimeout; + var internalCount = 0; + var kill = function() { + assert.ok(false, "Did not reach expected " + expected + " with an idle timeout of " + timeout); + } + var killTimeout = setTimeout(kill, timeout); + return { + add: function(count) { + count = count || 1; + internalCount += count; + clearTimeout(killTimeout) + if(internalCount < expected) { + killTimeout = setTimeout(kill, timeout) + } + else { + assert.equal(internalCount, expected); + callback(); + } + } + } +} + +var getTimezoneOffset = Date.prototype.getTimezoneOffset; + +var setTimezoneOffset = function(minutesOffset) { + Date.prototype.getTimezoneOffset = function () { return minutesOffset; }; +} + +var resetTimezoneOffset = function() { + Date.prototype.getTimezoneOffset = getTimezoneOffset; +} + +module.exports = { + Sink: Sink, + pg: require(__dirname + '/../lib/'), + args: args, + config: args, + sys: sys, + Client: Client, + setTimezoneOffset: setTimezoneOffset, + resetTimezoneOffset: resetTimezoneOffset +}; + + diff --git a/node_modules/pg/test/unit/client/cleartext-password-tests.js b/node_modules/pg/test/unit/client/cleartext-password-tests.js new file mode 100644 index 0000000..e880908 --- /dev/null +++ b/node_modules/pg/test/unit/client/cleartext-password-tests.js @@ -0,0 +1,21 @@ +require(__dirname+'/test-helper'); + +/* + * TODO: Add _some_ comments to explain what it is we're testing, and how the + * code-being-tested works behind the scenes. + */ + +test('cleartext password authentication', function(){ + + var client = createClient(); + client.password = "!"; + client.connection.stream.packets = []; + client.connection.emit('authenticationCleartextPassword'); + test('responds with password', function() { + var packets = client.connection.stream.packets; + assert.lengthIs(packets, 1); + var packet = packets[0]; + assert.equalBuffers(packet, [0x70, 0, 0, 0, 6, 33, 0]); + }); + +}); diff --git a/node_modules/pg/test/unit/client/configuration-tests.js b/node_modules/pg/test/unit/client/configuration-tests.js new file mode 100644 index 0000000..d42ee0e --- /dev/null +++ b/node_modules/pg/test/unit/client/configuration-tests.js @@ -0,0 +1,134 @@ +require(__dirname+'/test-helper'); + +var pguser = process.env['PGUSER'] || process.env.USER; +var pgdatabase = process.env['PGDATABASE'] || process.env.USER; +var pgport = process.env['PGPORT'] || 5432; + +test('client settings', function() { + + test('defaults', function() { + var client = new Client(); + assert.equal(client.user, pguser); + assert.equal(client.database, pgdatabase); + assert.equal(client.port, pgport); + }); + + test('custom', function() { + var user = 'brian'; + var database = 'pgjstest'; + var password = 'boom'; + var client = new Client({ + user: user, + database: database, + port: 321, + password: password + }); + + assert.equal(client.user, user); + assert.equal(client.database, database); + assert.equal(client.port, 321); + assert.equal(client.password, password); + }); + +}); + +test('initializing from a config string', function() { + + test('uses the correct values from the config string', function() { + var client = new Client("postgres://brian:pass@host1:333/databasename") + assert.equal(client.user, 'brian'); + assert.equal(client.password, "pass"); + assert.equal(client.host, "host1"); + assert.equal(client.port, 333); + assert.equal(client.database, "databasename"); + }); + + test('uses the correct values from the config string with space in password', function() { + var client = new Client("postgres://brian:pass word@host1:333/databasename") + assert.equal(client.user, 'brian'); + assert.equal(client.password, "pass word"); + assert.equal(client.host, "host1"); + assert.equal(client.port, 333); + assert.equal(client.database, "databasename"); + }); + + test('when not including all values the defaults are used', function() { + var client = new Client("postgres://host1"); + assert.equal(client.user, process.env['PGUSER'] || process.env.USER); + assert.equal(client.password, process.env['PGPASSWORD'] || null); + assert.equal(client.host, "host1"); + assert.equal(client.port, process.env['PGPORT'] || 5432); + assert.equal(client.database, process.env['PGDATABASE'] || process.env.USER); + }); + + test('when not including all values the environment variables are used', function() { + var envUserDefined = process.env['PGUSER'] !== undefined; + var envPasswordDefined = process.env['PGPASSWORD'] !== undefined; + var envDBDefined = process.env['PGDATABASE'] !== undefined; + var envHostDefined = process.env['PGHOST'] !== undefined; + var envPortDefined = process.env['PGPORT'] !== undefined; + + var savedEnvUser = process.env['PGUSER']; + var savedEnvPassword = process.env['PGPASSWORD']; + var savedEnvDB = process.env['PGDATABASE']; + var savedEnvHost = process.env['PGHOST']; + var savedEnvPort = process.env['PGPORT']; + + process.env['PGUSER'] = 'utUser1'; + process.env['PGPASSWORD'] = 'utPass1'; + process.env['PGDATABASE'] = 'utDB1'; + process.env['PGHOST'] = 'utHost1'; + process.env['PGPORT'] = 5464; + + var client = new Client("postgres://host1"); + assert.equal(client.user, process.env['PGUSER']); + assert.equal(client.password, process.env['PGPASSWORD']); + assert.equal(client.host, "host1"); + assert.equal(client.port, process.env['PGPORT']); + assert.equal(client.database, process.env['PGDATABASE']); + + if (envUserDefined) { + process.env['PGUSER'] = savedEnvUser; + } else { + delete process.env['PGUSER']; + } + + if (envPasswordDefined) { + process.env['PGPASSWORD'] = savedEnvPassword; + } else { + delete process.env['PGPASSWORD']; + } + + if (envDBDefined) { + process.env['PGDATABASE'] = savedEnvDB; + } else { + delete process.env['PGDATABASE']; + } + + if (envHostDefined) { + process.env['PGHOST'] = savedEnvHost; + } else { + delete process.env['PGHOST']; + } + + if (envPortDefined) { + process.env['PGPORT'] = savedEnvPort; + } else { + delete process.env['PGPORT']; + } + }); +}); + +test('calls connect correctly on connection', function() { + var client = new Client("/tmp"); + var usedPort = ""; + var usedHost = ""; + client.connection.connect = function(port, host) { + usedPort = port; + usedHost = host; + }; + client.connect(); + assert.equal(usedPort, "/tmp/.s.PGSQL." + pgport); + assert.strictEqual(usedHost, undefined); +}); + diff --git a/node_modules/pg/test/unit/client/connection-string-tests.js b/node_modules/pg/test/unit/client/connection-string-tests.js new file mode 100644 index 0000000..9316daa --- /dev/null +++ b/node_modules/pg/test/unit/client/connection-string-tests.js @@ -0,0 +1,27 @@ +require(__dirname + '/test-helper'); + +/* + * Perhaps duplicate of test named 'initializing from a config string' in + * configuration-tests.js + */ + +test("using connection string in client constructor", function() { + var client = new Client("postgres://brian:pw@boom:381/lala"); + + test("parses user", function() { + assert.equal(client.user,'brian'); + }); + test("parses password", function() { + assert.equal(client.password, 'pw'); + }); + test("parses host", function() { + assert.equal(client.host, 'boom'); + }); + test('parses port', function() { + assert.equal(client.port, 381) + }); + test('parses database', function() { + assert.equal(client.database, 'lala') + }); +}); + diff --git a/node_modules/pg/test/unit/client/early-disconnect-tests.js b/node_modules/pg/test/unit/client/early-disconnect-tests.js new file mode 100644 index 0000000..c67a783 --- /dev/null +++ b/node_modules/pg/test/unit/client/early-disconnect-tests.js @@ -0,0 +1,23 @@ +var helper = require(__dirname + '/test-helper'); +var net = require('net'); +var pg = require('../../..//lib/index.js'); + +/* console.log() messages show up in `make test` output. TODO: fix it. */ +var server = net.createServer(function(c) { + console.log('server connected'); + c.destroy(); + console.log('server socket destroyed.'); + server.close(function() { console.log('server closed'); }); +}); + +server.listen(7777, function() { + console.log('server listening'); + var client = new pg.Client('postgres://localhost:7777'); + console.log('client connecting'); + client.connect(assert.calls(function(err) { + if (err) console.log("Error on connect: "+err); + else console.log('client connected'); + assert(err); + })); + +}); diff --git a/node_modules/pg/test/unit/client/escape-tests.js b/node_modules/pg/test/unit/client/escape-tests.js new file mode 100644 index 0000000..e3f638a --- /dev/null +++ b/node_modules/pg/test/unit/client/escape-tests.js @@ -0,0 +1,72 @@ +var helper = require(__dirname + '/test-helper'); + +function createClient(callback) { + var client = new Client(helper.config); + client.connect(function(err) { + return callback(client); + }); +} + +var testLit = function(testName, input, expected) { + test(testName, function(){ + var client = new Client(helper.config); + var actual = client.escapeLiteral(input); + assert.equal(expected, actual); + }); +}; + +var testIdent = function(testName, input, expected) { + test(testName, function(){ + var client = new Client(helper.config); + var actual = client.escapeIdentifier(input); + assert.equal(expected, actual); + }); +}; + +testLit('escapeLiteral: no special characters', + 'hello world', "'hello world'"); + +testLit('escapeLiteral: contains double quotes only', + 'hello " world', "'hello \" world'"); + +testLit('escapeLiteral: contains single quotes only', + 'hello \' world', "'hello \'\' world'"); + +testLit('escapeLiteral: contains backslashes only', + 'hello \\ world', " E'hello \\\\ world'"); + +testLit('escapeLiteral: contains single quotes and double quotes', + 'hello \' " world', "'hello '' \" world'"); + +testLit('escapeLiteral: contains double quotes and backslashes', + 'hello \\ " world', " E'hello \\\\ \" world'"); + +testLit('escapeLiteral: contains single quotes and backslashes', + 'hello \\ \' world', " E'hello \\\\ '' world'"); + +testLit('escapeLiteral: contains single quotes, double quotes, and backslashes', + 'hello \\ \' " world', " E'hello \\\\ '' \" world'"); + +testIdent('escapeIdentifier: no special characters', + 'hello world', '"hello world"'); + +testIdent('escapeIdentifier: contains double quotes only', + 'hello " world', '"hello "" world"'); + +testIdent('escapeIdentifier: contains single quotes only', + 'hello \' world', '"hello \' world"'); + +testIdent('escapeIdentifier: contains backslashes only', + 'hello \\ world', '"hello \\ world"'); + +testIdent('escapeIdentifier: contains single quotes and double quotes', + 'hello \' " world', '"hello \' "" world"'); + +testIdent('escapeIdentifier: contains double quotes and backslashes', + 'hello \\ " world', '"hello \\ "" world"'); + +testIdent('escapeIdentifier: contains single quotes and backslashes', + 'hello \\ \' world', '"hello \\ \' world"'); + +testIdent('escapeIdentifier: contains single quotes, double quotes, and backslashes', + 'hello \\ \' " world', '"hello \\ \' "" world"'); diff --git a/node_modules/pg/test/unit/client/md5-password-tests.js b/node_modules/pg/test/unit/client/md5-password-tests.js new file mode 100644 index 0000000..bd5ca46 --- /dev/null +++ b/node_modules/pg/test/unit/client/md5-password-tests.js @@ -0,0 +1,21 @@ +require(__dirname + '/test-helper'); + +test('md5 authentication', function() { + var client = createClient(); + client.password = "!"; + var salt = Buffer([1, 2, 3, 4]); + client.connection.emit('authenticationMD5Password', {salt: salt}); + + test('responds', function() { + assert.lengthIs(client.connection.stream.packets, 1); + test('should have correct encrypted data', function() { + var encrypted = Client.md5(client.password + client.user); + encrypted = Client.md5(encrypted + salt.toString('binary')); + var password = "md5" + encrypted + //how do we want to test this? + assert.equalBuffers(client.connection.stream.packets[0], new BufferList() + .addCString(password).join(true,'p')); + }); + }); + +}); diff --git a/node_modules/pg/test/unit/client/notification-tests.js b/node_modules/pg/test/unit/client/notification-tests.js new file mode 100644 index 0000000..e6b0dff --- /dev/null +++ b/node_modules/pg/test/unit/client/notification-tests.js @@ -0,0 +1,10 @@ +var helper = require(__dirname + "/test-helper"); + +test('passes connection notification', function() { + var client = helper.client(); + assert.emits(client, 'notice', function(msg) { + assert.equal(msg, "HAY!!"); + }) + client.connection.emit('notice', "HAY!!"); +}) + diff --git a/node_modules/pg/test/unit/client/prepared-statement-tests.js b/node_modules/pg/test/unit/client/prepared-statement-tests.js new file mode 100644 index 0000000..6e26c79 --- /dev/null +++ b/node_modules/pg/test/unit/client/prepared-statement-tests.js @@ -0,0 +1,86 @@ +var helper = require(__dirname + '/test-helper'); + +var client = helper.client(); +var con = client.connection; +var parseArg = null; +con.parse = function(arg) { + parseArg = arg; + process.nextTick(function() { + con.emit('parseComplete'); + }); +}; + +var bindArg = null; +con.bind = function(arg) { + bindArg = arg; + process.nextTick(function(){ + con.emit('bindComplete'); + }); +}; + +var executeArg = null; +con.execute = function(arg) { + executeArg = arg; + process.nextTick(function() { + con.emit('rowData',{ fields: [] }); + con.emit('commandComplete', { text: "" }); + }); +}; + +var describeArg = null; +con.describe = function(arg) { + describeArg = arg; + process.nextTick(function() { + con.emit('rowDescription', { fields: [] }); + }); +}; + +var syncCalled = false; +con.flush = function() { +}; +con.sync = function() { + syncCalled = true; + process.nextTick(function() { + con.emit('readyForQuery'); + }); +}; + +test('bound command', function() { + test('simple, unnamed bound command', function() { + assert.ok(client.connection.emit('readyForQuery')); + + var query = client.query({ + text: 'select * from X where name = $1', + values: ['hi'] + }); + + assert.emits(query,'end', function() { + test('parse argument', function() { + assert.equal(parseArg.name, null); + assert.equal(parseArg.text, 'select * from X where name = $1'); + assert.equal(parseArg.types, null); + }); + + test('bind argument', function() { + assert.equal(bindArg.statement, null); + assert.equal(bindArg.portal, null); + assert.lengthIs(bindArg.values, 1); + assert.equal(bindArg.values[0], 'hi') + }); + + test('describe argument', function() { + assert.equal(describeArg.type, 'P'); + assert.equal(describeArg.name, ""); + }); + + test('execute argument', function() { + assert.equal(executeArg.portal, null); + assert.equal(executeArg.rows, null); + }); + + test('sync called', function() { + assert.ok(syncCalled); + }); + }); + }); +}); diff --git a/node_modules/pg/test/unit/client/query-queue-tests.js b/node_modules/pg/test/unit/client/query-queue-tests.js new file mode 100644 index 0000000..62b38bd --- /dev/null +++ b/node_modules/pg/test/unit/client/query-queue-tests.js @@ -0,0 +1,52 @@ +var helper = require(__dirname + '/test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); + +test('drain', function() { + var con = new Connection({stream: "NO"}); + var client = new Client({connection:con}); + con.connect = function() { + con.emit('connect'); + }; + con.query = function() { + }; + client.connect(); + + var raisedDrain = false; + client.on('drain', function() { + raisedDrain = true; + }); + + client.query("hello"); + client.query("sup"); + client.query('boom'); + + test("with pending queries", function() { + test("does not emit drain", function() { + assert.equal(raisedDrain, false); + }); + }); + + test("after some queries executed", function() { + con.emit('readyForQuery'); + test("does not emit drain", function() { + assert.equal(raisedDrain, false); + }); + }); + + test("when all queries are sent", function() { + con.emit('readyForQuery'); + con.emit('readyForQuery'); + test("does not emit drain", function() { + assert.equal(raisedDrain, false); + }); + }); + + test("after last query finishes", function() { + con.emit('readyForQuery'); + test("emits drain", function() { + process.nextTick(function() { + assert.ok(raisedDrain); + }) + }); + }); +}); diff --git a/node_modules/pg/test/unit/client/result-metadata-tests.js b/node_modules/pg/test/unit/client/result-metadata-tests.js new file mode 100644 index 0000000..435af25 --- /dev/null +++ b/node_modules/pg/test/unit/client/result-metadata-tests.js @@ -0,0 +1,39 @@ +var helper = require(__dirname + "/test-helper") + +var testForTag = function(tagText, callback) { + test('includes command tag data for tag ' + tagText, function() { + + var client = helper.client(); + client.connection.emit('readyForQuery') + + var query = client.query("whatever"); + assert.lengthIs(client.connection.queries, 1) + + assert.emits(query, 'end', function(result) { + assert.ok(result != null, "should pass something to this event") + callback(result) + }) + + client.connection.emit('commandComplete', { + text: tagText + }); + + client.connection.emit('readyForQuery'); + }) +} + +var check = function(oid, rowCount, command) { + return function(result) { + if(oid != null) { + assert.equal(result.oid, oid); + } + assert.equal(result.rowCount, rowCount); + assert.equal(result.command, command); + } +} + +testForTag("INSERT 0 3", check(0, 3, "INSERT")); +testForTag("INSERT 841 1", check(841, 1, "INSERT")); +testForTag("DELETE 10", check(null, 10, "DELETE")); +testForTag("UPDATE 11", check(null, 11, "UPDATE")); +testForTag("SELECT 20", check(null, 20, "SELECT")); diff --git a/node_modules/pg/test/unit/client/simple-query-tests.js b/node_modules/pg/test/unit/client/simple-query-tests.js new file mode 100644 index 0000000..19f05c1 --- /dev/null +++ b/node_modules/pg/test/unit/client/simple-query-tests.js @@ -0,0 +1,127 @@ +var helper = require(__dirname + "/test-helper"); + +test('executing query', function() { + + test("queing query", function() { + + test('when connection is ready', function() { + var client = helper.client(); + assert.empty(client.connection.queries); + client.connection.emit('readyForQuery'); + client.query('yes'); + assert.lengthIs(client.connection.queries, 1); + assert.equal(client.connection.queries, 'yes'); + }); + + test('when connection is not ready', function() { + var client = helper.client(); + + test('query is not sent', function() { + client.query('boom'); + assert.empty(client.connection.queries); + }); + + test('sends query to connection once ready', function() { + assert.ok(client.connection.emit('readyForQuery')); + assert.lengthIs(client.connection.queries, 1); + assert.equal(client.connection.queries[0], "boom"); + }); + + }); + + test("multiple in the queue", function() { + var client = helper.client(); + var connection = client.connection; + var queries = connection.queries; + client.query('one'); + client.query('two'); + client.query('three'); + assert.empty(queries); + + test("after one ready for query",function() { + connection.emit('readyForQuery'); + assert.lengthIs(queries, 1); + assert.equal(queries[0], "one"); + }); + + test('after two ready for query', function() { + connection.emit('readyForQuery'); + assert.lengthIs(queries, 2); + }); + + test("after a bunch more", function() { + connection.emit('readyForQuery'); + connection.emit('readyForQuery'); + connection.emit('readyForQuery'); + assert.lengthIs(queries, 3); + assert.equal(queries[0], "one"); + assert.equal(queries[1], 'two'); + assert.equal(queries[2], 'three'); + }); + }); + }); + + test("query event binding and flow", function() { + var client = helper.client(); + var con = client.connection; + var query = client.query('whatever'); + + test("has no queries sent before ready", function() { + assert.empty(con.queries); + }); + + test('sends query on readyForQuery event', function() { + con.emit('readyForQuery'); + assert.lengthIs(con.queries, 1); + assert.equal(con.queries[0], 'whatever'); + }); + + test('handles rowDescription message', function() { + var handled = con.emit('rowDescription',{ + fields: [{ + name: 'boom' + }] + }); + assert.ok(handled, "should have handlded rowDescription"); + }); + + test('handles dataRow messages', function() { + assert.emits(query, 'row', function(row) { + assert.equal(row['boom'], "hi"); + }); + + var handled = con.emit('dataRow', { fields: ["hi"] }); + assert.ok(handled, "should have handled first data row message"); + + assert.emits(query, 'row', function(row) { + assert.equal(row['boom'], "bye"); + }); + + var handledAgain = con.emit('dataRow', { fields: ["bye"] }); + assert.ok(handledAgain, "should have handled seciond data row message"); + }); + + //multiple command complete messages will be sent + //when multiple queries are in a simple command + test('handles command complete messages', function() { + con.emit('commandComplete', { + text: 'INSERT 31 1' + }); + }); + + test('removes itself after another readyForQuery message', function() { + return false; + assert.emits(query, "end", function(msg) { + //TODO do we want to check the complete messages? + }); + con.emit("readyForQuery"); + //this would never actually happen + ['dataRow','rowDescription', 'commandComplete'].forEach(function(msg) { + assert.equal(con.emit(msg), false, "Should no longer be picking up '"+ msg +"' messages"); + }); + }); + + }); + +}); + diff --git a/node_modules/pg/test/unit/client/stream-and-query-error-interaction-tests.js b/node_modules/pg/test/unit/client/stream-and-query-error-interaction-tests.js new file mode 100644 index 0000000..02d66c6 --- /dev/null +++ b/node_modules/pg/test/unit/client/stream-and-query-error-interaction-tests.js @@ -0,0 +1,26 @@ +var helper = require(__dirname + '/test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); +var Client = require(__dirname + '/../../../lib/client'); + +test('emits end when not in query', function() { + var stream = new (require('events').EventEmitter)(); + stream.write = function() { + //NOOP + } + var client = new Client({connection: new Connection({stream: stream})}); + client.connect(assert.calls(function() { + client.query('SELECT NOW()', assert.calls(function(err, result) { + assert(err); + })); + })); + assert.emits(client, 'end'); + client.connection.emit('connect'); + process.nextTick(function() { + client.connection.emit('readyForQuery'); + assert.equal(client.queryQueue.length, 0); + assert(client.activeQuery, 'client should have issued query'); + process.nextTick(function() { + stream.emit('close'); + }); + }); +}); diff --git a/node_modules/pg/test/unit/client/test-helper.js b/node_modules/pg/test/unit/client/test-helper.js new file mode 100644 index 0000000..a829402 --- /dev/null +++ b/node_modules/pg/test/unit/client/test-helper.js @@ -0,0 +1,19 @@ +var helper = require(__dirname+'/../test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); +var makeClient = function() { + var connection = new Connection({stream: "no"}); + connection.startup = function() {}; + connection.connect = function() {}; + connection.query = function(text) { + this.queries.push(text); + }; + connection.queries = []; + var client = new Client({connection: connection}); + client.connect(); + client.connection.emit('connect'); + return client; +}; + +module.exports = { + client: makeClient +}; diff --git a/node_modules/pg/test/unit/connection-parameters/creation-tests.js b/node_modules/pg/test/unit/connection-parameters/creation-tests.js new file mode 100644 index 0000000..8ccd988 --- /dev/null +++ b/node_modules/pg/test/unit/connection-parameters/creation-tests.js @@ -0,0 +1,215 @@ +var helper = require(__dirname + '/../test-helper'); +var assert = require('assert'); +var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters'); +var defaults = require(__dirname + '/../../../lib').defaults; + +//clear process.env +for(var key in process.env) { + delete process.env[key]; +} + +test('ConnectionParameters construction', function() { + assert.ok(new ConnectionParameters(), 'with null config'); + assert.ok(new ConnectionParameters({user: 'asdf'}), 'with config object'); + assert.ok(new ConnectionParameters('postgres://localhost/postgres'), 'with connection string'); +}); + +var compare = function(actual, expected, type) { + assert.equal(actual.user, expected.user, type + ' user'); + assert.equal(actual.database, expected.database, type + ' database'); + assert.equal(actual.port, expected.port, type + ' port'); + assert.equal(actual.host, expected.host, type + ' host'); + assert.equal(actual.password, expected.password, type + ' password'); + assert.equal(actual.binary, expected.binary, type + ' binary'); +}; + +test('ConnectionParameters initializing from defaults', function() { + var subject = new ConnectionParameters(); + compare(subject, defaults, 'defaults'); + assert.ok(subject.isDomainSocket === false); +}); + +test('ConnectionParameters initializing from config', function() { + var config = { + user: 'brian', + database: 'home', + port: 7777, + password: 'pizza', + binary: true, + encoding: 'utf8', + host: 'yo', + ssl: { + asdf: 'blah' + } + }; + var subject = new ConnectionParameters(config); + compare(subject, config, 'config'); + assert.ok(subject.isDomainSocket === false); +}); + +test('escape spaces if present', function() { + subject = new ConnectionParameters('postgres://localhost/post gres'); + assert.equal(subject.database, 'post gres'); +}); + +test('do not double escape spaces', function() { + subject = new ConnectionParameters('postgres://localhost/post%20gres'); + assert.equal(subject.database, 'post gres'); +}); + +test('initializing with unix domain socket', function() { + var subject = new ConnectionParameters('/var/run/'); + assert.ok(subject.isDomainSocket); + assert.equal(subject.host, '/var/run/'); + assert.equal(subject.database, defaults.user); +}); + +test('initializing with unix domain socket and a specific database, the simple way', function() { + var subject = new ConnectionParameters('/var/run/ mydb'); + assert.ok(subject.isDomainSocket); + assert.equal(subject.host, '/var/run/'); + assert.equal(subject.database, 'mydb'); +}); + +test('initializing with unix domain socket, the health way', function() { + var subject = new ConnectionParameters('socket:/some path/?db=my[db]&encoding=utf8'); + assert.ok(subject.isDomainSocket); + assert.equal(subject.host, '/some path/'); + assert.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); + assert.equal(subject.client_encoding, 'utf8'); +}); + +test('initializing with unix domain socket, the escaped health way', function() { + var subject = new ConnectionParameters('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); + assert.ok(subject.isDomainSocket); + assert.equal(subject.host, '/some path/'); + assert.equal(subject.database, 'my+db'); + assert.equal(subject.client_encoding, 'utf8'); +}); + +test('libpq connection string building', function() { + var checkForPart = function(array, part) { + assert.ok(array.indexOf(part) > -1, array.join(" ") + " did not contain " + part); + } + + test('builds simple string', function() { + var config = { + user: 'brian', + password: 'xyz', + port: 888, + host: 'localhost', + database: 'bam' + } + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "password='xyz'"); + checkForPart(parts, "port='888'"); + checkForPart(parts, "hostaddr=127.0.0.1"); + checkForPart(parts, "dbname='bam'"); + })); + }); + + test('builds dns string', function() { + var config = { + user: 'brian', + password: 'asdf', + port: 5432, + host: 'localhost' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "hostaddr=127.0.0.1"); + })); + }); + + test('error when dns fails', function() { + var config = { + user: 'brian', + password: 'asf', + port: 5432, + host: 'asdlfkjasldfkksfd#!$!!!!..com' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.ok(err); + assert.isNull(constring) + })); + }); + + test('connecting to unix domain socket', function() { + var config = { + user: 'brian', + password: 'asf', + port: 5432, + host: '/tmp/' + }; + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "user='brian'"); + checkForPart(parts, "host=/tmp/"); + })); + }); + + test("encoding can be specified by config", function() { + var config = { + client_encoding: "utf-8" + } + var subject = new ConnectionParameters(config); + subject.getLibpqConnectionString(assert.calls(function(err, constring) { + assert.isNull(err); + var parts = constring.split(" "); + checkForPart(parts, "client_encoding='utf-8'"); + })); + }) + + test('password contains < and/or > characters', function () { + return false; + var sourceConfig = { + user:'brian', + password: 'helloe', + port: 5432, + host: 'localhost', + database: 'postgres' + } + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = new ConnectionParameters(connectionString); + assert.equal(subject.password, sourceConfig.password); + }); + + test('username or password contains weird characters', function() { + var defaults = require('../../../lib/defaults'); + defaults.ssl = true; + var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; + var subject = new ConnectionParameters(strang); + assert.equal(subject.user, 'my f%irst name'); + assert.equal(subject.password, 'is&%awesome!'); + assert.equal(subject.host, 'localhost'); + assert.equal(subject.ssl, true); + }); + + test("url is properly encoded", function() { + var encoded = "pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl"; + var subject = new ConnectionParameters(encoded); + assert.equal(subject.user, "bi%na%%ry "); + assert.equal(subject.password, "s@f#"); + assert.equal(subject.host, 'localhost'); + assert.equal(subject.database, " u%20rl"); + }); + + test('ssl is set on client', function() { + var Client = require('../../../lib/client') + var defaults = require('../../../lib/defaults'); + defaults.ssl = true; + var c = new Client('postgres://user@password:host/database') + assert(c.ssl, 'Client should have ssl enabled via defaults') + }) + +}); diff --git a/node_modules/pg/test/unit/connection-parameters/environment-variable-tests.js b/node_modules/pg/test/unit/connection-parameters/environment-variable-tests.js new file mode 100644 index 0000000..5481915 --- /dev/null +++ b/node_modules/pg/test/unit/connection-parameters/environment-variable-tests.js @@ -0,0 +1,114 @@ +var helper = require(__dirname + '/../test-helper'); +var assert = require('assert'); +var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters'); +var defaults = require(__dirname + '/../../../lib').defaults; + +//clear process.env +var realEnv = {}; +for(var key in process.env) { + realEnv[key] = process.env[key]; + delete process.env[key]; +} + +test('ConnectionParameters initialized from environment variables', function(t) { + process.env['PGHOST'] = 'local'; + process.env['PGUSER'] = 'bmc2'; + process.env['PGPORT'] = 7890; + process.env['PGDATABASE'] = 'allyerbase'; + process.env['PGPASSWORD'] = 'open'; + + var subject = new ConnectionParameters(); + assert.equal(subject.host, 'local', 'env host'); + assert.equal(subject.user, 'bmc2', 'env user'); + assert.equal(subject.port, 7890, 'env port'); + assert.equal(subject.database, 'allyerbase', 'env database'); + assert.equal(subject.password, 'open', 'env password'); +}); + +test('ConnectionParameters initialized from mix', function(t) { + delete process.env['PGPASSWORD']; + delete process.env['PGDATABASE']; + var subject = new ConnectionParameters({ + user: 'testing', + database: 'zugzug' + }); + assert.equal(subject.host, 'local', 'env host'); + assert.equal(subject.user, 'testing', 'config user'); + assert.equal(subject.port, 7890, 'env port'); + assert.equal(subject.database, 'zugzug', 'config database'); + assert.equal(subject.password, defaults.password, 'defaults password'); +}); + +//clear process.env +for(var key in process.env) { + delete process.env[key]; +} + +test('connection string parsing', function(t) { + var string = 'postgres://brian:pw@boom:381/lala'; + var subject = new ConnectionParameters(string); + assert.equal(subject.host, 'boom', 'string host'); + assert.equal(subject.user, 'brian', 'string user'); + assert.equal(subject.password, 'pw', 'string password'); + assert.equal(subject.port, 381, 'string port'); + assert.equal(subject.database, 'lala', 'string database'); +}); + +test('connection string parsing - ssl', function(t) { + var string = 'postgres://brian:pw@boom:381/lala?ssl=true'; + var subject = new ConnectionParameters(string); + assert.equal(subject.ssl, true, 'ssl'); + + string = 'postgres://brian:pw@boom:381/lala?ssl=1'; + subject = new ConnectionParameters(string); + assert.equal(subject.ssl, true, 'ssl'); + + string = 'postgres://brian:pw@boom:381/lala?other&ssl=true'; + subject = new ConnectionParameters(string); + assert.equal(subject.ssl, true, 'ssl'); + + string = 'postgres://brian:pw@boom:381/lala?ssl=0'; + subject = new ConnectionParameters(string); + assert.equal(!!subject.ssl, false, 'ssl'); + + string = 'postgres://brian:pw@boom:381/lala'; + subject = new ConnectionParameters(string); + assert.equal(!!subject.ssl, false, 'ssl'); +}); + +//clear process.env +for(var key in process.env) { + delete process.env[key]; +} + + +test('ssl is false by default', function() { + var subject = new ConnectionParameters() + assert.equal(subject.ssl, false) +}) + +var testVal = function(mode, expected) { + //clear process.env + for(var key in process.env) { + delete process.env[key]; + } + process.env.PGSSLMODE = mode; + test('ssl is ' + expected + ' when $PGSSLMODE=' + mode, function() { + var subject = new ConnectionParameters(); + assert.equal(subject.ssl, expected); + }); +}; + +testVal('', false); +testVal('disable', false); +testVal('allow', false); +testVal('prefer', true); +testVal('require', true); +testVal('verify-ca', true); +testVal('verify-full', true); + + +//restore process.env +for(var key in realEnv) { + process.env[key] = realEnv[key]; +} diff --git a/node_modules/pg/test/unit/connection/error-tests.js b/node_modules/pg/test/unit/connection/error-tests.js new file mode 100644 index 0000000..98eb20a --- /dev/null +++ b/node_modules/pg/test/unit/connection/error-tests.js @@ -0,0 +1,30 @@ +var helper = require(__dirname + '/test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); +test("connection emits stream errors", function() { + var con = new Connection({stream: new MemoryStream()}); + assert.emits(con, 'error', function(err) { + assert.equal(err.message, "OMG!"); + }); + con.connect(); + con.stream.emit('error', new Error("OMG!")); +}); + +test('connection emits ECONNRESET errors during normal operation', function() { + var con = new Connection({stream: new MemoryStream()}); + con.connect(); + assert.emits(con, 'error', function(err) { + assert.equal(err.code, 'ECONNRESET'); + }); + var e = new Error('Connection Reset'); + e.code = 'ECONNRESET'; + con.stream.emit('error', e); +}); + +test('connection does not emit ECONNRESET errors during disconnect', function() { + var con = new Connection({stream: new MemoryStream()}); + con.connect(); + var e = new Error('Connection Reset'); + e.code = 'ECONNRESET'; + con.end(); + con.stream.emit('error', e); +}); diff --git a/node_modules/pg/test/unit/connection/inbound-parser-tests.js b/node_modules/pg/test/unit/connection/inbound-parser-tests.js new file mode 100644 index 0000000..55d71d5 --- /dev/null +++ b/node_modules/pg/test/unit/connection/inbound-parser-tests.js @@ -0,0 +1,470 @@ +require(__dirname+'/test-helper'); +return false; +var Connection = require(__dirname + '/../../../lib/connection'); +var buffers = require(__dirname + '/../../test-buffers'); +var PARSE = function(buffer) { + return new Parser(buffer).parse(); +}; + +var authOkBuffer = buffers.authenticationOk(); +var paramStatusBuffer = buffers.parameterStatus('client_encoding', 'UTF8'); +var readyForQueryBuffer = buffers.readyForQuery(); +var backendKeyDataBuffer = buffers.backendKeyData(1,2); +var commandCompleteBuffer = buffers.commandComplete("SELECT 3"); +var parseCompleteBuffer = buffers.parseComplete(); +var bindCompleteBuffer = buffers.bindComplete(); +var portalSuspendedBuffer = buffers.portalSuspended(); + +var addRow = function(bufferList, name, offset) { + return bufferList.addCString(name) //field name + .addInt32(offset++) //table id + .addInt16(offset++) //attribute of column number + .addInt32(offset++) //objectId of field's data type + .addInt16(offset++) //datatype size + .addInt32(offset++) //type modifier + .addInt16(0) //format code, 0 => text +}; + +var row1 = { + name: 'id', + tableID: 1, + attributeNumber: 2, + dataTypeID: 3, + dataTypeSize: 4, + typeModifier: 5, + formatCode: 0 +}; +var oneRowDescBuff = new buffers.rowDescription([row1]); +row1.name = 'bang'; + +var twoRowBuf = new buffers.rowDescription([row1,{ + name: 'whoah', + tableID: 10, + attributeNumber: 11, + dataTypeID: 12, + dataTypeSize: 13, + typeModifier: 14, + formatCode: 0 +}]) + + +var emptyRowFieldBuf = new BufferList() + .addInt16(0) + .join(true, 'D'); + +var emptyRowFieldBuf = buffers.dataRow(); + +var oneFieldBuf = new BufferList() + .addInt16(1) //number of fields + .addInt32(5) //length of bytes of fields + .addCString('test') + .join(true, 'D'); + +var oneFieldBuf = buffers.dataRow(['test']); + + +var expectedAuthenticationOkayMessage = { + name: 'authenticationOk', + length: 8 +}; + +var expectedParameterStatusMessage = { + name: 'parameterStatus', + parameterName: 'client_encoding', + parameterValue: 'UTF8', + length: 25 +}; + +var expectedBackendKeyDataMessage = { + name: 'backendKeyData', + processID: 1, + secretKey: 2 +}; + +var expectedReadyForQueryMessage = { + name: 'readyForQuery', + length: 5, + status: 'I' +}; + +var expectedCommandCompleteMessage = { + length: 13, + text: "SELECT 3" +}; +var emptyRowDescriptionBuffer = new BufferList() + .addInt16(0) //number of fields + .join(true,'T'); + +var expectedEmptyRowDescriptionMessage = { + name: 'rowDescription', + length: 6, + fieldCount: 0 +}; +var expectedOneRowMessage = { + name: 'rowDescription', + length: 27, + fieldCount: 1 +}; + +var expectedTwoRowMessage = { + name: 'rowDescription', + length: 53, + fieldCount: 2 +}; + +var testForMessage = function(buffer, expectedMessage) { + var lastMessage = {}; + test('recieves and parses ' + expectedMessage.name, function() { + var stream = new MemoryStream(); + var client = new Connection({ + stream: stream + }); + client.connect(); + + client.on('message',function(msg) { + lastMessage = msg; + }); + + client.on(expectedMessage.name, function() { + client.removeAllListeners(expectedMessage.name); + }); + + stream.emit('data', buffer); + assert.same(lastMessage, expectedMessage); + }); + return lastMessage; +}; + +var plainPasswordBuffer = buffers.authenticationCleartextPassword(); +var md5PasswordBuffer = buffers.authenticationMD5Password(); + +var expectedPlainPasswordMessage = { + name: 'authenticationCleartextPassword' +}; + +var expectedMD5PasswordMessage = { + name: 'authenticationMD5Password' +}; + +var notificationResponseBuffer = buffers.notification(4, 'hi', 'boom'); +var expectedNotificationResponseMessage = { + name: 'notification', + processId: 4, + channel: 'hi', + payload: 'boom' +}; + +test('Connection', function() { + testForMessage(authOkBuffer, expectedAuthenticationOkayMessage); + testForMessage(plainPasswordBuffer, expectedPlainPasswordMessage); + var msg = testForMessage(md5PasswordBuffer, expectedMD5PasswordMessage); + test('md5 has right salt', function() { + assert.equalBuffers(msg.salt, Buffer([1,2,3,4])); + }); + testForMessage(paramStatusBuffer, expectedParameterStatusMessage); + testForMessage(backendKeyDataBuffer, expectedBackendKeyDataMessage); + testForMessage(readyForQueryBuffer, expectedReadyForQueryMessage); + testForMessage(commandCompleteBuffer,expectedCommandCompleteMessage); + testForMessage(notificationResponseBuffer, expectedNotificationResponseMessage); + test('empty row message', function() { + var message = testForMessage(emptyRowDescriptionBuffer, expectedEmptyRowDescriptionMessage); + test('has no fields', function() { + assert.equal(message.fields.length, 0); + }); + }); + + test("no data message", function() { + testForMessage(Buffer([0x6e, 0, 0, 0, 4]), { + name: 'noData' + }); + }); + + test('one row message', function() { + var message = testForMessage(oneRowDescBuff, expectedOneRowMessage); + test('has one field', function() { + assert.equal(message.fields.length, 1); + }); + test('has correct field info', function() { + assert.same(message.fields[0], { + name: 'id', + tableID: 1, + columnID: 2, + dataTypeID: 3, + dataTypeSize: 4, + dataTypeModifier: 5, + format: 'text' + }); + }); + }); + + test('two row message', function() { + var message = testForMessage(twoRowBuf, expectedTwoRowMessage); + test('has two fields', function() { + assert.equal(message.fields.length, 2); + }); + test('has correct first field', function() { + assert.same(message.fields[0], { + name: 'bang', + tableID: 1, + columnID: 2, + dataTypeID: 3, + dataTypeSize: 4, + dataTypeModifier: 5, + format: 'text' + }) + }); + test('has correct second field', function() { + assert.same(message.fields[1], { + name: 'whoah', + tableID: 10, + columnID: 11, + dataTypeID: 12, + dataTypeSize: 13, + dataTypeModifier: 14, + format: 'text' + }); + }); + + }); + + test('parsing rows', function() { + + test('parsing empty row', function() { + var message = testForMessage(emptyRowFieldBuf, { + name: 'dataRow', + fieldCount: 0 + }); + test('has 0 fields', function() { + assert.equal(message.fields.length, 0); + }); + }); + + test('parsing data row with fields', function() { + var message = testForMessage(oneFieldBuf, { + name: 'dataRow', + fieldCount: 1 + }); + test('has 1 field', function() { + assert.equal(message.fields.length, 1); + }); + + test('field is correct', function() { + assert.equal(message.fields[0],'test'); + }); + }); + + }); + + test('notice message', function() { + //this uses the same logic as error message + var buff = buffers.notice([{type: 'C', value: 'code'}]); + testForMessage(buff, { + name: 'notice', + code: 'code' + }); + }); + + test('error messages', function() { + test('with no fields', function() { + var msg = testForMessage(buffers.error(),{ + name: 'error' + }); + }); + + test('with all the fields', function() { + var buffer = buffers.error([{ + type: 'S', + value: 'ERROR' + },{ + type: 'C', + value: 'code' + },{ + type: 'M', + value: 'message' + },{ + type: 'D', + value: 'details' + },{ + type: 'H', + value: 'hint' + },{ + type: 'P', + value: '100' + },{ + type: 'p', + value: '101' + },{ + type: 'q', + value: 'query' + },{ + type: 'W', + value: 'where' + },{ + type: 'F', + value: 'file' + },{ + type: 'L', + value: 'line' + },{ + type: 'R', + value: 'routine' + },{ + type: 'Z', //ignored + value: 'alsdkf' + }]); + + testForMessage(buffer,{ + name: 'error', + severity: 'ERROR', + code: 'code', + message: 'message', + detail: 'details', + hint: 'hint', + position: '100', + internalPosition: '101', + internalQuery: 'query', + where: 'where', + file: 'file', + line: 'line', + routine: 'routine' + }); + }); + }); + + test('parses parse complete command', function() { + testForMessage(parseCompleteBuffer, { + name: 'parseComplete' + }); + }); + + test('parses bind complete command', function() { + testForMessage(bindCompleteBuffer, { + name: 'bindComplete' + }); + }); + + test('parses portal suspended message', function() { + testForMessage(portalSuspendedBuffer, { + name: 'portalSuspended' + }); + }); +}); + +//since the data message on a stream can randomly divide the incomming +//tcp packets anywhere, we need to make sure we can parse every single +//split on a tcp message +test('split buffer, single message parsing', function() { + var fullBuffer = buffers.dataRow([null, "bang", "zug zug", null, "!"]); + var stream = new MemoryStream(); + stream.readyState = 'open'; + var client = new Connection({ + stream: stream + }); + client.connect(); + var message = null; + client.on('message', function(msg) { + message = msg; + }); + + test('parses when full buffer comes in', function() { + stream.emit('data', fullBuffer); + assert.lengthIs(message.fields, 5); + assert.equal(message.fields[0], null); + assert.equal(message.fields[1], "bang"); + assert.equal(message.fields[2], "zug zug"); + assert.equal(message.fields[3], null); + assert.equal(message.fields[4], "!"); + }); + + var testMessageRecievedAfterSpiltAt = function(split) { + var firstBuffer = new Buffer(fullBuffer.length-split); + var secondBuffer = new Buffer(fullBuffer.length-firstBuffer.length); + fullBuffer.copy(firstBuffer, 0, 0); + fullBuffer.copy(secondBuffer, 0, firstBuffer.length); + stream.emit('data', firstBuffer); + stream.emit('data', secondBuffer); + assert.lengthIs(message.fields, 5); + assert.equal(message.fields[0], null); + assert.equal(message.fields[1], "bang"); + assert.equal(message.fields[2], "zug zug"); + assert.equal(message.fields[3], null); + assert.equal(message.fields[4], "!"); + + }; + + test('parses when split in the middle', function() { + testMessageRecievedAfterSpiltAt(6); + }); + + test('parses when split at end', function() { + testMessageRecievedAfterSpiltAt(2); + }); + + test('parses when split at beginning', function() { + testMessageRecievedAfterSpiltAt(fullBuffer.length - 2); + testMessageRecievedAfterSpiltAt(fullBuffer.length - 1); + testMessageRecievedAfterSpiltAt(fullBuffer.length - 5); + }); +}); + +test('split buffer, multiple message parsing', function() { + var dataRowBuffer = buffers.dataRow(['!']); + var readyForQueryBuffer = buffers.readyForQuery(); + var fullBuffer = new Buffer(dataRowBuffer.length + readyForQueryBuffer.length); + dataRowBuffer.copy(fullBuffer, 0, 0); + readyForQueryBuffer.copy(fullBuffer, dataRowBuffer.length, 0); + + var messages = []; + var stream = new MemoryStream(); + var client = new Connection({ + stream: stream + }); + client.connect(); + client.on('message', function(msg) { + messages.push(msg); + }); + + + var verifyMessages = function() { + assert.lengthIs(messages, 2); + assert.same(messages[0],{ + name: 'dataRow', + fieldCount: 1 + }); + assert.equal(messages[0].fields[0],'!'); + assert.same(messages[1],{ + name: 'readyForQuery' + }); + messages = []; + }; + //sanity check + test('recieves both messages when packet is not split', function() { + stream.emit('data', fullBuffer); + verifyMessages(); + }); + var splitAndVerifyTwoMessages = function(split) { + var firstBuffer = new Buffer(fullBuffer.length-split); + var secondBuffer = new Buffer(fullBuffer.length-firstBuffer.length); + fullBuffer.copy(firstBuffer, 0, 0); + fullBuffer.copy(secondBuffer, 0, firstBuffer.length); + stream.emit('data', firstBuffer); + stream.emit('data', secondBuffer); + }; + + test('recieves both messages when packet is split', function() { + test('in the middle', function() { + splitAndVerifyTwoMessages(11); + }); + test('at the front', function() { + splitAndVerifyTwoMessages(fullBuffer.length-1); + splitAndVerifyTwoMessages(fullBuffer.length-4); + splitAndVerifyTwoMessages(fullBuffer.length-6); + }); + + test('at the end', function() { + splitAndVerifyTwoMessages(8); + splitAndVerifyTwoMessages(1); + }); + }); + +}); diff --git a/node_modules/pg/test/unit/connection/outbound-sending-tests.js b/node_modules/pg/test/unit/connection/outbound-sending-tests.js new file mode 100644 index 0000000..3dde8a3 --- /dev/null +++ b/node_modules/pg/test/unit/connection/outbound-sending-tests.js @@ -0,0 +1,200 @@ +require(__dirname + "/test-helper"); +var Connection = require(__dirname + '/../../../lib/connection'); +var stream = new MemoryStream(); +var con = new Connection({ + stream: stream +}); + +assert.received = function(stream, buffer) { + assert.lengthIs(stream.packets, 1); + var packet = stream.packets.pop(); + assert.equalBuffers(packet, buffer); +}; + +test("sends startup message", function() { + con.startup({ + user: 'brian', + database: 'bang' + }); + assert.received(stream, new BufferList() + .addInt16(3) + .addInt16(0) + .addCString('user') + .addCString('brian') + .addCString('database') + .addCString('bang') + .addCString('client_encoding') + .addCString("'utf-8'") + .addCString('').join(true)) +}); + +test('sends password message', function() { + con.password("!"); + assert.received(stream, new BufferList().addCString("!").join(true,'p')); +}); + +test('sends query message', function() { + var txt = 'select * from boom'; + con.query(txt); + assert.received(stream, new BufferList().addCString(txt).join(true,'Q')); +}); + +test('sends parse message', function() { + con.parse({text: '!'}); + var expected = new BufferList() + .addCString("") + .addCString("!") + .addInt16(0).join(true, 'P'); + assert.received(stream, expected); +}); + +test('sends parse message with named query', function() { + con.parse({ + name: 'boom', + text: 'select * from boom', + types: [] + }); + var expected = new BufferList() + .addCString("boom") + .addCString("select * from boom") + .addInt16(0).join(true,'P'); + assert.received(stream, expected); + + test('with multiple parameters', function() { + con.parse({ + name: 'force', + text: 'select * from bang where name = $1', + types: [1, 2, 3 ,4] + }); + var expected = new BufferList() + .addCString("force") + .addCString("select * from bang where name = $1") + .addInt16(4) + .addInt32(1) + .addInt32(2) + .addInt32(3) + .addInt32(4).join(true,'P'); + assert.received(stream, expected); + }); +}); + +test('bind messages', function() { + test('with no values', function() { + con.bind(); + + var expectedBuffer = new BufferList() + .addCString("") + .addCString("") + .addInt16(0) + .addInt16(0) + .addInt16(0) + .join(true,"B"); + assert.received(stream, expectedBuffer); + }); + + test('with named statement, portal, and values', function() { + con.bind({ + portal: 'bang', + statement: 'woo', + values: ['1', 'hi', null, 'zing'] + }); + var expectedBuffer = new BufferList() + .addCString('bang') //portal name + .addCString('woo') //statement name + .addInt16(0) + .addInt16(4) + .addInt32(1) + .add(Buffer("1")) + .addInt32(2) + .add(Buffer("hi")) + .addInt32(-1) + .addInt32(4) + .add(Buffer('zing')) + .addInt16(0) + .join(true, 'B'); + assert.received(stream, expectedBuffer); + }); +}); + +test('with named statement, portal, and buffer value', function() { + con.bind({ + portal: 'bang', + statement: 'woo', + values: ['1', 'hi', null, new Buffer('zing', 'UTF-8')] + }); + var expectedBuffer = new BufferList() + .addCString('bang') //portal name + .addCString('woo') //statement name + .addInt16(4)//value count + .addInt16(0)//string + .addInt16(0)//string + .addInt16(0)//string + .addInt16(1)//binary + .addInt16(4) + .addInt32(1) + .add(Buffer("1")) + .addInt32(2) + .add(Buffer("hi")) + .addInt32(-1) + .addInt32(4) + .add(new Buffer('zing', 'UTF-8')) + .addInt16(0) + .join(true, 'B'); + assert.received(stream, expectedBuffer); +}); + +test("sends execute message", function() { + + test("for unamed portal with no row limit", function() { + con.execute(); + var expectedBuffer = new BufferList() + .addCString('') + .addInt32(0) + .join(true,'E'); + assert.received(stream, expectedBuffer); + }); + + test("for named portal with row limit", function() { + con.execute({ + portal: 'my favorite portal', + rows: 100 + }); + var expectedBuffer = new BufferList() + .addCString("my favorite portal") + .addInt32(100) + .join(true, 'E'); + assert.received(stream, expectedBuffer); + }); +}); + +test('sends flush command', function() { + con.flush(); + var expected = new BufferList().join(true, 'H'); + assert.received(stream, expected); +}); + +test('sends sync command', function() { + con.sync(); + var expected = new BufferList().join(true,'S'); + assert.received(stream, expected); +}); + +test('sends end command', function() { + con.end(); + var expected = new Buffer([0x58, 0, 0, 0, 4]); + assert.received(stream, expected); +}); + +test('sends describe command',function() { + test('describe statement', function() { + con.describe({type: 'S', name: 'bang'}); + var expected = new BufferList().addChar('S').addCString('bang').join(true, 'D') + assert.received(stream, expected); + }); + + test("describe unnamed portal", function() { + con.describe({type: 'P'}); + var expected = new BufferList().addChar('P').addCString("").join(true, "D"); + assert.received(stream, expected); + }); +}); diff --git a/node_modules/pg/test/unit/connection/startup-tests.js b/node_modules/pg/test/unit/connection/startup-tests.js new file mode 100644 index 0000000..e3b4199 --- /dev/null +++ b/node_modules/pg/test/unit/connection/startup-tests.js @@ -0,0 +1,64 @@ +require(__dirname+'/test-helper'); +var Connection = require(__dirname + '/../../../lib/connection'); +test('connection can take existing stream', function() { + var stream = new MemoryStream(); + var con = new Connection({stream: stream}); + assert.equal(con.stream, stream); +}); + +test('using closed stream', function() { + var stream = new MemoryStream(); + stream.readyState = 'closed'; + stream.connect = function(port, host) { + this.connectCalled = true; + this.port = port; + this.host = host; + } + + var con = new Connection({stream: stream}); + + con.connect(1234, 'bang'); + + test('makes stream connect', function() { + assert.equal(stream.connectCalled, true); + }); + + test('uses configured port', function() { + assert.equal(stream.port, 1234); + }); + + test('uses configured host', function() { + assert.equal(stream.host, 'bang'); + }); + + test('after stream connects client emits connected event', function() { + + var hit = false; + + con.once('connect', function() { + hit = true; + }); + + assert.ok(stream.emit('connect')); + assert.ok(hit); + + }); +}); + +test('using opened stream', function() { + var stream = new MemoryStream(); + stream.readyState = 'open'; + stream.connect = function() { + assert.ok(false, "Should not call open"); + }; + var con = new Connection({stream: stream}); + test('does not call open', function() { + var hit = false; + con.once('connect', function() { + hit = true; + }); + con.connect(); + assert.ok(hit); + }); + +}); diff --git a/node_modules/pg/test/unit/connection/test-helper.js b/node_modules/pg/test/unit/connection/test-helper.js new file mode 100644 index 0000000..88cced6 --- /dev/null +++ b/node_modules/pg/test/unit/connection/test-helper.js @@ -0,0 +1 @@ +require(__dirname+'/../test-helper') diff --git a/node_modules/pg/test/unit/copystream/copyfrom-tests.js b/node_modules/pg/test/unit/copystream/copyfrom-tests.js new file mode 100644 index 0000000..7b96049 --- /dev/null +++ b/node_modules/pg/test/unit/copystream/copyfrom-tests.js @@ -0,0 +1,99 @@ +var helper = require(__dirname + '/../test-helper'); +var CopyFromStream = require(__dirname + '/../../../lib/copystream').CopyFromStream; +var ConnectionImitation = function () { + this.send = 0; + this.hasToBeSend = 0; + this.finished = 0; +}; +ConnectionImitation.prototype = { + endCopyFrom: function () { + assert.ok(this.finished++ === 0, "end shoud be called only once"); + assert.equal(this.send, this.hasToBeSend, "at the moment of the end all data has to be sent"); + }, + sendCopyFromChunk: function (chunk) { + this.send += chunk.length; + return true; + }, + updateHasToBeSend: function (chunk) { + this.hasToBeSend += chunk.length; + return chunk; + } +}; +var buf1 = new Buffer("asdfasd"), + buf2 = new Buffer("q03r90arf0aospd;"), + buf3 = new Buffer(542), + buf4 = new Buffer("93jfemialfjkasjlfas"); + +test('CopyFromStream, start streaming before data, end after data. no drain event', function () { + var stream = new CopyFromStream(); + var conn = new ConnectionImitation(); + stream.on('drain', function () { + assert.ok(false, "there has not be drain event"); + }); + stream.startStreamingToConnection(conn); + assert.ok(stream.write(conn.updateHasToBeSend(buf1))); + assert.ok(stream.write(conn.updateHasToBeSend(buf2))); + assert.ok(stream.write(conn.updateHasToBeSend(buf3))); + assert.ok(stream.writable, "stream has to be writable"); + stream.end(conn.updateHasToBeSend(buf4)); + assert.ok(!stream.writable, "stream has not to be writable"); + stream.end(); + assert.equal(conn.hasToBeSend, conn.send); +}); +test('CopyFromStream, start streaming after end, end after data. drain event', function () { + var stream = new CopyFromStream(); + assert.emits(stream, 'drain', function() {}, 'drain have to be emitted'); + var conn = new ConnectionImitation() + assert.ok(!stream.write(conn.updateHasToBeSend(buf1))); + assert.ok(!stream.write(conn.updateHasToBeSend(buf2))); + assert.ok(!stream.write(conn.updateHasToBeSend(buf3))); + assert.ok(stream.writable, "stream has to be writable"); + stream.end(conn.updateHasToBeSend(buf4)); + assert.ok(!stream.writable, "stream has not to be writable"); + stream.end(); + stream.startStreamingToConnection(conn); + assert.equal(conn.hasToBeSend, conn.send); +}); +test('CopyFromStream, start streaming between data chunks. end after data. drain event', function () { + var stream = new CopyFromStream(); + var conn = new ConnectionImitation() + assert.emits(stream, 'drain', function() {}, 'drain have to be emitted'); + stream.write(conn.updateHasToBeSend(buf1)); + stream.write(conn.updateHasToBeSend(buf2)); + stream.startStreamingToConnection(conn); + stream.write(conn.updateHasToBeSend(buf3)); + assert.ok(stream.writable, "stream has to be writable"); + stream.end(conn.updateHasToBeSend(buf4)); + assert.equal(conn.hasToBeSend, conn.send); + assert.ok(!stream.writable, "stream has not to be writable"); + stream.end(); +}); +test('CopyFromStream, start sreaming before end. end stream with data. drain event', function () { + var stream = new CopyFromStream(); + var conn = new ConnectionImitation() + assert.emits(stream, 'drain', function() {}, 'drain have to be emitted'); + stream.write(conn.updateHasToBeSend(buf1)); + stream.write(conn.updateHasToBeSend(buf2)); + stream.write(conn.updateHasToBeSend(buf3)); + stream.startStreamingToConnection(conn); + assert.ok(stream.writable, "stream has to be writable"); + stream.end(conn.updateHasToBeSend(buf4)); + assert.equal(conn.hasToBeSend, conn.send); + assert.ok(!stream.writable, "stream has not to be writable"); + stream.end(); +}); +test('CopyFromStream, start streaming after end. end with data. drain event', function(){ + var stream = new CopyFromStream(); + var conn = new ConnectionImitation() + assert.emits(stream, 'drain', function() {}, 'drain have to be emitted'); + stream.write(conn.updateHasToBeSend(buf1)); + stream.write(conn.updateHasToBeSend(buf2)); + stream.write(conn.updateHasToBeSend(buf3)); + stream.startStreamingToConnection(conn); + assert.ok(stream.writable, "stream has to be writable"); + stream.end(conn.updateHasToBeSend(buf4)); + stream.startStreamingToConnection(conn); + assert.equal(conn.hasToBeSend, conn.send); + assert.ok(!stream.writable, "stream has not to be writable"); + stream.end(); +}); diff --git a/node_modules/pg/test/unit/copystream/copyto-tests.js b/node_modules/pg/test/unit/copystream/copyto-tests.js new file mode 100644 index 0000000..7a6255b --- /dev/null +++ b/node_modules/pg/test/unit/copystream/copyto-tests.js @@ -0,0 +1,122 @@ +var helper = require(__dirname + '/../test-helper'); +var CopyToStream = require(__dirname + '/../../../lib/copystream').CopyToStream; +var DataCounter = function () { + this.sendBytes = 0; + this.recievedBytes = 0; +}; +DataCounter.prototype = { + send: function (buf) { + this.sendBytes += buf.length; + return buf; + }, + recieve: function (chunk) { + this.recievedBytes += chunk.length; + }, + assert: function () { + assert.equal(this.sendBytes, this.recievedBytes, "data bytes send and recieved has to match"); + } +}; +var buf1 = new Buffer("asdfasd"), + buf2 = new Buffer("q03r90arf0aospd;"), + buf3 = new Buffer(542), + buf4 = new Buffer("93jfemialfjkasjlfas"); +test('CopyToStream simple', function () { + var stream = new CopyToStream(), + dc = new DataCounter(); + assert.emits(stream, 'end', function () {}, ''); + stream.on('data', dc.recieve.bind(dc)); + stream.handleChunk(dc.send(buf1)); + stream.handleChunk(dc.send(buf2)); + stream.handleChunk(dc.send(buf3)); + stream.handleChunk(dc.send(buf4)); + dc.assert(); + stream.close(); +}); +test('CopyToStream pause/resume/close', function () { + var stream = new CopyToStream(), + dc = new DataCounter(); + stream.on('data', dc.recieve.bind(dc)); + assert.emits(stream, 'end', function () {}, 'stream has to emit end after closing'); + stream.pause(); + stream.handleChunk(dc.send(buf1)); + stream.handleChunk(dc.send(buf2)); + stream.handleChunk(dc.send(buf3)); + assert.equal(dc.recievedBytes, 0); + stream.resume(); + dc.assert(); + stream.handleChunk(dc.send(buf2)); + dc.assert(); + stream.handleChunk(dc.send(buf3)); + dc.assert(); + stream.pause(); + stream.handleChunk(dc.send(buf4)); + assert(dc.sendBytes - dc.recievedBytes, buf4.length, "stream has not emit, data while it is in paused state"); + stream.resume(); + dc.assert(); + stream.close(); +}); +test('CopyToStream error', function () { + var stream = new CopyToStream(), + dc = new DataCounter(); + stream.on('data', dc.recieve.bind(dc)); + assert.emits(stream, 'error', function () {}, 'stream has to emit error event, when error method called'); + stream.handleChunk(dc.send(buf1)); + stream.handleChunk(dc.send(buf2)); + stream.error(new Error('test error')); +}); +test('CopyToStream do not emit anything while paused', function () { + var stream = new CopyToStream(); + stream.on('data', function () { + assert.ok(false, "stream has not emit data when paused"); + }); + stream.on('end', function () { + assert.ok(false, "stream has not emit end when paused"); + }); + stream.on('error', function () { + assert.ok(false, "stream has not emit end when paused"); + }); + stream.pause(); + stream.handleChunk(buf2); + stream.close(); + stream.error(); +}); +test('CopyToStream emit data and error after resume', function () { + var stream = new CopyToStream(), + paused; + stream.on('data', function () { + assert.ok(!paused, "stream has not emit data when paused"); + }); + stream.on('end', function () { + assert.ok(!paused, "stream has not emit end when paused"); + }); + stream.on('error', function () { + assert.ok(!paused, "stream has not emit end when paused"); + }); + paused = true; + stream.pause(); + stream.handleChunk(buf2); + stream.error(); + paused = false; + stream.resume(); +}); +test('CopyToStream emit data and end after resume', function () { + var stream = new CopyToStream(), + paused; + stream.on('data', function () { + assert.ok(!paused, "stream has not emit data when paused"); + }); + stream.on('end', function () { + assert.ok(!paused, "stream has not emit end when paused"); + }); + stream.on('error', function () { + assert.ok(!paused, "stream has not emit end when paused"); + }); + paused = true; + stream.pause(); + stream.handleChunk(buf2); + stream.close(); + paused = false; + stream.resume(); +}); + + diff --git a/node_modules/pg/test/unit/pool/basic-tests.js b/node_modules/pg/test/unit/pool/basic-tests.js new file mode 100644 index 0000000..1e54672 --- /dev/null +++ b/node_modules/pg/test/unit/pool/basic-tests.js @@ -0,0 +1,214 @@ +var util = require('util'); +var EventEmitter = require('events').EventEmitter; + +var libDir = __dirname + '/../../../lib'; +var defaults = require(libDir + '/defaults'); +var pools = require(libDir + '/pool'); +var poolId = 0; + +require(__dirname + '/../../test-helper'); + +var FakeClient = function() { + EventEmitter.call(this); +} + +util.inherits(FakeClient, EventEmitter); + +FakeClient.prototype.connect = function(cb) { + process.nextTick(cb); +} + +FakeClient.prototype.end = function() { + this.endCalled = true; +} + +//Hangs the event loop until 'end' is called on client +var HangingClient = function(config) { + EventEmitter.call(this); + this.config = config; +} + +util.inherits(HangingClient, EventEmitter); + +HangingClient.prototype.connect = function(cb) { + this.intervalId = setInterval(function() { + console.log('hung client...'); + }, 1000); + process.nextTick(cb); +} + +HangingClient.prototype.end = function() { + clearInterval(this.intervalId); +} + +pools.Client = FakeClient; + +test('no pools exist', function() { + assert.empty(Object.keys(pools.all)); +}); + +test('pool creates pool on miss', function() { + var p = pools.getOrCreate(); + assert.ok(p); + assert.equal(Object.keys(pools.all).length, 1); + var p2 = pools.getOrCreate(); + assert.equal(p, p2); + assert.equal(Object.keys(pools.all).length, 1); + var p3 = pools.getOrCreate("postgres://postgres:password@localhost:5432/postgres"); + assert.notEqual(p, p3); + assert.equal(Object.keys(pools.all).length, 2); +}); + +test('pool follows defaults', function() { + var p = pools.getOrCreate(poolId++); + for(var i = 0; i < 100; i++) { + p.acquire(function(err, client) { + }); + } + assert.equal(p.getPoolSize(), defaults.poolSize); +}); + +test('pool#connect with 3 parameters', function() { + var p = pools.getOrCreate(poolId++); + var tid = setTimeout(function() { + throw new Error("Connection callback was never called"); + }, 100); + p.connect(function(err, client, done) { + clearTimeout(tid); + assert.ifError(err, null); + assert.ok(client); + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 1); + client.emit('drain'); + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 1); + done(); + assert.equal(p.availableObjectsCount(), 1); + assert.equal(p.getPoolSize(), 1); + p.destroyAllNow(); + }); +}); + +test('on client error, client is removed from pool', function() { + var p = pools.getOrCreate(poolId++); + p.connect(assert.success(function(client, done) { + assert.ok(client); + done(); + assert.equal(p.availableObjectsCount(), 1); + assert.equal(p.getPoolSize(), 1); + //error event fires on pool BEFORE pool.destroy is called with client + assert.emits(p, 'error', function(err) { + assert.equal(err.message, 'test error'); + assert.ok(!client.endCalled); + assert.equal(p.availableObjectsCount(), 1); + assert.equal(p.getPoolSize(), 1); + //after we're done in our callback, pool.destroy is called + process.nextTick(function() { + assert.ok(client.endCalled); + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 0); + p.destroyAllNow(); + }); + }); + client.emit('error', new Error('test error')); + })); +}); + +test('pool with connection error on connection', function() { + pools.Client = function() { + return { + connect: function(cb) { + process.nextTick(function() { + cb(new Error('Could not connect')); + }); + } + }; + } + test('two parameters', function() { + var p = pools.getOrCreate(poolId++); + p.connect(assert.calls(function(err, client) { + assert.ok(err); + assert.equal(client, null); + //client automatically removed + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 0); + })); + }); + test('three parameters', function() { + var p = pools.getOrCreate(poolId++); + var tid = setTimeout(function() { + assert.fail('Did not call connect callback'); + }, 100); + p.connect(function(err, client, done) { + clearTimeout(tid); + assert.ok(err); + assert.equal(client, null); + //done does nothing + done(new Error('OH NOOOO')); + done(); + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 0); + }); + }); +}); + +test('returnning an error to done()', function() { + var p = pools.getOrCreate(poolId++); + pools.Client = FakeClient; + p.connect(function(err, client, done) { + assert.equal(err, null); + assert(client); + done(new Error("BROKEN")); + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 0); + }); +}); + +test('fetching pool by object', function() { + var p = pools.getOrCreate({ + user: 'brian', + host: 'localhost', + password: 'password' + }); + var p2 = pools.getOrCreate({ + user: 'brian', + host: 'localhost', + password: 'password' + }); + assert.equal(p, p2); +}); + + +test('pool#connect client.poolCount', function() { + var p = pools.getOrCreate(poolId++); + var tid; + + setConnectTimeout = function() { + tid = setTimeout(function() { + throw new Error("Connection callback was never called"); + }, 100); + } + + setConnectTimeout(); + p.connect(function(err, client, done) { + clearTimeout(tid); + assert.equal(client.poolCount, 1, + 'after connect, poolCount should be 1'); + done(); + assert.equal(client.poolCount, 1, + 'after returning client to pool, poolCount should still be 1'); + setConnectTimeout(); + p.connect(function(err, client, done) { + clearTimeout(tid); + assert.equal(client.poolCount, 2, + 'after second connect, poolCount should be 2'); + done(); + setConnectTimeout(); + p.destroyAllNow(function() { + clearTimeout(tid); + assert.equal(client.poolCount, undefined, + 'after pool is destroyed, count should be undefined'); + }); + }) + }); +}); diff --git a/node_modules/pg/test/unit/pool/timeout-tests.js b/node_modules/pg/test/unit/pool/timeout-tests.js new file mode 100644 index 0000000..0fc96b2 --- /dev/null +++ b/node_modules/pg/test/unit/pool/timeout-tests.js @@ -0,0 +1,42 @@ +var util = require('util'); +var EventEmitter = require('events').EventEmitter; + +var libDir = __dirname + '/../../../lib'; +var defaults = require(libDir + '/defaults'); +var pools = require(libDir + '/pool'); +var poolId = 0; + +require(__dirname + '/../../test-helper'); + +var FakeClient = function() { + EventEmitter.call(this); +} + +util.inherits(FakeClient, EventEmitter); + +FakeClient.prototype.connect = function(cb) { + process.nextTick(cb); +} + +FakeClient.prototype.end = function() { + this.endCalled = true; +} + +defaults.poolIdleTimeout = 10; +defaults.reapIntervalMillis = 10; + +test('client times out from idle', function() { + pools.Client = FakeClient; + var p = pools.getOrCreate(poolId++); + p.connect(function(err, client, done) { + done(); + }); + process.nextTick(function() { + assert.equal(p.availableObjectsCount(), 1); + assert.equal(p.getPoolSize(), 1); + setTimeout(function() { + assert.equal(p.availableObjectsCount(), 0); + assert.equal(p.getPoolSize(), 0); + }, 50); + }); +}); diff --git a/node_modules/pg/test/unit/test-helper.js b/node_modules/pg/test/unit/test-helper.js new file mode 100644 index 0000000..3bcd21e --- /dev/null +++ b/node_modules/pg/test/unit/test-helper.js @@ -0,0 +1,30 @@ +var helper = require(__dirname+'/../test-helper'); +var EventEmitter = require('events').EventEmitter; +var Connection = require(__dirname + '/../../lib/connection'); +MemoryStream = function() { + EventEmitter.call(this); + this.packets = []; +}; + + +helper.sys.inherits(MemoryStream, EventEmitter); + +var p = MemoryStream.prototype; + +p.write = function(packet) { + this.packets.push(packet); +}; + +p.writable = true; + +createClient = function() { + var stream = new MemoryStream(); + stream.readyState = "open"; + var client = new Client({ + connection: new Connection({stream: stream}) + }); + client.connect(); + return client; +}; + +module.exports = helper; diff --git a/node_modules/pg/test/unit/utils-tests.js b/node_modules/pg/test/unit/utils-tests.js new file mode 100644 index 0000000..116dfdd --- /dev/null +++ b/node_modules/pg/test/unit/utils-tests.js @@ -0,0 +1,173 @@ +var helper = require(__dirname + '/test-helper'); +var utils = require(__dirname + "/../../lib/utils"); +var defaults = require(__dirname + "/../../lib").defaults; + + +test('ensure types is exported on root object', function() { + var pg = require('../../lib') + assert(pg.types) + assert(pg.types.getTypeParser) + assert(pg.types.setTypeParser) +}) + +//this tests the monkey patching +//to ensure comptability with older +//versions of node +test("EventEmitter.once", function(t) { + + //an event emitter + var stream = new MemoryStream(); + + var callCount = 0; + stream.once('single', function() { + callCount++; + }); + + stream.emit('single'); + stream.emit('single'); + assert.equal(callCount, 1); +}); + + +test('normalizing query configs', function() { + var config + var callback = function () {} + + config = utils.normalizeQueryConfig({text: 'TEXT'}) + assert.same(config, {text: 'TEXT'}) + + config = utils.normalizeQueryConfig({text: 'TEXT'}, [10]) + assert.deepEqual(config, {text: 'TEXT', values: [10]}) + + config = utils.normalizeQueryConfig({text: 'TEXT', values: [10]}) + assert.deepEqual(config, {text: 'TEXT', values: [10]}) + + config = utils.normalizeQueryConfig('TEXT', [10], callback) + assert.deepEqual(config, {text: 'TEXT', values: [10], callback: callback}) + + config = utils.normalizeQueryConfig({text: 'TEXT', values: [10]}, callback) + assert.deepEqual(config, {text: 'TEXT', values: [10], callback: callback}) +}) + +test('prepareValues: buffer prepared properly', function() { + var buf = new Buffer("quack"); + var out = utils.prepareValue(buf); + assert.strictEqual(buf, out); +}); + +test('prepareValues: date prepared properly', function() { + helper.setTimezoneOffset(-330); + + var date = new Date(2014, 1, 1, 11, 11, 1, 7); + var out = utils.prepareValue(date); + assert.strictEqual(out, "2014-02-01T11:11:01.007+05:30"); + + helper.resetTimezoneOffset(); +}); + +test('prepareValues: undefined prepared properly', function() { + var out = utils.prepareValue(void 0); + assert.strictEqual(out, null); +}); + +test('prepareValue: null prepared properly', function() { + var out = utils.prepareValue(null); + assert.strictEqual(out, null); +}); + +test('prepareValue: true prepared properly', function() { + var out = utils.prepareValue(true); + assert.strictEqual(out, 'true'); +}); + +test('prepareValue: false prepared properly', function() { + var out = utils.prepareValue(false); + assert.strictEqual(out, 'false'); +}); + +test('prepareValue: number prepared properly', function () { + var out = utils.prepareValue(3.042); + assert.strictEqual(out, '3.042'); +}); + +test('prepareValue: string prepared properly', function() { + var out = utils.prepareValue('big bad wolf'); + assert.strictEqual(out, 'big bad wolf'); +}); + +test('prepareValue: simple array prepared properly', function() { + var out = utils.prepareValue([1, null, 3, undefined, [5, 6, "squ,awk"]]); + assert.strictEqual(out, '{"1",NULL,"3",NULL,{"5","6","squ,awk"}}'); +}); + +test('prepareValue: complex array prepared properly', function() { + var out = utils.prepareValue([{ x: 42 }, { y: 84 }]); + assert.strictEqual(out, '{"{\\"x\\":42}","{\\"y\\":84}"}'); +}); + +test('prepareValue: date array prepared properly', function() { + helper.setTimezoneOffset(-330); + + var date = new Date(2014, 1, 1, 11, 11, 1, 7); + var out = utils.prepareValue([date]); + assert.strictEqual(out, '{"2014-02-01T11:11:01.007+05:30"}'); + + helper.resetTimezoneOffset(); +}); + +test('prepareValue: arbitrary objects prepared properly', function() { + var out = utils.prepareValue({ x: 42 }); + assert.strictEqual(out, '{"x":42}'); +}); + +test('prepareValue: objects with simple toPostgres prepared properly', function() { + var customType = { + toPostgres: function() { + return "zomgcustom!"; + } + }; + var out = utils.prepareValue(customType); + assert.strictEqual(out, "zomgcustom!"); +}); + +test('prepareValue: objects with complex toPostgres prepared properly', function() { + var buf = new Buffer("zomgcustom!"); + var customType = { + toPostgres: function() { + return [1, 2]; + } + }; + var out = utils.prepareValue(customType); + assert.strictEqual(out, '{"1","2"}'); +}); + +test('prepareValue: objects with toPostgres receive prepareValue', function() { + var customRange = { + lower: { toPostgres: function() { return 5; } }, + upper: { toPostgres: function() { return 10; } }, + toPostgres: function(prepare) { + return "[" + prepare(this.lower) + "," + prepare(this.upper) + "]"; + } + }; + var out = utils.prepareValue(customRange); + assert.strictEqual(out, "[5,10]"); +}); + +test('prepareValue: objects with circular toPostgres rejected', function() { + var buf = new Buffer("zomgcustom!"); + var customType = { + toPostgres: function() { + return { toPostgres: function () { return customType; } }; + } + }; + + //can't use `assert.throws` since we need to distinguish circular reference + //errors from call stack exceeded errors + try { + utils.prepareValue(customType); + } catch (e) { + assert.ok(e.message.match(/circular/), "Expected circular reference error but got " + e); + return; + } + throw new Error("Expected prepareValue to throw exception"); +}); diff --git a/node_modules/pg/wscript b/node_modules/pg/wscript new file mode 100644 index 0000000..2a340d5 --- /dev/null +++ b/node_modules/pg/wscript @@ -0,0 +1,32 @@ +import Options, Utils +from os import unlink, symlink, popen +from os.path import exists + +srcdir = '.' +blddir = 'build' +VERSION = '0.0.1' + +def set_options(opt): + opt.tool_options('compiler_cxx') + +def configure(conf): + conf.check_tool('compiler_cxx') + conf.check_tool('node_addon') + + pg_config = conf.find_program('pg_config', var='PG_CONFIG', mandatory=True) + pg_libdir = popen("%s --libdir" % pg_config).readline().strip() + conf.env.append_value("LIBPATH_PG", pg_libdir) + conf.env.append_value("LIB_PG", "pq") + pg_includedir = popen("%s --includedir" % pg_config).readline().strip() + conf.env.append_value("CPPPATH_PG", pg_includedir) + +def build(bld): + obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') + obj.cxxflags = ["-g", "-D_LARGEFILE_SOURCE", "-Wall"] + obj.target = 'binding' + obj.source = "./src/binding.cc" + obj.uselib = "PG" + +def test(test): + Utils.exec_command("node test/native/connection-tests.js") + Utils.exec_command("node test/native/evented-api-tests.js")