Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0730b76

Browse files
whxaxesdead-horse
authored andcommittedJun 13, 2019
feat: add sequelize-ts-example (eggjs#109)
1 parent 47e8c4d commit 0730b76

26 files changed

+677
-0
lines changed
 

‎.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ before_install:
1111
- 'mv zookeeper-3.4.6/conf/zoo_sample.cfg zookeeper-3.4.6/conf/zoo.cfg'
1212
- './zookeeper-3.4.6/bin/zkServer.sh start'
1313
- mysql -e 'CREATE DATABASE IF NOT EXISTS `egg-sequelize-example-unittest`;'
14+
- mysql -e 'CREATE DATABASE IF NOT EXISTS `egg-sequelize-ts-unittest`;'
1415
install:
1516
- npm i npminstall && npminstall
1617
script:

‎sequelize-ts/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
typings/

‎sequelize-ts/.sequelizerc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
5+
module.exports = {
6+
config: path.join(__dirname, 'database/config.json'),
7+
'migrations-path': path.join(__dirname, 'database/migrations'),
8+
'seeders-path': path.join(__dirname, 'database/seeders'),
9+
};

‎sequelize-ts/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# sequelize-ts-example
2+
3+
The [egg] example project that uses [egg-sequelize] plugin. It will show you how to use sequelize in egg project, use [migrations] to help you manage changes of database and use [factory-girl] to help you write test cases more maintainable.
4+
5+
## QuickStart
6+
7+
### Dependencies
8+
9+
- install mysql and create database
10+
11+
```bash
12+
brew install mysql # macOS
13+
brew service start mysql
14+
15+
mysql
16+
> create database `egg-sequelize-ts-dev`;
17+
> create database `egg-sequelize-ts-unittest`;
18+
```
19+
20+
- install dependencies
21+
22+
```bash
23+
npm install
24+
```
25+
26+
### Start Server and Run Test
27+
28+
- prepare database structure
29+
30+
```bash
31+
# for develop
32+
npm run sequelize -- db:migrate
33+
# for unittest
34+
NODE_ENV=test npm run sequelize -- db:migrate
35+
```
36+
37+
- start project
38+
39+
```bash
40+
npm run dev
41+
```
42+
43+
- run test
44+
45+
```bash
46+
npm test
47+
```
48+
49+
[egg]: https://eggjs.org
50+
[egg-sequelize]: https://github.com/eggjs/egg-sequelize
51+
[sequelize]: http://docs.sequelizejs.com/
52+
[migrations]: http://docs.sequelizejs.com/manual/tutorial/migrations.html
53+
[factory-girl]: https://github.com/aexmachina/factory-girl

‎sequelize-ts/README.zh-CN.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# sequelize-ts-example
2+
3+
这个 [egg] 示例项目示范如何使用 [egg-sequelize] 插件。它会展示如何在 egg 项目中使用 [sequelize] 连接数据库,使用 [migrations] 来管理数据结构变更,并通过 [factory-girl] 来编写更易于维护的测试用例。
4+
5+
## 快速开始
6+
7+
### 安装依赖
8+
9+
- 安装 mysql 并建立数据库
10+
11+
```bash
12+
brew install mysql # macOS
13+
brew services start mysql
14+
15+
mysql
16+
> create database `egg-sequelize-ts-dev`;
17+
> create database `egg-sequelize-ts-unittest`;
18+
```
19+
20+
- 安装 node 依赖
21+
22+
```bash
23+
npm install
24+
```
25+
26+
### 启动和测试
27+
28+
- 执行 migration 执行数据变更
29+
30+
```bash
31+
# for develop
32+
npm run sequelize -- db:migrate
33+
# for unittest
34+
NODE_ENV=test npm run sequelize -- db:migrate
35+
```
36+
37+
- 启动项目
38+
39+
```bash
40+
npm run dev
41+
```
42+
43+
- 运行测试
44+
45+
```bash
46+
npm test
47+
```
48+
49+
[egg]: https://eggjs.org
50+
[egg-sequelize]: https://github.com/eggjs/egg-sequelize
51+
[sequelize]: http://docs.sequelizejs.com/
52+
[migrations]: http://docs.sequelizejs.com/manual/tutorial/migrations.html
53+
[factory-girl]: https://github.com/aexmachina/factory-girl

‎sequelize-ts/app/controller/post.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
import { Controller } from 'egg';
4+
5+
export default class PostController extends Controller {
6+
async index() {
7+
const ctx = this.ctx;
8+
const query = {
9+
limit: ctx.helper.parseInt(ctx.query.limit),
10+
offset: ctx.helper.parseInt(ctx.query.offset),
11+
};
12+
ctx.body = await ctx.service.post.list(query);
13+
}
14+
15+
async show() {
16+
const ctx = this.ctx;
17+
ctx.body = await ctx.service.post.find(ctx.helper.parseInt(ctx.params.id));
18+
}
19+
20+
async create() {
21+
const ctx = this.ctx;
22+
const post = await ctx.service.post.create(ctx.request.body);
23+
ctx.status = 201;
24+
ctx.body = post;
25+
}
26+
27+
async update() {
28+
const ctx = this.ctx;
29+
const id = ctx.params.id;
30+
const updates = {
31+
title: ctx.request.body.title,
32+
content: ctx.request.body.content,
33+
};
34+
ctx.body = await ctx.service.post.update({ id, user_id: ctx.request.body.user_id, updates });
35+
}
36+
37+
async destroy() {
38+
const ctx = this.ctx;
39+
const id = ctx.helper.parseInt(ctx.params.id);
40+
const user_id = ctx.helper.parseInt(ctx.request.body.user_id);
41+
await ctx.service.post.destroy({ id, user_id });
42+
ctx.status = 200;
43+
}
44+
}

‎sequelize-ts/app/controller/user.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
import { Controller } from 'egg';
4+
5+
export default class UserController extends Controller {
6+
async index() {
7+
const ctx = this.ctx;
8+
const query = {
9+
limit: ctx.helper.parseInt(ctx.query.limit),
10+
offset: ctx.helper.parseInt(ctx.query.offset),
11+
};
12+
ctx.body = await ctx.service.user.list(query);
13+
}
14+
15+
async show() {
16+
const ctx = this.ctx;
17+
ctx.body = await ctx.service.user.find(ctx.helper.parseInt(ctx.params.id));
18+
}
19+
20+
async create() {
21+
const ctx = this.ctx;
22+
const user = await ctx.service.user.create(ctx.request.body);
23+
ctx.status = 201;
24+
ctx.body = user;
25+
}
26+
27+
async update() {
28+
const ctx = this.ctx;
29+
const id = ctx.helper.parseInt(ctx.params.id);
30+
const body = ctx.request.body;
31+
ctx.body = await ctx.service.user.update({ id, updates: body });
32+
}
33+
34+
async destroy() {
35+
const ctx = this.ctx;
36+
const id = ctx.helper.parseInt(ctx.params.id);
37+
await ctx.service.user.del(id);
38+
ctx.status = 200;
39+
}
40+
}
41+

‎sequelize-ts/app/extend/helper.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
parseInt(str: string | number) {
3+
if (typeof str === 'number') return str;
4+
if (!str) return 0;
5+
return parseInt(str) || 0;
6+
},
7+
}

