diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100755
index 0000000..b711605
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = { "extends": "airbnb-base" };
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index e17ea04..331ea9c
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,9 @@ a.out
build
node_modules
deps
-.idea
\ No newline at end of file
+.idea
+sandbox
+core
+oldtest
+.env
+.vscode/
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 7095b30..bfc39ca
--- a/README.md
+++ b/README.md
@@ -1,671 +1,888 @@
-node-odbc
----------
-
-An asynchronous/synchronous interface for node.js to unixODBC and its supported
-drivers.
-
-requirements
-------------
-
-* unixODBC binaries and development libraries for module compilation
- * on Ubuntu/Debian `sudo apt-get install unixodbc unixodbc-dev`
- * on RedHat/CentOS `sudo yum install unixODBC unixODBC-devel`
- * on OSX
- * using macports.org `sudo port unixODBC`
- * using brew `brew install unixODBC`
- * on IBM i `yum install unixODBC unixODBC-devel` (requires [yum](http://ibm.biz/ibmi-rpms))
-* odbc drivers for target database
-* properly configured odbc.ini and odbcinst.ini.
-
-install
--------
+# node-odbc
-After insuring that all requirements are installed you may install by one of the
-two following options:
+`node-odbc` is an ODBC database interface for Node.js. It allows connecting to any database management system if the system has been correctly configured, including installing of unixODBC and unixODBC-devel packages, installing an ODBC driver for your desired database, and configuring your odbc.ini and odbcinst.ini files. By using an ODBC, and it makes remote development a breeze through the use of ODBC data sources, and switching between DBMS systems is as easy as modifying your queries, as all your code can stay the same.
-### git
+---
-```bash
-git clone git://github.com/wankdanker/node-odbc.git
-cd node-odbc
-node-gyp configure build
-```
-### npm
+## Installation
+
+Instructions on how to set up your ODBC environment can be found in the SETUP.md. As an overview, three main steps must be done before `node-odbc` can interact with your database:
+
+* **Install unixODBC and unixODBC-devel:** Compilation of `node-odbc` on your system requires these packages to provide the correct headers.
+ * **Ubuntu/Debian**: `sudo apt-get install unixodbc unixodbc-dev`
+ * **RedHat/CentOS**: `sudo yum install unixODBC unixODBC-devel`
+ * **OSX**:
+ * **macports.org:** `sudo port unixODBC`
+ * **using brew:** `brew install unixODBC`
+ * **IBM i:** `yum install unixODBC unixODBC-devel` (requires [yum](http://ibm.biz/ibmi-rpms))
+* **Install ODBC drivers for target database:** Most database management system providers offer ODBC drivers for their product. See the website of your DBMS for more information.
+* **odbc.ini and odbcinst.ini**: These files define your DSNs (data source names) and ODBC drivers, respectively. They must be set up for ODBC functions to correctly interact with your database.
+
+When all these steps have been completed, install `node-odbc` into your Node.js project by using:
```bash
npm install odbc
```
+---
-quick example
--------------
+## Important Changes in 2.0
-```javascript
-var db = require('odbc')()
- , cn = process.env.ODBC_CONNECTION_STRING
- ;
-
-db.open(cn, function (err) {
- if (err) return console.log(err);
-
- db.query('select * from user where user_id = ?', [42], function (err, data) {
- if (err) console.log(err);
-
- console.log(data);
+`node-odbc` has recently been upgraded from its initial release. The following list highlights the major improvements and potential code-breaking changes.
- db.close(function () {
- console.log('done');
- });
- });
-});
+* **Promise support:** All asynchronous functions can now be used with native JavaScript Promises. If a callback function is not passed, the ODBC functions will return a native Promise. If a callback _is_ passed to the ODBC functions, then the old callback behavior will be used.
+
+* **Performance improvements:** The underlying ODBC function calls have been reworked to greatly improve performance. For ODBC afficianados, `node-odbc` used to retrieved results using SQLGetData, which works for small amounts of data but is slow for large datasets. `node-odbc` now uses SQLBindCol for binding result sets, which for large queries is orders of magnitude faster.
+
+* **Rewritten with N-API:** `node-odbc` was completely rewritten using node-addon-api, a C++ wrapper for N-API, which created an engine-agnostic and ABI-stable package. This means that if you upgrade your Node.js version, there is no need to recompile the package, it just works!
+
+* **API Changes:** The API has been changed and simplified. See the documentation below for a list of all the changes.
+
+---
+
+## API
+
+* [Connection](#Connection)
+ * [constructor (new Connection())](#constructor-\(new-connection\(connectionstring\)\))
+ * [.query()](#.query\(sql,-parameters?,-callback?\))
+ * [.callProcedure()](.callProcedure\(catalog,-schema,-name,-parameters?,-callback?\))
+ * [.createStatement()](.createStatement\(callback?\))
+ * [.tables()](#.tables\(catalog,-schema,-table,-type,-callback?\))
+ * [.columns()](#.columns\(catalog,-schema,-table,-column,-callback?\))
+ * [.beginTransaction()](#.beginTransaction\(callback?\))
+ * [.commit()](#.commit\(callback?\))
+ * [.rollback()](#.rollback\(callback?\))
+ * [.close()](#.close\(callback?\))
+* [Pool](#Pool)
+ * [constructor (new Pool())](#constructor-\(new-pool\(connectionstring\)\))
+ * [.init()](#.init\(callback?\))
+ * [.connect()](#.connect\(callback?\))
+ * [.query()](#.query\(sql,-parameters?,-callback?\))
+ * [.close()](#.close\(callback?\))
+* [Statement](#Statement)
+ * [.prepare()](#.prepare\(sql,-callback?\))
+ * [.bind()](#.bind\(parameters,-callback?\))
+ * [.execute()](#.execute\(callback?\))
+ * [.close()](#.close\(callback?\))
+
+### **Callbacks _or_ Promises**
+
+Every asynchronous function in the Node.js `node-odbc` package can be called with either a callback Function or a Promise. To use Promises, simply do not pass a callback function (in the API docs below, specified with a `callback?`). This will return a Promise object than can then be used with `.then` or the more modern `async/await` workflow. To use callbacks, simply pass a callback function. For each function explained in the documents below, both Callback and Promise examples are given.
+
+_All examples are shown using IBM i Db2 DSNs and queries. Because ODBC is DBMS-agnostic, examples will work as long as the query strings are modified for your particular DBMS._
+
+### **Result Array**
+
+All functions that return a result set do so in an array, where each row in the result set is an entry in the array. The format of data within the row can either be an array or an object, depending on the configuration option passed to the connection.
+
+The result array also contains several properties:
+* `count`: the number of rows affected by the statement or procedure. Returns the result from ODBC function SQLRowCount.
+* `columns`: a list of columns in the result set. This is returned in an array. Each column in the array has the following properties:
+ * `name`: The name of the column
+ * `dataType`: The data type of the column properties
+* `statement`: The statement used to return the result set
+* `parameters`: The parameters passed to the statement or procedure. For input/output and output parameters, this value will reflect the value updated from a procedure.
+* `return`: The return value from some procedures. For many DBMS, this will always be undefined.
+
+```
+[ { CUSNUM: 938472,
+ LSTNAM: 'Henning ',
+ INIT: 'G K',
+ STREET: '4859 Elm Ave ',
+ CITY: 'Dallas',
+ STATE: 'TX',
+ ZIPCOD: 75217,
+ CDTLMT: 5000,
+ CHGCOD: 3,
+ BALDUE: 37,
+ CDTDUE: 0 },
+ { CUSNUM: 839283,
+ LSTNAM: 'Jones ',
+ INIT: 'B D',
+ STREET: '21B NW 135 St',
+ CITY: 'Clay ',
+ STATE: 'NY',
+ ZIPCOD: 13041,
+ CDTLMT: 400,
+ CHGCOD: 1,
+ BALDUE: 100,
+ CDTDUE: 0 },
+ statement: 'SELECT * FROM QIWS.QCUSTCDT',
+ parameters: [],
+ return: undefined,
+ count: -1,
+ columns: [ { name: 'CUSNUM', dataType: 2 },
+ { name: 'LSTNAM', dataType: 1 },
+ { name: 'INIT', dataType: 1 },
+ { name: 'STREET', dataType: 1 },
+ { name: 'CITY', dataType: 1 },
+ { name: 'STATE', dataType: 1 },
+ { name: 'ZIPCOD', dataType: 2 },
+ { name: 'CDTLMT', dataType: 2 },
+ { name: 'CHGCOD', dataType: 2 },
+ { name: 'BALDUE', dataType: 2 },
+ { name: 'CDTDUE', dataType: 2 } ] ]
```
-api
+In this example, two rows are returned, with eleven columns each. The format of these columns is found on the `columns` property, with their names and dataType (which are integers mapped to SQL data types).
+
+With this result structure, users can iterate over the result set like any old array (in this case, `results.length` would return 2) while also accessing important information from the SQL call and result set.
+
+---
---
-### Database
+## **Connection**
+
+Connection has the following functions:
-The simple api is based on instances of the `Database` class. You may get an
-instance in one of the following ways:
+### `constructor (new Connection(connectionString))`
+
+Create a Connection object, which is opened (synchronously!)
```javascript
-require("odbc").open(connectionString, function (err, db){
- //db is already open now if err is falsy
-});
+const { Connection } = require('odbc');
+const connection = new Connection(connectionString);
```
-or by using the helper function:
+---
-```javascript
-var db = require("odbc")();
-```
+### `.query(sql, parameters?, callback?)`
-or by creating an instance with the constructor function:
+Run a query on the database. Can be passed an SQL string with parameter markers `?` and an array of parameters to bind to those markers.
-```javascript
-var Database = require("odbc").Database
- , db = new Database();
+```JavaScript
+const { Connection } = require('odbc');
+const connection = new Connection(connectionString);
+connection.query('SELECT * FROM QIWS.QCUSTCDT', (error, result) => {
+ if (error) { console.error(error) }
+ console.log(result);
+})
```
-#### .connected
+---
+
+### `.callProcedure(catalog, schema, name, parameters?, callback?)`
+
+Calls a database procedure, returning the results in a [result array](#result-array).
-Returns a Boolean of whether the database is currently connected.
+#### Parameters:
+* **catalog**: The name of the catalog where the procedure exists, or null to use the default catalog
+* **schema**: The name of the schema where the procedure exists, or null to use a default schema
+* **name**: The name of the procedure in the database
+* **{OPTIONAL} parameters**: An array of parameters to pass to the procedure. For input and input/output parameters, the JavaScript value passed in is expected to be of a type translatable to the SQL type the procedure expects. For output parameters, any JavaScript value can be passed in, and will be overwritten by the function. The number of parameters passed in must match the number of parameters expected by the procedure.
+* **{OPTIONAL} callback**: The function called when `.callProcedure` has finished execution. If no callback function is given, `.callProcedure` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * result: The result object from execution
+
+#### Examples:
+
+**Promises**
```javascript
-var db = require("odbc")();
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
-console.log( "Connected: " + db.connected );
+// can only use await keywork in an async function
+async function callProcedureExample() {
+ const statement = await connection.createStatement();
+ // now have a statement where sql can be prepared, bound, and executed
+}
+
+callProcedureExample();
```
-#### .open(connectionString, callback)
+**Callbacks**
-Open a connection to a database.
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(connectionString);
+connection.callProcedure(null, null, 'MY_PROC', [undefined], (error, result) => {
+ if (error) { console.error(error) } // handle
+ // result contains an array of results, and has a `parameters` property to access parameters returned by the procedure.
+ console.log(result);
+})
+```
-* **connectionString** - The ODBC connection string for your database
-* **callback** - `callback (err)`
+---
-```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+### `.createStatement(callback?)`
-db.open(cn, function (err) {
- if (err) {
- return console.log(err);
- }
+Returns a [Statement](#Statement) object from the connection.
- //we now have an open connection to the database
-});
-```
-#### .openSync(connectionString)
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.createStatement` has finished execution. If no callback function is given, `.createStatement` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * statement: The newly created Statement object
-Synchronously open a connection to a database.
+#### Examples:
-* **connectionString** - The ODBC connection string for your database
+**Promises**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
-try {
- var result = db.openSync(cn);
-}
-catch (e) {
- console.log(e.message);
+// can only use await keywork in an async function
+async function statementExample() {
+ const statement = await connection.createStatement();
+ // now have a statement where sql can be prepared, bound, and executed
}
-//we now have an open connection to the database
+statementExample();
```
-#### .query(sqlQuery [, bindingParameters], callback)
-
-Issue an asynchronous SQL query to the database which is currently open.
-
-* **sqlQuery** - The SQL query to be executed.
-* **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to
- any '?' characters in `sqlQuery`.
-* **callback** - `callback (err, rows, moreResultSets)`
+**Callbacks**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-db.open(cn, function (err) {
- if (err) {
- return console.log(err);
- }
-
- //we now have an open connection to the database
- //so lets get some data
- db.query("select top 10 * from customers", function (err, rows, moreResultSets) {
- if (err) {
- return console.log(err);
- }
-
- console.log(rows);
-
- //if moreResultSets is truthy, then this callback function will be called
- //again with the next set of rows.
- });
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// returns information about all tables in schema MY_SCHEMA
+connection.createStatement((error, statement) => {
+ if (error) { return; } // handle
+ // now have a statement where sql can be prepared, bound, and executed
});
```
-#### .querySync(sqlQuery [, bindingParameters])
+---
+
+### `.tables(catalog, schema, table, type, callback?)`
-Synchronously issue a SQL query to the database that is currently open.
+Returns information about the table specified in the parameters by calling the ODBC function [SQLTables](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqltables-function?view=sql-server-2017). Values passed to parameters will narrow the result set, while `null` will include all results of that level.
-* **sqlQuery** - The SQL query to be executed.
-* **bindingParameters** - _OPTIONAL_ - An array of values that will be bound to
- any '?' characters in `sqlQuery`.
+#### Parameters:
+* **catalog**: The name of the catalog, or null if not specified
+* **schema**: The name of the schema, or null if not specified
+* **table**: The name of the table, or null if not specified
+* **type**: The type of table that you want information about, or null if not specified
+* **{OPTIONAL} callback**: The function called when `.tables` has finished execution. If no callback function is given, `.tables` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * result: The result object from execution
+
+#### Examples:
+
+**Promises**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function getTables() {
+ // returns information about all tables in schema MY_SCHEMA
+ const result = await connection.tables(null, 'MY_SCHEMA', null, null);
+ console.log(result);
+}
-//blocks until the connection is opened.
-db.openSync(cn);
+getTables();
+```
+
+**Callbacks**
-//blocks until the query is completed and all data has been acquired
-var rows = db.querySync("select top 10 * from customers");
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
-console.log(rows);
+// returns information about all tables in schema MY_SCHEMA
+connection.columns(null, "MY_SCHEMA", null, null, (error, result) => {
+ if (error) { return; } // handle
+ console.log(result);
+});
```
-#### .close(callback)
+---
+
+### `.columns(catalog, schema, table, column, callback?)`
-Close the currently opened database.
+Returns information about the columns specified in the parameters by calling the ODBC function [SQLColumns](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumns-function?view=sql-server-2017). Values passed to parameters will narrow the result set, while `null` will include all results of that level.
-* **callback** - `callback (err)`
+#### Parameters:
+* **catalog**: The name of the catalog, or null if not specified
+* **schema**: The name of the schema, or null if not specified
+* **table**: The name of the table, or null if not specified
+* **column**: The name of the column that you want information about, or null if not specified
+* **{OPTIONAL} callback**: The function called when `.columns` has finished execution. If no callback function is given, `.columns` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * result: The result object from execution
+
+#### Examples:
+
+**Promises**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-db.open(cn, function (err) {
- if (err) {
- return console.log(err);
- }
-
- //we now have an open connection to the database
-
- db.close(function (err) {
- console.log("the database connection is now closed");
- });
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function getColumns() {
+ // returns information about all columns in table MY_SCEHMA.MY_TABLE
+ const result = await connection.columns(null, 'MY_SCHEMA', 'MY_TABLE', null);
+ console.log(result);
+}
+
+getColumns();
+```
+
+**Callbacks**
+
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// returns information about all columns in table MY_SCEHMA.MY_TABLE
+connection.columns(null, "MY_SCHEMA", "MY_TABLE", null, (error, result) => {
+ if (error) { return; } // handle
+ console.log(result);
});
```
-#### .closeSync()
+---
-Synchronously close the currently opened database.
+### `.beginTransaction(callback?)`
-```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+Begins a transaction on the connection. The transaction can be committed by calling `.commit` or rolled back by calling `.rollback`. **If a connection is closed with an open transaction, it will be rolled back.** Connection isolation level will affect the data that other transactions can view mid transaction.
-//Blocks until the connection is open
-db.openSync(cn);
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.beginTransaction` has finished execution. If no callback function is given, `.beginTransaction` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-//Blocks until the connection is closed
-db.closeSync();
-```
+#### Examples:
+
+**Promises**
-#### .prepare(sql, callback)
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
-Prepare a statement for execution.
+// can only use await keywork in an async function
+async function transaction() {
+ await connection.beginTransaction();
+ // transaction is now open
+}
-* **sql** - SQL string to prepare
-* **callback** - `callback (err, stmt)`
+transaction();
+```
-Returns a `Statement` object via the callback
+**Callbacks**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-//Blocks until the connection is open
-db.openSync(cn);
-
-db.prepare("insert into hits (col1, col2) VALUES (?, ?)", function (err, stmt) {
- if (err) {
- //could not prepare for some reason
- console.log(err);
- return db.closeSync();
- }
-
- //Bind and Execute the statment asynchronously
- stmt.execute(['something', 42], function (err, result) {
- result.closeSync();
-
- //Close the connection
- db.closeSync();
- });
-})
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// returns information about all columns in table MY_SCEHMA.MY_TABLE
+connection.beginTransaction((error) => {
+ if (error) { return; } // handle
+ // transaction is now open
+});
```
-#### .prepareSync(sql)
+---
-Synchronously prepare a statement for execution.
+### `.commit(callback?)`
-* **sql** - SQL string to prepare
+Commits an open transaction. If called on a connection that doesn't have an open transaction, will no-op.
-Returns a `Statement` object
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.commit` has finished execution. If no callback function is given, `.commit` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+#### Examples:
-//Blocks until the connection is open
-db.openSync(cn);
+**Promises**
-//Blocks while preparing the statement
-var stmt = db.prepareSync("insert into hits (col1, col2) VALUES (?, ?)")
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function commitTransaction() {
+ await connection.beginTransaction();
+ const insertResult = await connection.query('INSERT INTO MY_TABLE VALUES(1, \'Name\')');
+ await connection.commit();
+ // INSERT query has now been committed
+}
-//Bind and Execute the statment asynchronously
-stmt.execute(['something', 42], function (err, result) {
- result.closeSync();
+commitTransaction();
+```
+
+**Callbacks**
- //Close the connection
- db.closeSync();
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// returns information about all columns in table MY_SCEHMA.MY_TABLE
+connection.beginTransaction((error1) => {
+ if (error1) { return; } // handle
+ connection.query('INSERT INTO MY_TABLE VALUES(1, \'Name\')', (error2, result) => {
+ if (error2) { return; } // handle
+ connection.commit((error3) => {
+ // INSERT query has now been committed
+ })
+ })
});
```
-#### .beginTransaction(callback)
+---
-Begin a transaction
-* **callback** - `callback (err)`
+### `.rollback(callback?)`
-#### .beginTransactionSync()
+Rolls back an open transaction. If called on a connection that doesn't have an open transaction, will no-op.
-Synchronously begin a transaction
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.rollback` has finished execution. If no callback function is given, `.rollback` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-#### .commitTransaction(callback)
+#### Examples:
-Commit a transaction
+**Promises**
-* **callback** - `callback (err)`
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function rollbackTransaction() {
+ await connection.beginTransaction();
+ const insertResult = await connection.query('INSERT INTO MY_TABLE VALUES(1, \'Name\')');
+ await connection.rollback();
+ // INSERT query has now been rolled back
+}
+
+rollbackTransaction();
+```
+
+**Callbacks**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-//Blocks until the connection is open
-db.openSync(cn);
-
-db.beginTransaction(function (err) {
- if (err) {
- //could not begin a transaction for some reason.
- console.log(err);
- return db.closeSync();
- }
-
- var result = db.querySync("insert into customer (customerCode) values ('stevedave')");
-
- db.commitTransaction(function (err) {
- if (err) {
- //error during commit
- console.log(err);
- return db.closeSync();
- }
-
- console.log(db.querySync("select * from customer where customerCode = 'stevedave'"));
-
- //Close the connection
- db.closeSync();
- });
-})
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// returns information about all columns in table MY_SCEHMA.MY_TABLE
+connection.beginTransaction((error1) => {
+ if (error1) { return; } // handle
+ connection.query('INSERT INTO MY_TABLE VALUES(1, \'Name\')', (error2, result) => {
+ if (error2) { return; } // handle
+ connection.rollback((error3) => {
+ // INSERT query has now been rolled back
+ })
+ })
+});
```
-#### .commitTransactionSync()
+---
-Synchronously commit a transaction
+### `.close(callback?)`
-```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+Closes and open connection. Any transactions on the connection that have not been committed or rolledback will be rolledback.
-//Blocks until the connection is open
-db.openSync(cn);
+---
+---
-db.beginTransactionSync();
-var result = db.querySync("insert into customer (customerCode) values ('stevedave')");
+### **Pool**
-db.commitTransactionSync();
+### `constructor (new Pool(connectionString))`
-console.log(db.querySync("select * from customer where customerCode = 'stevedave'"));
+Creates a instance of the Pool class, storing information but not opening any connections.
-//Close the connection
-db.closeSync();
+```JavaScript
+const { Pool } = require('odbc');
+const pool = new Pool(connectionString);
```
-#### .rollbackTransaction(callback)
+**PLEASE NOTE:** The pool will not have any open connections until you call pool.init();
+
+### `.init(callback?)`
+
+Opens all the connections in the Pool asynchronously. Returns once all of the Connections have been opened.
-Rollback a transaction
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.init` has finished execution. If no callback function is given, `.init` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-* **callback** - `callback (err)`
+#### Examples:
+
+**Promises**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-//Blocks until the connection is open
-db.openSync(cn);
-
-db.beginTransaction(function (err) {
- if (err) {
- //could not begin a transaction for some reason.
- console.log(err);
- return db.closeSync();
- }
-
- var result = db.querySync("insert into customer (customerCode) values ('stevedave')");
-
- db.rollbackTransaction(function (err) {
- if (err) {
- //error during rollback
- console.log(err);
- return db.closeSync();
- }
-
- console.log(db.querySync("select * from customer where customerCode = 'stevedave'"));
-
- //Close the connection
- db.closeSync();
- });
-})
-```
+const { Pool } = require('odbc');
-#### .rollbackTransactionSync()
+// can only use await keywork in an async function
+async function connectExample() {
+ const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+ await pool.init();
+ // all Connections in the pool are now opened
+}
+
+connectExample();
+```
-Synchronously rollback a transaction
+**Callbacks**
```javascript
-var db = require("odbc")()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
+const { Pool } = require('odbc');
+const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+pool.init((error1) => {
+ if (error1) { return; } // handle
+ // all Connections in the pool are now opened
+});
+```
+
+### `.connect(callback?)`
-//Blocks until the connection is open
-db.openSync(cn);
+Returns a [Connection](#connection) object for you to use from the Pool. Doesn't actually open a connection, because they are already open in the pool when `.init` is called.
-db.beginTransactionSync();
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.connect` has finished execution. If no callback function is given, `.connect` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * connection: The [Connection](#connection) retrieved from the Pool.
-var result = db.querySync("insert into customer (customerCode) values ('stevedave')");
+#### Examples:
-db.rollbackTransactionSync();
+**Promises**
-console.log(db.querySync("select * from customer where customerCode = 'stevedave'"));
+```javascript
+const { Pool } = require('odbc');
+
+// can only use await keywork in an async function
+async function connectExample() {
+ const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+ await pool.init();
+ const connection = await pool.connect();
+ // now have a Connection to do work with
+}
-//Close the connection
-db.closeSync();
+connectExample();
+```
+
+**Callbacks**
+
+```javascript
+const { Pool } = require('odbc');
+const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+pool.init((error1) => {
+ if (error1) { return; } // handle
+ pool.connect((error2, connection) => {
+ if (error2) { return; } // handle
+ // now have a Connection to do work with
+ });
+});
```
-----------
+---
+
+### `.query(sql, parameters?, callback?)`
-### Pool
+Utility function to execute a query on any open connection in the pool. Will get a connection, fire of the query, return the results, and return the connection the the pool.
-The node-odbc `Pool` is a rudimentary connection pool which will attempt to have
-database connections ready and waiting for you when you call the `open` method.
+#### Parameters:
+* **sql**: An SQL string that will be executed. Can optionally be given parameter markers (`?`) and also given an array of values to bind to the parameters.
+* **{OPTIONAL} parameters**: An array of values to bind to the parameter markers, if there are any. The number of values in this array must match the number of parameter markers in the sql statement.
+* **{OPTIONAL} callback**: The function called when `.query` has finished execution. If no callback function is given, `.query` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * result: The [result array](#result-array) returned from the executed statement
-If you use a `Pool` instance, any connection that you close will cause another
-connection to be opened for that same connection string. That connection will
-be used the next time you call `Pool.open()` for the same connection string.
+#### Examples:
-This should probably be changed.
+**Promises**
-#### .open(connectionString, callback)
+```javascript
+const { Pool } = require('odbc');
+
+// can only use await keywork in an async function
+async function queryExample() {
+ const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+ await pool.init();
+ const result = await pool.query('SELECT * FROM MY_TABLE');
+ console.log(result);
+}
-Get a Database` instance which is already connected to `connectionString`
+queryExample();
+```
-* **connectionString** - The ODBC connection string for your database
-* **callback** - `callback (err, db)`
+**Callbacks**
```javascript
-var Pool = require("odbc").Pool
- , pool = new Pool()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-pool.open(cn, function (err, db) {
- if (err) {
- return console.log(err);
- }
-
- //db is now an open database connection and can be used like normal
- //if we run some queries with db.query(...) and then call db.close();
- //a connection to `cn` will be re-opened silently behind the scense
- //and will be ready the next time we do `pool.open(cn)`
+const { Pool } = require('odbc');
+const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+pool.init((error1) => {
+ if (error1) { return; } // handle
+ pool.query('SELECT * FROM MY_TABLE', (error2, result) => {
+ if (error2) { return; } // handle
+ console.log(result);
+ });
});
```
-#### .close(callback)
+---
+
+### `.close(callback?)`
+
+Closes the entire pool of currently unused connections. Will not close connections that are checked-out, but will discard the connections when they are closed with Connection's `.close` function. After calling close, must create a new Pool sprin up new Connections.
-Close all connections in the `Pool` instance
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.close` has finished execution. If no callback function is given, `.close` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-* **callback** - `callback (err)`
+#### Examples:
+
+**Promises**
```javascript
-var Pool = require("odbc").Pool
- , pool = new Pool()
- , cn = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname"
- ;
-
-pool.open(cn, function (err, db) {
- if (err) {
- return console.log(err);
- }
-
- //db is now an open database connection and can be used like normal
- //but all we will do now is close the whole pool
-
- pool.close(function () {
- console.log("all connections in the pool are closed");
- });
-});
+const { Pool } = require('odbc');
+
+// can only use await keywork in an async function
+async function closeExample() {
+ const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+ await pool.init();
+ await pool.close();
+ // pool is now closed
+}
+
+closeExample();
```
-example
--------
+**Callbacks**
```javascript
-var odbc = require("odbc")
- , util = require('util')
- , db = new odbc.Database()
- ;
-
-var connectionString = "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname";
-
-db.open(connectionString, function(err) {
- db.query("select * from table", function(err, rows, moreResultSets) {
- console.log(util.inspect(rows, null, 10));
-
- db.close(function() {
- console.log("Database connection closed");
- });
- });
+const { Pool } = require('odbc');
+const pool = new Pool(`${process.env.CONNECTION_STRING}`);
+pool.init((error1) => {
+ if (error1) { return; } // handle
+ pool.close((error2) => {
+ if (error2) { return; } // handle
+ // pool is now closed
+ });
});
```
-testing
--------
+---
+---
+
+## **Statement**
+
+A statement object is created from a Connection, and cannot be created _ad hoc_ with a constructor.
+
+Statements allow you to prepare a commonly used statement, then bind parameters to it multiple times, executing in between.
+
+---
-Tests can be run by executing `npm test` from within the root of the node-odbc
-directory. You can also run the tests by executing `node run-tests.js` from
-within the `/test` directory.
+### `.prepare(sql, callback?)`
-By default, the tests are setup to run against a sqlite3 database which is
-created at test time. This will require proper installation of the sqlite odbc
-driver. On Ubuntu: `sudo apt-get install libsqliteodbc`
+Prepares an SQL statement, with or without parameters (?) to bind to.
-build options
--------------
+#### Parameters:
+* **sql**: An SQL string that is prepared and can be executed with the .`execute` function.
+* **{OPTIONAL} callback**: The function called when `.prepare` has finished execution. If no callback function is given, `.prepare` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-### Debug
+#### Examples:
-If you would like to enable debugging messages to be displayed you can add the
-flag `DEBUG` to the defines section of the `binding.gyp` file and then execute
-`node-gyp rebuild`.
+**Promises**
```javascript
-
-'defines' : [
- "DEBUG"
-],
-
-```
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function prepareExample() {
+ const statement = await connection.createStatement();
+ await statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)');
+ // statement has been prepared, can bind and execute
+}
-### Dynodbc
+prepareExample();
+```
-You may also enable the ability to load a specific ODBC driver and bypass the
-ODBC driver management layer. A performance increase of ~5Kqps was seen using
-this method with the libsqlite3odbc driver. To do this, specify the `dynodbc`
-flag in the defines section of the `binding.gyp` file. You will also need to
-remove any library references in `binding.gyp`. Then execute `node-gyp
-rebuild`.
+**Callbacks**
```javascript
-
-'defines' : [
- "dynodbc"
-],
-'conditions' : [
- [ 'OS == "linux"', {
- 'libraries' : [
- //remove this: '-lodbc'
- ],
-
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+connection.createStatement((error1, statement) => {
+ if (error1) { return; } // handle
+ statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)' (error2) => {
+ if (error2) { return; } // handle
+ // statement has been prepared, can bind and execute
+ });
+});
```
-### Unicode
+---
+
+### `.bind(parameters, callback?)`
+
+Binds an array of values to the parameters on the prepared SQL statement. Cannot be called before `.prepare`.
+
+#### Parameters:
+* **sql**: An array of values to bind to the sql statement previously prepared. All parameters will be input parameters. The number of values passed in the array must match the number of parameters to bind to in the prepared statement.
+* **{OPTIONAL} callback**: The function called when `.bind` has finished execution. If no callback function is given, `.bind` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-By default, UNICODE suppport is enabled. This should provide the most accurate
-way to get Unicode strings submitted to your database. For best results, you
-may want to put your Unicode string into bound parameters.
+#### Examples:
-However, if you experience issues or you think that submitting UTF8 strings will
-work better or faster, you can remove the `UNICODE` define in `binding.gyp`
+**Promises**
```javascript
-
-'defines' : [
- "UNICODE"
-],
-
-```
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function bindExample() {
+ const statement = await connection.createStatement();
+ await statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)');
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ await statement.bind([1, 'Name']);
+ // statement has been prepared and values bound, can now execute
+}
-### timegm vs timelocal
+bindExample();
+```
-When converting a database time to a C time one may use `timegm` or `timelocal`. See
-`man timegm` for the details of these two functions. By default the node-odbc bindings
-use `timelocal`. If you would prefer for it to use `timegm` then specify the `TIMEGM`
-define in `binding.gyp`
+**Callbacks**
```javascript
-
-'defines' : [
- "TIMEGM"
-],
-
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+connection.createStatement((error1, statement) => {
+ if (error1) { return; } // handle
+ statement.prepare('INSERT INTO MY_TABLE VALUES(?, ?)' (error2) => {
+ if (error2) { return; } // handle
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ statement.bind([1, 'Name'], (error3) => {
+ if (error3) { return; } // handle
+ // statement has been prepared and values bound, can now execute
+ });
+ });
+});
```
-### Strict Column Naming
+---
+
+### `.execute(callback?)`
+
+Executes the prepared and optionally bound SQL statement.
+
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.execute` has finished execution. If no callback function is given, `.execute` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
+ * result: The [result array](#result-array) returned from the executed statement
+
+#### Examples:
+
+**Promises**
+
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function executeExample() {
+ const statement = await connection.createStatement();
+ await statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)');
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ await statement.bind([1, 'Name']);
+ const result = await statement.execute();
+ console.log(result);
+
+}
-When column names are retrieved from ODBC, you can request by SQL_DESC_NAME or
-SQL_DESC_LABEL. SQL_DESC_NAME is the exact column name or none if there is none
-defined. SQL_DESC_LABEL is the heading or column name or calculation.
-SQL_DESC_LABEL is used by default and seems to work well in most cases.
+executeExample();
+```
-If you want to use the exact column name via SQL_DESC_NAME, enable the `STRICT_COLUMN_NAMES`
-define in `binding.gyp`
+**Callbacks**
```javascript
-
-'defines' : [
- "STRICT_COLUMN_NAMES"
-],
-
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+connection.createStatement((error1, statement) => {
+ if (error1) { return; } // handle
+ statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)' (error2) => {
+ if (error2) { return; } // handle
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ statement.bind([1, 'Name'], (error3) => {
+ if (error3) { return; } // handle
+ statement.execute((error4, result) => {
+ if (error4) { return; } // handle
+ console.log(result);
+ })
+ });
+ });
+});
```
-tips
-----
-### Using node < v0.10 on Linux
+---
-Be aware that through node v0.9 the uv_queue_work function, which is used to
-execute the ODBC functions on a separate thread, uses libeio for its thread
-pool. This thread pool by default is limited to 4 threads.
+### `.close(callback?)`
-This means that if you have long running queries spread across multiple
-instances of odbc.Database() or using odbc.Pool(), you will only be able to
-have 4 concurrent queries.
+Closes the Statement, freeing the statement handle. Running functions on the statement after closing will result in an error.
-You can increase the thread pool size by using @developmentseed's [node-eio]
-(https://github.com/developmentseed/node-eio).
+#### Parameters:
+* **{OPTIONAL} callback**: The function called when `.close` has finished execution. If no callback function is given, `.close` will return a native JavaScript `Promise`. Callback signature is:
+ * error: The error that occured in execution, or `null` if no error
-#### install:
-```bash
-npm install eio
+#### Examples:
+
+**Promises**
+
+```javascript
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+// can only use await keywork in an async function
+async function executeExample() {
+ const statement = await connection.createStatement();
+ await statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)');
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ await statement.bind([1, 'Name']);
+ const result = await statement.execute();
+ console.log(result);
+ await statement.close();
+}
+
+executeExample();
```
-#### usage:
+**Callbacks**
+
```javascript
-var eio = require('eio');
-eio.setMinParallel(threadCount);
+const { Connection } = require('odbc');
+const connection = new Connection(`${process.env.CONNECTION_STRING}`);
+
+connection.createStatement((error1, statement) => {
+ if (error1) { return; } // handle
+ statement.prepare('INSTERT INTO MY_TABLE VALUES(?, ?)' (error2) => {
+ if (error2) { return; } // handle
+ // Assuming MY_TABLE has INTEGER and VARCHAR fields.
+ statement.bind([1, 'Name'], (error3) => {
+ if (error3) { return; } // handle
+ statement.execute((error4, result) => {
+ if (error4) { return; } // handle
+ console.log(result);
+ statement.close((error5) => {
+ if (error5) { return; } // handle
+ // statement closed successfully
+ })
+ })
+ });
+ });
+});
```
-### Using the FreeTDS ODBC driver
+---
+---
-* If you have column names longer than 30 characters, you should add
- "TDS_Version=7.0" to your connection string to retrive the full column name.
- * Example : "DRIVER={FreeTDS};SERVER=host;UID=user;PWD=password;DATABASE=dbname;TDS_Version=7.0"
-* If you got error "[unixODBC][FreeTDS][SQL Server]Unable to connect to data source"
- Try use SERVERNAME instead of SERVER
- * Example : "DRIVER={FreeTDS};SERVERNAME=host;UID=user;PWD=password;DATABASE=dbname"
-* Be sure that your odbcinst.ini has the proper threading configuration for your
- FreeTDS driver. If you choose the incorrect threading model it may cause
- the thread pool to be blocked by long running queries. This is what
- @wankdanker currently uses on Ubuntu 12.04:
+## Future improvements
-```
-[FreeTDS]
-Description = TDS driver (Sybase/MS SQL)
-Driver = libtdsodbc.so
-Setup = libtdsS.so
-CPTimeout = 120
-CPReuse =
-Threading = 0
-```
+Development of `node-odbc` is an ongoing endeavor, and there are many planned improvements for the package. If you would like to see something, simply add it to the Issues and we will respond!
-contributors
-------
+## contributors
+
+* Mark Irish (mirish@ibm.com)
* Dan VerWeire (dverweire@gmail.com)
* Lee Smith (notwink@gmail.com)
* Bruno Bigras
@@ -678,23 +895,12 @@ contributors
license
-------
-Copyright (c) 2013 Dan VerWeire
+Copyright (c) 2013 Dan VerWeire
Copyright (c) 2010 Lee Smith
-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.
+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 ofthe 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/binding.gyp b/binding.gyp
old mode 100644
new mode 100755
index 52f55f6..a2933d4
--- a/binding.gyp
+++ b/binding.gyp
@@ -1,20 +1,18 @@
{
'targets' : [
{
- 'target_name' : 'odbc_bindings',
+ 'target_name' : 'odbc',
'sources' : [
'src/odbc.cpp',
'src/odbc_connection.cpp',
'src/odbc_statement.cpp',
- 'src/odbc_result.cpp',
'src/dynodbc.cpp'
],
- 'cflags' : ['-Wall', '-Wextra', '-Wno-unused-parameter'],
+ 'cflags' : ['-Wall', '-Wextra', '-Wno-unused-parameter', '-DNAPI_DISABLE_CPP_EXCEPTIONS'],
'include_dirs': [
- " {
+ this.odbcConnection.query(sql, parameters, (error, result) => {
+ if (error) {
+ reject(error);
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ return this.odbcConnection.query(sql, parameters, callback);
+ }
+
+ /**
+ *
+ * @param {string} name
+ * @param {Array} parameters
+ * @param {function} [cb]
+ */
+ callProcedure(catalog, schema, name, params = undefined, cb = undefined) {
+ // name
+ // name, params
+ // name, cb
+ // name, params, cb
+
+ let callback = cb;
+ let parameters = params;
+
+ if (typeof callback === 'undefined') {
+ if (typeof parameters === 'function') {
+ callback = parameters;
+ parameters = null;
+ } else if (typeof parameters === 'undefined') {
+ parameters = null;
+ }
+ }
+
+ if (typeof name !== 'string'
+ || (parameters !== null && !Array.isArray(parameters))
+ || (typeof callback !== 'function' && typeof callback !== 'undefined')) {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.query({string}, {array}[optional], {function}[optional]).');
+ }
+
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.callProcedure(catalog, schema, name, parameters, (error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcConnection.callProcedure(catalog, schema, name, parameters, callback);
+ }
+
+ // TODO: Write the documentation
+ /**
+ *
+ * @param {*} callback
+ */
+ createStatement(callback = undefined) {
+ // type-checking
+ if (typeof callback !== 'function' && typeof callback !== 'undefined') {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.createStatement({function}[optional]).');
+ }
+
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.createStatement((error, odbcStatement) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ const statement = new Statement(odbcStatement);
+ resolve(statement);
+ }
+ });
+ });
+ }
+
+
+ // ...or callback
+ return this.odbcConnection.createStatement((error, odbcStatement) => {
+ if (error) { return callback(error, null); }
+
+ const statement = new Statement(odbcStatement);
+ return callback(null, statement);
+ });
+ }
+
+ /** TODO:
+ * Get the value of the passed attribute from the connection. Asynchronous, can be used either
+ * with a callback function or a Promise.
+ * @param {string} attribute - The title of the book.
+ * @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
+ */
+ close(callback = undefined) {
+ // type-checking
+ if (typeof callback !== 'function' && typeof callback !== 'undefined') {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to connection.close({function}[optional]).');
+ }
+
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.close((error) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcConnection.close(callback);
+ }
+
+ // TODO: Documentation
+ columns(catalog, schema, table, type, callback = undefined) {
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.columns(catalog, schema, table, type, (error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ this.odbcConnection.columns(catalog, schema, table, type, callback);
+ return undefined;
+ }
+
+ // TODO: Documentation
+ tables(catalog, schema, table, type, callback = undefined) {
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.tables(catalog, schema, table, type, (error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ this.odbcConnection.tables(catalog, schema, table, type, callback);
+ return undefined;
+ }
+
+ /**
+ * Begins a transaction, turning off auto-commit. Transaction is ended with commit() or
+ * rollback().
+ * @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
+ */
+ beginTransaction(callback = undefined) {
+ // promise...
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.beginTransaction((error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcConnection.beginTransaction(callback);
+ }
+
+ /**
+ * Asynchronously ends the transaction with a commit.
+ * @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
+ */
+ commit(callback = undefined) {
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.commit((error) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ return this.odbcConnection.commit(callback);
+ }
+
+ /**
+ * Asynchronously ends the transaction with a rollback.
+ * @param {function} [callback] - Callback function. If not passed, a Promise will be returned.
+ */
+ rollback(callback = undefined) {
+ if (callback === undefined) {
+ return new Promise((resolve, reject) => {
+ this.odbcConnection.rollback((error) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ return this.odbcConnection.rollback(callback);
+ }
+}
+
+module.exports.Connection = Connection;
diff --git a/lib/Pool.js b/lib/Pool.js
new file mode 100755
index 0000000..26c13c9
--- /dev/null
+++ b/lib/Pool.js
@@ -0,0 +1,229 @@
+const odbc = require('../build/Release/odbc.node');
+const { Connection } = require('./Connection');
+
+// TODO: Have to add options:
+// increase Pool size or no
+// max pool size?
+// starting pool size
+// increment size
+class Pool {
+ constructor(connectionString, initialSize = 10) {
+ this.isInitialized = false;
+ this.freeConnections = [];
+
+ if (typeof connectionString === 'object') {
+ const configObject = connectionString;
+ this.connectionString = configObject.connectionString;
+ if (Object.prototype.hasOwnProperty.call(configObject, 'connectionString')) {
+ this.connectionString = configObject.connectionString;
+ } else {
+ throw new Error('Pool configuration object must contain "connectionString" key');
+ }
+
+ this.initialSize = configObject.initialSize || 10;
+ this.incrementSize = configObject.incrementSize || configObject.initialSize || 10;
+ this.connectionTimeout = configObject.connectionTimeout || 1000;
+ this.idleTimeout = configObject.idleTimeout || 1000;
+ this.maxSize = configObject.maxSize || 64;
+ this.shrink = configObject.shrink || true;
+ } else {
+ this.connectionString = connectionString;
+ this.initialSize = initialSize;
+ this.incrementSize = initialSize;
+ this.maxSize = 100;
+ this.shrink = true;
+ }
+ }
+
+ async init(callback = undefined) {
+ if (!this.isInitialized) {
+ // promise...
+ if (typeof callback === 'undefined') {
+ return new Promise(async (resolve, reject) => {
+ try {
+ await this.increasePoolSize(this.initialSize);
+ this.isInitialized = true;
+ resolve(null);
+ } catch (error) {
+ reject(new Error(error));
+ }
+ });
+ }
+
+ // ...or callback
+ try {
+ await this.increasePoolSize(this.initialSize);
+ this.isInitialized = true;
+ } catch (error) {
+ return callback(error);
+ }
+ return callback(null);
+ }
+
+ console.log('.init() was called, but the Pool was already initialized.');
+ return undefined;
+ }
+
+ // TODO: Documentation
+ // TODO: Does this need to be async?
+ // returns a open connection, ready to use.
+ // should overwrite the 'close' function of the connection, and rename it is 'nativeClose', so
+ // that that close can still be called.
+ async connect(callback = undefined) {
+ if (this.freeConnections.length < this.poolSize) {
+ await this.increasePoolSize(this.incrementSize);
+ }
+
+ const connection = this.freeConnections.pop();
+
+ connection.nativeClose = connection.close;
+
+ connection.close = async (closeCallback = undefined) => {
+ if (typeof closeCallback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ connection.close((error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+
+ if (this.shrink === false || this.freeConnections.length < this.initialSize) {
+ this.increasePoolSize(1);
+ }
+ });
+ }
+
+ connection.nativeClose(closeCallback);
+
+ if (this.shrink === false || this.freeConnections.length < this.initialSize) {
+ try {
+ this.increasePoolSize(1);
+ } catch (error1) {
+ console.error(error1);
+ }
+ }
+
+ return undefined;
+ };
+
+ // promise...
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ if (connection == null) {
+ reject();
+ } else {
+ resolve(connection);
+ }
+ });
+ }
+
+ // ...or callback
+ return callback(null, connection);
+ }
+
+ query(sql, params, cb) {
+ // determine the parameters passed
+ let callback = cb;
+ let parameters = params;
+
+ if (typeof callback === 'undefined') {
+ if (typeof parameters === 'function') {
+ callback = parameters;
+ parameters = null;
+ } else if (typeof parameters === 'undefined') {
+ parameters = null;
+ } // else parameters = params, check type in this.ODBCconnection.query
+ }
+
+ const connection = this.freeConnections.pop();
+
+ // promise...
+ if (typeof callback !== 'function') {
+ return new Promise((resolve, reject) => {
+ connection.query(sql, parameters, (error, result) => {
+ // after running, close the connection whether error or not
+ connection.close((closeError) => {
+ this.freeConnections.push(new Connection(this.connectionString));
+ if (closeError) {
+ // TODO:: throw and error
+ }
+ });
+
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return connection.query(sql, parameters, (error, result) => {
+ // after running, close the connection whether error or not
+ connection.close((closeError) => {
+ this.freeConnections.push(new Connection(this.connectionString));
+ if (closeError) {
+ // TODO:: throw an error
+ }
+ });
+ callback(error, result);
+ });
+ }
+
+ // These are PRIVATE (although can't be made private in ES6... So don't use these)!
+
+ // odbc.connect runs on an AsyncWorker, so this is truly non-blocking
+ async increasePoolSize(count) {
+ return new Promise((resolve, reject) => {
+ Pool.generateConnections(this.connectionString, count, (error, connections) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ this.freeConnections = [...this.freeConnections, ...connections];
+ resolve();
+ }
+ });
+ });
+ }
+
+ static async generateConnections(connectionString, count, callback) {
+ // promise...
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ odbc.connect(connectionString, count, (error, odbcConnections) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ const connections = Pool.wrapConnections(odbcConnections);
+ resolve(connections);
+ }
+ });
+ });
+ }
+
+ // or callback
+ return odbc.connect(connectionString, count, (error, odbcConnections) => {
+ if (error) {
+ callback(error, null);
+ return undefined;
+ }
+
+ const connections = Pool.wrapConnections(odbcConnections);
+ callback(null, connections);
+ return undefined;
+ });
+ }
+
+ static wrapConnections(odbcConnections) {
+ const connectionsArray = [];
+ odbcConnections.forEach((odbcConnection) => {
+ connectionsArray.push(new Connection(odbcConnection));
+ });
+ return connectionsArray;
+ }
+}
+
+module.exports.Pool = Pool;
diff --git a/lib/Statement.js b/lib/Statement.js
new file mode 100755
index 0000000..6278fa9
--- /dev/null
+++ b/lib/Statement.js
@@ -0,0 +1,116 @@
+class Statement {
+ constructor(odbcStatement) {
+ this.odbcStatement = odbcStatement;
+ }
+
+ /**
+ * Prepare an SQL statement template to which parameters can be bound and the statement then executed.
+ * @param {string} sql - The SQL statement template to prepare, with or without unspecified parameters.
+ * @param {function} [callback] - The callback function that returns the result. If omitted, uses a Promise.
+ * @returns {undefined|Promise}
+ */
+ prepare(sql, callback = undefined) {
+ if (typeof sql !== 'string'
+ || (typeof callback !== 'function' && typeof callback !== 'undefined')) {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to statement.prepare({string}, {function}[optional]).');
+ }
+
+ // promise...
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ this.odbcStatement.prepare(sql, (error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcStatement.prepare(sql, callback);
+ }
+
+ /**
+ * Bind parameters on the previously prepared SQL statement template.
+ * @param {*[]} parameters - The parameters to bind to the previously prepared SQL statement.
+ * @param {function} [callback] - The callback function that returns the result. If omitted, uses a Promise.
+ * @return {undefined|Promise}
+ */
+ bind(parameters, callback = undefined) {
+ if (!Array.isArray(parameters)
+ || (typeof callback !== 'function' && typeof callback !== 'undefined')) {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to statement.bind({array}, {function}[optional]).');
+ }
+
+ // promise...
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ this.odbcStatement.bind(parameters, (error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcStatement.bind(parameters, callback);
+ }
+
+ /**
+ * Executes the prepared SQL statement template with the bound parameters, returning the result.
+ * @param {function} [callback] - The callback function that returns the result. If omitted, uses a Promise.
+ */
+ execute(callback = undefined) {
+ if (typeof callback !== 'function' && typeof callback !== 'undefined') {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to statement.execute({function}[optional]).');
+ }
+
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ this.odbcStatement.execute((error, result) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve(result);
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcStatement.execute(callback);
+ }
+
+ /**
+ * Closes the statement, deleting the prepared statement and freeing the handle, making further
+ * calls on the object invalid.
+ * @param {function} [callback] - The callback function that returns the result. If omitted, uses a Promise.
+ */
+ close(callback = undefined) {
+ if (typeof callback !== 'function' && typeof callback !== 'undefined') {
+ throw new TypeError('[node-odbc]: Incorrect function signature for call to statement.close({function}[optional]).');
+ }
+
+ if (typeof callback === 'undefined') {
+ return new Promise((resolve, reject) => {
+ this.odbcStatement.close((error) => {
+ if (error) {
+ reject(new Error(error));
+ } else {
+ resolve();
+ }
+ });
+ });
+ }
+
+ // ...or callback
+ return this.odbcStatement.close(callback);
+ }
+}
+
+module.exports.Statement = Statement;
diff --git a/lib/odbc.d.ts b/lib/odbc.d.ts
deleted file mode 100644
index a3c3a28..0000000
--- a/lib/odbc.d.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-declare function odbc(options?: odbc.DatabaseOptions): odbc.Database;
-
-declare namespace odbc {
- export const SQL_CLOSE: number;
- export const SQL_DROP: number;
- export const SQL_UNBIND: number;
- export const SQL_RESET_PARAMS: number;
- export const SQL_DESTROY: number;
- export const FETCH_ARRAY: number;
- export const FETCH_OBJECT: number;
-
- export let debug: boolean;
-
- export interface ConnctionInfo {
- [key: string]: string;
- }
-
- export interface DatabaseOptions {
- connectTimeout?: number;
- loginTimeout?: number;
- }
-
- export interface DescribeOptions {
- database: string;
- schema?: string;
- table?: string;
- type?: string;
- column?: string;
- }
-
- export interface SimpleQueue {
- push(fn: Function): void;
- next(): any;
- maybeNext(): any;
- }
-
- export interface ODBCTable {
- TABLE_CAT: string;
- TABLE_SCHEM: string;
- TABLE_NAME: string;
- TABLE_TYPE: string;
- REMARKS: string;
- }
-
- export interface ODBCColumn {
- TABLE_CAT: string;
- TABLE_SCHEM: string;
- TABLE_NAME: string;
- COLUMN_NAME: string;
- DATA_TYPE: number;
- TYPE_NAME: string;
- COLUMN_SIZE: number;
- BUFFER_LENGTH: number;
- DECIMAL_DIGITS: number;
- NUM_PREC_RADIX: number;
- NULLABLE: number;
- REMARKS: string;
- COLUMN_DEF: string;
- SQL_DATA_TYPE: number;
- SQL_DATETIME_SUB: number;
- CHAR_OCTET_LENGTH: number;
- ORDINAL_POSITION: number;
- IS_NULLABLE: string;
- }
-
- export interface ODBCConnection {
- connected: boolean;
- connectTimeout: number;
- loginTimeout: number;
- open(connctionString: string | ConnctionInfo, cb: (err: any, result: any) => void): void;
- openSync(connctionString: string | ConnctionInfo): void;
- close(cb: (err: any) => void): void;
- closeSync(): void;
- createStatement(cb: (err: any, stmt: ODBCStatement) => void): void;
- createStatementSync(): ODBCStatement;
- query(sql: string, cb: (err: any, rows: ResultRow[], moreResultSets: any) => void): void;
- query(sql: string, bindingParameters: any[], cb: (err: any, rows: ResultRow[], moreResultSets: any) => void): void;
- querySync(sql: string, bindingParameters?: any[]): ResultRow[];
- beginTransaction(cb: (err: any) => void): void;
- beginTransactionSync(): void;
- endTransaction(rollback: boolean, cb: (err: any) => void): void;
- endTransactionSync(rollback: boolean): void;
- tables(catalog: string | null, schema: string | null, table: string | null, type: string | null, cb: (err: any, result: ODBCResult) => void): void;
- columns(catalog: string | null, schema: string | null, table: string | null, column: string | null, cb: (err: any, result: ODBCResult) => void): void;
- }
-
- export interface ResultRow {
- [key: string]: any;
- }
-
- export interface ODBCResult {
- fetchMode: number;
- fetchAll(cb: (err: any, data: ResultRow[]) => void): void;
- fetchAllSync(): ResultRow[];
- fetch(cb: (err: any, data: ResultRow) => void): void;
- fetchSync(): ResultRow;
- closeSync(): void;
- moreResultsSync(): any;
- getColumnNamesSync(): string[];
- }
-
- export interface ODBCStatement {
- queue: SimpleQueue;
- execute(cb: (err: any, result: ODBCResult) => void): void;
- execute(bindingParameters: any[], cb: (err: any, result: ODBCResult) => void): void;
- executeSync(bindingParameters?: any[]): ODBCResult;
- executeDirect(sql: string, cb: (err: any, result: ODBCResult) => void): void;
- executeDirect(sql: string, bindingParameters: any[], cb: (err: any, result: ODBCResult) => void): void;
- executeDirectSync(sql: string, bindingParameters?: any[]): ODBCResult;
- executeNonQuery(cb: (err: any, result: number) => void): void;
- executeNonQuery(bindingParameters: any[], cb: (err: any, result: number) => void): void;
- executeNonQuerySync(bindingParameters?: any[]): number;
- prepare(sql: string, cb: (err: any) => void): void;
- prepareSync(sql: string): void;
- bind(bindingParameters: any[], cb: (err: any) => void): void;
- bindSync(bindingParameters: any[]): void;
- closeSync(): void;
- }
-
- export class Database {
- constructor(options?: DatabaseOptions);
- conn: ODBCConnection;
- queue: SimpleQueue;
- connected: boolean;
- connectTimeout: number;
- loginTimeout: number;
- SQL_CLOSE: number;
- SQL_DROP: number;
- SQL_UNBIND: number;
- SQL_RESET_PARAMS: number;
- SQL_DESTROY: number;
- FETCH_ARRAY: number;
- FETCH_OBJECT: number;
- open(connctionString: string | ConnctionInfo, cb: (err: any, result: any) => void): void;
- openSync(connctionString: string | ConnctionInfo): void;
- close(cb: (err: any) => void): void;
- closeSync(): void;
- query(sql: string, cb: (err: any, rows: ResultRow[], moreResultSets: any) => void): void;
- query(sql: string, bindingParameters: any[], cb: (err: any, rows: ResultRow[], moreResultSets: any) => void): void;
- querySync(sql: string, bindingParameters?: any[]): ResultRow[];
- queryResult(sql: string, cb: (err: any, result: ODBCResult) => void): void;
- queryResult(sql: string, bindingParameters: any[], cb: (err: any, result: ODBCResult) => void): void;
- queryResultSync(sql: string, bindingParameters?: any[]): ODBCResult;
- prepare(sql: string, cb: (err: any, statement: ODBCStatement) => void): void;
- prepareSync(sql: string): ODBCStatement;
- beginTransaction(cb: (err: any) => void): void;
- beginTransactionSync(): void;
- endTransaction(rollback: boolean, cb: (err: any) => void): void;
- endTransactionSync(rollback: boolean): void;
- commitTransaction(cb: (err: any) => void): void;
- commitTransactionSync(): void;
- rollbackTransaction(cb: (err: any) => void): void;
- rollbackTransactionSync(): void;
- tables(catalog: string | null, schema: string | null, table: string | null, type: string | null, cb: (err: any, result: ODBCTable[]) => void): void;
- columns(catalog: string | null, schema: string | null, table: string | null, column: string | null, cb: (err: any, result: ODBCColumn[]) => void): void;
- describe(options: DescribeOptions, cb: (err: any, result: (ODBCTable & ODBCColumn)[]) => void): void;
- }
-
- export class Pool {
- constructor(options?: DatabaseOptions);
- open(connctionString: string, cb: (err: any, db: Database) => void): void;
- close(cb: (err: any) => void): void;
- }
-
- export function open(connctionString: string | ConnctionInfo, cb: (err: any, result: any) => void): void;
-}
-
-export = odbc;
diff --git a/lib/odbc.js b/lib/odbc.js
old mode 100644
new mode 100755
index 23a2de4..6caa8c0
--- a/lib/odbc.js
+++ b/lib/odbc.js
@@ -1,820 +1,9 @@
-/*
- Copyright (c) 2013, Dan VerWeire
- Copyright (c) 2010, Lee Smith
-
- 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.
-*/
-
-var odbc = require("bindings")("odbc_bindings")
- , SimpleQueue = require("./simple-queue")
- , util = require("util")
- ;
-
-module.exports = function (options) {
- return new Database(options);
-}
-
-module.exports.debug = false;
-
-module.exports.Database = Database;
-module.exports.ODBC = odbc.ODBC;
-module.exports.ODBCConnection = odbc.ODBCConnection;
-module.exports.ODBCStatement = odbc.ODBCStatement;
-module.exports.ODBCResult = odbc.ODBCResult;
-module.exports.loadODBCLibrary = odbc.loadODBCLibrary;
-
-module.exports.open = function (connectionString, options, cb) {
- var db;
-
- if (typeof options === 'function') {
- cb = options;
- options = null;
- }
-
- db = new Database(options);
-
- db.open(connectionString, function (err) {
- cb(err, db);
- });
-}
-
-function Database(options) {
- var self = this;
-
- options = options || {};
-
- if (odbc.loadODBCLibrary) {
- if (!options.library && !module.exports.library) {
- throw new Error("You must specify a library when complied with dynodbc, "
- + "otherwise this jams will segfault.");
- }
-
- if (!odbc.loadODBCLibrary(options.library || module.exports.library)) {
- throw new Error("Could not load library. You may need to specify full "
- + "path.");
- }
- }
-
- self.odbc = (options.odbc) ? options.odbc : new odbc.ODBC();
- self.odbc.domain = process.domain;
- self.queue = new SimpleQueue();
- self.fetchMode = options.fetchMode || null;
- self.connected = false;
- self.connectTimeout = (options.hasOwnProperty('connectTimeout'))
- ? options.connectTimeout
- : null
- ;
- self.loginTimeout = (options.hasOwnProperty('loginTimeout'))
- ? options.loginTimeout
- : null
- ;
-}
-
-//Expose constants
-Object.keys(odbc.ODBC).forEach(function (key) {
- if (typeof odbc.ODBC[key] !== "function") {
- //On the database prototype
- Database.prototype[key] = odbc.ODBC[key];
-
- //On the exports
- module.exports[key] = odbc.ODBC[key];
- }
-});
-
-Database.prototype.open = function (connectionString, cb) {
- var self = this;
-
- if (typeof(connectionString) == "object") {
- var obj = connectionString;
- connectionString = "";
-
- Object.keys(obj).forEach(function (key) {
- connectionString += key + "=" + obj[key] + ";";
- });
- }
-
- self.odbc.createConnection(function (err, conn) {
- if (err) return cb(err);
-
- self.conn = conn;
- self.conn.domain = process.domain;
-
- if (self.connectTimeout || self.connectTimeout === 0) {
- self.conn.connectTimeout = self.connectTimeout;
- }
-
- if (self.loginTimeout || self.loginTimeout === 0) {
- self.conn.loginTimeout = self.loginTimeout;
- }
-
- self.conn.open(connectionString, function (err, result) {
- if (err) return cb(err);
-
- self.connected = true;
-
- return cb(err, result);
- });
- });
-};
-
-Database.prototype.openSync = function (connectionString) {
- var self = this;
-
- self.conn = self.odbc.createConnectionSync();
-
- if (self.connectTimeout || self.connectTimeout === 0) {
- self.conn.connectTimeout = self.connectTimeout;
- }
-
- if (self.loginTimeout || self.loginTimeout === 0) {
- self.conn.loginTimeout = self.loginTimeout;
- }
-
- if (typeof(connectionString) == "object") {
- var obj = connectionString;
- connectionString = "";
-
- Object.keys(obj).forEach(function (key) {
- connectionString += key + "=" + obj[key] + ";";
- });
- }
-
- var result = self.conn.openSync(connectionString);
-
- if (result) {
- self.connected = true;
- }
-
- return result;
-}
-
-Database.prototype.close = function (cb) {
- var self = this;
-
- self.queue.push(function (next) {
- //check to see if conn still exists (it's deleted when closed)
- if (!self.conn) {
- if (cb) cb(null);
- return next();
- }
-
- self.conn.close(function (err) {
- self.connected = false;
- delete self.conn;
-
- if (cb) cb(err);
- return next();
- });
- });
-};
-
-Database.prototype.closeSync = function () {
- var self = this;
-
- var result = self.conn.closeSync();
-
- self.connected = false;
- delete self.conn;
-
- return result
-}
-
-Database.prototype.query = function (sql, params, cb) {
- var self = this;
-
- if (typeof(params) == 'function') {
- cb = params;
- params = null;
- }
-
- if (!self.connected) {
- return cb({ message : "Connection not open."}, [], false);
- }
-
- self.queue.push(function (next) {
- function cbQuery (initialErr, result) {
- fetchMore();
-
- function fetchMore() {
- if (self.fetchMode) {
- result.fetchMode = self.fetchMode;
- }
-
- result.fetchAll(function (err, data) {
- var moreResults, moreResultsError = null;
-
- try {
- moreResults = result.moreResultsSync();
- }
- catch (e) {
- moreResultsError = e;
- //force to check for more results
- moreResults = true;
- }
-
- //close the result before calling back
- //if there are not more result sets
- if (!moreResults) {
- result.closeSync();
- }
-
- cb(err || initialErr, data, moreResults);
- initialErr = null;
-
- while (moreResultsError) {
- try {
- moreResults = result.moreResultsSync();
- cb(moreResultsError, [], moreResults); // No errors left - still need to report the
- // last one, though
- moreResultsError = null;
- } catch (e) {
- cb(moreResultsError, [], moreResults);
- moreResultsError = e;
- }
- }
-
- if (moreResults) {
- return fetchMore();
- }
- else {
- return next();
- }
- });
- }
- }
-
- if (params) {
- self.conn.query(sql, params, cbQuery);
- }
- else {
- self.conn.query(sql, cbQuery);
- }
- });
-};
-
-Database.prototype.queryResult = function (sql, params, cb) {
- var self = this;
-
- if (typeof(params) == 'function') {
- cb = params;
- params = null;
- }
-
- if (!self.connected) {
- return cb({ message : "Connection not open."}, null);
- }
-
- self.queue.push(function (next) {
- //ODBCConnection.query() is the fastest-path querying mechanism.
- if (params) {
- self.conn.query(sql, params, cbQuery);
- }
- else {
- self.conn.query(sql, cbQuery);
- }
-
- function cbQuery (err, result) {
- if (err) {
- cb(err, null);
-
- return next();
- }
-
- if (self.fetchMode) {
- result.fetchMode = self.fetchMode;
- }
-
- cb(err, result);
-
- return next();
- }
- });
-};
-
-Database.prototype.queryResultSync = function (sql, params) {
- var self = this, result;
-
- if (!self.connected) {
- throw ({ message : "Connection not open."});
- }
-
- if (params) {
- result = self.conn.querySync(sql, params);
- }
- else {
- result = self.conn.querySync(sql);
- }
-
- if (self.fetchMode) {
- result.fetchMode = self.fetchMode;
- }
-
- return result;
-};
-
-Database.prototype.querySync = function (sql, params) {
- var self = this, result;
-
- if (!self.connected) {
- throw ({ message : "Connection not open."});
- }
-
- if (params) {
- result = self.conn.querySync(sql, params);
- }
- else {
- result = self.conn.querySync(sql);
- }
-
- if (self.fetchMode) {
- result.fetchMode = self.fetchMode;
- }
-
- var data = result.fetchAllSync();
-
- result.closeSync();
-
- return data;
-};
-
-Database.prototype.beginTransaction = function (cb) {
- var self = this;
-
- self.conn.beginTransaction(cb);
-
- return self;
-};
-
-Database.prototype.endTransaction = function (rollback, cb) {
- var self = this;
-
- self.conn.endTransaction(rollback, cb);
-
- return self;
-};
-
-Database.prototype.commitTransaction = function (cb) {
- var self = this;
-
- self.conn.endTransaction(false, cb); //don't rollback
-
- return self;
-};
-
-Database.prototype.rollbackTransaction = function (cb) {
- var self = this;
-
- self.conn.endTransaction(true, cb); //rollback
-
- return self;
-};
-
-Database.prototype.beginTransactionSync = function () {
- var self = this;
-
- self.conn.beginTransactionSync();
-
- return self;
-};
-
-Database.prototype.endTransactionSync = function (rollback) {
- var self = this;
-
- self.conn.endTransactionSync(rollback);
-
- return self;
-};
-
-Database.prototype.commitTransactionSync = function () {
- var self = this;
-
- self.conn.endTransactionSync(false); //don't rollback
-
- return self;
-};
-
-Database.prototype.rollbackTransactionSync = function () {
- var self = this;
-
- self.conn.endTransactionSync(true); //rollback
-
- return self;
-};
-
-Database.prototype.columns = function(catalog, schema, table, column, callback) {
- var self = this;
- if (!self.queue) self.queue = [];
-
- callback = callback || arguments[arguments.length - 1];
-
- self.queue.push(function (next) {
- self.conn.columns(catalog, schema, table, column, function (err, result) {
- if (err) return callback(err, [], false);
-
- result.fetchAll(function (err, data) {
- result.closeSync();
-
- callback(err, data);
-
- return next();
- });
- });
- });
-};
-
-Database.prototype.tables = function(catalog, schema, table, type, callback) {
- var self = this;
- if (!self.queue) self.queue = [];
-
- callback = callback || arguments[arguments.length - 1];
-
- self.queue.push(function (next) {
- self.conn.tables(catalog, schema, table, type, function (err, result) {
- if (err) return callback(err, [], false);
-
- result.fetchAll(function (err, data) {
- result.closeSync();
-
- callback(err, data);
-
- return next();
- });
- });
- });
-};
-
-Database.prototype.describe = function(obj, callback) {
- var self = this;
-
- if (typeof(callback) != "function") {
- throw({
- error : "[node-odbc] Missing Arguments",
- message : "You must specify a callback function in order for the describe method to work."
- });
-
- return false;
- }
-
- if (typeof(obj) != "object") {
- callback({
- error : "[node-odbc] Missing Arguments",
- message : "You must pass an object as argument 0 if you want anything productive to happen in the describe method."
- }, []);
-
- return false;
- }
-
- if (!obj.database) {
- callback({
- error : "[node-odbc] Missing Arguments",
- message : "The object you passed did not contain a database property. This is required for the describe method to work."
- }, []);
-
- return false;
- }
-
- //set some defaults if they weren't passed
- obj.schema = obj.schema || "%";
- obj.type = obj.type || "table";
-
- if (obj.table && obj.column) {
- //get the column details
- self.columns(obj.database, obj.schema, obj.table, obj.column, callback);
- }
- else if (obj.table) {
- //get the columns in the table
- self.columns(obj.database, obj.schema, obj.table, "%", callback);
- }
- else {
- //get the tables in the database
- self.tables(obj.database, obj.schema, null, obj.type || "table", callback);
- }
-};
-
-Database.prototype.prepare = function (sql, cb) {
- var self = this;
-
- self.conn.createStatement(function (err, stmt) {
- if (err) return cb(err);
-
- stmt.queue = new SimpleQueue();
-
- stmt.prepare(sql, function (err) {
- if (err) return cb(err);
-
- return cb(null, stmt);
- });
- });
-}
-
-Database.prototype.prepareSync = function (sql, cb) {
- var self = this;
-
- var stmt = self.conn.createStatementSync();
-
- stmt.queue = new SimpleQueue();
-
- stmt.prepareSync(sql);
-
- return stmt;
-}
-
-//Proxy all of the asynchronous functions so that they are queued
-odbc.ODBCStatement.prototype._execute = odbc.ODBCStatement.prototype.execute;
-odbc.ODBCStatement.prototype._executeDirect = odbc.ODBCStatement.prototype.executeDirect;
-odbc.ODBCStatement.prototype._executeNonQuery = odbc.ODBCStatement.prototype.executeNonQuery;
-odbc.ODBCStatement.prototype._prepare = odbc.ODBCStatement.prototype.prepare;
-odbc.ODBCStatement.prototype._bind = odbc.ODBCStatement.prototype.bind;
-
-odbc.ODBCStatement.prototype.execute = function (params, cb) {
- var self = this;
-
- self.queue = self.queue || new SimpleQueue();
-
- if (!cb) {
- cb = params;
- params = null;
- }
-
- self.queue.push(function (next) {
- //If params were passed to this function, then bind them and
- //then execute.
- if (params) {
- self._bind(params, function (err) {
- if (err) {
- return cb(err);
- }
-
- self._execute(function (err, result) {
- cb(err, result);
-
- return next();
- });
- });
- }
- //Otherwise execute and pop the next bind call
- else {
- self._execute(function (err, result) {
- cb(err, result);
-
- //NOTE: We only execute the next queued bind call after
- // we have called execute() or executeNonQuery(). This ensures
- // that we don't call a bind() a bunch of times without ever
- // actually executing that bind. Not
- self.bindQueue && self.bindQueue.next();
-
- return next();
- });
- }
- });
-};
-
-odbc.ODBCStatement.prototype.executeDirect = function (sql, cb) {
- var self = this;
-
- self.queue = self.queue || new SimpleQueue();
-
- self.queue.push(function (next) {
- self._executeDirect(sql, function (err, result) {
- cb(err, result);
-
- return next();
- });
- });
-};
-
-odbc.ODBCStatement.prototype.executeNonQuery = function (params, cb) {
- var self = this;
-
- self.queue = self.queue || new SimpleQueue();
-
- if (!cb) {
- cb = params;
- params = null;
- }
-
- self.queue.push(function (next) {
- //If params were passed to this function, then bind them and
- //then executeNonQuery.
- if (params) {
- self._bind(params, function (err) {
- if (err) {
- return cb(err);
- }
-
- self._executeNonQuery(function (err, result) {
- cb(err, result);
-
- return next();
- });
- });
- }
- //Otherwise executeNonQuery and pop the next bind call
- else {
- self._executeNonQuery(function (err, result) {
- cb(err, result);
-
- //NOTE: We only execute the next queued bind call after
- // we have called execute() or executeNonQuery(). This ensures
- // that we don't call a bind() a bunch of times without ever
- // actually executing that bind. Not
- self.bindQueue && self.bindQueue.next();
-
- return next();
- });
- }
- });
-};
-
-odbc.ODBCStatement.prototype.prepare = function (sql, cb) {
- var self = this;
-
- self.queue = self.queue || new SimpleQueue();
-
- self.queue.push(function (next) {
- self._prepare(sql, function (err) {
- cb(err);
-
- return next();
- });
- });
-};
-
-odbc.ODBCStatement.prototype.bind = function (ary, cb) {
- var self = this;
-
- self.bindQueue = self.bindQueue || new SimpleQueue();
-
- self.bindQueue.push(function () {
- self._bind(ary, function (err) {
- cb(err);
-
- //NOTE: we do not call next() here because
- //we want to pop the next bind call only
- //after the next execute call
- });
- });
-};
-
-
-//proxy the ODBCResult fetch function so that it is queued
-odbc.ODBCResult.prototype._fetch = odbc.ODBCResult.prototype.fetch;
-
-odbc.ODBCResult.prototype.fetch = function (cb) {
- var self = this;
-
- self.queue = self.queue || new SimpleQueue();
-
- self.queue.push(function (next) {
- self._fetch(function (err, data) {
- if (cb) cb(err, data);
-
- return next();
- });
- });
-};
-
-module.exports.Pool = Pool;
-
-Pool.count = 0;
-
-function Pool (options) {
- var self = this;
- self.index = Pool.count++;
- self.availablePool = {};
- self.usedPool = {};
- self.odbc = new odbc.ODBC();
- self.options = options || {}
- self.options.odbc = self.odbc;
-}
-
-Pool.prototype.open = function (connectionString, callback) {
- var self = this
- , db
- ;
-
- //check to see if we already have a connection for this connection string
- if (self.availablePool[connectionString] && self.availablePool[connectionString].length) {
- db = self.availablePool[connectionString].shift()
- self.usedPool[connectionString].push(db)
-
- callback(null, db);
- }
- else {
- db = new Database(self.options);
- db.realClose = db.close;
-
- db.close = function (cb) {
- //call back early, we can do the rest of this stuff after the client thinks
- //that the connection is closed.
- cb(null);
-
-
- //close the connection for real
- //this will kill any temp tables or anything that might be a security issue.
- db.realClose(function () {
- //remove this db from the usedPool
- self.usedPool[connectionString].splice(self.usedPool[connectionString].indexOf(db), 1);
-
- //re-open the connection using the connection string
- db.open(connectionString, function (error) {
- if (error) {
- console.error(error);
- return;
- }
-
- //add this clean connection to the connection pool
- self.availablePool[connectionString] = self.availablePool[connectionString] || [];
- self.availablePool[connectionString].push(db);
- exports.debug && console.dir(self);
- });
- });
- };
-
- db.open(connectionString, function (error) {
- exports.debug && console.log("odbc.js : pool[%s] : pool.db.open callback()", self.index);
-
- self.usedPool[connectionString] = self.usedPool[connectionString] || [];
- self.usedPool[connectionString].push(db);
-
- callback(error, db);
- });
- }
-};
-
-Pool.prototype.close = function (callback) {
- var self = this
- , required = 0
- , received = 0
- , connections
- , key
- , x
- ;
-
- exports.debug && console.log("odbc.js : pool[%s] : pool.close()", self.index);
- //we set a timeout because a previous db.close() may
- //have caused the a behind the scenes db.open() to prepare
- //a new connection
- setTimeout(function () {
- //merge the available pool and the usedPool
- var pools = {};
-
- for (key in self.availablePool) {
- pools[key] = (pools[key] || []).concat(self.availablePool[key]);
- }
-
- for (key in self.usedPool) {
- pools[key] = (pools[key] || []).concat(self.usedPool[key]);
- }
-
- exports.debug && console.log("odbc.js : pool[%s] : pool.close() - setTimeout() callback", self.index);
- exports.debug && console.dir(pools);
-
- if (Object.keys(pools).length == 0) {
- return callback();
- }
-
- for (key in pools) {
- connections = pools[key];
- required += connections.length;
-
- exports.debug && console.log("odbc.js : pool[%s] : pool.close() - processing pools %s - connections: %s", self.index, key, connections.length);
-
- for (x = 0 ; x < connections.length; x ++) {
- (function (x) {
- //call the realClose method to avoid
- //automatically re-opening the connection
- exports.debug && console.log("odbc.js : pool[%s] : pool.close() - calling realClose() for connection #%s", self.index, x);
-
- connections[x].realClose(function () {
- exports.debug && console.log("odbc.js : pool[%s] : pool.close() - realClose() callback for connection #%s", self.index, x);
- received += 1;
-
- if (received === required) {
- callback();
-
- //prevent mem leaks
- self = null;
- connections = null;
- required = null;
- received = null;
- key = null;
-
- return;
- }
- });
- })(x);
- }
- }
- }, 2000);
+const { Connection } = require('./Connection');
+const { Pool } = require('./Pool');
+const legacy = require('./legacy/legacy'); // v1.x behavior
+
+module.exports = {
+ Pool,
+ Connection,
+ legacy,
};
diff --git a/lib/simple-queue.js b/lib/simple-queue.js
deleted file mode 100644
index a6f784e..0000000
--- a/lib/simple-queue.js
+++ /dev/null
@@ -1,40 +0,0 @@
-module.exports = SimpleQueue;
-
-function SimpleQueue() {
- var self = this;
-
- self.fifo = [];
- self.executing = false;
-}
-
-SimpleQueue.prototype.push = function (fn) {
- var self = this;
-
- self.fifo.push(fn);
-
- self.maybeNext();
-};
-
-SimpleQueue.prototype.maybeNext = function () {
- var self = this;
-
- if (!self.executing) {
- self.next();
- }
-};
-
-SimpleQueue.prototype.next = function () {
- var self = this;
-
- if (self.fifo.length) {
- var fn = self.fifo.shift();
-
- self.executing = true;
-
- fn(function () {
- self.executing = false;
-
- self.maybeNext();
- });
- }
-};
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
old mode 100644
new mode 100755
index 17417d4..7b37094
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,18 +1,1467 @@
{
"name": "odbc",
- "version": "1.4.5",
+ "version": "2.0.0-beta.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
- "bindings": {
+ "@babel/code-frame": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
+ "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
+ "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "acorn": {
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz",
+ "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
+ "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "6.8.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz",
+ "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
+ "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "circular-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.15.1",
+ "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dotenv": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
+ "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
+ "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "is-callable": "^1.1.4",
+ "is-regex": "^1.0.4",
+ "object-keys": "^1.0.12"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+ "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "eslint": {
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.13.0.tgz",
+ "integrity": "sha512-nqD5WQMisciZC5EHZowejLKQjWGuFS5c70fxqSKlnDME+oz9zmE8KTlX+lHSg+/5wsC/kf9Q9eMkC8qS3oM2fg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.5.3",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^2.1.0",
+ "eslint-scope": "^4.0.0",
+ "eslint-utils": "^1.3.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^5.0.0",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.7.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.1.0",
+ "js-yaml": "^3.12.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.5",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^5.5.1",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "^2.0.1",
+ "table": "^5.0.2",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-airbnb-base": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz",
+ "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==",
+ "dev": true,
+ "requires": {
+ "eslint-restricted-globals": "^0.1.1",
+ "object.assign": "^4.1.0",
+ "object.entries": "^1.0.4"
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "resolve": "^1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz",
+ "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.8",
+ "pkg-dir": "^2.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz",
+ "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==",
+ "dev": true,
+ "requires": {
+ "contains-path": "^0.1.0",
+ "debug": "^2.6.9",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.3.2",
+ "eslint-module-utils": "^2.3.0",
+ "has": "^1.0.3",
+ "lodash": "^4.17.11",
+ "minimatch": "^3.0.4",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.9.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-restricted-globals": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
+ "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
+ "dev": true
+ },
+ "eslint-scope": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
+ "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
+ "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
+ "dev": true
+ },
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz",
+ "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.2",
+ "acorn-jsx": "^5.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "external-editor": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
+ "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+ "dev": true,
+ "requires": {
+ "circular-json": "^0.3.1",
+ "graceful-fs": "^4.1.2",
+ "rimraf": "~2.6.2",
+ "write": "^0.2.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "globals": {
+ "version": "11.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz",
+ "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==",
+ "dev": true
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+ "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+ "dev": true
+ },
+ "he": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
+ "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz",
+ "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.11",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz",
+ "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz",
+ "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.0.0"
+ }
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
+ "dev": true
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
+ "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz",
+ "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "mocha": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+ "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "1.3.1",
+ "commander": "2.15.1",
+ "debug": "3.1.0",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.2",
+ "growl": "1.10.5",
+ "he": "1.1.1",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "supports-color": "5.4.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "node-addon-api": {
"version": "1.3.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
- "integrity": "sha1-s0b27PapX1qBXFg5/HzbIlAvHtc="
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.3.0.tgz",
+ "integrity": "sha512-yagD4yKkZLeG4EJkh+8Qbqhqw+owDQ/PowqD8vb5a5rfNXS/PRC21SGyIbUVXfPp/jl4s+jyeZj6xnLnDPLazw=="
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-keys": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+ "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+ "dev": true
+ },
+ "object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ }
+ },
+ "object.entries": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz",
+ "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.12.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz",
+ "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.0.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.1.0"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ }
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+ "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rxjs": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+ "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
+ "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "table": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.2.2.tgz",
+ "integrity": "sha512-f8mJmuu9beQEDkKHLzOv4VxVYlU68NpdzjbGPl69i4Hx0sTopJuNxuzJd17iV2h24dAfa93u794OnDA5jqXvfQ==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.6.1",
+ "lodash": "^4.17.11",
+ "slice-ansi": "^2.0.0",
+ "string-width": "^2.1.1"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "tslib": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+ "dev": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
},
- "nan": {
- "version": "2.10.0",
- "resolved": "https://npm.paviliongift.com/nan/-/nan-2.10.0.tgz",
- "integrity": "sha1-ltDNYQ69WNS03pzAxoKM2pnHVI8="
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
}
}
}
diff --git a/package.json b/package.json
old mode 100644
new mode 100755
index b001b25..fc7e231
--- a/package.json
+++ b/package.json
@@ -1,10 +1,9 @@
{
"name": "odbc",
"description": "unixodbc bindings for node",
- "version": "1.4.5",
- "main": "lib/odbc.js",
- "types": "./lib/odbc.d.ts",
+ "version": "2.0.0-beta.0",
"homepage": "http://github.com/wankdanker/node-odbc/",
+ "main": "./lib/odbc.js",
"repository": {
"type": "git",
"url": "git://github.com/wankdanker/node-odbc.git"
@@ -13,6 +12,10 @@
"url": "https://github.com/w1nk/node-odbc/issues"
},
"contributors": [
+ {
+ "name": "Mark Irish",
+ "email": "mirish@ibm.com"
+ },
{
"name": "Dan VerWeire",
"email": "dverweire@gmail.com"
@@ -30,11 +33,17 @@
},
"scripts": {
"install": "node-gyp configure build",
- "test": "cd test && node run-tests.js"
+ "test": "mocha --slow 5000 --timeout 10000"
},
"dependencies": {
- "bindings": "^1.3.0",
- "nan": "^2.10.0"
+ "dotenv": "^6.2.0",
+ "node-addon-api": "^1.3.0"
},
- "gypfile": true
+ "gypfile": true,
+ "devDependencies": {
+ "eslint": "^5.13.0",
+ "eslint-config-airbnb-base": "^13.1.0",
+ "eslint-plugin-import": "^2.16.0",
+ "mocha": "^5.2.0"
+ }
}
diff --git a/src/dynodbc.cpp b/src/dynodbc.cpp
old mode 100644
new mode 100755
diff --git a/src/dynodbc.h b/src/dynodbc.h
old mode 100644
new mode 100755
diff --git a/src/odbc.cpp b/src/odbc.cpp
old mode 100644
new mode 100755
index 114b1f4..1dcead1
--- a/src/odbc.cpp
+++ b/src/odbc.cpp
@@ -15,797 +15,984 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include
-#include
-#include
-#include
+#include
#include
-#include
+#include
#include "odbc.h"
#include "odbc_connection.h"
-#include "odbc_result.h"
#include "odbc_statement.h"
#ifdef dynodbc
#include "dynodbc.h"
#endif
-#ifdef _WIN32
-#include "strptime.h"
-#endif
-
-using namespace v8;
-using namespace node;
-
uv_mutex_t ODBC::g_odbcMutex;
+SQLHENV ODBC::hEnv;
-Nan::Persistent ODBC::constructor;
+Napi::Value ODBC::Init(Napi::Env env, Napi::Object exports) {
-void ODBC::Init(v8::Handle