From e75d4cf58809268318963efdc6a5fbd62352e825 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Thu, 29 Dec 2016 01:38:26 +0800 Subject: [PATCH 1/2] test: use assert instead of should --- README.md | 24 +-- README.zh-CN.md | 35 ++-- config/config.default.js | 8 +- lib/mysql.js | 12 +- package.json | 7 +- test/{prepare.js => .setup.js} | 0 .../apps/mysqlapp/app/controller/home.js | 3 +- test/mocha.opts | 1 - test/mysql.test.js | 168 +++++++++--------- 9 files changed, 125 insertions(+), 133 deletions(-) rename test/{prepare.js => .setup.js} (100%) delete mode 100644 test/mocha.opts diff --git a/README.md b/README.md index 98b4d74..0b755ab 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,13 @@ exports.mysql = { // port port: '3306', // username - user: 'mobile_pub', + user: 'test_user', // password - password: 'password', + password: 'test_password', // database - database: 'mobile_pub', + database: 'test', }, - // load into app, default is open + // load into app, default is open app: true, // load into agent, default is close agent: false, @@ -82,17 +82,17 @@ app.mysql.query(sql, values); // you can access to simple database instance by u exports.mysql = { clients: { // clientId, access the client instance by app.mysql.get('clientId') - mypay1: { + db1: { // host host: 'mysql.com', // port port: '3306', // username - user: 'mobile_pub', + user: 'test_user', // password - password: 'password', + password: 'test_password', // database - database: 'mobile_pub', + database: 'test', }, // ... }, @@ -101,7 +101,7 @@ exports.mysql = { }, - // load into app, default is open + // load into app, default is open app: true, // load into agent, default is close agent: false, @@ -111,10 +111,10 @@ exports.mysql = { Usage: ```js -const client1 = app.mysql.get('client1'); +const client1 = app.mysql.get('db1'); client1.query(sql, values); -const client2 = app.mysql.get('client2'); +const client2 = app.mysql.get('db2'); client2.query(sql, values); ``` @@ -191,7 +191,7 @@ try { - `scope`: A generatorFunction which will execute all sqls of this transaction. - `ctx`: The context object of current request, it will ensures that even in the case of a nested transaction, there is only one active transaction in a request at the same time. - adventage: easy to use, as if there is no transaction in your code. -- disadvantage: all transation will be successful or failed, cannot control precisely +- disadvantage: all transation will be successful or failed, cannot control precisely ```js const result = yield app.mysql.beginTransactionScope(function* (conn) { diff --git a/README.zh-CN.md b/README.zh-CN.md index 12eb89c..f3e2e8c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -20,21 +20,19 @@ [download-image]: https://img.shields.io/npm/dm/egg-mysql.svg?style=flat-square [download-url]: https://npmjs.org/package/egg-mysql -Aliyun rds client(support mysql portocal) for egg framework +MySQL 插件是为 egg 提供 MySQL 数据库访问的功能 -## Install +此插件基于 [ali-rds](https://github.com/ali-sdk/ali-rds) 实现一个简单的配置封装,具体使用方法你还需要阅读 [ali-rds](https://github.com/ali-sdk/ali-rds) 的文档。 + +## 安装 ```bash $ npm i egg-mysql --save ``` -MySQL Plugin 是为 egg 提供 MySQL 数据库访问的功能 - -此插件基于 [ali-rds](https://github.com/ali-sdk/ali-rds) 实现一个简单的配置封装,具体使用方法你还需要阅读 [ali-rds](https://github.com/ali-sdk/ali-rds) 的文档。 - ## 配置 -修改 `${app_root}/config/plugin.js` 启动 MySQL 插件: +通过 `config/plugin.js` 配置启动 MySQL 插件: ```js exports.mysql = { @@ -43,24 +41,24 @@ exports.mysql = { }; ``` -在 `${app_root}/config/config.default.js` 配置数据库相关的信息: +在 `config/config.${env}.js` 配置各个环境的数据库连接信息: ### 单数据源 ```js exports.mysql = { - // 数据库信息配置 + // 单数据库信息配置 client: { // host host: 'mysql.com', // 端口号 port: '3306', // 用户名 - user: 'mobile_pub', + user: 'test_user', // 密码 - password: 'password', + password: 'test_password', // 数据库名 - database: 'mobile_pub', + database: 'test', }, // 是否加载到 app 上,默认开启 app: true, @@ -75,24 +73,23 @@ exports.mysql = { app.mysql.query(sql, values); // 单实例可以直接通过 app.mysql 访问 ``` - ### 多数据源 ```js exports.mysql = { clients: { // clientId, 获取client实例,需要通过 app.mysql.get('clientId') 获取 - mypay1: { + db1: { // host host: 'mysql.com', // 端口号 port: '3306', // 用户名 - user: 'mobile_pub', + user: 'test_user', // 密码 - password: 'password', + password: 'test_password', // 数据库名 - database: 'mobile_pub', + database: 'test', }, // ... }, @@ -111,10 +108,10 @@ exports.mysql = { 使用方式: ```js -const client1 = app.mysql.get('client1'); +const client1 = app.mysql.get('db1'); client1.query(sql, values); -const client2 = app.mysql.get('client2'); +const client2 = app.mysql.get('db2'); client2.query(sql, values); ``` diff --git a/config/config.default.js b/config/config.default.js index b81db99..878715b 100644 --- a/config/config.default.js +++ b/config/config.default.js @@ -5,11 +5,10 @@ exports.mysql = { database: null, connectionLimit: 5, }, - // 在 app 上初始化 app: true, - // 在 agent 上初始化 agent: false, - // 单数据库 + + // Single Database // client: { // host: 'host', // port: 'port', @@ -17,7 +16,8 @@ exports.mysql = { // password: 'password', // database: 'database', // }, - // 多数据库 + + // Multi Databases // clients: { // db1: { // host: 'host', diff --git a/lib/mysql.js b/lib/mysql.js index 49ae4a1..ef6d5c8 100644 --- a/lib/mysql.js +++ b/lib/mysql.js @@ -6,13 +6,13 @@ const co = require('co'); let count = 0; -module.exports = function(app) { - app.addSingleton('mysql', createMysql); +module.exports = app => { + app.addSingleton('mysql', createClient); }; -function createMysql(config, app) { +function createClient(config, app) { const index = count++; - const done = app.readyCallback(`createMysql-${index}`); + const done = app.readyCallback(`egg-mysql-createClient-${index}`); app.coreLogger.info('[egg-mysql] connecting %s@%s:%s/%s', config.user, config.host, config.port, config.database); assert(config.host && config.port && config.user && config.database, @@ -20,9 +20,9 @@ function createMysql(config, app) { const client = rds(config); client._superQuery = client.query; - client.query = function* () { + client.query = function* query() { const sql = this.format.apply(this, arguments); - const ins = app.instrument('rds', sql); + const ins = app.instrument('egg-mysql', sql); const result = yield this._superQuery.apply(this, arguments); ins.end(); return result; diff --git a/package.json b/package.json index 33c9ccf..dcb131b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "egg-mysql", "version": "1.0.0", - "description": "mysql plugin for egg", + "description": "MySQL plugin for egg", "eggPlugin": { "name": "mysql" }, @@ -15,13 +15,12 @@ }, "devDependencies": { "autod": "^2.7.1", - "egg": "~0.1.0", + "egg": "^0.6.2", "egg-bin": "^1.3.0", "egg-mock": "^0.0.4", "eslint": "^3.4.0", "eslint-config-egg": "^3.1.0", "pedding": "^1.0.0", - "should": "^11.1.0", "supertest": "^2.0.0", "utility": "^1.8.0" }, @@ -37,7 +36,7 @@ "autod": "autod" }, "ci": { - "version": "4, 6" + "version": "4, 6, 7" }, "repository": { "type": "git", diff --git a/test/prepare.js b/test/.setup.js similarity index 100% rename from test/prepare.js rename to test/.setup.js diff --git a/test/fixtures/apps/mysqlapp/app/controller/home.js b/test/fixtures/apps/mysqlapp/app/controller/home.js index 097b275..a19920d 100644 --- a/test/fixtures/apps/mysqlapp/app/controller/home.js +++ b/test/fixtures/apps/mysqlapp/app/controller/home.js @@ -1,11 +1,10 @@ 'use strict'; module.exports = function* () { - console.log(9999); const users = yield this.service.user.list(this); this.body = { status: 'success', - users: users, + users, }; }; diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 4d0ad90..0000000 --- a/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---require ./test/prepare.js diff --git a/test/mysql.test.js b/test/mysql.test.js index b1362e7..9d8dc0d 100644 --- a/test/mysql.test.js +++ b/test/mysql.test.js @@ -1,10 +1,6 @@ 'use strict'; -/** - * Module dependencies. - */ - -const should = require('should'); +const assert = require('assert'); const request = require('supertest'); const mm = require('egg-mock'); const utility = require('utility'); @@ -15,25 +11,23 @@ describe('test/mysql.test.js', () => { let app; const uid = utility.randomString(); - before(function* () { + before(() => { app = mm.app({ baseDir: 'apps/mysqlapp', plugin: 'mysql', }); - yield app.ready(); - - should.exist(app.mysql); + return app.ready(); }); beforeEach(function* () { - // 先初始化测试数据,避免为空 + // init test datas try { yield app.mysql.query(`insert into npm_auth set user_id = 'egg-${uid}-1', password = '1'`); yield app.mysql.query(`insert into npm_auth set user_id = 'egg-${uid}-2', password = '2'`); yield app.mysql.query(`insert into npm_auth set user_id = 'egg-${uid}-3', password = '3'`); yield app.mysql.queryOne(`select * from npm_auth where user_id = 'egg-${uid}-3'`); } catch (err) { - console.log(err); + console.log('init test datas error: %s', err); } }); @@ -43,63 +37,65 @@ describe('test/mysql.test.js', () => { }); after(done => { - app.mysql.end(done); + app.mysql.end(err => { + app.close(); + done(err); + }); }); afterEach(mm.restore); - it('should query mysql user table success', done => { - request(app.callback()) - .get('/') - .expect(200, done); + it('should query mysql user table success', () => { + return request(app.callback()) + .get('/') + .expect(200); }); it('should query limit 2', function* () { const users = yield app.mysql.query('select * from npm_auth order by id desc limit 2'); - users.should.be.an.Array; - users.should.length(2); + assert(users.length === 2); const rows = yield app.mysql.select('npm_auth', { orders: [[ 'id', 'desc' ]], limit: 2, }); - rows.should.length(2); - rows[0].should.eql(users[0]); - rows[1].should.eql(users[1]); + assert(rows.length === 2); + assert.deepEqual(rows[0], users[0]); + assert.deepEqual(rows[1], users[1]); }); it('should update successfully', function* () { const user = yield app.mysql.queryOne('select * from npm_auth order by id desc limit 10'); const result = yield app.mysql.update('npm_auth', { id: user.id, user_id: `79744-${uid}-update` }); - result.affectedRows.should.eql(1); + assert(result.affectedRows === 1); }); it('should delete successfully', function* () { const user = yield app.mysql.queryOne('select * from npm_auth order by id desc limit 10'); const result = yield app.mysql.delete('npm_auth', { id: user.id }); - result.affectedRows.should.eql(1); + assert(result.affectedRows === 1); }); it('should query one success', function* () { const user = yield app.mysql.queryOne('select * from npm_auth order by id desc limit 10'); - should.exist(user); - user.user_id.should.be.a.String; + assert(user); + assert(typeof user.user_id === 'string' && user.user_id); const row = yield app.mysql.get('npm_auth', { user_id: user.user_id }); - row.id.should.equal(user.id); + assert(row.id === user.id); }); it('should query one not exists return null', function* () { let user = yield app.mysql.queryOne('select * from npm_auth where id = -1'); - should.not.exist(user); + assert(!user); user = yield app.mysql.get('npm_auth', { id: -1 }); - should.not.exist(user); + assert(!user); }); it('should escape value', () => { const val = app.mysql.escape('\'"?><=!@#'); - val.should.equal('\'\\\'\\"?><=!@#\''); + assert(val === '\'\\\'\\"?><=!@#\''); }); it('should agent error when password wrong on multi clients', done => { @@ -118,95 +114,97 @@ describe('test/mysql.test.js', () => { }); }); - it('should agent.mysql work', done => { - const app = mm.cluster({ - baseDir: 'apps/mysqlapp', - plugin: 'mysql', - }); - app.ready(() => { - app.close(); - const result = fs.readFileSync(path.join(__dirname, './fixtures/apps/mysqlapp/run/agent_result.json'), 'utf8'); - result.should.match(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/); - done(); - }); + it('should queryOne work on transaction', function* () { + const result = yield app.mysql.beginTransactionScope(function* (conn) { + const row = yield conn.queryOne('select * from npm_auth order by id desc limit 10'); + return { row }; + }, {}); + assert(result.row); + assert(result.row.user_id && typeof result.row.user_id === 'string'); + assert(result.row.password === '3'); }); - it('should disable app work', done => { - const app = mm.app({ - baseDir: 'apps/mysqlapp-disable', - plugin: 'mysql', + describe('config.mysql.agent = true', () => { + let app; + before(() => { + app = mm.cluster({ + baseDir: 'apps/mysqlapp', + plugin: 'mysql', + }); + return app.ready(); }); - app.ready(() => { - should.not.exist(app.mysql); - done(); + after(() => app.close()); + + it('should agent.mysql work', () => { + const result = fs.readFileSync(path.join(__dirname, + './fixtures/apps/mysqlapp/run/agent_result.json'), 'utf8'); + assert(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/.test(result)); }); }); - it('should queryOne work on transaction', function* () { - const result = yield app.mysql.beginTransactionScope(function* (conn) { - const row = yield conn.queryOne('select * from npm_auth order by id desc limit 10'); - return { row }; - }, {}); - should.exist(result.row); - result.row.user_id.should.be.a.String; - result.row.password.should.equal('3'); + describe('config.mysql.app = false', () => { + let app; + before(() => { + app = mm.app({ + baseDir: 'apps/mysqlapp-disable', + plugin: 'mysql', + }); + return app.ready(); + }); + after(() => app.close()); + + it('should disable app work', () => { + assert(!app.mysql); + }); }); describe('newConfig', () => { let app; - before(done => { + before(() => { app = mm.cluster({ baseDir: 'apps/mysqlapp-new', plugin: 'mysql', }); - app.ready(done); + return app.ready(); }); - after(() => { - app.close(); - }); + after(() => app.close()); - it('should new config agent.mysql work', done => { - app.ready(() => { - const result = fs.readFileSync(path.join(__dirname, './fixtures/apps/mysqlapp-new/run/agent_result.json'), 'utf8'); - result.should.match(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/); - done(); - }); + it('should new config agent.mysql work', () => { + const result = fs.readFileSync(path.join(__dirname, + './fixtures/apps/mysqlapp-new/run/agent_result.json'), 'utf8'); + assert(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/.test(result)); }); - it('should query mysql user table success', done => { - request(app.callback()) - .get('/') - .expect(200, done); + it('should query mysql user table success', () => { + return request(app.callback()) + .get('/') + .expect(200); }); }); describe('createInstance', () => { let app; - before(done => { + before(() => { app = mm.cluster({ baseDir: 'apps/mysqlapp-dynamic', plugin: 'mysql', }); - app.ready(done); + return app.ready(); }); - after(() => { - app.close(); - }); + after(() => app.close()); - it('should new config agent.mysql work', done => { - app.ready(() => { - const result = fs.readFileSync(path.join(__dirname, './fixtures/apps/mysqlapp-dynamic/run/agent_result.json'), 'utf8'); - result.should.match(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/); - done(); - }); + it('should new config agent.mysql work', () => { + const result = fs.readFileSync(path.join(__dirname, + './fixtures/apps/mysqlapp-dynamic/run/agent_result.json'), 'utf8'); + assert(/\[\{"currentTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z"\}\]/.test(result)); }); - it('should query mysql user table success', done => { - request(app.callback()) - .get('/') - .expect(200, done); + it('should query mysql user table success', () => { + return request(app.callback()) + .get('/') + .expect(200); }); }); }); From 187feb14b3dc28e6691e0719726c594cf703e080 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Thu, 29 Dec 2016 01:45:36 +0800 Subject: [PATCH 2/2] docs: add app.js and agent.js extend intro --- .github/ISSUE_TEMPLATE.md | 21 --------------------- .travis.yml | 1 + README.zh-CN.md | 29 ++++++++++++++++++++++++++++- appveyor.yml | 1 + lib/mysql.js | 6 +++--- package.json | 2 +- 6 files changed, 34 insertions(+), 26 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index b021f10..0000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,21 +0,0 @@ - - -* **Node Version**: -* **Egg Version**: -* **Plugin Name**: -* **Plugin Version**: -* **Platform**: - - diff --git a/.travis.yml b/.travis.yml index 9c10f2f..84e8b77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ language: node_js node_js: - '4' - '6' + - '7' install: - npm i npminstall && npminstall script: diff --git a/README.zh-CN.md b/README.zh-CN.md index f3e2e8c..e098636 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -22,7 +22,7 @@ MySQL 插件是为 egg 提供 MySQL 数据库访问的功能 -此插件基于 [ali-rds](https://github.com/ali-sdk/ali-rds) 实现一个简单的配置封装,具体使用方法你还需要阅读 [ali-rds](https://github.com/ali-sdk/ali-rds) 的文档。 +此插件基于 [ali-rds](https://github.com/ali-sdk/ali-rds) 实现一个简单的配置封装,具体使用方法你还需要阅读 [ali-rds] 的文档。 ## 安装 @@ -115,6 +115,30 @@ const client2 = app.mysql.get('db2'); client2.query(sql, values); ``` +## 扩展 + +### app.js + +#### app.mysql + +如果开启了 `config.mysql.app = true`,则会在 app 上注入 [ali-rds] 客户端 的 [Singleton 单例](https://github.com/eggjs/egg/blob/master/lib/core/singleton.js)。 + +```js +app.mysql.query(sql); +app.mysql.get('db1').query(sql); +``` + +### agent.js + +#### agent.mysql + +如果开启了 `config.mysql.agent = true`,则会在 agent 上注入 [ali-rds] 客户端 的 [Singleton 单例](https://github.com/eggjs/egg/blob/master/lib/core/singleton.js)。 + +```js +agent.mysql.query(sql); +agent.mysql.get('db1').query(sql); +``` + ## CRUD 使用指南 ### Create @@ -243,3 +267,6 @@ Please open an issue [here](https://github.com/eggjs/egg/issues). ## License [MIT](LICENSE) + + +[ali-rds]: https://github.com/ali-sdk/ali-rds diff --git a/appveyor.yml b/appveyor.yml index e489376..2efd0fa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,7 @@ environment: matrix: - nodejs_version: '4' - nodejs_version: '6' + - nodejs_version: '7' install: - ps: Install-Product node $env:nodejs_version diff --git a/lib/mysql.js b/lib/mysql.js index ef6d5c8..4b7ebbf 100644 --- a/lib/mysql.js +++ b/lib/mysql.js @@ -7,12 +7,12 @@ const co = require('co'); let count = 0; module.exports = app => { - app.addSingleton('mysql', createClient); + app.addSingleton('mysql', createOneClient); }; -function createClient(config, app) { +function createOneClient(config, app) { const index = count++; - const done = app.readyCallback(`egg-mysql-createClient-${index}`); + const done = app.readyCallback(`egg-mysql-createOneClient-${index}`); app.coreLogger.info('[egg-mysql] connecting %s@%s:%s/%s', config.user, config.host, config.port, config.database); assert(config.host && config.port && config.user && config.database, diff --git a/package.json b/package.json index dcb131b..c2ecf58 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "test": "npm run lint && npm run test-local", "test-local": "egg-bin test", "cov": "egg-bin cov", - "lint": "eslint --ext js . --fix", + "lint": "eslint --ext js .", "ci": "npm run lint && npm run cov", "autod": "autod" },