‎sequelize-ts/app/model/post.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
import { Application } from 'egg';
4+
5+
export default function(app: Application) {
6+
const { STRING, INTEGER, DATE } = app.Sequelize;
7+
8+
const Post = app.model.define('post', {
9+
id: {
10+
type: INTEGER,
11+
primaryKey: true,
12+
autoIncrement: true,
13+
},
14+
title: STRING(30),
15+
content: STRING(255),
16+
user_id: INTEGER,
17+
created_at: DATE(6),
18+
updated_at: DATE(6),
19+
});
20+
21+
return class extends Post {
22+
static associate() {
23+
app.model.Post.belongsTo(app.model.User, { as: 'user', foreignKey: 'user_id' });
24+
}
25+
26+
static async findByIdWithUser(id: number, userId: number) {
27+
return await this.findOne({
28+
where: { id, user_id: userId },
29+
});
30+
}
31+
}
32+
}

‎sequelize-ts/app/model/user.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
import { Application } from 'egg';
4+
5+
export default function(app: Application) {
6+
const { STRING, INTEGER, DATE } = app.Sequelize;
7+
const User = app.model.define('user', {
8+
id: {
9+
type: INTEGER,
10+
primaryKey: true,
11+
autoIncrement: true,
12+
},
13+
name: STRING(30),
14+
age: INTEGER,
15+
created_at: DATE(6),
16+
updated_at: DATE(6),
17+
});
18+
19+
return class extends User {
20+
static associate() {
21+
app.model.User.hasMany(app.model.Post, { as: 'posts' });
22+
}
23+
}
24+
}

