Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] tegg 支持 leoric #4725

Closed
1 task
killagu opened this issue Jul 27, 2021 · 3 comments
Closed
1 task

[RFC] tegg 支持 leoric #4725

killagu opened this issue Jul 27, 2021 · 3 comments

Comments

@killagu
Copy link
Contributor

killagu commented Jul 27, 2021

背景

在 tegg 中以注解的方式来集成我们的 ORM 框架 Leoric。注解的几点优势:

  • 配置元信息化,不需要启动应用即可获取信息。方便静态分析,比如产出 sql
  • 类型强类型化,字段不用通过 define/attributes 等静态方法来定义,直接定义在类中

伪代码

import { Model, Index, Attribute, DataTypes, Bone, DataSource } from '@eggjs/tegg/orm';

// model/User.ts
@DataSource('foo')
@Model({
  tableName: 'users',
})
@Index([ 'gmt_modified' ])
@Index([ 'name' ], { unique: true, name: 'uk_name' })
export class User extends Bone {
  @Attribute(DataTypes.BIGINT, { primary: true, allowNull: false, autoIncrement: true })
  id: number;

  @Attribute(DataTypes.STRING, { name: 'user_name', allowNull: false })
  name: string;

  @Attribute(DataTypes.DATE)
  gmtModified: Date;
}

注解定义

Model

function Model (opts: {
  // 默认值为类名转 _ + s
  tableName?: string;
  // 未来可以扩展 comment, encoding 等字段
})

Index

function Index (fields: string[], opts?: {
  // 是否为唯一索引,默认 false
  unique?: boolean;
  // 是否为主键,默认 false
  primary?: boolean;
  // 索引名
  // 普通索引默认为 idx + 字段名
  // 唯一索引默认为 uk + 字段名
  name?: string;
})

Attribute

function Attribute(dataType: DataTypes, opts?: {
  // 字段名,默认为属性名
  name?: string;
 // 是否可空,默认为 true
 allowNull?: boolean;
 // 是否自增,默认 false
 autoIncrement?: boolean;
 // 是否是主键,默认 false
 // 如果是联合主键,请使用 Index 注解
 primary?: boolean;
 // 是否唯一,默认 false
 // 如果是联合索引,请使用 Index 注解
 unique?: boolean;
})

DataSource

// 多数据源情况下,指定数据源名称
// 对应 egg 的多客户端配置
function DataSource(dataSource) {
}

包导出

通过 @eggjs/tegg 包的 orm 路径来导出注解以及继承基类。Model, Index, Attribute, DataTypes 等注解没有问题,Bone 会有问题。Bone 中涉及了大量 ORM 实现细节,注解包不应该耦合实现,并且可能存在版本不统一情况。

解决方案:注解包可以将 leoric 设置为 peerDep,安装了 orm 插件之后即可统一,没有安装的情况下按照指定的版本为 leoric。存在一种特殊的情况,插件安装路径不是在项目的 node_modules 下面,这种还是会导致有两个 leoric 的存在,需要插件在启动时把注解中的 leoric 替换为实际运行时的。

跟进

  • PR URL
@cyjake
Copy link
Contributor

cyjake commented Jul 28, 2021

Index 目前 leoric 中还没有自动 diff 并执行 sql 的机制,只有两个操作索引的 api 可供手动调用:

await driver.addIndex(table, attributes, { name, type });
await driver.removeIndex(table, attributes, { name });

由于索引只需要在第一次配置的时候执行到数据,所以部分不适合放到 Model.initialize() 里面,准备按 static indexes = 方式实现,参考 cyjake/leoric#150

p.s. primary index 用得很少,似乎可以考虑先不支持,sequelize 里暂时也没有对应的

@killagu
Copy link
Contributor Author

killagu commented Jul 28, 2021

Index 目前 leoric 中还没有自动 diff 并执行 sql 的机制,只有两个操作索引的 api 可供手动调用

这个可以后面补齐的。rfc 的内容是想把所有的场景枚举出来。实际实现可以根据实际的实现情况来走。

@cyjake
Copy link
Contributor

cyjake commented Jul 28, 2021

嗯呐,我先放到计划中,会在 1.x 版本中实现掉

@killagu killagu closed this as completed Dec 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants