From 67f8f1fa828cc1795ee3d2c995e2a5206ebed741 Mon Sep 17 00:00:00 2001 From: ChangedenChan Date: Thu, 13 Aug 2020 09:22:35 +0800 Subject: [PATCH] feat: support plugins for special clients (#41) --- .travis.yml | 2 ++ README.md | 4 +++ lib/mongoose.js | 15 ++++++++- .../app/controller/book.js | 28 +++++++++++++++++ .../app/controller/user.js | 16 ++++++++++ .../app/model/Book.js | 12 +++++++ .../app/model/other.js | 5 +++ .../app/model/user.js | 11 +++++++ .../app/router.js | 6 ++++ .../config/config.default.js | 20 ++++++++++++ .../lib/mongoose.js | 15 +++++++++ .../package.json | 4 +++ test/mongoose.test.js | 31 +++++++++++++++++++ 13 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/controller/book.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/controller/user.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/model/Book.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/model/other.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/model/user.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/app/router.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/config/config.default.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/lib/mongoose.js create mode 100644 test/fixtures/apps/mongoose-multi-client-plugins/package.json diff --git a/.travis.yml b/.travis.yml index 2c41f78..a833e90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,3 +12,5 @@ after_script: - npminstall codecov && codecov services: - mongodb +cache: + npm: false diff --git a/README.md b/README.md index 9287bdf..bbbcf96 100644 --- a/README.md +++ b/README.md @@ -95,12 +95,16 @@ exports.mongoose = { db1: { url: 'mongodb://127.0.0.1/example1', options: {}, + // client scope plugin array + plugins: [] }, db2: { url: 'mongodb://127.0.0.1/example2', options: {}, }, }, + // public scope plugin array + plugins: [] }; ``` diff --git a/lib/mongoose.js b/lib/mongoose.js index 336341d..d47d220 100644 --- a/lib/mongoose.js +++ b/lib/mongoose.js @@ -8,6 +8,8 @@ const filterURLPassword = require('./filterURLPassword'); let count = 0; +const globalPlugins = []; + module.exports = app => { const { client, clients, url, options, defaultDB, customPromise, loadModel, plugins } = app.config.mongoose; @@ -26,6 +28,7 @@ module.exports = app => { mongoose.plugin.apply(mongoose, Array.isArray(plugin) ? plugin : [ plugin ]); }); } + globalPlugins.push(...mongoose.plugins || []); // TODO addSingleton support config[this.configName]? app.addSingleton('mongoose', createOneClient); @@ -53,7 +56,7 @@ module.exports = app => { }; function createOneClient(config, app) { - const { url, options } = config; + const { url, options, plugins } = config; const filteredURL = filterURLPassword(url); assert(url, '[egg-mongoose] url is required on config'); @@ -66,6 +69,16 @@ function createOneClient(config, app) { } app.coreLogger.info('[egg-mongoose] connecting %s', filteredURL); + // remove all plugins + const length = Array.isArray(mongoose.plugins) ? mongoose.plugins.length : 0; + for (let index = length; index > 0; index--) { + mongoose.plugins.pop(); + } + // combine clients plugins and public plugins + [].concat(plugins || [], globalPlugins).forEach(plugin => { + mongoose.plugin.apply(mongoose, Array.isArray(plugin) ? plugin : [ plugin ]); + }); + const db = mongoose.createConnection(url, options); /* istanbul ignore next */ diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/book.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/book.js new file mode 100644 index 0000000..2604e3b --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/book.js @@ -0,0 +1,28 @@ +'use strict'; + +module.exports = app => { + class BookController extends app.Controller { + * create() { + const book = new this.ctx.model.Book({ + name: this.ctx.request.body.name, + user: this.ctx.request.body.user, + }); + yield book.save(); + this.ctx.body = book; + } + + * show() { + const id = this.ctx.params.id; + const book = yield this.ctx.model.Book.findById(id) + .populate({ + path: 'user', + model: this.ctx.model.User, + }) + .exec(); + this.ctx.body = book; + } + } + + return BookController; + +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/user.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/user.js new file mode 100644 index 0000000..34e7724 --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/controller/user.js @@ -0,0 +1,16 @@ +'use strict'; + +module.exports = app => { + class UserController extends app.Controller { + * create() { + const user = new this.ctx.model.User({ + name: this.ctx.request.body.name, + }); + yield user.save(); + this.ctx.body = user; + } + } + + return UserController; + +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/model/Book.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/Book.js new file mode 100644 index 0000000..64abf44 --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/Book.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports = app => { + const db2 = app.mongooseDB.get('db2'); + const { Schema } = app.mongoose; + const BoookSchema = new Schema({ + name: { type: String }, + user: { type: Schema.Types.ObjectId, ref: 'User' }, + }); + + return db2.model('Book', BoookSchema); +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/model/other.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/other.js new file mode 100644 index 0000000..057414a --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/other.js @@ -0,0 +1,5 @@ +'use strict'; + +module.export = { + +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/model/user.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/user.js new file mode 100644 index 0000000..6283118 --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/model/user.js @@ -0,0 +1,11 @@ +'use strict'; + +module.exports = app => { + const db1 = app.mongooseDB.get('db2'); + const { Schema } = app.mongoose; + const UserSchema = new Schema({ + name: { type: String }, + }); + + return db1.model('User', UserSchema); +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/app/router.js b/test/fixtures/apps/mongoose-multi-client-plugins/app/router.js new file mode 100644 index 0000000..828ade7 --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/app/router.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = function(app) { + app.resources('users', '/users', 'user'); + app.resources('books', '/books', 'book'); +}; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/config/config.default.js b/test/fixtures/apps/mongoose-multi-client-plugins/config/config.default.js new file mode 100644 index 0000000..d88ee5b --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/config/config.default.js @@ -0,0 +1,20 @@ +'use strict'; + +const { lastModifiedPlugin } = require('../lib/mongoose'); + +exports.mongoose = { + clients: { + db1: { + url: process.env.MONGODB_URL_1, + options: {}, + }, + db2: { + url: process.env.MONGODB_URL, + options: {}, + plugins: [[ lastModifiedPlugin, { field: 'updatedAt' }]], + }, + }, + plugins: [ lastModifiedPlugin ], +}; + +exports.keys = 'aaa'; diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/lib/mongoose.js b/test/fixtures/apps/mongoose-multi-client-plugins/lib/mongoose.js new file mode 100644 index 0000000..6ec48c3 --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/lib/mongoose.js @@ -0,0 +1,15 @@ +'use strict'; + +module.exports = { + lastModifiedPlugin, +}; + +function lastModifiedPlugin(schema, options = {}) { + const { field = 'lastMod' } = options; + schema.add({ [field]: Date }); + + schema.pre('save', function(next) { + this.$set(field, new Date()); + next(); + }); +} diff --git a/test/fixtures/apps/mongoose-multi-client-plugins/package.json b/test/fixtures/apps/mongoose-multi-client-plugins/package.json new file mode 100644 index 0000000..dec528e --- /dev/null +++ b/test/fixtures/apps/mongoose-multi-client-plugins/package.json @@ -0,0 +1,4 @@ +{ + "name": "mongoose-test", + "version": "0.0.1" +} \ No newline at end of file diff --git a/test/mongoose.test.js b/test/mongoose.test.js index fa5d3ed..40ac53d 100644 --- a/test/mongoose.test.js +++ b/test/mongoose.test.js @@ -292,4 +292,35 @@ describe('test/mongoose.test.js', () => { assert(book.updatedAt instanceof Date); }); }); + + + describe('multi client plugins', () => { + let app; + before(function* () { + app = mm.app({ + baseDir: 'apps/mongoose-multi-client-plugins', + }); + yield app.ready(); + }); + + after(function* () { + yield app.close(); + }); + afterEach(mm.restore); + afterEach(function* () { + yield app.model.Book.remove({}); + yield app.model.User.remove({}); + }); + + it('should has model extra property', function* () { + const user = yield app.model.User.create({}); + const book = yield app.model.Book.create({}); + assert(user); + assert(user.lastMod instanceof Date); + assert(user.updatedAt instanceof Date); + assert(book); + assert(book.lastMod instanceof Date); + assert(book.updatedAt instanceof Date); + }); + }); });