From e4cc63c4117afed16c910c6a845da210c18d9dec Mon Sep 17 00:00:00 2001 From: Morgan Date: Sun, 10 Jan 2021 13:05:45 +0100 Subject: [PATCH] schema/field: add DefaultFunc for numeric types and add support for it in entc (#1153) * entc/load: allow defaultfuncs on numeric types * schema/field: add DefaultFunc on numeric types * docs: document DefaultFunc better * chore: update generated files * pr: address issues * docs: updates on faq, address requested changes --- doc/md/faq.md | 90 +++++++++++++++++++++++--- doc/md/schema-fields.md | 25 +++++++- entc/load/internal/bindata.go | 4 +- entc/load/schema.go | 2 +- entc/load/schema_test.go | 6 ++ schema/field/field_test.go | 15 +++++ schema/field/internal/numeric.tmpl | 10 +++ schema/field/numeric.go | 100 +++++++++++++++++++++++++++++ 8 files changed, 239 insertions(+), 13 deletions(-) diff --git a/doc/md/faq.md b/doc/md/faq.md index d52e415ee..eecd3147a 100644 --- a/doc/md/faq.md +++ b/doc/md/faq.md @@ -6,13 +6,14 @@ sidebar_label: FAQ ## Questions -[How to create an entity from a struct `T`?](#how-to-create-an-entity-from-a-struct-t) -[How to create a struct (or a mutation) level validator?](#how-to-create-a-mutation-level-validator) -[How to write an audit-log extension?](#how-to-write-an-audit-log-extension) -[How to write custom predicates?](#how-to-write-custom-predicates) -[How to add custom predicates to the codegen assets?](#how-to-add-custom-predicates-to-the-codegen-assets) -[How to define a network address field in PostgreSQL?](#how-to-define-a-network-address-field-in-postgresql) -[How to customize time fields to type `DATETIME` in MySQL?](#how-to-customize-time-fields-to-type-datetime-in-mysql) +[How to create an entity from a struct `T`?](#how-to-create-an-entity-from-a-struct-t) \ +[How to create a struct (or a mutation) level validator?](#how-to-create-a-mutation-level-validator) \ +[How to write an audit-log extension?](#how-to-write-an-audit-log-extension) \ +[How to write custom predicates?](#how-to-write-custom-predicates) \ +[How to add custom predicates to the codegen assets?](#how-to-add-custom-predicates-to-the-codegen-assets) \ +[How to define a network address field in PostgreSQL?](#how-to-define-a-network-address-field-in-postgresql) \ +[How to customize time fields to type `DATETIME` in MySQL?](#how-to-customize-time-fields-to-type-datetime-in-mysql) \ +[How do I use a custom generator of IDs?](#how-do-i-use-a-custom-generator-of-ids) ## Answers @@ -307,7 +308,7 @@ func (i Inet) Value() (driver.Value, error) { #### How to customize time fields to type `DATETIME` in MySQL? `Time` fields use the MySQL `TIMESTAMP` type in the schema creation by default, and this type - has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC (see, [MySQL docs](https://dev.mysql.com/doc/refman/5.6/en/datetime.html)). + has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC (see, [MySQL docs](https://dev.mysql.com/doc/refman/5.6/en/datetime.html)). In order to customize time fields for a wider range, use the MySQL `DATETIME` as follows: ```go @@ -316,4 +317,75 @@ field.Time("birth_date"). SchemaType(map[string]string{ dialect.MySQL: "datetime", }), -``` \ No newline at end of file +``` + +#### How do I use a custom generator of IDs? + +If you're using a custom ID generator instead of using auto-incrementing IDs in +your database (e.g. Twitter's [Snowflake](https://github.com/twitter-archive/snowflake/tree/snowflake-2010)), +you will need to write a custom ID field which automatically calls the generator +on resource creation. + +To achieve this, you can either make use of `DefaultFunc` or of schema hooks - +depending on your use case. If the generator does not return an error, +`DefaultFunc` is more concise, whereas setting a hook on resource creation +will allow you to capture errors as well. An example of how to use +`DefaultFunc` can be seen in the section regarding [the ID field](schema-fields.md#id-field). + +Here is an example of how to use a custom generator with hooks, taking as an +example [sonyflake](https://github.com/sony/sonyflake). + +```go +// BaseMixin to be shared will all different schemas. +type BaseMixin struct { + mixin.Schema +} + +func (BaseMixin) Fields() []ent.Field { + return []ent.Field{ + field.Uint64("id"), + } +} + +func (BaseMixin) Hooks() []ent.Hook { + return []ent.Hook{ + hook.On(IDHook(), ent.OpCreate), + } +} + +var sf = sonyflake.NewSonyflake(sonyflage.Settings{}) + +func IDHook() ent.Hook { + type IDSetter interface { + SetID(uint64) + } + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + is, ok := m.(IDSetter) + if !ok { + return nil, fmt.Errorf("unexpected mutation %T", m) + } + id, err := sf.NextID() + if err != nil { + return nil, err + } + is.SetID(id) + return next.Mutate(ctx, m) + }) + } +} + +// User holds the schema definition for the User entity. +type User struct { + ent.Schema +} + +// Mixin of the User. +func (User) Mixin() []ent.Mixin { + return []ent.Mixin{ + // Embed the BaseMixin in the user schema. + BaseMixin{}, + } +} +``` + diff --git a/doc/md/schema-fields.md b/doc/md/schema-fields.md index 0dc59461f..bd13f843c 100755 --- a/doc/md/schema-fields.md +++ b/doc/md/schema-fields.md @@ -144,6 +144,25 @@ func (Pet) Fields() []ent.Field { } ``` +If you need to set a custom function to generate IDs, you can use `DefaultFunc` +to specify a function which will always be ran when the resource is created. +See the [related FAQ](faq.md#how-do-i-use-a-custom-generator-of-ids) for more information. + +```go +var globalIDCounter int64 = 0 + +// Fields of the User. +func (User) Fields() []ent.Field { + return []ent.Field{ + field.Int64("id"). + DefaultFunc(func() int64 { + // example of a dumb ID generator - use a production-ready alternative instead + return time.Now().Unix() << 8 | atomic.AddInt64(&counter, 1) % 256 + }), + } +} +``` + ## Database Type Each database dialect has its own mapping from Go type to database type. For example, @@ -169,7 +188,7 @@ func (Card) Fields() []ent.Field { return []ent.Field{ field.Float("amount"). SchemaType(map[string]string{ - dialect.MySQL: "decimal(6,2)", // Override MySQL. + dialect.MySQL: "decimal(6,2)", // Override MySQL. dialect.Postgres: "numeric", // Override Postgres. }), } @@ -223,6 +242,7 @@ func (Card) Fields() []ent.Field { ## Default Values **Non-unique** fields support default values using the `Default` and `UpdateDefault` methods. +You can also specify `DefaultFunc` instead to have a custom generator. ```go // Fields of the User. @@ -241,6 +261,9 @@ func (User) Fields() []ent.Field { } ``` +In case your `DefaultFunc` is also returning an error, it is better if it is +handled properly. [See this FAQ.](faq.md#how-do-i-use-a-custom-generator-of-ids) + ## Validators A field validator is a function from type `func(T) error` that is defined in the schema diff --git a/entc/load/internal/bindata.go b/entc/load/internal/bindata.go index b73a94ef9..4316bc66c 100644 --- a/entc/load/internal/bindata.go +++ b/entc/load/internal/bindata.go @@ -98,7 +98,7 @@ func templateMainTmpl() (*asset, error) { return a, nil } -var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5a\x5f\x6f\xdc\x36\x12\x7f\xde\xfd\x14\x53\x03\x0d\xb4\xc1\x56\xee\x15\x45\x71\xb7\xb9\x3d\xa0\x68\x53\xd4\xd7\x8b\x1b\x34\x49\x5f\x0c\xc3\xa5\xa5\x91\xcd\x58\xa2\xb6\x24\xd7\xb1\xeb\xfa\xbb\x1f\x38\x43\x4a\x94\x56\xda\xdd\xf8\x4f\x5e\xb2\x1a\xce\x0c\x67\x7e\x9a\x7f\xa4\x7c\x78\x08\x3f\xd4\xab\x5b\x2d\x2f\x2e\x2d\x7c\xf3\xf5\x3f\xfe\xf5\xd5\x4a\xa3\x41\x65\xe1\x27\x91\xe1\x79\x5d\x5f\xc1\x91\xca\x52\xf8\xbe\x2c\x81\x98\x0c\xb8\x75\x7d\x8d\x79\x3a\x3d\x3c\x84\xf7\x97\xd2\x80\xa9\xd7\x3a\x43\xc8\xea\x1c\x41\x1a\x28\x65\x86\xca\x60\x0e\x6b\x95\xa3\x06\x7b\x89\xf0\xfd\x4a\x64\x97\x08\xdf\xa4\x5f\x87\x55\x28\xea\xb5\xca\x9d\x0a\xa9\x88\xe5\x7f\x47\x3f\xbc\x3e\x7e\xf7\x1a\x0a\x59\x62\xa0\xe9\xba\xb6\x90\x4b\x8d\x99\xad\xf5\x2d\xd4\x05\xd8\x68\x3f\xab\x11\xd3\xe9\x74\x25\xb2\x2b\x71\x81\x50\xd6\x22\x9f\x4e\x65\xb5\xaa\xb5\x85\x64\x3a\x39\x40\x95\xd5\xb9\x54\x17\x87\x1f\x4d\xad\x0e\xa6\x93\x83\xa2\xb2\xee\x3f\x8d\x45\x89\x99\x3d\x98\x4e\x27\x07\x17\xd2\x5e\xae\xcf\xd3\xac\xae\x0e\x0b\xef\xf0\x21\x2a\x62\x1b\x59\x3a\x34\xd9\x25\x56\x62\x37\xc7\x21\xe6\x17\xb8\x07\x5b\x21\xb1\xcc\xf7\xe0\x93\x2a\xc7\x9b\x83\xe9\x6c\xea\x40\x7b\x47\x34\xd0\xe8\x5f\x97\x01\xa1\x00\x95\x4d\xfd\x82\xbd\x14\x16\x3e\x09\x43\xa8\x60\x0e\x85\xae\x2b\x10\x90\xd5\xd5\xaa\x94\xee\xd5\x18\xd4\xe0\x91\x4b\xa7\xf6\x76\x85\x41\xa5\xb1\x7a\x9d\x59\xb8\x9b\x4e\x8e\x45\x85\xe0\xff\x19\xab\xa5\xba\x80\xfe\xbf\x3f\x1c\xb4\x8b\x03\x25\x2a\x9c\xd7\x95\xb4\x58\xad\xec\xed\xc1\x1f\xd3\xc9\x0f\xb5\x2a\xa4\xe7\x77\x66\xc5\xcf\x5d\xd9\x8c\x56\xba\xd2\xaf\xf3\x0b\x34\x9e\xed\xe4\xf4\xa5\x7b\x1c\xd9\xd9\x61\x6c\xba\xc2\x3f\x39\x3c\x4d\x23\x4c\x8f\xc3\xc2\x84\x7c\x4f\xfa\xc8\xa1\xec\x37\x3f\x39\x7d\x49\x8f\xc3\xd2\x92\x39\xbb\xe2\x3f\xd7\xf5\x55\x64\xf9\xdb\xda\x48\x2b\x6b\x35\x20\x7e\xe9\x38\xbb\xc2\x6f\xeb\x52\x66\xb7\xfb\x08\xaf\x88\xb3\x2b\xfd\xbd\x52\xb5\x15\x4e\xc0\x40\x25\x56\x27\xfc\xca\x4e\xa5\xb2\xa8\x5d\x3c\xdd\xdd\x07\x69\xd1\x72\x76\x54\xdc\x53\x68\x35\xdb\xe6\x68\x32\x2d\xcf\xd1\x80\x80\x55\x20\xfa\xcc\xe4\x98\xf4\x91\xd3\x48\xb4\xb1\x13\xe1\x26\x95\x05\x38\x3c\x04\x26\x79\x79\x82\xfe\xd0\x61\x00\xa5\x34\x36\x9d\x4e\xde\xc8\x1b\xcc\x8f\xc8\xd9\xf3\xba\x2e\xbd\x84\xcc\x84\x45\x03\xb2\x88\x76\x85\xfa\xfc\x23\x66\x1c\xde\x95\x93\xfa\x4a\x2a\x56\x20\x55\xd8\x84\xb7\x24\x12\xc8\x78\xe3\x8a\x48\xbc\x27\xfb\xcb\x01\xb2\x99\x49\x4c\x7f\x40\x22\xb1\xe0\x70\x1e\x8d\x66\xd2\x78\x2a\x1d\xa9\xa2\x6e\xd9\x5e\x12\x72\xe9\xfb\xdb\x15\x76\x16\xbc\xb8\x33\xa0\x2b\xfe\x5e\xc4\x9b\xed\xd8\xdd\x8a\x5e\x26\xbe\x93\x7f\x45\xb6\xbf\x94\xca\x7e\xf7\xed\xa8\xb4\x91\x7f\xf5\x36\x7f\xad\xd6\x95\x69\xd8\x4e\x4e\x19\x94\x3b\x38\x9e\xc3\xef\xc1\x96\x26\x2c\xd1\x31\x77\xe5\x3f\x28\xf9\xe7\xba\x31\x80\xe2\x62\xe0\x9f\x97\x5f\x13\x73\x57\xc1\xb1\x2c\x4b\x71\x5e\xe2\x5e\x0a\x94\x67\xee\xaa\xf8\x75\xe5\x62\x5b\x94\x7b\xa9\xa8\x3d\x73\x57\xc5\x8f\x58\x88\x75\x69\xf7\x73\x23\x67\xe6\x41\x0d\xbf\x8b\xd2\xc1\x11\xe7\xf4\xb8\x86\xb3\x6b\xc7\x3d\xa8\xe7\x17\xa9\x5c\x4d\xf4\x9d\x30\xf5\x8f\x63\x7a\xae\xa4\xca\x7b\xef\x65\x95\x0b\x8b\xc1\xad\x5d\xef\x85\x98\xcf\x06\xfd\x3a\xaa\xaa\xb5\x6d\x5e\xd0\x0e\x45\x32\x30\x77\x75\xfc\x2e\x4a\x99\x0b\x5b\x6b\x8a\x34\xca\xfd\x71\x1d\xd7\x0d\x73\x2f\xd0\x6d\xad\xc5\x05\xfe\x82\x54\x7f\x77\xa4\x89\x61\xe6\xb3\x2b\xbc\xed\x57\xf0\xb8\x64\x0f\x56\xf0\xb8\x88\xf3\x6a\xcf\x10\x54\x8e\x7c\xbd\x17\x22\x26\x30\xf7\x74\x50\x9d\x74\x35\xc2\xf1\x46\xcd\xa0\xe3\x57\xd0\x41\xcc\x67\x9b\x95\x23\x6e\x28\x30\xd6\x52\xf6\xeb\x29\xd4\xc1\x37\x4b\x2c\x91\x1f\x50\x61\x49\xee\x69\x06\x95\x00\xd2\x6e\xd9\xed\xa5\x75\x87\x6c\xbf\xae\xfe\x86\x45\x63\xf5\x76\x51\x8d\xc5\xd9\xa6\xd9\xbf\x61\xd1\x30\x0e\xce\x47\xb1\xfc\x78\x4d\x1d\x09\xaf\x2d\x05\xf5\x48\x5d\xa3\x36\x5b\x83\xb3\x99\x8f\x88\xb3\x6f\xf7\x9f\x6b\xa9\x31\xdf\x2d\xae\x3d\xe7\x78\x9a\xbe\x74\xc3\x5f\xda\x4d\xdc\x3d\x72\xf4\xa9\xe6\x24\x1e\x35\x36\x83\x9a\xe9\x0f\x88\x6a\x16\x6c\xc3\x3a\x7a\x51\x0d\x54\x5b\xde\x4c\x34\x34\x9f\x84\x44\xdf\x6b\x4a\xee\x73\x0f\x8d\xc5\x11\xca\x4d\xb8\xee\x00\x9a\x51\x3a\xc6\x4f\x14\x9e\x99\x46\x9a\xe4\x84\x0a\x88\x38\xa3\x18\x16\xfa\xc5\xd3\xe6\xca\xd6\x3a\x9d\x16\x6b\x95\x05\xc9\x04\x73\xff\xa6\x7f\x6c\x38\x66\x3e\xe6\xef\xa6\x13\x85\xb0\x58\xc2\x0b\xf7\x78\x37\x9d\xb8\x94\x5c\x34\x91\x84\x79\xfa\x5e\x5c\xcc\x1d\xf9\x76\x85\x8b\x98\xec\x72\x79\x3a\xa1\xca\x11\xd3\xdd\xb3\xa3\x33\xf4\x8b\x86\xce\xcf\x6e\xc5\xc7\xff\x22\xac\xf8\x67\xb7\x14\x62\x7b\xe1\x97\xc2\x33\xaf\x15\xed\x5e\xb4\x56\x84\xbd\x5a\x68\x17\xb4\xd4\x3e\xbb\xd5\x28\x5a\x17\x50\x89\x2b\x4c\x86\x63\x76\x36\x9f\x4e\xee\xa7\x93\xa2\xd6\x70\x36\x07\x61\x1d\x2a\x5a\xa8\x0b\x74\x2a\xe3\x90\x77\x28\x29\x4c\x45\x9e\xb7\xd4\x44\xd8\x19\x89\xcb\xc2\xcd\x04\x4e\x96\x6d\x7c\x45\x8f\x5f\x2c\x41\xc9\x32\x48\xba\xd2\xb3\x6c\xde\x8e\xc6\x62\xc6\xf4\x28\x44\x96\xc0\x7c\x11\x8d\xd4\x6b\xb4\x6b\xad\x40\x61\x1b\x1c\x3c\x2c\x6f\x46\x07\x05\x21\x87\x07\xff\x1c\x8a\x0f\x12\x4e\x8a\x3c\x4c\xc5\x71\x84\x24\x7c\xf2\x9b\x03\x6a\xed\x9e\xef\xc8\xbb\x22\x4f\x5f\x6b\x1d\x7b\x14\x6c\x92\xe5\x1c\x8a\xca\xba\xe5\x5a\x17\x09\x67\x01\x7c\xf9\xe7\x02\xbe\xbc\x3e\x98\x3b\x41\x7a\x61\x5e\x03\xc3\x65\x08\xaa\x17\xb4\xd1\x5d\x3f\x9c\xa0\x91\xa1\xb0\x29\xea\xee\x8a\xa3\xcc\xfb\x11\x4b\x2b\x3e\x66\x69\x76\x5e\xc4\x0b\x44\xd9\x08\x4f\x5a\x6a\x03\x34\x4c\xbc\x8b\xd6\x86\x30\xd6\x4e\x27\xcd\x30\xdb\xae\x06\x8a\x5b\xf5\x03\xdd\xa2\xd5\x1b\x46\x3c\x06\x8c\xf6\x8e\x47\xbf\x05\xed\xdd\x19\x06\x5b\xce\x66\xb6\x5b\x34\x3e\x37\x03\x5c\x3f\xee\x69\xb9\x1b\xf9\xed\x58\x47\xeb\x25\xaa\xa4\xc8\xd3\x96\x3a\x23\x25\x61\x00\x6a\xf6\x68\x28\xb4\xdc\x0c\x42\xcd\x1e\x0d\x65\x23\xbb\xe0\x61\xf9\x55\x6c\xe6\x97\x29\xc6\xf3\xcb\x14\xf4\xea\x61\xb9\x3b\x04\x2b\x69\x8c\x2b\xb5\xd4\x1d\xa4\x13\x72\xdb\x87\xc0\x3c\x98\x3b\x5d\x2e\xc0\x5a\xdd\xee\xb4\xb6\x58\x02\x1d\xd3\x1c\x5a\xee\xf8\x36\x7b\xc5\xf4\x2f\x96\xf0\x75\xb0\x8e\x8e\x75\x4b\x78\xe1\x16\x22\xc3\xc2\x3b\xf4\x5c\xf1\x61\x61\xd9\x1c\x16\x1c\x76\xbf\x16\x49\x1b\x1c\x33\x3a\x3f\x24\x6c\x85\x6b\x8c\x7c\x58\xf7\xf3\x3e\xd0\x29\x04\x32\xa1\xe0\x1c\x81\xee\xe4\x30\x07\x5b\x13\xcf\x05\x2a\xd4\x82\x72\xda\x49\xfe\x54\x6b\xc0\x1b\x51\xad\x4a\x9c\x83\xaa\x2d\x08\x70\xa9\x4e\x23\x74\x29\xaf\x10\xac\xac\x30\x3d\xae\x3f\xa5\x64\xf1\x19\x25\xb7\x73\xd8\x75\xa2\xf4\x8d\xd0\xe6\x52\x94\xb1\x65\xaf\x88\x21\x82\xba\xf5\x8a\x8f\x52\xcb\x28\xc8\xe3\x12\x65\x8a\xb9\x93\x69\xeb\x14\x37\xe7\xcd\x3a\xc5\x97\x0b\x54\xa7\xf8\xe7\x50\x9d\x22\xe1\x44\xe6\x37\xee\x04\x9d\xe3\x4d\xb7\x95\xb1\xea\xbb\x66\xef\x17\x44\x70\xd6\x52\x4b\xf7\xd9\x28\xf3\x1b\x9a\x97\xa9\x00\x70\xf7\x5e\x34\x0b\xfc\xdc\x2f\x0d\x6e\xa5\x2d\x0c\x71\xbe\xb9\x95\x4e\xb6\xdd\x7b\x4f\x3d\x86\xfe\x2e\x90\xdf\x16\xbd\xa9\xe8\x6e\xb1\xc9\x0a\xf7\xab\x06\x01\xff\x7d\xf7\xeb\xb1\x13\xa6\x99\xc7\xbf\xe8\x1c\xf9\x45\x13\x8b\x53\xf0\xae\x73\x77\xc3\xff\x79\x84\x3a\x9b\x26\x26\xec\xed\x46\x29\xbf\xd3\x0c\x92\x73\x38\x39\x3d\xbf\xb5\xc8\xef\xbc\x2d\xea\x86\x4a\x30\xcb\x3a\xcc\xf8\xa6\xd1\x83\xe6\xaf\xa9\x98\x96\xcc\x36\x5a\xbe\x54\x7c\xbb\x9c\xf4\x82\x9b\xe5\x66\x33\x4a\x2f\x96\xfb\xcc\x46\x2c\x8b\x10\x9b\x26\x75\xa1\x42\x57\x51\x41\x2f\x87\xe5\x1e\x4d\xc8\x63\xd1\x74\x21\xe3\x9b\x10\x86\x0e\xd4\x5e\x05\x47\xc3\x2a\xd4\xd7\xa8\xb5\xcc\xb1\xb9\x1e\x8b\x57\xd3\xc1\x2a\xe6\x91\x8a\xbc\x4c\x66\x9c\x31\xe3\xa5\xac\xe3\x20\x87\xe0\xd3\x7b\xc8\xb3\x6b\xb3\x97\x28\x90\xb2\x20\x6c\xd4\x18\xf2\x14\x7b\x79\x5c\x30\x1e\x9e\xdc\x50\xcd\x38\xf0\x80\xbd\x04\xb1\x5a\xa1\xca\x13\x4f\x98\xb7\x83\x6a\x94\xd6\xc9\x6c\xe6\x61\xf2\xb7\xc4\xb1\x03\xfe\x8e\xf9\x39\x5d\x70\xb5\xa6\x71\xc2\xdb\xe0\xdd\x08\x37\xdc\x91\x23\x47\xc1\xc8\xb8\x56\x0d\x7a\xd3\x7b\xe9\x74\xdd\xfd\xf4\xef\xbc\xbf\x0d\x5f\x8c\x3f\xfd\x3e\x5e\xb0\xd3\x3d\xcc\xcc\x97\xc2\x0f\xaa\xea\x14\x43\xae\x68\x86\xfb\x96\xbc\x46\x05\xe7\xeb\xa2\x40\x0d\x54\x03\x7d\x3b\x08\xf7\xe2\x54\xd7\x7a\x1a\x92\xf3\x75\xe1\x8b\x98\x1b\x4f\x99\x38\x1f\x2b\x65\x1d\x18\xc8\xc2\x46\x9d\x53\x34\x07\xb3\x1d\x08\xd4\x3a\x0e\x88\x22\x4a\x75\xdf\x2e\x48\xa4\xdd\xa3\x48\x7d\xc7\x36\xc9\xa6\xe6\x4d\xd5\x4e\x77\xd4\x2f\xe3\x76\xd9\xd4\x3b\xfa\x65\xfc\x9d\xbb\xad\xc3\xfd\x3d\x1f\xfa\xe2\xfa\xee\x01\x4b\x0c\x78\x58\x66\xd0\x2f\x9a\xfd\x86\x40\xb0\x39\xdb\x48\x7b\x27\xbf\x3a\xb5\x76\x4b\x76\xc5\x10\xc9\x39\x54\x51\xca\xb0\xc9\x74\xe2\x11\x95\x9f\xa9\x86\x5b\x45\x75\xd3\xb4\x89\xe9\x64\xe2\xcf\xce\xb1\x35\xbe\x30\x56\x37\xb3\x16\xee\x01\x64\xbb\x83\x9f\xdb\xbd\x89\x5b\x15\x45\xad\xb3\x97\x0c\xfe\xd8\x79\xa7\x45\xfb\x46\x27\x6e\x76\xf1\xfb\xb7\x67\xa4\x6e\x36\x3b\xb6\x01\x53\x3e\xd7\x16\x32\xc6\xcd\x54\xcd\x45\xe7\x12\x5e\x84\xdf\xac\x91\xca\x89\xef\xb7\x1f\xe7\x44\xf2\x5f\x7a\x88\x68\x35\x0f\x27\x93\xe8\xf3\xcd\x02\xe4\xbc\x55\x1e\x82\x35\x2a\x57\x7e\xda\x01\x53\x04\x40\xc6\x9a\xc4\x53\x83\x3e\xd6\x1c\x1e\xd4\x1d\x48\xeb\xb6\xfe\xf0\x0c\xd6\x8f\xf6\x85\xc7\x34\x06\xda\x80\xbf\x67\xc6\x6e\x70\x73\x78\xf2\xb8\x6f\xed\xa7\x2d\x83\xf5\xfc\xe5\x35\xb2\xfd\x67\x36\xe8\x09\xe3\x31\x98\xe1\xbf\xbe\xc6\xbe\xfa\x0e\xf5\x94\xce\xca\x02\x78\xa3\x8e\x22\x93\xfa\xaf\xc4\x91\xa7\x6f\xbd\x3d\x3d\x57\x3f\xdb\xaf\x81\xb1\xb0\xba\x19\x18\x09\x87\x67\xc2\x6e\x43\xe8\x76\x03\x9f\xc3\xdc\x0e\xf8\x00\xfb\x80\x76\xd0\x19\x31\x47\xfb\xc1\x78\x09\xfe\xec\x8e\x30\x5c\x60\xf7\xab\xaf\xe3\x41\xd0\xb4\xcf\xd1\xca\x19\x5e\x0f\xf1\xec\x2a\x80\x1b\x98\x0f\x62\x17\x4f\x6a\xa3\xd0\x8d\xe5\xf0\x67\x02\x37\x94\xa1\xfb\x26\x68\x93\x9f\x1c\x9b\x4d\x0c\x17\xa2\xe4\x5b\xd6\xfb\xbd\x5d\xee\x4c\x8d\xa3\x3e\x8f\x27\xf3\xfe\x5e\x0f\xa6\xea\x7e\x99\xba\x9f\x3b\xbd\x74\x53\x9b\xc7\x35\xca\xcc\x6c\xad\xf5\x1c\xea\x2b\x9e\x9c\xa3\xc4\x3d\x11\xca\xcf\x28\xa7\x64\xed\x17\xf5\x95\xb7\x71\x98\xc9\xd9\xac\x1a\x3f\x83\x8f\x55\xd0\xed\xf6\x49\x3d\x3e\xe9\x1b\xd4\x17\xa8\x67\xaf\x60\xb7\xce\x8a\x99\x13\xa1\x66\xfe\xca\x81\x3d\x45\xbe\xcf\x7f\x90\x9f\xb8\x8f\x9f\x63\x4c\x8f\xf1\x73\x8b\xce\x31\x3f\x0b\xe0\x4b\xe9\x07\x39\x5a\xec\xe3\xe8\x18\xd3\x63\x1c\xdd\xa2\x73\xb7\xa3\xed\x99\xa2\x4d\x39\x67\x6f\x7b\xd9\xf8\xf7\xdf\xee\xe9\x48\x15\x75\x7a\xbc\xae\x50\xcb\xcc\xb7\x99\x28\x27\x9c\xbd\xaa\x05\x22\xbe\xc2\x4b\x93\xa2\xac\x85\xfd\xee\xdb\x59\x07\x88\x81\x86\xbb\x56\x78\xb3\xc2\xcc\x62\xde\xbb\x9b\xa4\xfb\xd5\xe6\x6a\x75\xc1\x77\xab\xf1\xd5\xaa\xf9\x24\x6d\x76\x09\x96\x77\x27\x53\xdd\xf4\xff\x8a\x5e\x91\x30\x08\x16\xfe\xb3\x84\xf8\x2f\x73\xec\x3f\xe1\xc5\x0b\xb0\xf0\xef\x1e\xf9\xbb\x6f\x17\x84\x68\xef\x12\x92\x2f\x6c\x1d\x88\x43\xea\x3e\xc8\x61\x7d\x1f\xe4\xa8\xc2\x75\xab\x71\xa8\x27\xb7\x4d\x11\x3e\x69\xb1\x32\xf1\xdf\x74\x79\xba\x50\x39\x9f\x82\x02\xa1\x42\x7b\x59\xe7\xf0\x49\xda\x4b\xd0\x98\xd5\xd7\x7c\xf4\x45\x65\xd6\x1a\x41\xd5\xb0\x12\x4a\x66\x06\xa4\x02\x7f\x4e\x95\xea\xc2\x77\xf2\xa8\x09\x17\x79\xf4\xe7\x2b\xe0\x89\x33\x38\x39\x6d\xff\xe6\xea\x7e\x06\x89\xef\xb7\x11\xb9\x7f\xf1\x97\xa3\x3b\x7c\x3b\xf5\x3e\x5e\x64\x01\xd7\xd4\x7a\xd8\x38\x77\x8a\xbd\xee\xf4\x5f\xba\x0b\xee\x84\xc4\x97\xef\x83\x77\x6c\x7c\xf3\xb1\x67\x0e\xd7\x74\xc0\x29\x42\xef\xa5\x28\xa4\x11\xc7\x9d\xf3\x42\x74\xe5\x69\x70\x60\xde\x43\x97\x8f\x03\x1b\xe0\x32\xf9\xb1\x50\xc6\x37\x60\x31\x9a\x4c\x0f\x60\xd2\x27\x52\x87\x25\x9f\x53\x5a\xe2\x73\x20\xd9\xf1\xaf\x03\x26\x03\x89\xfe\x78\x34\x88\x63\x2c\xbc\x09\x65\x38\x97\x6c\x80\x19\x16\x1e\x0b\x67\xf7\x3e\x2e\x06\x34\xac\x04\x48\xf9\xaa\xde\x61\x1a\xce\x4e\x11\xfd\x19\x61\x0d\x9e\x0e\x00\x2b\x9b\x53\xdb\x36\x68\x1b\x47\xfa\xe0\xf2\x3d\xcd\x06\xb4\x4c\x7e\x2c\xb0\xdb\xee\x6f\x12\x3e\xff\x30\x7e\x6f\xda\x3b\x9c\x67\xc1\x8f\xdd\x19\x40\x8f\x8d\xd8\x8e\x1d\x7b\xb1\x81\x1c\xcf\xb3\x1b\xc8\x31\xf9\xb1\xc8\x75\xc6\xf5\x28\x20\x99\x1e\xc2\xd1\x3d\x51\x34\xf2\x9c\xdd\x12\x9f\x11\x4a\xf6\x6f\x00\xca\x4b\x3f\xdf\x6f\x83\xd2\x9b\xdf\x87\xd2\x0f\xca\x1b\x58\x7a\xfa\x63\xc1\xec\x1e\x04\x22\x34\xfd\xc2\x8c\x62\xd3\x6f\xe6\xe0\xf4\xc3\x7c\x4b\x7d\x46\x3c\xfd\xb6\x03\x80\xae\xc2\xf1\x61\x1b\xa2\xc1\x85\x79\xe7\xec\xd0\x5c\x56\xda\xce\x67\xdb\x59\xe7\x89\x0e\xcb\xb5\x06\xeb\xbf\xdf\xc2\xb2\xfd\xc8\xfb\xd6\xd2\xa4\x36\xb1\xb0\x04\x9b\xbe\x2e\xb1\x4a\x3a\xa3\x84\x9d\xde\x4f\xff\x1f\x00\x00\xff\xff\xa6\x55\xc8\xfc\x3c\x32\x00\x00") +var _schemaGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x5a\x5f\x6f\xdb\x46\x12\x7f\x96\x3e\xc5\xd4\x40\x0d\x32\x50\xe9\x5e\x51\x14\x77\xca\xe9\x80\xa2\x4d\x50\x5f\x2f\x6e\xd0\x24\x7d\x31\x0c\x77\x4d\x0e\xad\x8d\xc9\xa5\xb2\x5c\x39\x76\x5d\x7f\xf7\xc3\xce\xec\x92\x4b\x8a\x94\x14\xff\xc9\x4b\xc4\xd9\x9d\xd9\x99\x1f\xe7\xdf\x0e\x7d\x74\x04\x3f\x55\xab\x5b\x2d\x2f\x97\x06\xbe\xfb\xf6\x1f\xff\xfa\x66\xa5\xb1\x46\x65\xe0\xb5\x48\xf1\xa2\xaa\xae\xe0\x58\xa5\x09\xfc\x58\x14\x40\x9b\x6a\xb0\xeb\xfa\x1a\xb3\x64\x7a\x74\x04\xef\x97\xb2\x86\xba\x5a\xeb\x14\x21\xad\x32\x04\x59\x43\x21\x53\x54\x35\x66\xb0\x56\x19\x6a\x30\x4b\x84\x1f\x57\x22\x5d\x22\x7c\x97\x7c\xeb\x57\x21\xaf\xd6\x2a\xb3\x22\xa4\xa2\x2d\xff\x3b\xfe\xe9\xd5\xc9\xbb\x57\x90\xcb\x02\x3d\x4d\x57\x95\x81\x4c\x6a\x4c\x4d\xa5\x6f\xa1\xca\xc1\x04\xe7\x19\x8d\x98\x4c\xa7\x2b\x91\x5e\x89\x4b\x84\xa2\x12\xd9\x74\x2a\xcb\x55\xa5\x0d\x44\xd3\xc9\x01\xaa\xb4\xca\xa4\xba\x3c\xfa\x58\x57\xea\x60\x3a\x39\xc8\x4b\x63\xff\xd3\x98\x17\x98\x9a\x83\xe9\x74\x72\x70\x29\xcd\x72\x7d\x91\xa4\x55\x79\x94\x3b\x83\x8f\x50\xd1\xb6\x91\xa5\xa3\x3a\x5d\x62\x29\x76\xef\x38\xc2\xec\x12\xf7\xd8\x96\x4b\x2c\xb2\x3d\xf6\x49\x95\xe1\xcd\xc1\x34\x9e\x5a\xd0\xde\x11\x0d\x34\xba\xd7\x55\x83\x50\x80\xca\x24\x6e\xc1\x2c\x85\x81\xcf\xa2\x26\x54\x30\x83\x5c\x57\x25\x08\x48\xab\x72\x55\x48\xfb\x6a\x6a\xd4\xe0\x90\x4b\xa6\xe6\x76\x85\x5e\x64\x6d\xf4\x3a\x35\x70\x37\x9d\x9c\x88\x12\xc1\xfd\xab\x8d\x96\xea\x12\xfa\xff\xfe\xb4\xd0\xce\x0f\x94\x28\x71\x56\x95\xd2\x60\xb9\x32\xb7\x07\x7f\x4e\x27\x3f\x55\x2a\x97\x6e\xbf\x55\x2b\x7c\xee\xf2\xa6\xb4\xd2\xe5\x7e\x95\x5d\x62\xed\xb6\x9d\x9e\xbd\xb0\x8f\x23\x27\x5b\x8c\xeb\x2e\xf3\x6b\x8b\x67\xdd\x30\xd3\xe3\x30\x33\x21\xdf\xe3\x3e\xb6\x28\xbb\xc3\x4f\xcf\x5e\xd0\xe3\x30\xb7\xe4\x9d\x5d\xf6\x5f\xaa\xea\x2a\xd0\xfc\x6d\x55\x4b\x23\x2b\x35\xc0\xbe\xb4\x3b\xbb\xcc\x6f\xab\x42\xa6\xb7\xfb\x30\xaf\x68\x67\x97\xfb\x47\xa5\x2a\x23\x2c\x43\x0d\xa5\x58\x9d\xf2\x2b\x3b\x93\xca\xa0\xb6\xfe\x74\x77\xef\xb9\x45\xbb\xb3\x23\xe2\x9e\x5c\xab\x39\x36\xc3\x3a\xd5\xf2\x02\x6b\x10\xb0\xf2\x44\x17\x99\xec\x93\xce\x73\x1a\x8e\xd6\x77\x02\xdc\xa4\x32\x00\x47\x47\xc0\x24\xc7\x4f\xd0\x1f\x59\x0c\xa0\x90\xb5\x49\xa6\x93\x37\xf2\x06\xb3\x63\x32\xf6\xa2\xaa\x0a\xc7\x21\x53\x61\xb0\x06\x99\x07\xa7\x42\x75\xf1\x11\x53\x76\xef\xd2\x72\x7d\x23\x15\x0b\x90\xca\x1f\xc2\x47\x12\x09\x64\x78\x70\x49\x24\x3e\x93\xed\x65\x07\xd9\x8c\x24\xa6\x3f\x20\x90\x98\x71\x38\x8e\x46\x23\x69\x3c\x94\x8e\x55\x5e\xb5\xdb\x5e\x10\x72\xc9\xfb\xdb\x15\x76\x16\x1c\xbb\x55\xa0\xcb\xfe\x5e\x84\x87\xed\x38\xdd\x88\x5e\x24\xbe\x93\x7f\x05\xba\xbf\x90\xca\xfc\xf0\xfd\x28\x77\x2d\xff\xea\x1d\xfe\x4a\xad\xcb\xba\xd9\x76\x7a\xc6\xa0\xdc\xc1\xc9\x0c\xfe\xf0\xba\x34\x6e\x89\x76\x73\x97\xff\x83\x92\x9f\xd6\x8d\x02\xe4\x17\x03\xff\x1c\xff\x9a\x36\x77\x05\x9c\xc8\xa2\x10\x17\x05\xee\x25\x40\xb9\xcd\x5d\x11\xbf\xad\xac\x6f\x8b\x62\x2f\x11\x95\xdb\xdc\x15\xf1\x33\xe6\x62\x5d\x98\xfd\xcc\xc8\x78\xf3\xa0\x84\x3f\x44\x61\xe1\x08\x63\x7a\x5c\xc2\xf9\xb5\xdd\x3d\x28\xe7\x57\xa9\x6c\x4e\x74\x95\x30\x71\x8f\x63\x72\xae\xa4\xca\x7a\xef\x65\x95\x09\x83\xde\xac\x5d\xef\x85\x36\x9f\x0f\xda\x75\x5c\x96\x6b\xd3\xbc\xa0\x1d\x82\xa4\xdf\xdc\x95\xf1\x87\x28\x64\x26\x4c\xa5\xc9\xd3\x28\xf6\xc7\x65\x5c\x37\x9b\x7b\x8e\x6e\x2a\x2d\x2e\xf1\x57\xa4\xfc\xbb\x23\x4c\x6a\xde\x7c\x7e\x85\xb7\xfd\x0c\x1e\xa6\xec\xc1\x0c\x1e\x26\x71\x5e\xed\x29\x82\xca\x92\xaf\xf7\x42\xa4\xf6\x9b\x7b\x32\x28\x4f\xda\x1c\x61\xf7\x06\xc5\xa0\x63\x97\x97\x41\x9b\xcf\x37\x33\x47\x58\x50\x60\xac\xa4\xec\x57\x53\xa8\x82\x6f\xa6\x58\x22\x3f\x20\xc3\x12\xdf\xd3\x34\x2a\x1e\xa4\xdd\xbc\xdb\x53\xeb\x0e\xde\x7e\x5e\xfd\x1d\xf3\x46\xeb\xed\xac\x1a\xf3\xf3\x4d\xb5\x7f\xc7\xbc\xd9\x38\xd8\x1f\x85\xfc\xe3\x39\x75\xc4\xbd\xb6\x24\xd4\x63\x75\x8d\xba\xde\xea\x9c\x4d\x7f\x44\x3b\xfb\x7a\x7f\x5a\x4b\x8d\xd9\x6e\x76\xed\x76\x8e\x87\xe9\x0b\xdb\xfc\x25\xdd\xc0\xdd\x23\x46\x9f\xaa\x4f\xe2\x56\x63\xd3\xa9\x99\xfe\x00\xaf\x66\xc6\xd6\xad\x83\x17\xd5\x40\xb5\xe5\xcd\x04\x4d\xf3\xa9\x0f\xf4\xbd\xba\xe4\xfe\xee\xa1\xb6\x38\x40\xb9\x71\xd7\x1d\x40\x33\x4a\x27\xf8\x99\xdc\x33\xd5\x48\x9d\x9c\x50\x1e\x11\xab\x14\xc3\x42\xbf\xb8\xdb\x5c\x99\x4a\x27\xd3\x7c\xad\x52\xcf\x19\x61\xe6\xde\xf4\xcf\xcd\x8e\xd8\xf9\xfc\xdd\x74\xa2\x10\xe6\x0b\x38\xb4\x8f\x77\xd3\x89\x0d\xc9\x79\xe3\x49\x98\x25\xef\xc5\xe5\xcc\x92\x6f\x57\x38\x0f\xc9\x36\x96\xa7\x13\xca\x1c\x21\xdd\x3e\x5b\x3a\x43\x3f\x6f\xe8\xfc\x6c\x57\x9c\xff\xcf\xfd\x8a\x7b\xb6\x4b\xde\xb7\xe7\x6e\xc9\x3f\xf3\x5a\xde\x9e\x45\x6b\xb9\x3f\xab\x85\x76\x4e\x4b\xed\xb3\x5d\x0d\xbc\x75\x0e\xa5\xb8\xc2\x68\xd8\x67\xe3\xd9\x74\x72\x3f\x9d\xe4\x95\x86\xf3\x19\x08\x63\x51\xd1\x42\x5d\xa2\x15\x19\xba\xbc\x45\x49\x61\x22\xb2\xac\xa5\x46\xc2\xc4\xc4\x2e\x73\xdb\x13\x58\x5e\xd6\xf1\x25\x3d\x7e\xb5\x00\x25\x0b\xcf\x69\x53\xcf\xa2\x79\x3b\x1a\xf3\x98\xe9\x81\x8b\x2c\x80\xf7\x05\x34\x12\xaf\xd1\xac\xb5\x02\x85\xad\x73\x70\xb3\xbc\xe9\x1d\xe4\x84\xec\x1e\xfc\x73\xc8\x3f\x88\x39\xca\x33\xdf\x15\x87\x1e\x12\xf1\xcd\x6f\x06\xa8\xb5\x7d\xbe\x23\xeb\xf2\x2c\x79\xa5\x75\x68\x91\xd7\x49\x16\x33\xc8\x4b\x63\x97\x2b\x9d\x47\x1c\x05\xf0\xf5\xa7\x39\x7c\x7d\x7d\x30\xb3\x8c\xf4\xc2\x9c\x04\x86\xab\x26\xa8\x0e\xe9\xa0\xbb\xbe\x3b\x41\xc3\x43\x6e\x93\x57\xdd\x15\x4b\x99\xf5\x3d\x96\x56\x9c\xcf\x52\xef\x3c\x0f\x17\x88\xb2\xe1\x9e\xb4\xd4\x3a\xa8\xef\x78\xe7\xad\x0e\xbe\xad\x9d\x4e\x9a\x66\xb6\x5d\xf5\x14\xbb\xea\x1a\xba\x79\x2b\xd7\xb7\x78\x0c\x18\x9d\x1d\xb6\x7e\x73\x3a\xbb\xd3\x0c\xb6\x3b\x9b\xde\x6e\xde\xd8\xdc\x34\x70\x7d\xbf\xa7\xe5\xae\xe7\xb7\x6d\x1d\xad\x17\xa8\xa2\x3c\x4b\x5a\x6a\x4c\x42\x7c\x03\xd4\x9c\xd1\x50\x68\xb9\x69\x84\x9a\x33\x1a\xca\x46\x74\xc1\xc3\xe2\x2b\xdf\x8c\xaf\x3a\x1f\x8f\xaf\x3a\xa7\x57\x0f\x8b\xdd\x2e\x58\xca\xba\xb6\xa9\x96\xaa\x83\xb4\x4c\xf6\x78\xef\x98\x07\x33\x2b\xcb\x3a\x58\x2b\xdb\xde\xd6\xe6\x0b\xa0\x6b\x9a\x45\xcb\x5e\xdf\xe2\x97\x4c\xff\x6a\x01\xdf\x7a\xed\xe8\x5a\xb7\x80\x43\xbb\x10\x28\xe6\xdf\xa1\xdb\x15\x5e\x16\x16\xcd\x65\xc1\x62\xf7\x5b\x1e\xb5\xce\x11\xd3\xfd\x21\x62\x2d\x6c\x61\xe4\xcb\xba\xeb\xf7\x81\x6e\x21\x90\x0a\x05\x17\x08\x34\x93\xc3\x0c\x4c\x45\x7b\x2e\x51\xa1\x16\x14\xd3\x96\xf3\x75\xa5\x01\x6f\x44\xb9\x2a\x70\x06\xaa\x32\x20\xc0\x86\x3a\xb5\xd0\x85\xbc\x42\x30\xb2\xc4\xe4\xa4\xfa\x9c\x90\xc6\xe7\x14\xdc\xd6\x60\x5b\x89\x92\x37\x42\xd7\x4b\x51\x84\x9a\xbd\xa4\x0d\x01\xd4\xad\x55\x7c\x95\x5a\x04\x4e\x1e\xa6\xa8\x3a\x9f\x59\x9e\x36\x4f\x71\x71\xde\xcc\x53\x3c\x5c\xa0\x3c\xc5\x3f\x87\xf2\x14\x31\x47\x32\xbb\xb1\x37\xe8\x0c\x6f\xba\xa5\x8c\x45\xdf\x35\x67\x1f\x12\xc1\x6a\x4b\x25\xdd\x45\xa3\xcc\x6e\xa8\x5f\xa6\x04\xc0\xd5\x7b\xde\x2c\xf0\x73\x3f\x35\xd8\x95\x36\x31\x84\xf1\x66\x57\x3a\xd1\x76\xef\x2c\x75\x18\xba\x59\x20\xbf\x2d\x7a\x53\xc1\x6c\xb1\x89\x0a\xfb\xab\x02\x01\xff\x7d\xf7\xdb\x89\x65\xa6\x9e\xc7\xbd\xe8\x0c\xf9\x45\xd3\x16\x2b\xe0\x5d\x67\x76\xc3\xff\x39\x84\x3a\x87\x46\xb5\x3f\xdb\xb6\x52\xee\xa4\x18\xa2\x0b\x38\x3d\xbb\xb8\x35\xc8\xef\xbc\x4d\xea\x35\xa5\x60\xe6\xb5\x98\xf1\xa4\xd1\x81\xe6\xc6\x54\x4c\x8b\xe2\x8d\x92\x2f\x15\x4f\x97\xa3\x9e\x73\x33\x5f\x1c\x53\x78\x31\xdf\x17\x16\x62\x99\x7b\xdf\xac\x13\xeb\x2a\x34\x8a\xf2\x72\xd9\x2d\xf7\x28\x42\x0e\x8b\xa6\x0a\xd5\xae\x08\xa1\xaf\x40\xed\x28\x38\x68\x56\xa1\xba\x46\xad\x65\x86\xcd\x78\x2c\x5c\x4d\x06\xb3\x98\x43\x2a\xb0\x32\x8a\x39\x62\xc6\x53\x59\xc7\x40\x76\xc1\xa7\xb7\x90\x7b\xd7\xe6\x2c\x91\x23\x45\x81\x3f\xa8\x51\xe4\x29\xce\x72\xb8\x60\xd8\x3c\xd9\xa6\x9a\x71\xe0\x06\x7b\x01\x62\xb5\x42\x95\x45\x8e\x30\x6b\x1b\xd5\x20\xac\xa3\x38\x76\x30\xb9\x29\x71\x68\x80\x9b\x31\x3f\xa7\x09\x36\xd7\x34\x46\x38\x1d\x9c\x19\x7e\xc2\x1d\x18\x72\xec\x95\x0c\x73\xd5\xa0\x35\xbd\x97\x4e\xe3\xee\xa7\x7f\xe7\xfd\x63\x78\x30\xfe\xf4\xe7\x38\xc6\x4e\xf5\xa8\x63\x97\x0a\x3f\xa8\xb2\x93\x0c\x39\xa3\xd5\x5c\xb7\xe4\x35\x2a\xb8\x58\xe7\x39\x6a\xa0\x1c\xe8\xca\x81\x9f\x8b\x53\x5e\xeb\x49\x88\x2e\xd6\xb9\x4b\x62\xb6\x3d\x65\xe2\x6c\x2c\x95\x75\x60\x20\x0d\x1b\x71\x56\xd0\x0c\xea\xed\x40\xa0\xd6\xa1\x43\xe4\x41\xa8\xbb\x72\x41\x2c\xed\x19\x79\xe2\x2a\x76\x1d\x6d\x4a\xde\x14\x6d\x65\x07\xf5\x32\x2c\x97\x4d\xbe\xa3\x5f\xb5\x9b\xb9\x9b\xca\xcf\xef\xf9\xd2\x17\xe6\x77\x07\x58\x54\x83\x83\x25\x86\x7e\xd2\xec\x17\x04\x82\xcd\xea\x46\xd2\x3b\xf1\xd5\xc9\xb5\x5b\xa2\x2b\x84\x48\xce\xa0\x0c\x42\x86\x55\xa6\x1b\x8f\x28\x5d\x4f\x35\x5c\x2a\xca\x9b\xa6\x4c\x4c\x27\x13\x77\x77\x0e\xb5\x71\x89\xb1\xbc\x89\x5b\xb8\x07\x90\xed\x36\x7e\xf6\xf4\xc6\x6f\x55\xe0\xb5\x56\x5f\x52\xf8\x63\xe7\x9d\xe6\xed\x1b\x9d\xd8\xde\xc5\x9d\xdf\xde\x91\xba\xd1\x6c\xb7\x0d\xa8\xf2\xa5\xba\x90\x32\xb6\xa7\x6a\x06\x9d\x0b\x38\xf4\xbf\x59\x22\xa5\x13\x57\x6f\x3f\xce\x88\xe4\xbe\xf4\x10\xd1\x68\x6e\x4e\x26\xc1\xe7\x9b\x39\xc8\x59\x2b\xdc\x3b\x6b\x90\xae\x5c\xb7\x03\x75\xee\x01\x19\x2b\x12\x4f\x0d\xfa\x58\x71\x78\x50\x75\x20\xa9\xdb\xea\xc3\x33\x68\x3f\x5a\x17\x1e\x53\x18\xe8\x00\xfe\x9e\x19\x9a\xc1\xc5\xe1\xc9\xfd\xbe\xd5\x9f\x8e\xf4\xda\xf3\x97\xd7\x40\xf7\x5f\x58\xa1\x27\xf4\x47\xaf\x86\xfb\xfa\x1a\xda\xea\x2a\xd4\x53\x1a\x2b\x73\xe0\x83\x3a\x82\xea\xc4\x7d\x25\x0e\x2c\x7d\xeb\xf4\xe9\x99\xfa\xc5\x76\x0d\xb4\x85\xe5\xcd\x40\x4b\x38\xdc\x13\x76\x0b\x42\xb7\x1a\xb8\x18\xe6\x72\xc0\x17\xd8\x07\x94\x83\x4e\x8b\x39\x5a\x0f\xc6\x53\xf0\x17\x57\x84\xe1\x04\xbb\x5f\x7e\x1d\x77\x82\xa6\x7c\x8e\x66\x4e\xff\x7a\x68\xcf\xae\x04\xb8\x81\xf9\x20\x76\x61\xa7\x36\x0a\xdd\x58\x0c\x7f\x21\x70\x43\x11\xba\x6f\x80\x36\xf1\xc9\xbe\xd9\xf8\x70\x2e\x0a\x9e\xb2\xde\xef\x6d\x72\xa7\x6b\x1c\xb5\x79\x3c\x98\xf7\xb7\x7a\x30\x54\xf7\x8b\xd4\xfd\xcc\xe9\x85\x9b\xda\xbc\xae\x51\x64\xa6\x6b\xad\x67\x50\x5d\x71\xe7\x1c\x04\xee\xa9\x50\xae\x47\x39\x23\x6d\xbf\xaa\xae\x9c\x8e\xc3\x9b\xac\xce\xaa\xb1\xd3\xdb\x58\x7a\xd9\xf6\x9c\xc4\xe1\x93\xbc\x41\x7d\x89\x3a\x7e\x09\xbb\x65\x96\xbc\x39\x12\x2a\x76\x23\x07\xb6\x14\x79\x9e\xff\x20\x3b\x71\x1f\x3b\xc7\x36\x3d\xc6\xce\x2d\x32\xc7\xec\xcc\x81\x87\xd2\x0f\x32\x34\xdf\xc7\xd0\xb1\x4d\x8f\x31\x74\x8b\xcc\xdd\x86\xb6\x77\x8a\x36\xe4\xac\xbe\xed\xb0\xf1\xef\xbf\xed\xd3\xb1\xca\xab\xe4\x64\x5d\xa2\x96\x69\x14\x5b\x62\x6f\xfe\xd8\x0e\x20\x5f\xdb\x23\xba\xd7\x1d\x32\x48\xb5\x48\x85\x33\xbe\x24\xca\x8b\x4a\x98\x1f\xbe\x8f\x3b\x48\x0d\x54\xe4\xb5\xc2\x9b\x15\xa6\x06\xb3\xde\xf0\x92\x06\xb0\xcd\xec\x75\xce\xc3\xd7\x70\xf6\x5a\x7f\x96\x26\x5d\x82\xe1\xd3\xc9\x16\x7b\x3d\x78\x49\xef\x50\xd4\x08\x06\xfe\xb3\x80\xf0\x4f\x77\xcc\x3f\xe1\xf0\x10\x0c\xfc\xbb\x47\xfe\xe1\xfb\x39\x41\xde\x9b\x52\xf2\x44\xd7\xa2\x3c\x24\xee\x83\x1c\x96\xf7\x41\x8e\x0a\x5c\xb7\x12\x87\x8a\x76\x5b\x35\xe1\xb3\x16\xab\x3a\xfc\xa3\x2f\x47\x17\x2a\xe3\x6b\x92\x27\x94\x68\x96\x55\x06\x9f\xa5\x59\x82\xc6\xb4\xba\xe6\xbb\x31\xaa\x7a\xad\x11\x54\x05\x2b\xa1\x64\x5a\x83\x54\xe0\x2e\xb2\x52\x5d\xba\x52\x1f\x54\xe9\x3c\x0b\xfe\xbe\x05\x1c\x31\x86\xd3\xb3\xf6\x8f\xb2\xee\x63\x88\x5c\x41\x0e\xc8\xfd\xc9\x60\x86\xf6\x76\x6e\xc5\xbb\xbe\x45\xe6\x70\x4d\xb5\x89\x95\xb3\xd7\xdc\xeb\x4e\x81\xa6\x61\x71\xc7\x25\xbe\x7e\xef\xad\x63\xe5\x9b\xaf\x41\x33\xb8\xa6\x1b\x50\xee\x8b\x33\x79\x21\xf5\x40\xf6\x22\xe8\xbd\x2b\x4b\xbc\x01\xb3\x1e\xba\x7c\x5f\xd8\x00\x97\xc9\x8f\x85\x32\x1c\x91\x85\x68\x32\xdd\x83\x49\xdf\x50\x2d\x96\x7c\x91\x69\x89\xcf\x81\x64\xc7\xbe\x0e\x98\x0c\x24\xba\xfb\xd3\x20\x8e\x21\xf3\x26\x94\xfe\xe2\xb2\x01\xa6\x5f\x78\x2c\x9c\xdd\x81\x5d\x08\xa8\x5f\xf1\x90\xf2\x2c\xdf\x62\xea\x2f\x57\x01\xfd\x19\x61\xf5\x96\x0e\x00\x2b\x9b\x6b\xdd\x36\x68\x1b\x43\xfa\xe0\xf2\x20\x67\x03\x5a\x26\x3f\x16\xd8\x6d\x03\x9e\x88\x2f\x48\x8c\xdf\x9b\x76\xc8\xf3\x2c\xf8\xb1\x39\x03\xe8\xb1\x12\xdb\xb1\x63\x2b\x36\x90\xe3\x86\x77\x03\x39\x26\x3f\x16\xb9\x4e\x3f\x1f\x38\x24\xd3\xbd\x3b\xda\x27\xf2\x46\x6e\xc4\x5b\xe2\x33\x42\xc9\xf6\x0d\x40\xb9\x74\x17\x80\x6d\x50\x3a\xf5\xfb\x50\xba\x4e\x7a\x03\x4b\x47\x7f\x2c\x98\xdd\x9b\x42\x80\xa6\x5b\x88\xc9\x37\xdd\x61\x16\x4e\xd7\xed\xb7\xd4\x67\xc4\xd3\x1d\x3b\x00\xe8\xca\xdf\x2f\xb6\x21\xea\x4d\x98\x75\x2e\x17\xcd\x34\xd3\x74\xbe\xeb\xc6\x9d\x27\xba\x4d\x57\x1a\x8c\xfb\xc0\x1b\x36\x61\x6f\x0d\xb5\x72\x13\x03\x0b\x30\xc9\xab\x02\xcb\xa8\xd3\x4a\x98\xe9\xfd\xf4\xff\x01\x00\x00\xff\xff\xc4\x45\xce\xcc\x5d\x32\x00\x00") func schemaGoBytes() ([]byte, error) { return bindataRead( @@ -113,7 +113,7 @@ func schemaGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "schema.go", size: 12860, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "schema.go", size: 12893, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/load/schema.go b/entc/load/schema.go index e6e850777..5398082b4 100644 --- a/entc/load/schema.go +++ b/entc/load/schema.go @@ -352,7 +352,7 @@ func (f *Field) addAnnotation(an schema.Annotation) { } func (f *Field) defaults() error { - if !f.Default || !f.Info.Numeric() { + if !f.Default || !f.Info.Numeric() || f.DefaultKind == reflect.Func { return nil } n, ok := f.DefaultValue.(float64) diff --git a/entc/load/schema_test.go b/entc/load/schema_test.go index 9d197c885..0ee638074 100644 --- a/entc/load/schema_test.go +++ b/entc/load/schema_test.go @@ -263,6 +263,10 @@ func (WithDefaults) Fields() []ent.Field { Default(true), field.Time("updated_at"). UpdateDefault(time.Now), + // see issue #1146 + field.Int("int_default_func").DefaultFunc(func() int { + return 1e9 + }), } } @@ -290,6 +294,8 @@ func TestMarshalDefaults(t *testing.T) { require.True(t, schema.Fields[3].Default) require.False(t, schema.Fields[4].Default) require.True(t, schema.Fields[4].UpdateDefault) + require.True(t, schema.Fields[5].Default) + require.Equal(t, schema.Fields[5].DefaultKind, reflect.Func) } type TimeMixin struct { diff --git a/schema/field/field_test.go b/schema/field/field_test.go index cb2f6fcba..6a301f35e 100644 --- a/schema/field/field_test.go +++ b/schema/field/field_test.go @@ -90,6 +90,21 @@ func TestInt(t *testing.T) { assert.Error(t, fd.Err) } +func TestInt_DefaultFunc(t *testing.T) { + type CustomInt int + + f1 := func() CustomInt { return 1000 } + fd := field.Int("id").DefaultFunc(f1).GoType(CustomInt(0)).Descriptor() + assert.NoError(t, fd.Err) + + fd = field.Int("id").DefaultFunc(f1).Descriptor() + assert.Error(t, fd.Err, "`var _ int = f1()` should fail") + + f2 := func() int { return 1000 } + fd = field.Int("dir").GoType(CustomInt(0)).DefaultFunc(f2).Descriptor() + assert.Error(t, fd.Err, "`var _ CustomInt = f2()` should fail") +} + func TestFloat(t *testing.T) { f := field.Float("age").Positive() fd := f.Descriptor() diff --git a/schema/field/internal/numeric.tmpl b/schema/field/internal/numeric.tmpl index 4eafd0ffb..2f37b16de 100644 --- a/schema/field/internal/numeric.tmpl +++ b/schema/field/internal/numeric.tmpl @@ -108,6 +108,13 @@ func (b *{{ $builder }}) Default(i {{ $t }}) *{{ $builder }} { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *{{ $builder }}) DefaultFunc(fn interface{}) *{{ $builder }} { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *{{ $builder }}) Nillable() *{{ $builder }} { @@ -191,6 +198,9 @@ func (b *{{ $builder }}) Annotations(annotations ...schema.Annotation) *{{ $buil // Descriptor implements the ent.Field interface by returning its descriptor. func (b *{{ $builder }}) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc({{ $t }}Type) + } return b.desc } diff --git a/schema/field/numeric.go b/schema/field/numeric.go index 3d67fe900..5d473ca76 100644 --- a/schema/field/numeric.go +++ b/schema/field/numeric.go @@ -174,6 +174,13 @@ func (b *intBuilder) Default(i int) *intBuilder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *intBuilder) DefaultFunc(fn interface{}) *intBuilder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *intBuilder) Nillable() *intBuilder { @@ -256,6 +263,9 @@ func (b *intBuilder) Annotations(annotations ...schema.Annotation) *intBuilder { // Descriptor implements the ent.Field interface by returning its descriptor. func (b *intBuilder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(intType) + } return b.desc } @@ -314,6 +324,13 @@ func (b *uintBuilder) Default(i uint) *uintBuilder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *uintBuilder) DefaultFunc(fn interface{}) *uintBuilder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *uintBuilder) Nillable() *uintBuilder { @@ -396,6 +413,9 @@ func (b *uintBuilder) Annotations(annotations ...schema.Annotation) *uintBuilder // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uintBuilder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(uintType) + } return b.desc } @@ -464,6 +484,13 @@ func (b *int8Builder) Default(i int8) *int8Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *int8Builder) DefaultFunc(fn interface{}) *int8Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *int8Builder) Nillable() *int8Builder { @@ -546,6 +573,9 @@ func (b *int8Builder) Annotations(annotations ...schema.Annotation) *int8Builder // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int8Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(int8Type) + } return b.desc } @@ -614,6 +644,13 @@ func (b *int16Builder) Default(i int16) *int16Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *int16Builder) DefaultFunc(fn interface{}) *int16Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *int16Builder) Nillable() *int16Builder { @@ -696,6 +733,9 @@ func (b *int16Builder) Annotations(annotations ...schema.Annotation) *int16Build // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int16Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(int16Type) + } return b.desc } @@ -764,6 +804,13 @@ func (b *int32Builder) Default(i int32) *int32Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *int32Builder) DefaultFunc(fn interface{}) *int32Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *int32Builder) Nillable() *int32Builder { @@ -846,6 +893,9 @@ func (b *int32Builder) Annotations(annotations ...schema.Annotation) *int32Build // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int32Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(int32Type) + } return b.desc } @@ -914,6 +964,13 @@ func (b *int64Builder) Default(i int64) *int64Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *int64Builder) DefaultFunc(fn interface{}) *int64Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *int64Builder) Nillable() *int64Builder { @@ -996,6 +1053,9 @@ func (b *int64Builder) Annotations(annotations ...schema.Annotation) *int64Build // Descriptor implements the ent.Field interface by returning its descriptor. func (b *int64Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(int64Type) + } return b.desc } @@ -1054,6 +1114,13 @@ func (b *uint8Builder) Default(i uint8) *uint8Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *uint8Builder) DefaultFunc(fn interface{}) *uint8Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *uint8Builder) Nillable() *uint8Builder { @@ -1136,6 +1203,9 @@ func (b *uint8Builder) Annotations(annotations ...schema.Annotation) *uint8Build // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint8Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(uint8Type) + } return b.desc } @@ -1194,6 +1264,13 @@ func (b *uint16Builder) Default(i uint16) *uint16Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *uint16Builder) DefaultFunc(fn interface{}) *uint16Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *uint16Builder) Nillable() *uint16Builder { @@ -1276,6 +1353,9 @@ func (b *uint16Builder) Annotations(annotations ...schema.Annotation) *uint16Bui // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint16Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(uint16Type) + } return b.desc } @@ -1334,6 +1414,13 @@ func (b *uint32Builder) Default(i uint32) *uint32Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *uint32Builder) DefaultFunc(fn interface{}) *uint32Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *uint32Builder) Nillable() *uint32Builder { @@ -1416,6 +1503,9 @@ func (b *uint32Builder) Annotations(annotations ...schema.Annotation) *uint32Bui // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint32Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(uint32Type) + } return b.desc } @@ -1474,6 +1564,13 @@ func (b *uint64Builder) Default(i uint64) *uint64Builder { return b } +// DefaultFunc sets the function that is applied to set the default value +// of the field on creation. +func (b *uint64Builder) DefaultFunc(fn interface{}) *uint64Builder { + b.desc.Default = fn + return b +} + // Nillable indicates that this field is a nillable. // Unlike "Optional" only fields, "Nillable" fields are pointers in the generated field. func (b *uint64Builder) Nillable() *uint64Builder { @@ -1556,6 +1653,9 @@ func (b *uint64Builder) Annotations(annotations ...schema.Annotation) *uint64Bui // Descriptor implements the ent.Field interface by returning its descriptor. func (b *uint64Builder) Descriptor() *Descriptor { + if b.desc.Default != nil { + b.desc.checkDefaultFunc(uint64Type) + } return b.desc }