schema/field: initial work for UUID fields

Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/175

Reviewed By: idoshveki

Differential Revision: D18614288

fbshipit-source-id: d36e6dc6e7745e982cf91bb4c4548dcd3d9d33ac
This commit is contained in:
Ariel Mashraki
2019-11-20 07:13:15 -08:00
committed by Facebook Github Bot
parent 49c8efce3c
commit 33d08673cf
3 changed files with 110 additions and 19 deletions

View File

@@ -131,6 +131,18 @@ func Enum(name string) *enumBuilder {
}}
}
// UUID returns a new Field with type UUID. An example for defining UUID field is as follows:
//
// field.UUID("id").
// Default(uuid.New)
//
func UUID(name string) *uuidBuilder {
return &uuidBuilder{&Descriptor{
Name: name,
Info: &TypeInfo{Type: TypeUUID, Nillable: true},
}}
}
// stringBuilder is the builder for string fields.
type stringBuilder struct {
desc *Descriptor
@@ -526,3 +538,63 @@ func (b *enumBuilder) StructTag(s string) *enumBuilder {
func (b *enumBuilder) Descriptor() *Descriptor {
return b.desc
}
// uuidBuilder is the builder for uuid fields.
type uuidBuilder struct {
desc *Descriptor
}
// StorageKey sets the storage key of the field.
// In SQL dialects is the column name and Gremlin is the property.
func (b *uuidBuilder) StorageKey(key string) *uuidBuilder {
b.desc.StorageKey = key
return b
}
// Optional indicates that this field is optional on create.
// Unlike edges, fields are required by default.
func (b *uuidBuilder) Optional() *uuidBuilder {
b.desc.Optional = true
return b
}
// Immutable indicates that this field cannot be updated.
func (b *uuidBuilder) Immutable() *uuidBuilder {
b.desc.Immutable = true
return b
}
// Comment sets the comment of the field.
func (b *uuidBuilder) Comment(c string) *uuidBuilder {
return b
}
// StructTag sets the struct tag of the field.
func (b *uuidBuilder) StructTag(s string) *uuidBuilder {
b.desc.Tag = s
return b
}
// Type sets a custom type of the UUID field. It defaults to [16]byte.
func (b *uuidBuilder) Type(typ interface{}) *uuidBuilder {
t := reflect.TypeOf(typ)
b.desc.Info.Ident = t.String()
b.desc.Info.PkgPath = t.PkgPath()
return b
}
// Default sets the function that is applied to set default value
// of the field on creation. For example:
//
// field.UUID("id").
// Default(uuid.New)
//
func (b *uuidBuilder) Default(f func() [16]byte) *uuidBuilder {
b.desc.Default = f
return b
}
// Descriptor implements the ent.Field interface by returning its descriptor.
func (b *uuidBuilder) Descriptor() *Descriptor {
return b.desc
}

View File

@@ -10,10 +10,9 @@ import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/facebookincubator/ent/schema/field"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)
@@ -111,29 +110,29 @@ func TestJSON(t *testing.T) {
fd := field.JSON("name", map[string]string{}).
Optional().
Descriptor()
require.True(t, fd.Optional)
require.Empty(t, fd.Info.PkgPath)
require.Equal(t, "name", fd.Name)
require.Equal(t, field.TypeJSON, fd.Info.Type)
require.Equal(t, "map[string]string", fd.Info.String())
assert.True(t, fd.Optional)
assert.Empty(t, fd.Info.PkgPath)
assert.Equal(t, "name", fd.Name)
assert.Equal(t, field.TypeJSON, fd.Info.Type)
assert.Equal(t, "map[string]string", fd.Info.String())
fd = field.JSON("dir", http.Dir("dir")).
Optional().
Descriptor()
require.True(t, fd.Optional)
require.Equal(t, field.TypeJSON, fd.Info.Type)
require.Equal(t, "dir", fd.Name)
require.Equal(t, "net/http", fd.Info.PkgPath)
require.Equal(t, "http.Dir", fd.Info.String())
assert.True(t, fd.Optional)
assert.Equal(t, field.TypeJSON, fd.Info.Type)
assert.Equal(t, "dir", fd.Name)
assert.Equal(t, "net/http", fd.Info.PkgPath)
assert.Equal(t, "http.Dir", fd.Info.String())
fd = field.Strings("strings").
Optional().
Descriptor()
require.True(t, fd.Optional)
require.Empty(t, fd.Info.PkgPath)
require.Equal(t, "strings", fd.Name)
require.Equal(t, field.TypeJSON, fd.Info.Type)
require.Equal(t, "[]string", fd.Info.String())
assert.True(t, fd.Optional)
assert.Empty(t, fd.Info.PkgPath)
assert.Equal(t, "strings", fd.Name)
assert.Equal(t, field.TypeJSON, fd.Info.Type)
assert.Equal(t, "[]string", fd.Info.String())
}
func TestField_Tag(t *testing.T) {
@@ -151,6 +150,23 @@ func TestField_Enums(t *testing.T) {
"master",
).
Descriptor()
require.Equal(t, "role", fd.Name)
require.Equal(t, []string{"user", "admin", "master"}, fd.Enums)
assert.Equal(t, "role", fd.Name)
assert.Equal(t, []string{"user", "admin", "master"}, fd.Enums)
}
func TestField_UUID(t *testing.T) {
fd := field.UUID("id").
Default(func() [16]byte { return uuid.New() }).
Descriptor()
assert.Equal(t, "id", fd.Name)
assert.Equal(t, "[16]byte", fd.Info.String())
assert.NotNil(t, fd.Default)
fd = field.UUID("id").
Type(uuid.UUID{}).
Descriptor()
assert.Equal(t, "id", fd.Name)
assert.Equal(t, "uuid.UUID", fd.Info.String())
assert.Equal(t, "github.com/google/uuid", fd.Info.PkgPath)
assert.Nil(t, fd.Default)
}

View File

@@ -15,6 +15,7 @@ const (
TypeBool
TypeTime
TypeJSON
TypeUUID
TypeBytes
TypeEnum
TypeString
@@ -101,6 +102,7 @@ var (
TypeBool: "bool",
TypeTime: "time.Time",
TypeJSON: "json.RawMessage",
TypeUUID: "[16]byte",
TypeBytes: "[]byte",
TypeEnum: "string",
TypeString: "string",
@@ -119,6 +121,7 @@ var (
}
constNames = [...]string{
TypeJSON: "TypeJSON",
TypeUUID: "TypeUUID",
TypeTime: "TypeTime",
TypeEnum: "TypeEnum",
TypeBytes: "TypeBytes",