《甘十九妹》 ent 实现之 Schema 定义

《西游记》是我看过最多遍的小说,《甘十九妹》是我看过最多遍的电视剧,或许是我想学会孙悟空的神通广大,然后去江湖里挽救那个『不知何故落人间』的甘妹,那个说过『人生天地,如果能把持住是非曲直,敢爱敢恨,恩怨分明,就不愧人生天地一场。』的奇女子,那首二十余年仍在脑海中徘徊的《如果来生还是今世的重复》。

最近在无意中看到了 Facebook 出品的一个 Golang ORM 库—— ent,初步翻阅了一遍文档后,有种强烈的冲动,用它来实现甘妹江湖,尽管它不能拯救我的甘妹,却能让我具现出她的银碗盛雪。

江湖画布

先创建出一个江湖吧,不然我颠倒乾坤的甘妹放哪里呢?

mkdir /resources/codes/golang/ganshijiumei && cd $_
go mod init github.com/BiLuoHui/ganshijiumei

上面两句不摆了噻,诸君肯定比我懂,初始化的江湖是这样的:

马良神笔

要画出《甘十九妹》的江湖,先得买支笔噻,我这里选了 ent

go get github.com/facebookincubator/ent/cmd/entc

如此,你将会看到这支笔 entc。插,怎么多了个 c,好吧,其实我不知道,也不关心。挺好的,这个 c 就当是甘妹脸上那张遮住她绝世容颜的轻纱了。

门派与江湖儿女

走江湖的总得弄碗江湖的水喝喝,行走江湖的人多半都是某个门派的弟子,就如甘妹来自丹枫轩,剑平虽然历事多师,本没有归附于某个门派,但在岳阳门覆灭之时,答应冼冰做岳阳门忠贞不二的弟子,也就此开启了与甘妹的爱恨纠缠。

创建 Schema

所以我们先定义两个 Schema,一曰 MenPai,二曰 JiangHuRen。是的,你们没有看错,它们是拼音,我不会告诉诸君我英语很烂,更何况我也不认为英语有这样的词汇。管他呢,读者诸君就当它们是时下流行的 fanny mud pee 吧。

entc init MenPai JiangHuRen

现在江湖是这样的:

尽管在 build 时会自动 download 相关的库,但有强迫症的我还是先 get 一下:

go get -u github.com/facebookincubator/ent

门派

刚创建的门派 Schema 长这样:

package schema

import "github.com/facebookincubator/ent"

// MenPai holds the schema definition for the MenPai entity.
type MenPai struct {
  ent.Schema
}

// Fields of the MenPai.
func (MenPai) Fields() []ent.Field {
  return nil
}

// Edges of the MenPai.
func (MenPai) Edges() []ent.Edge {
  return nil
}

稍稍提一下:

  • Fields 函数定义一个 Entity 的属性。
  • Edges 函数定义一个 Entity 与其他 Entity 的关系,换个词叫 relations,Edge 是图这种数据结构的边界。

一个门派肯定有名字和地址对吧:

// Fields of the MenPai.
func (MenPai) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").Unique().Comment("门派名号"),
        field.String("address").Default("").Comment("门派府台尊地"),
    }
}

Mixin

通常辉煌历史有助于门派在江湖上叫字号,比如岳阳门就有300年的基业;而门派最近一次招收弟子是什么时候呢,有助于江湖人知道它是否还活跃于江湖,比如岳阳门最近一次招收弟子就是在月余前,那个人就是剑平大帅哥。对于江湖人也有类似的情况,比如姑娘你出生在什么时候,最后一次跟小和尚唱《皈依》是什么时候呢。

所以本着躺着不能坐着的原则我们创建一个 Mixin

touch ent/schema/mixin.go

然后来定义怎么记下你的生日,及你最后一次跟小和尚唱《皈依》的时间:

package schema

import (
    "github.com/facebookincubator/ent"
    "github.com/facebookincubator/ent/schema/field"
    "time"
)

type TimeMixin struct{}

func (TimeMixin) Fields() []ent.Field {
    return []ent.Field{
        field.Time("created_at").
            Immutable().
            Default(time.Now),
        field.Time("updated_at").
            Default(time.Now).
            UpdateDefault(time.Now),
    }
}

Immutable 函数告诉我们,生下来后你的出生年月就定了,不能改变。你明明是半老徐娘就不能说自己芳龄十八。

然后我们给门派加上这两个属性:

//  menpai.go
func (MenPai) Mixin() []ent.Mixin {
    return []ent.Mixin{
        TimeMixin{},
    }
}

有着优秀历史就不要藏着掖着,300年的岳阳门都能在江湖上叫字号,何况我们种花家呢。

江湖儿女

江湖儿女我就不赘述了,直接上代码:

package schema

import (
    "github.com/facebookincubator/ent"
    "github.com/facebookincubator/ent/schema/field"
)

// JiangHuRen holds the schema definition for the JiangHuRen entity.
type JiangHuRen struct {
    ent.Schema
}

// Fields of the JiangHuRen.
func (JiangHuRen) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").Unique().Comment("江湖名号一定要独一无二"),
        field.Uint("age").Comment("姑娘你芳龄几何"),
    }
}

// Edges of the JiangHuRen.
func (JiangHuRen) Edges() []ent.Edge {
    return nil
}

func (JiangHuRen) Mixin() []ent.Mixin {
    return []ent.Mixin{
        TimeMixin{},
    }
}

至此,江湖里最重要的两个元素就定义完了。当然还有武功,这个就不说了,大家都是大侠,不献丑了。

生成代码

entc generate ./ent/schema

然后就发现,哇,江湖里多了好多东西,然而这一切都只能算是甘妹江湖的构想。现在江湖是这样的:

他们是什么东东呢?且听下回分解。

ent
本作品采用《CC 协议》,转载必须注明作者和本文链接
折扇轻合书已竟,入戏太深我共卿。
讨论数量: 2

follow up ~ 自己最近也在跟着 geektutu 上的 7 天实现系列来写 Golang 的 ORM 和 Cache 这些。

4年前 评论

我草,这年轻人,这江湖,我都向往了

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!