├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README-EN.md ├── README.md ├── _config.yml ├── appveyor.yml ├── examples ├── execute.bat ├── execute.js ├── execute.ts ├── node-adodb.ldb ├── node-adodb.mdb ├── query.bat ├── query.js ├── query.ts ├── scalar.bat ├── scalar.js ├── scalar.ts ├── schema.bat ├── schema.js ├── schema.ts ├── transaction.bat ├── transaction.js └── transaction.ts ├── index.d.ts ├── index.js ├── lib ├── adodb.js ├── adodb │ ├── adodb.js │ ├── json.js │ ├── main.js │ └── utils.js ├── engine.js ├── proxy.js └── spawn.js ├── package.json ├── rollup.js ├── test └── test.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | # Use 4 spaces for the Python files 13 | [*.py] 14 | indent_size = 4 15 | max_line_length = 80 16 | 17 | # The JSON files contain newlines inconsistently 18 | [*.json] 19 | insert_final_newline = ignore 20 | 21 | # Minified JavaScript files shouldn't be changed 22 | [*.min.js] 23 | indent_style = ignore 24 | insert_final_newline = ignore 25 | 26 | # Makefiles always use tabs for indentation 27 | [Makefile] 28 | indent_style = tab 29 | 30 | # Batch files use tabs for indentation 31 | [*.bat] 32 | indent_style = tab 33 | 34 | [*.md] 35 | trim_trailing_whitespace = false 36 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://paypal.me/nuintun 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # vscode 61 | .vscode 62 | 63 | # npm lock file 64 | package-lock.json 65 | 66 | # tests mdb file 67 | /test/node-adodb.mdb 68 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # git ignore configuration 61 | .gitignore 62 | 63 | # npm ignore configuration 64 | .npmignore 65 | 66 | # travis configuration 67 | .travis.yml 68 | 69 | # appveyor configuration 70 | appveyor.yml 71 | 72 | # tests directories 73 | tests 74 | test 75 | 76 | # npm configuration 77 | .npmrc 78 | 79 | # vscode configuration 80 | .vscode 81 | 82 | # npm lock file 83 | package-lock.json 84 | 85 | # yarn lock file 86 | yarn.lock 87 | 88 | # adodb src file 89 | /lib/adodb/ 90 | 91 | # rollup configuration 92 | /rollup.js 93 | 94 | # GitHub Pages 95 | _config.yml 96 | 97 | # github 98 | .github/ 99 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 128, 3 | "singleQuote": true, 4 | "overrides": [ 5 | { 6 | "files": ["*.css", "*.less", "*.scss"], 7 | "options": { 8 | "singleQuote": false 9 | } 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 5.0.3 / 2020/03/02 2 | 3 | - Fixed error catch 4 | 5 | # 5.0.3 / 2019/09/12 6 | 7 | - Bump deps 8 | 9 | # 5.0.1 / 2019/01/07 10 | 11 | - Bump dev deps 12 | 13 | # 5.0.0 / 2018/11/20 14 | 15 | - Add `ADODB.PATH` configrue 16 | - [Breaking] Drop `node < 6.0.0` support 17 | 18 | # 4.2.2 / 2018/05/06 19 | 20 | - Update typescript declaration file 21 | 22 | # 4.2.1 / 2018/05/06 23 | 24 | - Update json.js 25 | - Add message for SQL contain reserved words and symbols [#55](https://github.com/nuintun/node-adodb/issues/55) 26 | 27 | # 4.2.0 / 2018/05/02 28 | 29 | - Support x64 30 | - Fixed spawn error catch bugs 31 | 32 | # 4.1.0 / 2018/04/28 33 | 34 | - Refactoring code 35 | - Add node 10 test 36 | 37 | # 4.0.9 / 2018/03/31 38 | 39 | - Clean code and file 40 | - Update configure file 41 | - Refactoring proxy.js, ensure the integrity of data reception 42 | 43 | # 4.0.8 / 2018/03/14 44 | 45 | - Clean `package.json` 46 | - Use `require.resolve` instead `__dirname` 47 | 48 | # 4.0.7 / 2018/01/15 49 | 50 | - Update deps 51 | 52 | # 4.0.6 / 2017/12/28 53 | 54 | - Update deps 55 | - Update docs 56 | - Fixed .editorconfig 57 | 58 | # 4.0.5 / 2017/11/27 59 | 60 | - Improving structure 61 | - Clean .npmignore 62 | - Update deps 63 | - Update test case 64 | 65 | # 4.0.4 / 2017/11/22 66 | 67 | - Update docs 68 | - Update deps 69 | - Use prettier format code 70 | - Support binary data [#45](https://github.com/nuintun/node-adodb/issues/45) 71 | - Support long SQL(use child process stdin instead of command line arguments) 72 | 73 | # 4.0.3 / 2017/11/16 74 | 75 | - `package.json` add `os` limit 76 | 77 | # 4.0.2 / 2017/11/16 78 | 79 | - Improving structure and clean code 80 | 81 | # 4.0.1 / 2017/11/13 82 | 83 | - Add js docs comments 84 | 85 | # 4.0.0 / 2017/11/13 86 | 87 | - Rewrite with ES6 88 | - Add `schema` method 89 | - Break changed 90 | - `execute` return a promise 91 | - `query` remove schema param(use `schema` method instead) and return a promise 92 | 93 | # 3.1.3 / 2017-11-07 94 | 95 | - Update deps 96 | - Update docs 97 | 98 | # 3.1.2 / 2017-09-13 99 | 100 | - Update deps 101 | - Update LICENSE 102 | - Update rollup config 103 | - Update editorconfig 104 | 105 | # 3.1.1 / 2017-08-09 106 | 107 | - Update deps 108 | - Update examples and docs 109 | 110 | # 3.1.0 / 2017-06-12 111 | 112 | - Support fields schema [#31](https://github.com/nuintun/node-adodb/issues/31) [#34](https://github.com/nuintun/node-adodb/issues/34) 113 | - Remove `message` param in event `done` 114 | 115 | # 3.0.3 / 2017-05-11 116 | 117 | - Update debug 118 | - Update uglify-js 119 | 120 | # 3.0.2 / 2017-04-27 121 | 122 | - Remove `executeScalar` and combine it to `execute` method 123 | - Use `debug` lib 124 | - Use faster `events` lib 125 | - Use `encodeURI` instead of `base64` encode 126 | - Use new build tools `rollup` build cscript lib 127 | - Add `AppVeyor` test and badges 128 | - Add `Coveralls` badges 129 | - Fixed a fatal error 130 | - Better error catch 131 | 132 | # 2.0.3 / 2016-02-29 133 | 134 | - Fixed date parse bug 135 | 136 | # 2.0.2 / 2015-06-01 137 | 138 | - Bug fixed 139 | 140 | # 2.0.1 / 2015-06-01 141 | 142 | - Clean code 143 | 144 | # 2.0.0 / 2015-05-31 145 | 146 | - Fixed [#10](https://github.com/nuintun/node-adodb/issues/10) 147 | 148 | # 1.3.3 / 2015-05-20 149 | 150 | - Update json.js 151 | 152 | # 1.3.2 / 2015-05-19 153 | 154 | - Update license 155 | 156 | # 1.3.1 / 2015-05-19 157 | 158 | - Update deps 159 | 160 | # 1.3.0 / 2015-04-20 161 | 162 | - Add executeScalar method 163 | - Update json shim code 164 | 165 | # 1.2.0 / 2015-03-16 166 | 167 | - Add encoding setting 168 | - Support date/time 169 | - Improve reliability 170 | - Add english document 171 | 172 | # 1.0.2 / 2014-04-07 173 | 174 | - Change author name 175 | 176 | # 1.0.1 / 2014-04-05 177 | 178 | - Useing npm colors and add npm colors dependencies 179 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 nuintun 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # node-adodb 2 | 3 | > A node.js javascript client implementing the ADODB protocol on windows. 4 | > 5 | > [![NPM Version][npm-image]][npm-url] 6 | > [![Download Status][download-image]][npm-url] 7 | > [![Windows Status][appveyor-image]][appveyor-url] 8 | > [![Test Coverage][coveralls-image]][coveralls-url] 9 | > ![Node Version][node-image] 10 | > [![Dependencies][david-image]][david-url] 11 | 12 | ### Install 13 | 14 | [![NPM](https://nodei.co/npm/node-adodb.png)](https://nodei.co/npm/node-adodb/) 15 | 16 | ### Introduction: 17 | 18 | ##### ES6 19 | 20 | ```js 21 | 'use strict'; 22 | 23 | const ADODB = require('node-adodb'); 24 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 25 | 26 | // Transaction 27 | connection 28 | .transaction([`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Tom", "Male", "1981/5/10", 0);`, 29 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (11, "Brenda", "Female", "2001/1/11", 0);`, 30 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Bill", "Male", "1991/3/9", 0);`]) 31 | .then(data => { 32 | console.log("We will not arrive because a duplicate id is generated. When encountering an error do not insert any record."); 33 | }) 34 | .catch(error => { 35 | console.error(error); 36 | }); 37 | 38 | // Execute 39 | connection 40 | .execute('INSERT INTO Users(UserName, UserSex, UserAge) VALUES ("Newton", "Male", 25)') 41 | .then(data => { 42 | console.log(JSON.stringify(data, null, 2)); 43 | }) 44 | .catch(error => { 45 | console.error(error); 46 | }); 47 | 48 | // Execute with scalar 49 | connection 50 | .execute('INSERT INTO Users(UserName, UserSex, UserAge) VALUES ("Newton", "Male", 25)', 'SELECT @@Identity AS id') 51 | .then(data => { 52 | console.log(JSON.stringify(data, null, 2)); 53 | }) 54 | .catch(error => { 55 | console.error(error); 56 | }); 57 | 58 | // Query 59 | connection 60 | .query('SELECT * FROM Users') 61 | .then(data => { 62 | console.log(JSON.stringify(data, null, 2)); 63 | }) 64 | .catch(error => { 65 | console.error(error); 66 | }); 67 | 68 | // Schema 69 | connection 70 | .schema(20) 71 | .then(schema => { 72 | console.log(JSON.stringify(schema, null, 2)); 73 | }) 74 | .catch(error => { 75 | console.error(error); 76 | }); 77 | ``` 78 | 79 | ##### ES7 async/await 80 | 81 | ```js 82 | 'use strict'; 83 | 84 | const ADODB = require('node-adodb'); 85 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 86 | 87 | async function query() { 88 | try { 89 | const users = await connection.query('SELECT * FROM Users'); 90 | 91 | console.log(JSON.stringify(users, null, 2)); 92 | } catch (error) { 93 | console.error(error); 94 | } 95 | } 96 | 97 | query(); 98 | ``` 99 | 100 | ### API: 101 | 102 | `ADODB.open(connection[, x64]): ADODB` 103 | 104 | > Initialization database link parameters. 105 | 106 | `ADODB.query(sql): Promise` 107 | 108 | > Execute a SQL statement that returns a value. 109 | 110 | `ADODB.execute(sql[, scalar]): Promise` 111 | 112 | > Execute a SQL statement with no return value or with updated statistics. 113 | 114 | `ADODB.transaction(sql[]): Promise` 115 | 116 | > Execute multiple SQL statement as a transaction. 117 | 118 | `ADODB.schema(type[, criteria][, id]): Promise` 119 | 120 | > Query database schema information. see: [OpenSchema](https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/openschema-method) 121 | 122 | ### Debug: 123 | 124 | > Set env `DEBUG=ADODB`, see: [debug](https://github.com/visionmedia/debug) 125 | 126 | ### Extension: 127 | 128 | > This library theory supports all databases on the Windows platform that support ADODB connections, and only need to change the database connection string to achieve the operation! 129 | 130 | > Common access connection strings: 131 | > 132 | > - Access 2000-2003 (\*.mdb): `Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;` 133 | > - Access > 2007 (\*.accdb): `Provider=Microsoft.ACE.OLEDB.12.0;Data Source=adodb.accdb;Persist Security Info=False;` or `Provider=Microsoft.ACE.OLEDB.15.0;Data Source=adodb.accdb;Persist Security Info=False;` 134 | 135 | ### Notes: 136 | 137 | > The library need system support `Microsoft.Jet.OLEDB.4.0` or `Microsoft.ACE.OLEDB.12.0`, `Windows XP SP2` above support `Microsoft.Jet.OLEDB.4.0` by default, Others need to install support! 138 | > 139 | > Recommended use `Microsoft.ACE.OLEDB.12.0`, download: [Microsoft.ACE.OLEDB.12.0](https://www.microsoft.com/en-us/download/details.aspx?id=13255) 140 | 141 | ### Electron 142 | 143 | > If you want to use this module in an electron app running from an asar package you'll need to make some changes. 144 | 145 | > 1. Move `adodb.js` outside the asar package (in this example I use electron-builder, the `extraResources` option can move the file outside the asar package) 146 | 147 | ```json 148 | "extraResources": [ 149 | { 150 | "from": "./node_modules/node-adodb/lib/adodb.js", 151 | "to": "adodb.js" 152 | } 153 | ] 154 | ``` 155 | 156 | > 2. Tell the module where to find `adodb.js` while running from an asar package (I added this in electron's `main.js` file) 157 | 158 | ```javascript 159 | // Are we running from inside an asar package ? 160 | if (process.mainModule.filename.indexOf('app.asar') !== -1) { 161 | // In that case we need to set the correct path to adodb.js 162 | ADODB.PATH = './resources/adodb.js'; 163 | } 164 | ``` 165 | 166 | [npm-image]: https://img.shields.io/npm/v/node-adodb.svg?style=flat-square 167 | [npm-url]: https://www.npmjs.org/package/node-adodb 168 | [download-image]: https://img.shields.io/npm/dm/node-adodb.svg?style=flat-square 169 | [appveyor-image]: https://img.shields.io/appveyor/ci/nuintun/node-adodb/master.svg?style=flat-square&label=windows 170 | [appveyor-url]: https://ci.appveyor.com/project/nuintun/node-adodb 171 | [coveralls-image]: http://img.shields.io/coveralls/nuintun/node-adodb/master.svg?style=flat-square 172 | [coveralls-url]: https://coveralls.io/r/nuintun/node-adodb?branch=master 173 | [david-image]: https://img.shields.io/david/nuintun/node-adodb.svg?style=flat-square 174 | [david-url]: https://david-dm.org/nuintun/node-adodb 175 | [node-image]: https://img.shields.io/node/v/node-adodb.svg?style=flat-square 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-adodb 2 | 3 | > 一个用 Node.js 实现的 windows 上的 ADODB 协议。 4 | > 5 | > [![NPM Version][npm-image]][npm-url] 6 | > [![Download Status][download-image]][npm-url] 7 | > [![Windows Status][appveyor-image]][appveyor-url] 8 | > [![Test Coverage][coveralls-image]][coveralls-url] 9 | > ![Node Version][node-image] 10 | > [![Dependencies][david-image]][david-url] 11 | 12 | ### 安装 13 | 14 | [![NPM](https://nodei.co/npm/node-adodb.png)](https://nodei.co/npm/node-adodb/) 15 | 16 | ### 使用示例: 17 | 18 | ##### ES6 19 | 20 | ```js 21 | 'use strict'; 22 | 23 | const ADODB = require('node-adodb'); 24 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 25 | 26 | // 交易 27 | connection 28 | .transaction([`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Tom", "Male", "1981/5/10", 0);`, 29 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (11, "Brenda", "Female", "2001/1/11", 0);`, 30 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Bill", "Male", "1991/3/9", 0);`]) 31 | .then(data => { 32 | console.log("我们不会到达,因为生成了重复的ID。遇到错误时,请勿插入任何记录。"); 33 | }) 34 | .catch(error => { 35 | console.error(error); 36 | }); 37 | 38 | // 不带返回的执行 39 | connection 40 | .execute('INSERT INTO Users(UserName, UserSex, UserAge) VALUES ("Newton", "Male", 25)') 41 | .then(data => { 42 | console.log(JSON.stringify(data, null, 2)); 43 | }) 44 | .catch(error => { 45 | console.error(error); 46 | }); 47 | 48 | // 带返回标识的执行 49 | connection 50 | .execute('INSERT INTO Users(UserName, UserSex, UserAge) VALUES ("Newton", "Male", 25)', 'SELECT @@Identity AS id') 51 | .then(data => { 52 | console.log(JSON.stringify(data, null, 2)); 53 | }) 54 | .catch(error => { 55 | console.error(error); 56 | }); 57 | 58 | // 带返回的查询 59 | connection 60 | .query('SELECT * FROM Users') 61 | .then(data => { 62 | console.log(JSON.stringify(data, null, 2)); 63 | }) 64 | .catch(error => { 65 | console.error(error); 66 | }); 67 | 68 | // 带字段描述的查询 69 | connection 70 | .schema(20) 71 | .then(schema => { 72 | console.log(JSON.stringify(schema, null, 2)); 73 | }) 74 | .catch(error => { 75 | console.error(error); 76 | }); 77 | ``` 78 | 79 | ##### ES7 async/await 80 | 81 | ```js 82 | 'use strict'; 83 | 84 | const ADODB = require('node-adodb'); 85 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 86 | 87 | async function query() { 88 | try { 89 | const users = await connection.query('SELECT * FROM Users'); 90 | 91 | console.log(JSON.stringify(users, null, 2)); 92 | } catch (error) { 93 | console.error(error); 94 | } 95 | } 96 | 97 | query(); 98 | ``` 99 | 100 | ### 接口文档: 101 | 102 | `ADODB.open(connection[, x64]): ADODB` 103 | 104 | > 初始化数据库链接参数。 105 | 106 | `ADODB.query(sql): Promise` 107 | 108 | > 执行有返回值的 SQL 语句。 109 | 110 | `ADODB.execute(sql[, scalar]): Promise` 111 | 112 | > 执行无返回值或者带更新统计的的 SQL 语句。 113 | 114 | `ADODB.transaction(sql[]): Promise` 115 | 116 | > 执行多个SQL语句作为事务。 117 | 118 | `ADODB.schema(type[, criteria][, id]): Promise` 119 | 120 | > 查询数据库架构信息。参考: [OpenSchema](https://docs.microsoft.com/zh-cn/sql/ado/reference/ado-api/openschema-method) 121 | 122 | ### 调试: 123 | 124 | > 设置环境变量 `DEBUG=ADODB`。参考: [debug](https://github.com/visionmedia/debug) 125 | 126 | ### 扩展: 127 | 128 | > 该类库理论支持 Windows 平台下所有支持 ADODB 连接的数据库,只需要更改数据库连接字符串即可实现操作! 129 | 130 | > 数据库连接字符串: 131 | > 132 | > - Access 2000-2003 (\*.mdb): `Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;` 133 | > - Access > 2007 (\*.accdb): `Provider=Microsoft.ACE.OLEDB.12.0;Data Source=adodb.accdb;Persist Security Info=False;` 或者   `Provider=Microsoft.ACE.OLEDB.15.0;Data Source=adodb.accdb;Persist Security Info=False;` 134 | 135 | ### 注意: 136 | 137 | > 该类库需要系统支持 `Microsoft.Jet.OLEDB.4.0` 或者 `Microsoft.ACE.OLEDB.12.0`,对于 `Windows XP SP2` 以上系统默认支持 `Microsoft.Jet.OLEDB.4.0`,其它需要自己安装支持! 138 | > 139 | > 推荐使用 `Microsoft.ACE.OLEDB.12.0`,获取地址: [Microsoft.ACE.OLEDB.12.0](https://www.microsoft.com/zh-CN/download/details.aspx?id=13255) 140 | 141 | ### Electron 142 | 143 | > 如果你想在 `ASAR` 包中运行这个模块,你需要做一些修改。 144 | 145 | > 1. 从 `asar` 包中排除 `adodb.js`(使用 `electron-builder`, 可以配置 `extraResources` 将制定文件排除在外) 146 | 147 | ```json 148 | "extraResources": [ 149 | { 150 | "from": "./node_modules/node-adodb/lib/adodb.js", 151 | "to": "adodb.js" 152 | } 153 | ] 154 | ``` 155 | 156 | > 2. 告诉 `asar` 从哪里运行 `adodb.js` (可以将配置写在 `Electron` 的 `main.js` 文件中) 157 | 158 | ```javascript 159 | // Are we running from inside an asar package ? 160 | if (process.mainModule.filename.indexOf('app.asar') !== -1) { 161 | // In that case we need to set the correct path to adodb.js 162 | ADODB.PATH = './resources/adodb.js'; 163 | } 164 | ``` 165 | 166 | [npm-image]: https://img.shields.io/npm/v/node-adodb.svg?style=flat-square 167 | [npm-url]: https://www.npmjs.org/package/node-adodb 168 | [download-image]: https://img.shields.io/npm/dm/node-adodb.svg?style=flat-square 169 | [appveyor-image]: https://img.shields.io/appveyor/ci/nuintun/node-adodb/master.svg?style=flat-square&label=windows 170 | [appveyor-url]: https://ci.appveyor.com/project/nuintun/node-adodb 171 | [coveralls-image]: http://img.shields.io/coveralls/nuintun/node-adodb/master.svg?style=flat-square 172 | [coveralls-url]: https://coveralls.io/r/nuintun/node-adodb?branch=master 173 | [david-image]: https://img.shields.io/david/nuintun/node-adodb.svg?style=flat-square 174 | [david-url]: https://david-dm.org/nuintun/node-adodb 175 | [node-image]: https://img.shields.io/node/v/node-adodb.svg?style=flat-square 176 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: "8" 4 | - nodejs_version: "9" 5 | - nodejs_version: "10" 6 | - nodejs_version: "11" 7 | - nodejs_version: "12" 8 | platform: 9 | - x86 10 | - x64 11 | install: 12 | - ps: Install-Product node $env:nodejs_version 13 | - npm install 14 | - npm install mocha 15 | - npm install istanbul 16 | build: off 17 | test_script: 18 | - node --version 19 | - npm --version 20 | - npm run test-ci 21 | - npm install coveralls 22 | - type .\coverage\lcov.info | node ./node_modules/coveralls/bin/coveralls.js 23 | version: "{build}" 24 | -------------------------------------------------------------------------------- /examples/execute.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo node-adodb examples: 3 | node execute.js 4 | pause 5 | -------------------------------------------------------------------------------- /examples/execute.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // External lib 4 | const ADODB = require('../'); 5 | 6 | // Variable declaration 7 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 8 | 9 | // Execute 10 | connection 11 | .execute('INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Bill", "Male", "1991/3/9", 0)') 12 | .then(data => { 13 | console.log(JSON.stringify(data, null, 2)); 14 | }) 15 | .catch(error => { 16 | console.log(error); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/execute.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const process: any; 4 | 5 | // External lib 6 | import ADODB = require('node-adodb'); 7 | 8 | // Variable declaration 9 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 10 | 11 | // Execute 12 | connection 13 | .execute('INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Bill", "Male", "1991/3/9", 0)') 14 | .then(data => { 15 | console.log(JSON.stringify(data, null, 2)); 16 | }) 17 | .catch(error => { 18 | console.log(error); 19 | }); 20 | -------------------------------------------------------------------------------- /examples/node-adodb.ldb: -------------------------------------------------------------------------------- 1 | JAVIPC Admin -------------------------------------------------------------------------------- /examples/node-adodb.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nuintun/node-adodb/1089dae636e23ba6ca61c027b75543d095871373/examples/node-adodb.mdb -------------------------------------------------------------------------------- /examples/query.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo node-adodb examples: 3 | node query.js 4 | pause 5 | -------------------------------------------------------------------------------- /examples/query.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // External lib 4 | const ADODB = require('../'); 5 | 6 | // Variable declaration 7 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 8 | 9 | // Query 10 | connection 11 | .query('SELECT * FROM Users') 12 | .then(data => { 13 | console.log(JSON.stringify(data, null, 2)); 14 | }) 15 | .catch(error => { 16 | console.log(error); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/query.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const process: any; 4 | 5 | // External lib 6 | import ADODB = require('node-adodb'); 7 | 8 | // Variable declaration 9 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 10 | 11 | // Query 12 | connection 13 | .query('SELECT * FROM Users') 14 | .then(data => { 15 | console.log(JSON.stringify(data, null, 2)); 16 | }) 17 | .catch(error => { 18 | console.log(error); 19 | }); 20 | -------------------------------------------------------------------------------- /examples/scalar.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo node-adodb examples: 3 | node scalar.js 4 | pause 5 | -------------------------------------------------------------------------------- /examples/scalar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // External lib 4 | const ADODB = require('../'); 5 | 6 | // Variable declaration 7 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 8 | 9 | // Scalar 10 | connection 11 | .execute( 12 | 'INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Bill", "Male", "1991/3/9", 0)', 13 | 'SELECT @@Identity AS id' 14 | ) 15 | .then(data => { 16 | console.log(JSON.stringify(data, null, 2)); 17 | }) 18 | .catch(error => { 19 | console.log(error); 20 | }); 21 | -------------------------------------------------------------------------------- /examples/scalar.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const process: any; 4 | 5 | // External lib 6 | import ADODB = require('node-adodb'); 7 | 8 | // Variable declaration 9 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 10 | 11 | // Scalar 12 | connection 13 | .execute( 14 | 'INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Bill", "Male", "1991/3/9", 0)', 15 | 'SELECT @@Identity AS id' 16 | ) 17 | .then(data => { 18 | console.log(JSON.stringify(data, null, 2)); 19 | }) 20 | .catch(error => { 21 | console.log(error); 22 | }); 23 | -------------------------------------------------------------------------------- /examples/schema.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo node-adodb examples: 3 | node schema.js 4 | pause 5 | -------------------------------------------------------------------------------- /examples/schema.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // External lib 4 | const ADODB = require('../'); 5 | 6 | // Variable declaration 7 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 8 | 9 | // Schema 10 | connection 11 | .schema(20) 12 | .then(schema => { 13 | console.log(JSON.stringify(schema, null, 2)); 14 | }) 15 | .catch(error => { 16 | console.log(error); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/schema.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const process: any; 4 | 5 | // External lib 6 | import ADODB = require('node-adodb'); 7 | 8 | // Variable declaration 9 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 10 | 11 | // Schema 12 | connection 13 | .schema(20) 14 | .then(schema => { 15 | console.log(JSON.stringify(schema, null, 2)); 16 | }) 17 | .catch(error => { 18 | console.log(error); 19 | }); 20 | -------------------------------------------------------------------------------- /examples/transaction.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | echo node-adodb examples: 3 | node transaction.js 4 | pause 5 | -------------------------------------------------------------------------------- /examples/transaction.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // External lib 4 | const ADODB = require('../'); 5 | 6 | // Variable declaration 7 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 8 | 9 | //Prepare queries 10 | let querys=[]; 11 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Tom", "Male", "1981/5/10", 0);`); 12 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (11, "Brenda", "Female", "2001/1/11", 0);`); 13 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Bill", "Male", "1991/3/9", 0);`); 14 | 15 | // Execute 16 | connection 17 | .transaction(querys) 18 | .then(data => { 19 | console.log("Queries executed correctly") 20 | }) 21 | .catch(error => { 22 | console.log("No query has been run because an error was encountered"); 23 | console.log(error); 24 | }); 25 | -------------------------------------------------------------------------------- /examples/transaction.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare const process: any; 4 | 5 | // External lib 6 | import ADODB = require('node-adodb'); 7 | 8 | // Variable declaration 9 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=node-adodb.mdb;'); 10 | 11 | //Prepare queries 12 | let querys=[]; 13 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Tom", "Male", "1981/5/10", 0);`); 14 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (11, "Brenda", "Female", "2001/1/11", 0);`); 15 | querys.push(`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Bill", "Male", "1991/3/9", 0);`); 16 | 17 | // Execute 18 | connection 19 | .transaction(querys) 20 | .then(data => { 21 | console.log("Queries executed correctly") 22 | }) 23 | .catch(error => { 24 | console.log("No query has been run because an error was encountered"); 25 | console.log(error); 26 | }); 27 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'node-adodb' { 2 | let PATH: string; 3 | const open: (connection: string, x64?: boolean) => open; 4 | 5 | export interface open { 6 | query(sql: string): Promise; 7 | execute(sql: string, scalar?: string): Promise; 8 | transaction(sql: string[]): Promise; 9 | schema(type: number, criteria?: any[], id?: string): Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module index 3 | * @license MIT 4 | * @version 2017/11/09 5 | */ 6 | 7 | 'use strict'; 8 | 9 | // Import lib 10 | const Proxy = require('./lib/proxy'); 11 | const engine = require('./lib/engine'); 12 | const debug = require('debug')('ADODB'); 13 | 14 | // Set debug color 15 | debug.color = 6; 16 | 17 | /** 18 | * @class ADODB 19 | */ 20 | class ADODB { 21 | /** 22 | * @constructor 23 | * @param {string} connection 24 | * @param {boolean} [x64] 25 | */ 26 | constructor(connection, x64) { 27 | this.connection = connection; 28 | this.proxy = new Proxy(engine(x64)); 29 | } 30 | 31 | /** 32 | * @method execute 33 | * @param {string} sql 34 | * @param {string} [scalar] 35 | * @returns {Promise} 36 | */ 37 | execute(sql, scalar) { 38 | debug('cmd:', 'execute'); 39 | debug('sql:', sql); 40 | 41 | const connection = this.connection; 42 | const params = { connection, sql }; 43 | 44 | if (arguments.length > 1) { 45 | debug('scalar:', scalar); 46 | 47 | params.scalar = scalar; 48 | } 49 | 50 | return this.proxy.exec('execute', params); 51 | } 52 | 53 | /** 54 | * @method transaction 55 | * @param {string} sql 56 | * @returns {Promise} 57 | */ 58 | transaction(sql) { 59 | debug('cmd:', 'transaction'); 60 | debug('sql:', sql); 61 | 62 | const connection = this.connection; 63 | const params = { connection, sql }; 64 | 65 | return this.proxy.exec('transaction', params); 66 | } 67 | 68 | /** 69 | * @method query 70 | * @param {string} sql 71 | * @returns {Promise} 72 | */ 73 | query(sql) { 74 | debug('cmd:', 'query'); 75 | debug('sql:', sql); 76 | 77 | const connection = this.connection; 78 | 79 | return this.proxy.exec('query', { connection, sql }); 80 | } 81 | 82 | /** 83 | * @method schema 84 | * @param {number} type 85 | * @param {Array} [criteria] 86 | * @param {string} [id] 87 | * @returns {Promise} 88 | */ 89 | schema(type, criteria, id) { 90 | debug('cmd:', 'schema'); 91 | debug('type:', type); 92 | 93 | const length = arguments.length; 94 | const connection = this.connection; 95 | const params = { connection, type }; 96 | 97 | if (length > 1) { 98 | debug('criteria:', criteria); 99 | 100 | params.criteria = criteria; 101 | } 102 | 103 | if (length > 2) { 104 | debug('id:', id); 105 | 106 | params.id = id; 107 | } 108 | 109 | return this.proxy.exec('schema', params); 110 | } 111 | } 112 | 113 | // Exports 114 | module.exports = { 115 | /** 116 | * @property PATH 117 | * @description Set ADODB PATH 118 | */ 119 | set PATH(adodb) { 120 | Proxy.adodb = adodb; 121 | }, 122 | 123 | /** 124 | * @property PATH 125 | * @description Get ADODB PATH 126 | */ 127 | get PATH() { 128 | return Proxy.adodb; 129 | }, 130 | 131 | /** 132 | * @function open 133 | * @param {string} connection 134 | * @param {boolean} [x64] 135 | * @returns {ADODB} 136 | */ 137 | open: (connection, x64) => new ADODB(connection, x64) 138 | }; 139 | -------------------------------------------------------------------------------- /lib/adodb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module node-adodb 3 | * @author nuintun 4 | * @license MIT 5 | * @version 5.0.3 6 | * @description A Node.js JavaScript Client implementing the ADODB protocol. 7 | * @see https://github.com/nuintun/node-adodb#readme 8 | */ 9 | !function(){"use strict";function t(t){t.State&&t.Close()}function e(t){WScript.StdOut.Write(JSON.stringify(t))}function n(t){var e,n=t.number,r=t.description;r||(r="Unspecified error, SQL may contain reserved words and symbols, surround it with brackets []"),e={code:n,message:r},WScript.StdErr.Write(JSON.stringify(e))}function o(t){return 7===t||64===t||133===t||134===t||135===t}function c(t){return 128===t||204===t||205===t}function u(e){var n=new ActiveXObject("ADODB.Stream");n.Type=1,n.Open(),n.Position=0,n.Write(e),n.Position=0,n.Type=2;var r=n.ReadText();return t(n),r}function f(t){var e=[],n=t.Fields;if(!t.BOF||!t.EOF){var r,i,f,a,s,p=n.Count;for(t.MoveFirst();!t.EOF;){for(i={},r=0;r { 25 | if (x64) return cscript64; 26 | 27 | return cscript32; 28 | }; 29 | -------------------------------------------------------------------------------- /lib/proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module proxy 3 | * @license MIT 4 | * @version 2017/11/09 5 | */ 6 | 7 | 'use strict'; 8 | 9 | // Import lib 10 | const spawn = require('./spawn'); 11 | 12 | /** 13 | * @class Proxy 14 | */ 15 | class Proxy { 16 | /** 17 | * @constructor 18 | * @param {string} engine 19 | */ 20 | constructor(engine) { 21 | this.engine = engine; 22 | } 23 | 24 | /** 25 | * @method exec 26 | * @param {string} command 27 | * @param {Object} params 28 | * @returns {Promise} 29 | */ 30 | exec(command, params) { 31 | const engine = this.engine; 32 | 33 | // Params to string 34 | params = JSON.stringify(params); 35 | 36 | // Spawn args 37 | const args = [Proxy.adodb, '//E:JScript', '//Nologo', '//U', '//B', command]; 38 | 39 | // Spawn 40 | return spawn(engine, args, params, { encoding: 'utf16le' }) 41 | .then(data => JSON.parse(data)) 42 | .catch(error => { 43 | if (error.process) { 44 | error.process = JSON.parse(error.process); 45 | } 46 | 47 | throw error; 48 | }); 49 | } 50 | } 51 | 52 | // ADODB actuator 53 | Proxy.adodb = require.resolve('./adodb'); 54 | 55 | // Exports 56 | module.exports = Proxy; 57 | -------------------------------------------------------------------------------- /lib/spawn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module spawn 3 | * @license MIT 4 | * @version 2018/04/28 5 | * @see https://github.com/panosoft/spawn-promise 6 | */ 7 | 8 | 'use strict'; 9 | 10 | let transcode = require('buffer').transcode; 11 | const childProcess = require('child_process'); 12 | 13 | // Hack transcode 14 | if (!transcode) { 15 | /** 16 | * @function toBuffer 17 | * @param {string} string 18 | * @param {string} encoding 19 | * @returns {Buffer} 20 | */ 21 | const toBuffer = 22 | Buffer.from || 23 | function(string, encoding) { 24 | return new Buffer(string, encoding); 25 | }; 26 | 27 | /** 28 | * @function transcode 29 | * @param {Buffer} source 30 | * @param {string} fromEncoding 31 | * @param {string} toEncoding 32 | * @returns {Buffer} 33 | */ 34 | transcode = function(source, fromEncoding, toEncoding) { 35 | // Same encoding 36 | if (fromEncoding === toEncoding) return source; 37 | 38 | // Transcode 39 | return toBuffer(source.toString(fromEncoding), toEncoding); 40 | }; 41 | } 42 | 43 | // Exit messages 44 | const exitMessages = { 45 | 1: 'Uncaught Fatal Exception', 46 | 3: 'Internal JavaScript Parse Error', 47 | 4: 'Internal JavaScript Evaluation Failure', 48 | 5: 'Fatal Error', 49 | 6: 'Non-function Internal Exception Handler', 50 | 7: 'Internal Exception Handler Run-Time Failure', 51 | 9: 'Invalid Argument', 52 | 10: 'Internal JavaScript Run-Time Failure', 53 | 12: 'Invalid Debug Argument' 54 | }; 55 | 56 | /** 57 | * @function isEmpty 58 | * @description Is object empty 59 | * @param {Object} object 60 | * @returns {boolean} 61 | */ 62 | const isEmpty = object => Object.keys(object).length === 0; 63 | 64 | /** 65 | * @function spawn 66 | * @description Spawn a child process and receive output via a Promise interface. 67 | * @param {string} command Command to spawn. 68 | * @param {string[]} args Array of arguments to run command with. 69 | * @param {string|Buffer} input Input to pass command via stdin. 70 | * @param {Object} options Spawn configure 71 | * @returns {Promise} Resolved with buffer of stdout or rejected with error 72 | */ 73 | const spawn = function(command, args, input, options) { 74 | return new Promise((resolve, reject) => { 75 | // Options normalize 76 | options = Object.assign({ encoding: 'utf8', windowsHide: true }, options); 77 | 78 | // Vars 79 | const stderrOutput = []; 80 | const encoding = options.encoding; 81 | const errors = Object.create(null); 82 | 83 | // Delete options encoding 84 | delete options.encoding; 85 | 86 | // Spawn command 87 | const child = childProcess.spawn(command, args, options); 88 | 89 | // Capture errors 90 | child.on('error', error => (errors.spawn = error)); 91 | child.stdin.on('error', error => (errors.stdin = error)); 92 | child.stdout.on('error', error => (errors.stdout = error)); 93 | child.stderr.on('error', error => (errors.stderr = error)); 94 | child.stderr.on('data', data => stderrOutput.push(data)); 95 | 96 | // Capture output 97 | const buffers = []; 98 | 99 | // Capture data 100 | child.stdout.on('data', data => buffers.push(data)); 101 | 102 | // Spawn close 103 | child.on('close', exitCode => { 104 | // Exit code not 0 105 | if (exitCode !== 0) { 106 | errors.exitMessage = exitMessages[exitCode]; 107 | } 108 | 109 | // Stderr output 110 | if (stderrOutput.length) { 111 | errors.process = Buffer.concat(stderrOutput).toString(encoding); 112 | } 113 | 114 | // Errors not empty 115 | if (!isEmpty(errors)) { 116 | // Set exit code 117 | errors.exitCode = exitCode; 118 | 119 | // Reject error 120 | return reject(Object.assign(new Error(`Spawn ${command} error`), errors)); 121 | } 122 | 123 | // Resolve data 124 | return resolve(transcode(Buffer.concat(buffers), encoding, 'utf8')); 125 | }); 126 | 127 | // Send input data 128 | child.stdin.end(input, encoding); 129 | }); 130 | }; 131 | 132 | // Exports 133 | module.exports = spawn; 134 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-adodb", 3 | "version": "5.0.3", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "keywords": [ 7 | "sql", 8 | "adodb", 9 | "access", 10 | "database", 11 | "node-adodb", 12 | "microsoft adodb" 13 | ], 14 | "homepage": "https://github.com/nuintun/node-adodb#readme", 15 | "description": "A Node.js JavaScript Client implementing the ADODB protocol.", 16 | "author": { 17 | "name": "nuintun", 18 | "email": "nuintun@qq.com" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/nuintun/node-adodb/issues" 22 | }, 23 | "os": [ 24 | "win32" 25 | ], 26 | "engines": { 27 | "node": ">=6.0.0" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/nuintun/node-adodb.git" 32 | }, 33 | "dependencies": { 34 | "arch": "^2.1.1", 35 | "debug": "^4.1.1" 36 | }, 37 | "devDependencies": { 38 | "chai": "^4.2.0", 39 | "rollup": "^1.32.0", 40 | "terser": "^4.6.4", 41 | "holding": "^3.1.1", 42 | "fs-extra": "^8.1.0" 43 | }, 44 | "scripts": { 45 | "prepublishOnly": "node rollup.js", 46 | "test": "mocha --timeout 6000 --check-leaks --reporter spec --bail --exit", 47 | "test-ci": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --timeout 6000 --check-leaks --reporter spec --exit", 48 | "test-cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- --timeout 6000 --check-leaks --reporter dot --exit" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /rollup.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module rollup 3 | * @license MIT 4 | * @version 2017/11/09 5 | */ 6 | 7 | 'use strict'; 8 | 9 | const fs = require('fs-extra'); 10 | const terser = require('terser'); 11 | const rollup = require('rollup'); 12 | const pkg = require('./package.json'); 13 | 14 | /** 15 | * @function build 16 | * @param {Object} inputOptions 17 | * @param {Object} outputOptions 18 | */ 19 | async function build(inputOptions, outputOptions) { 20 | await fs.remove(outputOptions.file); 21 | 22 | const bundle = await rollup.rollup(inputOptions); 23 | const { output } = await bundle.generate(outputOptions); 24 | const [result] = output; 25 | 26 | const file = outputOptions.file; 27 | const minify = terser.minify(result.code, { ie8: true, output: { comments: false } }); 28 | 29 | await fs.outputFile(file, banner + minify.code); 30 | 31 | console.log(`Build ${file} success!`); 32 | } 33 | 34 | const banner = `/** 35 | * @module ${pkg.name} 36 | * @author ${pkg.author.name} 37 | * @license ${pkg.license} 38 | * @version ${pkg.version} 39 | * @description ${pkg.description} 40 | * @see ${pkg.homepage} 41 | */ 42 | `; 43 | 44 | const inputOptions = { 45 | input: 'lib/adodb/main.js' 46 | }; 47 | 48 | const outputOptions = { 49 | indent: true, 50 | strict: true, 51 | format: 'iife', 52 | file: 'lib/adodb.js' 53 | }; 54 | 55 | build(inputOptions, outputOptions); 56 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module test 3 | * @license MIT 4 | * @version 2017/11/09 5 | */ 6 | 7 | 'use strict'; 8 | 9 | const fs = require('fs'); 10 | const path = require('path'); 11 | const arch = require('arch'); 12 | const ADODB = require('../index'); 13 | const expect = require('chai').expect; 14 | const holding = require('holding').assert; 15 | 16 | const source = path.resolve('test/node-adodb.mdb'); 17 | const mdb = fs.readFileSync(require.resolve('../examples/node-adodb.mdb')); 18 | 19 | fs.writeFileSync(source, mdb); 20 | 21 | // Variable declaration 22 | const x64 = arch() === 'x64'; 23 | const sysroot = process.env['systemroot'] || process.env['windir']; 24 | const cscript = path.join(sysroot, x64 ? 'SysWOW64' : 'System32', 'cscript.exe'); 25 | 26 | if (fs.existsSync(cscript) && fs.existsSync(source)) { 27 | console.log('Use:', cscript); 28 | console.log('Database:', source); 29 | 30 | // Variable declaration 31 | const connection = ADODB.open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=' + source + ';'); 32 | 33 | describe('ADODB', () => { 34 | it('query', next => { 35 | connection 36 | .query('SELECT * FROM Users') 37 | .then(data => { 38 | expect(data.length).to.equal(3); 39 | expect(data[0].UserName).to.equal('Nuintun'); 40 | expect(data[0]).to.have.ownProperty('UserBirthday'); 41 | expect(data[2].UserName).to.equal('张三'); 42 | next(); 43 | }) 44 | .catch(next); 45 | }); 46 | 47 | it('transaction', next => { 48 | connection 49 | .transaction([`INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Tom", "Male", "1981/5/10", 0);`, 50 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (11, "Brenda", "Female", "2001/1/11", 0);`, 51 | `INSERT INTO Users(UserId, UserName, UserSex, UserBirthday, UserMarried) VALUES (10, "Bill", "Male", "1991/3/9", 0);`]) 52 | .then(data => { 53 | expect.fail(); 54 | // next(); 55 | }) 56 | .catch(ex => { 57 | connection 58 | .query('SELECT * FROM Users') 59 | .then(data => { 60 | expect(data.length).to.equal(3); 61 | next(); 62 | }) 63 | .catch(next); 64 | }); 65 | }); 66 | 67 | it('schema', next => { 68 | const cb = holding(2, next); 69 | 70 | connection 71 | .schema(20) 72 | .then(data => { 73 | expect(data).to.be.an('array'); 74 | 75 | if (data.length) { 76 | expect(data[0]).to.include.all.keys(['TABLE_NAME', 'TABLE_TYPE']); 77 | } 78 | 79 | cb(); 80 | }) 81 | .catch(cb); 82 | 83 | connection 84 | .schema(4, [null, null, 'Users']) 85 | .then(data => { 86 | expect(data).to.be.an('array'); 87 | 88 | if (data.length) { 89 | expect(data[0]).to.include.all.keys(['COLUMN_NAME', 'DATA_TYPE']); 90 | } 91 | 92 | cb(); 93 | }) 94 | .catch(cb); 95 | 96 | connection 97 | .schema(-1, [null, null, 'Users'], 'TABLE') 98 | .then(data => { 99 | expect(data).to.be.an('array'); 100 | cb(); 101 | }) 102 | .catch(() => cb()); 103 | }); 104 | 105 | it('Invaid sql syntax', next => { 106 | connection.query('SELECT * FROM Users-non-exist').catch(error => { 107 | expect(error).to.be.exist; 108 | next(); 109 | }); 110 | }); 111 | 112 | describe('execute', () => { 113 | it('no scalar', next => { 114 | connection 115 | .execute('INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Bill", "Male", "1991/3/9", 0)') 116 | .then(data => { 117 | expect(data.length).to.equal(0); 118 | next(); 119 | }) 120 | .catch(next); 121 | }); 122 | 123 | it('with scalar', next => { 124 | connection 125 | .execute( 126 | 'INSERT INTO Users(UserName, UserSex, UserBirthday, UserMarried) VALUES ("Alice", "Female", "1986/3/9", 0)', 127 | 'SELECT @@Identity AS id' 128 | ) 129 | .then(function(data) { 130 | expect(data.length).to.equal(1); 131 | expect(data[0].id).to.equal(13); 132 | next(); 133 | }) 134 | .catch(next); 135 | }); 136 | }); 137 | }); 138 | } else { 139 | console.log('This OS not support node-adodb.'); 140 | } 141 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/estree@*": 6 | version "0.0.42" 7 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11" 8 | integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ== 9 | 10 | "@types/node@*": 11 | version "13.7.7" 12 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" 13 | integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== 14 | 15 | acorn@^7.1.0: 16 | version "7.1.1" 17 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" 18 | integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== 19 | 20 | arch@^2.1.1: 21 | version "2.1.1" 22 | resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" 23 | integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== 24 | 25 | assertion-error@^1.1.0: 26 | version "1.1.0" 27 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 28 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 29 | 30 | buffer-from@^1.0.0: 31 | version "1.1.1" 32 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 33 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 34 | 35 | chai@^4.2.0: 36 | version "4.2.0" 37 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" 38 | integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== 39 | dependencies: 40 | assertion-error "^1.1.0" 41 | check-error "^1.0.2" 42 | deep-eql "^3.0.1" 43 | get-func-name "^2.0.0" 44 | pathval "^1.1.0" 45 | type-detect "^4.0.5" 46 | 47 | check-error@^1.0.2: 48 | version "1.0.2" 49 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 50 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 51 | 52 | commander@^2.20.0: 53 | version "2.20.3" 54 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 55 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 56 | 57 | debug@^4.1.1: 58 | version "4.1.1" 59 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 60 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 61 | dependencies: 62 | ms "^2.1.1" 63 | 64 | deep-eql@^3.0.1: 65 | version "3.0.1" 66 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 67 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 68 | dependencies: 69 | type-detect "^4.0.0" 70 | 71 | fs-extra@^8.1.0: 72 | version "8.1.0" 73 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" 74 | integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== 75 | dependencies: 76 | graceful-fs "^4.2.0" 77 | jsonfile "^4.0.0" 78 | universalify "^0.1.0" 79 | 80 | get-func-name@^2.0.0: 81 | version "2.0.0" 82 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 83 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 84 | 85 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 86 | version "4.2.3" 87 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 88 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== 89 | 90 | holding@^3.1.1: 91 | version "3.1.1" 92 | resolved "https://registry.yarnpkg.com/holding/-/holding-3.1.1.tgz#601b8770794e24552bb227eead96b43766fd1c04" 93 | integrity sha512-467ENnVR4iYdbqtyQFEzBVNPYMvHTbwbcy8Lm2Q0xibHr0fZ83S6Z3ushXAHcLvSD6cY+YMNTLWj1F8QAsoanA== 94 | 95 | jsonfile@^4.0.0: 96 | version "4.0.0" 97 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 98 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 99 | optionalDependencies: 100 | graceful-fs "^4.1.6" 101 | 102 | ms@^2.1.1: 103 | version "2.1.2" 104 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 105 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 106 | 107 | pathval@^1.1.0: 108 | version "1.1.0" 109 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" 110 | integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= 111 | 112 | rollup@^1.32.0: 113 | version "1.32.0" 114 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.0.tgz#c65ce134850aca1ce595fcac07d1dc5d53bf227c" 115 | integrity sha512-ab2tF5pdDqm2zuI8j02ceyrJSScl9V2C24FgWQ1v1kTFTu1UrG5H0hpP++mDZlEFyZX4k0chtGEHU2i+pAzBgA== 116 | dependencies: 117 | "@types/estree" "*" 118 | "@types/node" "*" 119 | acorn "^7.1.0" 120 | 121 | source-map-support@~0.5.12: 122 | version "0.5.16" 123 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" 124 | integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== 125 | dependencies: 126 | buffer-from "^1.0.0" 127 | source-map "^0.6.0" 128 | 129 | source-map@^0.6.0, source-map@~0.6.1: 130 | version "0.6.1" 131 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 132 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 133 | 134 | terser@^4.6.4: 135 | version "4.6.4" 136 | resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.4.tgz#40a0b37afbe5b57e494536815efa68326840fc00" 137 | integrity sha512-5fqgBPLgVHZ/fVvqRhhUp9YUiGXhFJ9ZkrZWD9vQtFBR4QIGTnbsb+/kKqSqfgp3WnBwGWAFnedGTtmX1YTn0w== 138 | dependencies: 139 | commander "^2.20.0" 140 | source-map "~0.6.1" 141 | source-map-support "~0.5.12" 142 | 143 | type-detect@^4.0.0, type-detect@^4.0.5: 144 | version "4.0.8" 145 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 146 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 147 | 148 | universalify@^0.1.0: 149 | version "0.1.2" 150 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 151 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 152 | --------------------------------------------------------------------------------