ent ( entgo.io/ent ) で ULID を使う
※この内容は https://nazo.hatenablog.com/entry/entgo-ulid と同一です
ent では UUID 型がデフォルトでサポートされているのですが、それとは別に ULID を使う方法を解説します。
ULID の実装は https://github.com/oklog/ulid を使用します。
ent の UUID 型は、driver.Valuer Interface を利用して値を取得しますが、 oklog/ulid の Value()
の実装がバイナリを返却するようになっているため、このままでは可読性が悪いです。 Value()
が String を返すようにした ULID 型を新たに定義するのが良いでしょう。そのようにすると、他の interface も実装する必要があります。
結論から言うと https://github.com/ent/contrib/blob/6623819401500db45747a2419172963217cef619/entgql/internal/todopulid/ent/schema/pulid/pulid.go にそのものの実装があります[1]。この実装はライブラリ化されているものではない( internal )ので、そのままコピペして利用するのが良いでしょう。
使用する場合には以下のようになります。
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("id").
GoType(pulid.ID("")).
DefaultFunc(func() pulid.ID { return pulid.MustNew("US") }),
field.Int("age").Positive(),
field.String("name").Default("unknown"),
}
}
prefixが不要な場合はprefixの部分を削ってしまうのが良いかと思います。
このままの実装でもう少し手軽に書きたい場合は、同リポジトリに mixin が存在しますので、これを持ち出すと良いと思います。
ent は各フィールドを固有の型にできますので、例えば上記例で ID を UserID
型にしたい場合は以下のようになります。
type UserID pulid.ID
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("id").
GoType(UserID("")).
DefaultFunc(func() UserID { return UserID(pulid.MustNew("US")) }),
field.Int("age").Positive(),
field.String("name").Default("unknown"),
}
}
-
https://github.com/tmc/pulid のように見えるのですが、こちらは
Value()
はバイナリを返すようです。 ↩︎
Discussion