Skip to content

Commit

Permalink
fix: allow models be extended from Bone directly (#12)
Browse files Browse the repository at this point in the history
* fix: allow models be extended from Bone directly

... to make codebases that use v0.4.x a bit easier to upgrade

* release: v1.1.4
  • Loading branch information
cyjake authored Jun 25, 2021
1 parent d52a7ee commit 58a1929
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 81 deletions.
8 changes: 7 additions & 1 deletion History.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
1.1.4 / 2021-06-25
==================

**fixes**
* [#12](https://github.com/eggjs/egg-orm/pull/12) - fix: allow models be extended from Bone directly to make codebases that use v0.4.x a bit easier to upgrade (Chen Yangjian <<[email protected]>>)

1.1.3 / 2021-06-16
==================

**fixes**
* [#9](https://github.com/eggjs/egg-orm/pull/9) - fix: ctx.model.ctx injection
* [#9](https://github.com/eggjs/egg-orm/pull/9) - fix: ctx.model.ctx injection (Chen Yangjian <<[email protected]>>)

1.1.2 / 2021-03-04
==================
Expand Down
10 changes: 9 additions & 1 deletion config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@

exports.orm = {
client: 'mysql',
database: '',
database: 'test',
host: 'localhost',
port: 3306,
user: 'root',

delegate: 'model',
baseDir: 'model',
migrations: 'database',

define: {
underscored: true,
},

// or put your config into datasources array to connect multiple databases
// datasources: [],
};
40 changes: 14 additions & 26 deletions lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,6 @@
const path = require('path');
const Realm = require('leoric');

const defaultConfig = {
client: 'mysql',
delegate: 'model',
baseDir: 'model',
logging(...args) {
// if benchmark enabled, log used
const used = typeof args[1] === 'number' ? `(${args[1]}ms)` : '';
global.app.logger.info('[egg-orm] %s %s', used, args[0]);
},
host: 'localhost',
port: 3306,
username: 'root',
define: {
freezeTableName: false,
underscored: true,
},
};

module.exports = class BootHook {
constructor(app) {
this.app = app;
Expand All @@ -30,13 +12,16 @@ module.exports = class BootHook {
async willReady() {
const { app } = this;
const config = app.config.orm;
const databases = (config.datasources || [ config ])
.map(datasource => loadDatabase(app, { ...defaultConfig, ...datasource }));
const datasources = config.datasources || [ config ];
// Make muitiple copies of Bone to support multiple databases, otherwise use Bone directly
const subclass = datasources.length > 1;
const databases = datasources.map(datasource => {
return loadDatabase(app, { subclass, ...datasource });
});
await Promise.all(databases.map(authenticate));
}
};


function injectContext(app, delegate) {
const RPOXY = Symbol('egg-orm:proxy');
const realm = app[delegate];
Expand Down Expand Up @@ -87,16 +72,19 @@ function loadDatabase(app, config) {
const modelDir = path.join(app.baseDir, 'app', config.baseDir);
const target = Symbol(config.delegate);
const models = [];
const { delegate, ...options } = config;

const realm = new Realm({ ...config, models });
const realm = new Realm({ ...options, models });
const Model = realm.Bone;
app[config.delegate] = realm;
app[delegate] = realm;

app.loader.loadToApp(modelDir, target, {
caseStyle: 'upper',
ignore: config.exclude,
initializer(factory) {
if (typeof factory === 'function') {
// module.exports = class User extends Bone {};
if (factory.prototype instanceof Model) return factory;
return factory(app, Model);
}
},
Expand All @@ -120,10 +108,10 @@ function loadDatabase(app, config) {
}
realm[model.name] = model;
}
app[config.delegate].Model = Model;
injectContext(app, config.delegate);
app[delegate].Model = Model;
injectContext(app, delegate);

return app[config.delegate];
return app[delegate];
}

async function authenticate(realm) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "egg-orm",
"version": "1.1.3",
"version": "1.1.4",
"description": "Object relational mapping for Egg applications",
"eggPlugin": {
"name": "orm"
Expand Down Expand Up @@ -29,7 +29,7 @@
"author": "Chen Yangjian <[email protected]>",
"license": "MIT",
"dependencies": {
"leoric": "^1.4.0-alpha.3"
"leoric": "^1.4.1"
},
"devDependencies": {
"egg": "^2.25.0",
Expand Down
51 changes: 27 additions & 24 deletions test/delegate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ describe('test/delegate.test.js', () => {
const user2 = new ctx.orm.User({
nickname: 'bar nickname',
});
console.log(user2.toObject());
assert(user2.nickname === 'bar nickname');
});

Expand All @@ -69,30 +68,34 @@ describe('test/delegate.test.js', () => {
assert.notEqual(ctx.orm, ctx2.orm);
assert.notEqual(ctx.orm.User, ctx2.orm.User);
});
});

describe('GET /users/:id, POST /users', () => {
it('should create and get user successfully', async () => {
const res = await app.httpRequest()
.post('/users')
.send({
nickname: 'rose',
email: '[email protected]',
});
assert(res.status === 200);
assert(res.body.id);
assert(res.body.nickname === 'rose');
assert(res.body.email === '[email protected]');
assert(res.body.createdAt);

const res2 = await app.httpRequest()
.get(`/users/${res.body.id}`)
.send({
nickname: 'rose',
email: '[email protected]',
});
assert(res2.status === 200);
assert.deepEqual(res2.body, res.body);
});
describe('GET /users/:id, POST /users', () => {
beforeEach(async function() {
await app.orm.User.truncate();
});

it('should create and get user successfully', async () => {
const res = await app.httpRequest()
.post('/users')
.send({
nickname: 'rose',
email: '[email protected]',
});
assert(res.status === 200);
assert(res.body.id);
assert(res.body.nickname === 'rose');
assert(res.body.email === '[email protected]');
assert(res.body.createdAt);

const res2 = await app.httpRequest()
.get(`/users/${res.body.id}`)
.send({
nickname: 'rose',
email: '[email protected]',
});
assert(res2.status === 200);
assert.deepEqual(res2.body, res.body);
});
});
});
4 changes: 2 additions & 2 deletions test/fixtures/apps/basic/app/model/post.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict';

module.exports = (app) => {
module.exports = function(app) {
const { DataTypes: { BIGINT, TEXT, STRING } } = app.model;
const Post = app.model.define('Post', {
id: { type: BIGINT, autoIncrement: true },
content: TEXT,
description: STRING,
})
});
return Post;
};
18 changes: 18 additions & 0 deletions test/fixtures/apps/legacy/app/controller/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

module.exports = app => {
return class UsersController extends app.Controller {
async show() {
const user = await this.ctx.model.User.findOne(this.ctx.params.id);
this.ctx.body = user;
}

async create() {
const user = await app.model.User.create({
nickname: this.ctx.request.body.nickname,
email: this.ctx.request.body.email,
});
this.ctx.body = user;
}
};
};
5 changes: 5 additions & 0 deletions test/fixtures/apps/legacy/app/model/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

const { Bone } = require('leoric');

module.exports = class User extends Bone {};
5 changes: 5 additions & 0 deletions test/fixtures/apps/legacy/app/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = function(app) {
app.resources('users', '/users', 'users');
};
16 changes: 16 additions & 0 deletions test/fixtures/apps/legacy/config/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const { Bone } = require('leoric');

exports.orm = {
database: 'egg-orm',
port: process.env.MYSQL_PORT,
// connect to Bone directly
Bone,
};

exports.keys = 'hello';

exports.security = {
csrf: false,
};
3 changes: 3 additions & 0 deletions test/fixtures/apps/legacy/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "legacy"
}
53 changes: 53 additions & 0 deletions test/legacy.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

const assert = require('assert').strict;
const mm = require('egg-mock');

describe('test/legacy.test.js', () => {
let app;

before(() => {
app = mm.app({
baseDir: 'apps/legacy',
});
return app.ready();
});

after(mm.restore);

describe('app.model', function() {
it('should be accessible via app.model', function() {
assert(app.model);
assert(app.model.User);
});
});

describe('GET /users/:id, POST /users', () => {
beforeEach(async function() {
await app.model.User.truncate();
});

it('should create and get user successfully', async () => {
const res = await app.httpRequest()
.post('/users')
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res.status === 200);
assert(res.body.id);
assert(res.body.nickname === 'jack');
assert(res.body.email === '[email protected]');
assert(res.body.createdAt);

const res2 = await app.httpRequest()
.get(`/users/${res.body.id}`)
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res2.status === 200);
assert.deepEqual(res2.body, res.body);
});
});
});
52 changes: 27 additions & 25 deletions test/plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ describe('test/plugin.test.js', () => {
const user2 = new ctx.model.User({
nickname: 'bar nickname',
});
console.log(user2.toObject());
assert(user2.nickname === 'bar nickname');
});

Expand Down Expand Up @@ -81,7 +80,6 @@ describe('test/plugin.test.js', () => {
const post2 = new ctx.model.Post({
description: 'bar nickname',
});
console.log(post2.toObject());
assert(post2.description === 'bar nickname');
});

Expand All @@ -101,30 +99,34 @@ describe('test/plugin.test.js', () => {
assert.notEqual(ctx.model, ctx2.model);
assert.notEqual(ctx.model.User, ctx2.model.User);
});
});

describe('GET /users/:id, POST /users', () => {
it('should create and get user successfully', async () => {
const res = await app.httpRequest()
.post('/users')
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res.status === 200);
assert(res.body.id);
assert(res.body.nickname === 'jack');
assert(res.body.email === '[email protected]');
assert(res.body.createdAt);

const res2 = await app.httpRequest()
.get(`/users/${res.body.id}`)
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res2.status === 200);
assert.deepEqual(res2.body, res.body);
});
describe('GET /users/:id, POST /users', () => {
beforeEach(async function() {
await app.model.User.truncate();
});

it('should create and get user successfully', async () => {
const res = await app.httpRequest()
.post('/users')
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res.status === 200);
assert(res.body.id);
assert(res.body.nickname === 'jack');
assert(res.body.email === '[email protected]');
assert(res.body.createdAt);

const res2 = await app.httpRequest()
.get(`/users/${res.body.id}`)
.send({
nickname: 'jack',
email: '[email protected]',
});
assert(res2.status === 200);
assert.deepEqual(res2.body, res.body);
});
});
});

0 comments on commit 58a1929

Please sign in to comment.