‎sequelize-ts/app/router.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
import { Application } from 'egg';
4+
5+
export default function(app: Application) {
6+
app.resources('users', '/users', app.controller.user);
7+
app.resources('posts', '/posts', app.controller.post);
8+
}

‎sequelize-ts/app/service/post.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
import { Service } from 'egg';
4+
import { CreateOptions } from 'sequelize';
5+
6+
export default class Post extends Service {
7+
async list({ offset = 0, limit = 10, user_id = undefined }: { offset: number; limit: number; user_id?: number }) {
8+
return this.ctx.model.Post.findAndCountAll({
9+
offset,
10+
limit,
11+
attributes: [ 'id', 'title', 'user_id', 'created_at', 'updated_at' ],
12+
order: [[ 'created_at', 'desc' ], [ 'id', 'desc' ]],
13+
where: user_id ? { user_id } : undefined,
14+
});
15+
}
16+
17+
async find(id: number) {
18+
const post = await this.ctx.model.Post.findByPk(id, {
19+
include: [{
20+
model: this.ctx.model.User,
21+
as: 'user',
22+
attributes: [ 'id', 'name', 'age' ],
23+
}],
24+
});
25+
if (!post) {
26+
this.ctx.throw(404, 'post not found');
27+
}
28+
return post;
29+
}
30+
31+
async create(post: CreateOptions) {
32+
return this.ctx.model.Post.create(post);
33+
}
34+
35+
async update({ id, user_id, updates }: { id: number; user_id: number; updates: object }) {
36+
const post = await this.ctx.model.Post.findByIdWithUser(id, user_id);
37+
if (!post) this.ctx.throw(404, 'post not found');
38+
return post!.update(updates);
39+
}
40+
41+
async destroy({ id, user_id }: { id: number; user_id: number }) {
42+
const post = await this.ctx.model.Post.findByIdWithUser(id, user_id);
43+
if (!post) this.ctx.throw(404, 'post not found');
44+
return post!.destroy();
45+
}
46+
}

‎sequelize-ts/app/service/user.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
import { Service } from 'egg';
4+
import { CreateOptions } from 'sequelize';
5+
6+
class User extends Service {
7+
async list({ offset = 0, limit = 10 }: { offset: number; limit: number; }) {
8+
return this.ctx.model.User.findAndCountAll({
9+
offset,
10+
limit,
11+
order: [[ 'created_at', 'desc' ], [ 'id', 'desc' ]],
12+
});
13+
}
14+
15+
async find(id: number) {
16+
const user = await this.ctx.model.User.findByPk(id);
17+
if (!user) {
18+
this.ctx.throw(404, 'user not found');
19+
}
20+
return user!;
21+
}
22+
23+
async create(user: CreateOptions) {
24+
return this.ctx.model.User.create(user);
25+
}
26+
27+
async update({ id, updates }: { id: number; updates: object }) {
28+
const user = await this.ctx.model.User.findByPk(id);
29+
if (!user) {
30+
this.ctx.throw(404, 'user not found');
31+
}
32+
return user!.update(updates);
33+
}
34+
35+
async del(id: number) {
36+
const user = await this.ctx.model.User.findByPk(id);
37+
if (!user) {
38+
this.ctx.throw(404, 'user not found');
39+
}
40+
return user!.destroy();
41+
}
42+
}
43+
44+
module.exports = User;
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.