From d9da7243f9787277c1d901d22bbe8dccf90e2cea Mon Sep 17 00:00:00 2001 From: Ariel Mashraki Date: Thu, 14 Nov 2019 08:19:54 -0800 Subject: [PATCH] entc/gen: initial support for user-defined ids Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/162 Reviewed By: alexsn Differential Revision: D18485086 fbshipit-source-id: 9bb6ccff592bc0cb8b218625161ed492f67bc170 --- entc/gen/func.go | 3 +- entc/gen/graph.go | 5 +- entc/gen/internal/bindata.go | 16 +- entc/gen/template/builder/create.tmpl | 5 +- entc/gen/template/builder/setter.tmpl | 10 +- entc/gen/template/builder/update.tmpl | 10 +- entc/gen/template/where.tmpl | 2 +- entc/gen/type.go | 18 +- entc/integration/customid/ent/client.go | 265 ++++++++ entc/integration/customid/ent/config.go | 51 ++ entc/integration/customid/ent/context.go | 20 + entc/integration/customid/ent/ent.go | 235 +++++++ entc/integration/customid/ent/example_test.go | 73 +++ entc/integration/customid/ent/group.go | 92 +++ entc/integration/customid/ent/group/group.go | 29 + entc/integration/customid/ent/group/where.go | 195 ++++++ entc/integration/customid/ent/group_create.go | 92 +++ entc/integration/customid/ent/group_delete.go | 80 +++ entc/integration/customid/ent/group_query.go | 583 ++++++++++++++++++ entc/integration/customid/ent/group_update.go | 305 +++++++++ .../customid/ent/migrate/migrate.go | 67 ++ .../customid/ent/migrate/schema.go | 71 +++ .../customid/ent/predicate/predicate.go | 13 + entc/integration/customid/ent/schema/group.go | 26 + entc/integration/customid/ent/schema/user.go | 27 + entc/integration/customid/ent/tx.go | 96 +++ entc/integration/customid/ent/user.go | 85 +++ entc/integration/customid/ent/user/user.go | 29 + entc/integration/customid/ent/user/where.go | 186 ++++++ entc/integration/customid/ent/user_create.go | 96 +++ entc/integration/customid/ent/user_delete.go | 80 +++ entc/integration/customid/ent/user_query.go | 583 ++++++++++++++++++ entc/integration/customid/ent/user_update.go | 326 ++++++++++ 33 files changed, 3748 insertions(+), 26 deletions(-) create mode 100644 entc/integration/customid/ent/client.go create mode 100644 entc/integration/customid/ent/config.go create mode 100644 entc/integration/customid/ent/context.go create mode 100644 entc/integration/customid/ent/ent.go create mode 100644 entc/integration/customid/ent/example_test.go create mode 100644 entc/integration/customid/ent/group.go create mode 100644 entc/integration/customid/ent/group/group.go create mode 100644 entc/integration/customid/ent/group/where.go create mode 100644 entc/integration/customid/ent/group_create.go create mode 100644 entc/integration/customid/ent/group_delete.go create mode 100644 entc/integration/customid/ent/group_query.go create mode 100644 entc/integration/customid/ent/group_update.go create mode 100644 entc/integration/customid/ent/migrate/migrate.go create mode 100644 entc/integration/customid/ent/migrate/schema.go create mode 100644 entc/integration/customid/ent/predicate/predicate.go create mode 100644 entc/integration/customid/ent/schema/group.go create mode 100644 entc/integration/customid/ent/schema/user.go create mode 100644 entc/integration/customid/ent/tx.go create mode 100644 entc/integration/customid/ent/user.go create mode 100644 entc/integration/customid/ent/user/user.go create mode 100644 entc/integration/customid/ent/user/where.go create mode 100644 entc/integration/customid/ent/user_create.go create mode 100644 entc/integration/customid/ent/user_delete.go create mode 100644 entc/integration/customid/ent/user_query.go create mode 100644 entc/integration/customid/ent/user_update.go diff --git a/entc/gen/func.go b/entc/gen/func.go index 526c1a0cb..302ab8dec 100644 --- a/entc/gen/func.go +++ b/entc/gen/func.go @@ -26,7 +26,8 @@ var ( Funcs = template.FuncMap{ "ops": ops, "add": add, - "append": reflect.AppendSlice, + "append": reflect.Append, + "appends": reflect.AppendSlice, "order": order, "snake": snake, "pascal": pascal, diff --git a/entc/gen/graph.go b/entc/gen/graph.go index c30ecece6..3bc27f3d4 100644 --- a/entc/gen/graph.go +++ b/entc/gen/graph.go @@ -331,8 +331,9 @@ func (g *Graph) Tables() (all []*schema.Table) { }) case M2M: t1, t2 := tables[n.Table()], tables[e.Type.Table()] - c1 := &schema.Column{Name: e.Rel.Columns[0], Type: field.TypeInt} - c2 := &schema.Column{Name: e.Rel.Columns[1], Type: field.TypeInt} + fk1, fk2 := n.ID, e.Type.ID + c1 := &schema.Column{Name: e.Rel.Columns[0], Type: fk1.Type.Type} + c2 := &schema.Column{Name: e.Rel.Columns[1], Type: fk2.Type.Type} all = append(all, &schema.Table{ Name: e.Rel.Table, Columns: []*schema.Column{c1, c2}, diff --git a/entc/gen/internal/bindata.go b/entc/gen/internal/bindata.go index 5d6e7c733..ad1f00654 100644 --- a/entc/gen/internal/bindata.go +++ b/entc/gen/internal/bindata.go @@ -141,7 +141,7 @@ func templateBaseTmpl() (*asset, error) { return a, nil } -var _templateBuilderCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x5f\x6f\xdb\xb6\x17\x7d\x96\x3e\xc5\xad\xe0\xfe\x60\x1b\x89\xdc\xf6\xed\xe7\x21\x03\xba\x34\x05\x02\x6c\xd9\x80\x64\x43\x81\x75\x18\x18\xe9\xca\xe6\x42\x93\x2a\x49\x39\x09\x04\x7d\xf7\xe1\x92\x94\x44\x39\x7f\xe0\xee\xc9\x32\x45\x9e\x7b\x78\xce\xe1\x15\xdb\x76\xb5\x4c\xcf\x55\xfd\xa8\xf9\x66\x6b\xe1\xc3\xbb\xf7\xff\x3f\xad\x35\x1a\x94\x16\x3e\xb3\x02\x6f\x95\xba\x83\x4b\x59\xe4\xf0\x51\x08\x70\x93\x0c\xd0\x7b\xbd\xc7\x32\x4f\x6f\xb6\xdc\x80\x51\x8d\x2e\x10\x0a\x55\x22\x70\x03\x82\x17\x28\x0d\x96\xd0\xc8\x12\x35\xd8\x2d\xc2\xc7\x9a\x15\x5b\x84\x0f\xf9\xbb\xfe\x2d\x54\xaa\x91\x65\xca\xa5\x7b\xff\xf3\xe5\xf9\xc5\xd5\xf5\x05\x54\x5c\x20\x84\x31\xad\x94\x85\x92\x6b\x2c\xac\xd2\x8f\xa0\x2a\xb0\x51\x31\xab\x11\xf3\x74\xb9\xea\xba\x34\x6d\x5b\x28\xb1\xe2\x12\x21\x2b\x34\x32\x8b\x19\x74\x1d\x8d\xce\xea\xbb\x0d\xac\xcf\xe0\x96\x19\x84\x59\x7e\xae\x64\xc5\x37\xf9\x6f\xac\xb8\x63\x1b\x84\xb0\xd4\xe2\xae\x16\xcc\x22\x64\x5b\x64\x25\xea\x0c\x66\x4f\x5f\xf1\x5d\xad\xb4\x8d\x5e\xcd\x6e\x1b\x2e\x68\x7b\xeb\x33\xa8\x35\x97\x16\xe6\x35\x33\x05\x13\x30\xcb\xaf\xd8\x0e\x17\x90\x9d\x4f\xb9\x68\x2c\x90\xef\xfd\x8a\xe1\x79\x80\x21\xd8\xd5\x0a\x62\xe4\xae\x23\x35\x49\x8a\x7e\xa4\x52\x1a\xdc\x0e\xb9\xdc\x00\x73\x93\x5d\x31\x9a\x8a\xd2\x72\xfb\x98\xa7\xf6\xb1\xc6\x43\x18\x63\x75\x53\x58\x68\xd3\xa4\x70\x12\xa4\x49\xdb\x82\x66\x72\x83\x30\xfb\xfb\x04\x66\x15\x71\x9a\xe5\x9f\x39\x8a\xd2\x10\x95\x24\x69\xdb\x53\x98\x55\xf9\x4f\x1e\xc4\xbd\x21\xa4\x25\x21\x57\xf9\x0d\x15\xa1\x79\x6d\x0b\x28\xcb\xf0\x78\x1a\x63\xa2\xc7\xbc\x28\x37\x18\x43\xe2\x13\xc8\x1d\xab\xff\x74\x3b\xb9\xfc\xd4\xe3\xfe\xe5\x09\xb7\x63\x81\xd3\xae\x4b\xbd\xf0\xf7\xdc\x6e\x01\x1f\x2c\x8d\xce\x20\x0b\x68\xd9\x44\xc9\x64\xe2\x9d\x41\x6b\x69\x46\x1e\x9c\x08\x84\x49\xee\x6b\xb6\x47\xaf\x28\x7a\xa5\x27\x92\x86\x20\x96\xcc\x32\x4a\x50\x9e\x56\x8d\x2c\x60\x3e\x31\xb3\xd7\x64\xac\xbe\x70\xa8\xf3\xc2\x3e\x40\xa1\xa4\xc5\x07\x4b\xc1\xa3\xdf\x05\xcc\x97\x71\x81\x13\x40\xad\x95\x5e\x90\x31\xaf\x19\x72\x3a\xc8\xc7\x2b\x50\x9a\x0c\xf8\x84\x15\x6b\x84\x85\xb9\x54\x96\xfe\xff\x5a\x5b\xae\x24\x13\x8b\x30\x39\xe1\x15\x1c\xf0\xcc\xbd\x75\x87\xf2\x9f\x9d\x81\xe4\x82\x28\x24\x54\x83\x4a\x44\xf8\x01\x2d\x49\xf6\xc4\xc8\x91\x1f\x8f\x4f\x40\x0c\x73\xc3\xa6\x06\x88\x4b\x73\xc3\xdd\xc8\x7c\x11\xa5\x24\x54\x39\x86\x18\xfc\x6f\xdf\x93\x42\x61\x70\xe4\xa2\xd1\x36\x5a\x12\xed\xa0\xa0\xc9\xaf\xf0\x7e\x9e\xf5\x27\xbe\xeb\xd6\xb0\xe3\xc6\xd0\x29\xd1\xf8\xad\xe1\x1a\x4b\xa8\x1c\xee\xd7\xcc\x17\x0b\x64\xbf\x66\xd9\x62\xa8\x11\x62\x96\x24\x89\x97\x3b\x1a\xe9\x73\xe7\xc5\xff\x83\x09\x5e\x32\xab\xb4\xf1\xfb\xbc\x90\xcd\xae\x5f\x4a\xfd\x14\x58\x59\x82\x6c\x84\x60\xb7\x02\xa1\xd8\x62\x71\x07\x4a\x8a\x47\x77\x7e\x55\x70\xca\x13\x32\x0e\x57\x35\x96\x3a\x98\x53\x7c\xcf\x44\x83\xb0\x5c\x8d\x80\x30\x1b\xb0\xd6\x67\xc0\x28\xf7\xa3\xe1\x43\x02\x82\x0b\x8b\x71\x9d\x8b\xcb\xb8\x96\x02\x7d\x6c\x28\xde\x84\x50\xc0\x54\x17\x4a\x15\x6a\xfd\x72\x14\x06\x65\xc8\xf6\xe5\x51\xb5\x16\x3f\x38\xc8\x37\x71\x0c\x27\x0e\x57\x3b\x9b\x5f\x90\xcb\xd5\xd4\xe1\xfd\x50\xab\x62\x5c\x90\xc3\xf4\xf8\xbc\xcb\x6b\x78\xbb\xcf\x5c\x58\xbc\xdd\x2f\x2a\xd4\x41\x9c\xd5\x78\xf7\xd3\xe7\x23\x5a\x1d\x41\x63\xfe\xbb\xe4\xdf\x1a\x8c\x4e\xa5\x40\x79\xd8\x41\x9c\x30\x4f\x1a\xe3\x02\x7e\x84\xf7\x41\x90\xa3\x12\xdf\x08\xcb\x6b\x81\xc0\x8c\xe1\x1b\xb9\x43\x69\x0d\x28\x09\x0c\x1a\xcf\x01\xcb\x0d\x06\x69\xf0\xf0\x00\x3c\x93\x78\xb7\x03\x17\x2e\x1c\xd3\xf6\x7a\x77\x79\xda\xdc\x27\xdd\xe5\x3f\x9d\xdb\xef\x61\x7d\xe8\x11\x59\x90\xff\x42\xba\x5c\x5b\xa5\x29\xa9\x9e\xbf\xb9\xe7\xb6\xd8\x3e\xd9\x42\xa9\xe9\x29\xff\xc4\x99\xc0\xc2\xce\x5d\x5f\x3e\xf4\xda\x04\x20\xe7\x78\x8f\xea\x40\x0b\xba\x64\xb4\x2d\xfc\xa3\xb8\x1c\xe6\xf5\x60\x06\xb2\x13\xa0\xab\xc0\x3a\x1d\x85\x78\x4e\x42\x33\x40\xf6\x5f\x91\x45\x20\x31\xa4\x32\x74\x8a\x18\xe9\x55\x49\x1b\x69\x9a\x9a\xae\x2f\x58\x42\xe9\xe9\x38\xf9\x82\x48\x51\x6f\x7d\x99\x17\x97\x25\x3e\x44\x3b\x7e\x37\x25\x18\xf1\x1b\x3f\xac\x5f\xa0\x60\x42\x18\xff\x91\xa5\xb6\x55\x33\xc9\x0b\x43\xae\xb8\x21\x5f\xcd\x00\x93\x9e\xfa\x77\x7d\x5f\xbf\x3c\xff\x81\x9d\x7c\x5f\xc9\xbf\xfd\x49\xdc\xb1\xe2\x5d\x45\xf4\x43\x5b\x8b\x7a\x90\xa3\x3a\xf7\xfd\xa2\x4b\x7b\x61\xf6\xfe\x0e\x72\x5c\x20\x8e\xbd\xab\xb8\x0e\x6f\x77\xb5\x18\xae\x92\x15\x64\xc1\xa7\xd5\x5b\xb3\xea\xaf\xb4\x51\x34\xfc\xa2\x87\xe1\x8a\xe3\x97\xe7\x07\x37\xb2\xe8\xaa\x33\x3e\xfe\x1b\x00\x00\xff\xff\xfd\x60\x10\x96\xf0\x0b\x00\x00") +var _templateBuilderCreateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\xef\x6f\xdb\x36\x10\xfd\x2c\xfd\x15\x57\x41\x1d\x6c\x23\x96\xdb\x7e\x9b\x87\x0c\xe8\x92\x14\x08\xb0\x75\x03\xda\x0e\x05\xd6\x61\x60\xa4\x93\xcd\x85\x26\x55\x92\x72\x13\x18\xfa\xdf\x87\x23\x29\x89\x72\x7e\xc0\xdd\x27\xcb\xfc\xf1\xee\xf1\xde\xe3\xf1\x0e\x87\xd5\x22\xbd\x50\xcd\xbd\xe6\x9b\xad\x85\x37\xaf\x5e\xff\xb8\x6c\x34\x1a\x94\x16\xde\xb1\x12\x6f\x94\xba\x85\x6b\x59\x16\xf0\x56\x08\x70\x8b\x0c\xd0\xbc\xde\x63\x55\xa4\x1f\xb7\xdc\x80\x51\xad\x2e\x11\x4a\x55\x21\x70\x03\x82\x97\x28\x0d\x56\xd0\xca\x0a\x35\xd8\x2d\xc2\xdb\x86\x95\x5b\x84\x37\xc5\xab\x7e\x16\x6a\xd5\xca\x2a\xe5\xd2\xcd\xff\x7a\x7d\x71\xf5\xfe\xc3\x15\xd4\x5c\x20\x84\x31\xad\x94\x85\x8a\x6b\x2c\xad\xd2\xf7\xa0\x6a\xb0\x51\x30\xab\x11\x8b\x74\xb1\xea\xba\x34\x3d\x1c\xa0\xc2\x9a\x4b\x84\xac\xd4\xc8\x2c\x66\xd0\x75\x34\x9a\x37\xb7\x1b\x58\x9f\xc3\x0d\x33\x08\x79\x71\xa1\x64\xcd\x37\xc5\x1f\xac\xbc\x65\x1b\x84\xb0\xd5\xe2\xae\x11\xcc\x22\x64\x5b\x64\x15\xea\x0c\xf2\x87\x53\x7c\xd7\x28\x6d\xa3\xa9\xfc\xa6\xe5\x82\x8e\xb7\x3e\x87\x46\x73\x69\x61\xd6\x30\x53\x32\x01\x79\xf1\x9e\xed\x70\x0e\xd9\xc5\x94\x8b\xc6\x12\xf9\xde\xef\x18\xbe\x07\x18\x82\x5d\xad\x20\x46\xee\x3a\xca\x26\xa5\xa2\x1f\xa9\x95\x06\x77\x42\x2e\x37\xc0\xdc\x62\x17\x8c\x96\xa2\xb4\xdc\xde\x17\xa9\xbd\x6f\xf0\x18\xc6\x58\xdd\x96\x16\x0e\x69\x52\xba\x14\xa4\xc9\xe1\xb0\x04\x5e\x43\x5e\x5c\x5f\x16\x9f\x0c\xea\x4b\x97\xbf\x8a\x68\x24\x89\xc3\xbd\xbe\x2c\x7e\xf1\x08\xef\x38\x0a\x9a\x81\x45\x3f\xf1\x91\x62\xd0\x52\x82\x41\x59\x85\x6f\xd0\x4c\x6e\x10\xf2\x7f\xce\x20\xaf\xe9\x98\x79\xe1\xf6\x9a\x1e\x76\x09\x79\xfd\x38\x6a\x1d\x63\x46\x90\xcb\x18\x13\x3d\xe6\x55\xb5\xc1\x18\x12\x1f\x40\xee\x58\xf3\x17\xa1\xa2\x43\x8d\x18\xff\xed\x33\x71\x18\xc3\x2c\xbb\x2e\xf5\x8a\x7e\xe3\x76\x0b\x78\x67\x69\x34\x87\x2c\x60\x66\x13\x89\x92\x89\x29\x0c\x5a\x4b\x2b\x8a\x20\x71\xa0\x4d\x3a\x7e\x60\x7b\xf4\x52\xa1\x97\x70\xa2\x55\x70\x78\xc5\x2c\x23\x6b\x16\x69\xdd\xca\x12\x66\x13\x97\xf4\x99\x19\xa3\xcf\x1d\xea\xac\xb4\x77\x50\x2a\x69\xf1\xce\x92\xa3\xe9\x77\x0e\xb3\x45\x1c\xe0\x0c\x50\x6b\xa5\xe7\xa4\xf8\x73\xb2\x2c\x87\x24\xf2\x1a\x94\x26\x19\x2e\xb1\x66\xad\xb0\x30\x93\xca\xd2\xff\xdf\x1b\xcb\x95\x64\x62\x1e\x16\x27\xbc\x86\x23\x9e\x85\x17\xf0\x58\x84\xf3\x73\x90\x5c\x10\x85\xc4\x59\x8a\xec\x36\xe2\x07\xb4\x24\xd9\x13\x23\x47\x7e\xbc\x97\x01\x31\xac\x0d\x87\x1a\x20\xae\xcd\x47\xee\x46\x66\xf3\xc8\x2b\x21\xca\x29\xc4\xe0\x87\x7d\x4f\x0a\x85\xc1\x91\x8b\x46\xdb\x6a\x49\xb4\x43\x06\x4d\xf1\x1e\xbf\xcd\xb2\xbe\x94\x74\xdd\x1a\x76\xdc\x18\xba\x7e\x1a\xbf\xb6\x5c\x63\x05\xb5\xc3\xfd\x92\xf9\x60\x81\xec\x97\x2c\x9b\x0f\x31\x82\xcd\x92\x24\x09\xb7\x6b\x1c\xe9\x7d\xe7\x93\xff\x27\x13\xbc\x62\x56\x69\xe3\xcf\x79\x25\xdb\x5d\xbf\x95\x0a\x35\xb0\xaa\x02\xd9\x0a\xc1\x6e\x04\x42\xb9\xc5\xf2\x16\x94\x14\xf7\xae\x30\xa8\xa0\x94\x27\x64\x1c\xae\x6a\x2d\x95\x46\x97\xf1\x3d\x13\x2d\xc2\x62\x35\x02\x42\x3e\x60\xad\xcf\x81\x91\xef\x47\xc1\x07\x07\x04\x15\xe6\xe3\x3e\x5f\x3a\x86\xbd\x64\xe8\x53\x4d\xf1\x22\x98\x02\xa6\x79\x21\x57\xa1\xd6\x4f\x5b\x61\xc8\x0c\xc9\xbe\x38\x29\xd6\xfc\x27\x07\xf9\x22\xb6\xe1\x44\xe1\x7a\x67\x8b\x2b\x52\xb9\x9e\x2a\xbc\x1f\x62\xd5\x8c\x0b\x52\x98\x3e\x1f\x57\x79\x0d\x2f\xf7\x99\x33\x8b\x97\xfb\xc9\x0c\x75\x10\x7b\x35\x3e\xfd\xf4\xfb\x84\x82\x47\xd0\x58\x7c\x92\xfc\x6b\x8b\xd1\xad\x14\x28\x8f\x2b\x48\xe1\x8b\xe0\x71\x62\xe0\x67\x78\x1d\x12\x72\x92\xe3\x5b\x61\x79\x23\x10\x98\x31\x7c\x23\x77\x28\xad\x01\x25\x81\x41\xeb\x39\x60\xb5\xc1\x90\x1a\x3c\xbe\x00\x8f\x38\xde\x9d\xc0\x99\x0b\x47\xb7\x3d\x5f\x5d\x1e\x96\xf8\x49\x75\xf9\x5f\xf7\xf6\x7b\x58\x1f\x6b\xe4\x9e\xce\xdf\x28\x2f\x1f\xac\xd2\xe4\x54\xcf\xdf\x7c\xe3\xb6\xdc\x3e\x38\x42\xa5\xe9\xab\xb8\xe4\x4c\x60\x69\x67\xae\x2e\x1f\x6b\x6d\x02\x90\x53\xbc\x47\x75\xa0\x25\x75\x2f\x87\x03\xfc\xab\xb8\x1c\xd6\xf5\x60\x06\xb2\x33\xa0\x1e\x63\x9d\x8e\x89\x78\x2c\x85\x66\x80\xec\x5f\x91\x79\x20\x31\xb8\x32\x54\x8a\x18\xe9\xd9\x94\xb6\xd2\xb4\x0d\xf5\x45\x58\x41\xe5\xe9\xb8\xf4\xf5\x8d\xc1\x58\x5b\x9f\xe6\xc5\x65\x85\x77\xd1\x89\x5f\x4d\x09\x46\xfc\xc6\x87\xf5\x33\x94\x4c\x08\xe3\x1f\x59\x2a\x5b\x0d\x93\xbc\x34\xa4\x8a\x1b\xf2\xd1\x0c\x30\xe9\xa9\x7f\xd7\xfb\xfa\xf9\xf1\x07\x76\xf2\xbe\x92\x7e\xfb\xb3\xb8\x62\xc5\xa7\x8a\xe8\x87\xb2\x16\xd5\x20\x47\x75\xe6\xeb\x45\x97\xf6\x89\xd9\xfb\x1e\xe4\x34\x43\x9c\xda\xab\xb8\x0a\x6f\x77\x8d\x18\x7a\xd4\x1a\xb2\xa0\xd3\xea\xa5\x59\xf5\xbd\x72\x64\x0d\xbf\xe9\x6e\x68\x71\xfc\xf6\xe2\xa8\x2f\x8b\x5a\x9d\xf1\xf3\xbf\x00\x00\x00\xff\xff\x0f\xde\x28\x05\x49\x0c\x00\x00") func templateBuilderCreateTmplBytes() ([]byte, error) { return bindataRead( @@ -156,7 +156,7 @@ func templateBuilderCreateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/create.tmpl", size: 3056, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/create.tmpl", size: 3145, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -201,7 +201,7 @@ func templateBuilderQueryTmpl() (*asset, error) { return a, nil } -var _templateBuilderSetterTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\xcd\x8e\xdb\x36\x10\x3e\x4b\x4f\x31\x15\xdc\x42\x72\xb3\x74\x92\x5b\x0b\xf8\xb0\x8d\x13\xc0\x40\xbb\x39\x38\x39\x2d\x16\x85\x56\x1c\x79\xd9\x68\x49\x85\xa4\xdc\x2e\x5c\xbd\x7b\xc1\x3f\x49\x96\x65\xaf\x37\x6d\x6f\x36\x39\xff\xf3\xcd\xc7\xd1\x7e\xbf\x98\xc7\xef\x44\xfd\x24\xd9\xf6\x41\xc3\xdb\xd7\x6f\x7e\xba\xaa\x25\x2a\xe4\x1a\x3e\xe4\x05\xde\x0b\xf1\x05\xd6\xbc\x20\x70\x5d\x55\x60\x85\x14\x98\x7b\xb9\x43\x4a\xe2\x4f\x0f\x4c\x81\x12\x8d\x2c\x10\x0a\x41\x11\x98\x82\x8a\x15\xc8\x15\x52\x68\x38\x45\x09\xfa\x01\xe1\xba\xce\x8b\x07\x84\xb7\xe4\x75\xb8\x85\x52\x34\x9c\xc6\x8c\xdb\xfb\x5f\xd7\xef\xde\xdf\x6c\xde\x43\xc9\x2a\x04\x7f\x26\x85\xd0\x40\x99\xc4\x42\x0b\xf9\x04\xa2\x04\x3d\x70\xa6\x25\x22\x89\xe7\x8b\xb6\x8d\xe3\xfd\x1e\x28\x96\x8c\x23\x24\x0a\xb5\x46\x99\x40\xdb\x9a\xd3\xd9\x7d\xc3\x2a\x13\xc3\xcf\x4b\xa8\x73\x55\xe4\x15\xcc\xc8\xa6\x10\x35\x92\x5f\xfc\x8d\x17\x94\x58\x20\xdb\x39\xc9\xee\x77\xa7\xee\x85\x4a\x86\x15\x55\x46\x64\x46\x3e\xb8\xdf\xfe\xa6\xa9\x69\xae\x9d\x76\x99\x57\x0a\xdd\xf9\x15\xb0\x12\x84\x84\xf4\x21\x57\x9b\xa6\x2c\xd9\x5f\xbd\xc9\xe4\xb3\x55\x49\xb2\x73\xb7\x1f\xb9\x11\x68\xdb\x38\x1a\x3a\x59\x82\x96\x0d\x76\xc7\x3e\x2a\x13\xd4\x6f\x8d\xce\xef\x2b\x1c\xc6\x76\x05\xc8\x29\xf8\x2a\xc9\x9c\x6f\x11\x66\xbf\xbf\x82\x59\x69\xd3\x28\x3b\x49\x6b\xaa\x3e\x4c\xbf\x24\x9f\x9e\x6a\x24\x1b\x2d\x19\xdf\xf6\xfe\x1a\x5e\xd8\x82\x4a\xc6\x35\x24\x1b\xd4\x89\x11\xdd\x68\xd9\x14\xda\xba\xb6\xa2\x8b\x05\x74\xd2\x6d\x0b\x0a\xb5\xb2\x6d\xb5\x87\xe4\x26\x7f\x34\x19\x80\x0d\x80\xc4\x91\x15\x4b\x0f\x3a\xd1\xb6\x30\x1f\xf6\xb0\x6d\xb3\xa1\xc5\xd4\x05\xdc\xb6\xde\xa2\x09\xd5\xca\x8c\x94\x60\x1f\x47\xd1\xc8\x30\x71\x2a\x1e\x03\x21\x66\x58\xc2\x0f\xc1\xa8\xd5\xb9\x82\xc5\xdc\x04\xae\x4d\xfa\xbc\x79\x44\xc9\x0a\xd0\xc6\x8f\xd8\xa1\x94\x8c\x22\xd4\x12\x77\x4c\x34\x0a\x8a\xbc\xaa\x14\x68\x01\xd7\x94\x12\xb0\xb8\x74\x26\x58\x09\x39\xa7\x5d\x31\x6f\xbc\x99\xae\x9b\x56\xf0\x28\xc0\x9c\xd2\x53\x31\x72\x56\x79\xd3\xbe\xb3\x51\x24\x51\x37\x92\xc3\xc8\x48\x1c\xb5\xb1\x69\xd9\x62\x0e\xf9\x4e\x30\x0a\x5b\xe4\x28\x5d\x32\xac\xaa\x0c\x52\xc0\xcd\x8b\x82\x52\xc8\xfe\xd0\xa4\xa8\x42\x12\xfb\x7d\x48\x21\xe5\x42\xf7\x79\x78\xe1\x0c\x52\x61\xa1\xf2\xb1\xd6\x4c\x70\x33\x61\x25\x59\x61\x99\x37\x95\xce\x9c\x4a\x6a\xf3\x0f\xf9\xce\x4a\xe2\xc0\x1d\x84\xb2\x50\x6e\x98\x85\x08\x3e\x1c\x41\x2c\xb8\x9b\x84\x5a\xc0\xda\x81\xfa\x33\x98\x33\x49\x99\xab\x2d\xdb\x21\x87\x5d\x5e\x35\x96\xbb\x4c\xbc\x9c\x55\x24\x8e\x5e\x02\xc9\x91\xe3\x1e\x9a\xf3\x0b\xb0\x19\xb1\x12\x3a\x85\xef\x6c\x7f\xdd\xf9\x34\x6a\xbd\x8b\x79\x50\xc9\x8c\xa8\xc5\xd0\x29\x14\x44\xae\x8b\x81\x07\x06\x1d\x3d\x0f\xca\x89\x61\xbf\xa6\xf4\x6c\x07\xc2\xb4\xe7\x94\xaa\x3e\x29\x2d\x0e\x3b\xf0\xc2\xea\x7e\xcb\xc0\x87\xa2\x5e\x36\x53\xe7\x8a\x7e\x66\x12\x87\x6c\x11\xb5\x80\x86\xf8\x9d\x91\xf9\xc5\x56\x7e\x5c\xc2\x81\x95\x6f\x6e\x64\x3f\x7f\xcf\x35\xf1\x5d\x85\xb9\xbc\xa8\x8d\x85\x91\x74\x23\xe4\x26\x44\x94\xff\x49\x27\x4f\xf4\xec\x52\x96\x76\x0c\x78\x24\x6e\xa3\x3d\xa5\x63\x9e\xcc\xcb\x6b\x3b\xa8\xf2\xe1\xb3\x89\xee\xf5\x7f\x4f\xb7\xd8\x3f\x9b\xc2\xbe\x9b\x49\x6e\x86\xa3\x6d\x5d\x57\x66\x48\x3e\x73\xf6\xd5\xbe\xd3\x5e\x66\x69\xd7\x13\x2f\x12\xb8\xdb\xdc\x31\xaa\x0e\x19\x2f\x0d\xcb\x8a\xa8\x33\x48\x15\xe3\xdb\xa6\xca\xa5\xb1\x69\xeb\xfe\xb7\x5f\x66\x32\x48\xd6\x2b\x75\xda\x67\xb0\x3b\x6d\x36\xfc\x71\x46\xad\xad\x51\x6c\x1e\x0d\xc1\x8c\x9f\x3c\x61\xb0\xda\xf3\x2a\x76\xbc\x8a\x74\x8b\x61\xd6\xd1\x13\x8b\xbf\xba\x7f\x02\x46\x5d\x90\xf6\x11\x19\x04\xaa\x3a\x87\x2f\x5b\x03\xfa\xa8\xd2\xe3\xec\xad\x33\x74\x8b\x18\xa3\x0a\x08\x21\x9d\x1b\xab\x4d\xd6\xab\xf3\x04\x32\xc1\x1f\x2e\xaf\x73\xe4\x71\xa1\x06\x3c\xe6\x5f\x30\x7d\xcc\xeb\xdb\x51\x28\x77\xca\x0e\xe4\xde\x92\xba\x9f\xde\x83\xcc\xae\xa6\xb7\x85\x49\x3f\xb7\x8c\xde\xc1\x12\x82\xc9\x7d\x58\x48\x6c\x59\xbc\x21\xf3\xec\x33\xbb\xf4\x59\x88\x9b\x52\x9d\x7e\x7a\xa6\x3c\xa8\x5b\x76\x77\xe4\x25\x6a\x2f\x5f\x50\x86\x24\xd6\xa5\x39\xc3\x9e\xce\x8e\x96\x83\xf5\x4a\x9d\xdd\x0f\xf0\x80\xd6\x3c\xaa\x8f\x97\x84\x60\x66\xbc\x27\x5c\x8e\xe7\xff\x65\x85\xe8\xc3\x4a\x19\x75\xa2\xcf\x62\xd5\x80\x95\xd1\xd3\xbb\x83\xc5\xdc\x54\x47\x07\x33\x34\x67\xf4\xa5\x9b\x44\xff\xc9\x50\x89\x3f\x51\x42\x6a\xdb\x51\x42\xf2\x3d\x79\xa3\x92\x83\x9a\x75\x1f\x31\xac\x04\xfc\x6a\xb4\x0e\x2a\xe2\x0c\x2d\x21\xd9\x25\xfe\xef\xd0\x45\x79\x9a\x1b\x47\xcd\x9e\xf8\xee\x78\x96\xb1\xf6\xfb\x31\x29\x0d\x39\x69\xba\xff\xff\xfe\x83\x65\x82\x08\x87\x1c\x35\x1f\xf9\x3c\xf3\x5d\x33\xc5\x0f\xd3\xfd\x1b\xb7\x3c\xc4\x43\xd6\xab\x6c\x82\x1b\x98\xfb\xd4\xb5\x5c\x75\x7b\x37\x02\xe2\x2b\xa8\x90\x77\x16\xb2\x2c\xb0\x92\x25\x93\x84\xf5\x6f\x92\xe9\x36\x73\x52\xee\x7e\x09\xc9\x1f\x83\x77\x66\x40\x44\xee\xbe\x6d\x7b\x3e\xea\x2b\x66\x31\x6d\xe8\x26\x08\xdd\x41\xbf\x38\xf5\x87\x64\xbd\x7a\x06\xc4\xe3\x22\x30\xaa\x08\x21\xd9\x88\xb0\x86\x1b\x40\xff\xeb\x9f\x00\x00\x00\xff\xff\xef\x50\x94\x55\x2c\x11\x00\x00") +var _templateBuilderSetterTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x57\xcd\x8e\xdb\x36\x10\x3e\x4b\x4f\x31\x15\xdc\x42\x72\xb3\x74\x92\x5b\x0b\xf8\xb0\x8d\x13\xc0\x40\x9b\x1c\x9c\x3d\x2d\x16\x85\x56\x1c\x79\xd9\x68\x49\x85\xa4\xdc\x2e\x5c\xbd\x7b\xc1\x3f\x49\x96\x65\xaf\x37\x6d\x6f\x36\x39\xff\xf3\xcd\xc7\xd1\x7e\xbf\x98\xc7\xef\x44\xfd\x24\xd9\xf6\x41\xc3\xdb\xd7\x6f\x7e\xba\xaa\x25\x2a\xe4\x1a\x3e\xe4\x05\xde\x0b\xf1\x05\xd6\xbc\x20\x70\x5d\x55\x60\x85\x14\x98\x7b\xb9\x43\x4a\xe2\xcf\x0f\x4c\x81\x12\x8d\x2c\x10\x0a\x41\x11\x98\x82\x8a\x15\xc8\x15\x52\x68\x38\x45\x09\xfa\x01\xe1\xba\xce\x8b\x07\x84\xb7\xe4\x75\xb8\x85\x52\x34\x9c\xc6\x8c\xdb\xfb\x5f\xd7\xef\xde\x7f\xdc\xbc\x87\x92\x55\x08\xfe\x4c\x0a\xa1\x81\x32\x89\x85\x16\xf2\x09\x44\x09\x7a\xe0\x4c\x4b\x44\x12\xcf\x17\x6d\x1b\xc7\xfb\x3d\x50\x2c\x19\x47\x48\x14\x6a\x8d\x32\x81\xb6\x35\xa7\xb3\xfb\x86\x55\x26\x86\x9f\x97\x50\xe7\xaa\xc8\x2b\x98\x91\x4d\x21\x6a\x24\xbf\xf8\x1b\x2f\x28\xb1\x40\xb6\x73\x92\xdd\xef\x4e\xdd\x0b\x95\x0c\x2b\xaa\x8c\xc8\x8c\x7c\x70\xbf\xfd\x4d\x53\xd3\x5c\x3b\xed\x32\xaf\x14\xba\xf3\x2b\x60\x25\x08\x09\xe9\x43\xae\x36\x4d\x59\xb2\xbf\x7a\x93\xc9\x8d\x55\x49\xb2\x73\xb7\x9f\xb8\x11\x68\xdb\x38\x1a\x3a\x59\x82\x96\x0d\x76\xc7\x3e\x2a\x13\xd4\x6f\x8d\xce\xef\x2b\x1c\xc6\x76\x05\x68\xe2\x61\x25\xcc\xc8\x7a\x45\x6e\x14\xca\x95\xad\x15\x3d\x36\x90\xd7\x35\x72\xda\x1d\x18\x85\xce\x08\xb7\xf2\x26\x59\x99\xf3\x2d\xc2\xec\xf7\x57\x30\x2b\x6d\x2d\xca\xce\x9d\x35\x57\x1f\xd6\xb0\x24\x9f\x9f\x6a\x24\x1b\x2d\x19\xdf\xf6\x3e\x1b\x5e\xd8\xae\x48\xc6\x35\x24\x1b\xd4\x89\x11\xdd\x68\xd9\x14\xda\xc6\x6f\x45\x17\x0b\xe8\xa4\xdb\x16\x14\x6a\x65\xb1\x61\x0f\xc9\xc7\xfc\xd1\x94\x01\x6c\x00\x24\x8e\xac\x58\x7a\xd0\xce\xb6\x85\xf9\x10\x08\x6d\x9b\x0d\x2d\xa6\x2e\xe0\xb6\xf5\x16\x4d\xa8\x56\x66\xa4\x04\xfb\x38\x8a\x46\x86\x89\x53\xf1\x40\x0a\x31\xc3\x12\x7e\x08\x46\xad\xce\x15\x2c\xe6\x26\x70\x6d\xd2\xe7\xcd\x23\x4a\x56\x80\x36\x7e\xc4\x0e\xa5\x64\x14\xa1\x96\xb8\x63\xa2\x51\x50\xe4\x55\xa5\x40\x0b\xb8\xa6\x94\x80\x05\xb7\x33\xc1\x4a\xc8\x6d\x67\x5c\x31\x3f\x7a\x33\x1d\x24\xac\xe0\x51\x80\x39\xa5\xa7\x62\xe4\xac\xf2\xa6\x7d\x67\xa3\x48\xa2\x6e\x24\x87\x91\x91\x38\x6a\x63\xd3\xb2\xc5\x1c\xf2\x9d\x60\x14\xb6\xc8\x51\xba\x64\x58\x55\x19\xb8\x81\x1b\x3a\x05\xa5\x90\xfd\xa1\x49\x51\x85\x24\xf6\xfb\x90\x42\xca\x85\xee\xf3\xf0\xc2\x19\xa4\xc2\x42\xe5\x53\xad\x99\xe0\x66\x4c\x4b\xb2\xc2\x32\x6f\x2a\x9d\x39\x95\xd4\xe6\x1f\xf2\x9d\x95\xc4\x4d\x48\x10\xca\x42\xb9\x61\x16\x22\xf8\x70\x04\xb1\xe0\x6e\x12\x6a\x01\x6b\x07\xea\xcf\x60\xce\x24\x65\xae\xb6\x6c\x87\x1c\x76\x79\xd5\x58\x02\x34\xf1\x72\x56\x91\x38\x7a\x09\x24\x47\x8e\x7b\x68\xce\x2f\xc0\x66\xc4\x4a\xe8\x14\xbe\xb3\xfd\x75\xe7\xd3\xa8\xf5\x2e\xe6\x41\x25\x33\xa2\x16\x43\xa7\x50\x10\xb9\x2e\x06\x1e\x18\x74\xf4\x3c\x28\x27\x86\xfd\x9a\xd2\xb3\x1d\x08\xd3\x9e\x53\xaa\xfa\xa4\xb4\x38\xec\xc0\x0b\xab\xfb\x2d\x03\x1f\x8a\x7a\xd9\x4c\x9d\x2b\xfa\x99\x49\x1c\xb2\x45\xd4\x3a\xb6\x76\x46\xe6\x17\x5b\xf9\x71\x09\x07\x56\xbe\xb9\x91\xfd\xfc\x3d\xd7\xc4\x77\x15\xe6\xf2\xa2\x36\x16\x46\xd2\x8d\x90\x9b\x10\x51\xfe\x27\x9d\x3c\xd1\xb3\x4b\x59\xda\x31\xe0\x91\xb8\x8d\xf6\x94\x8e\x79\x77\x2f\xaf\xed\xa0\xca\x87\xcf\x26\xba\x15\xe2\x3d\xdd\x62\xff\x6c\x0a\xfb\x6e\x26\xb9\x19\x8e\xb6\x75\x5d\x99\x21\xb9\xe1\xec\xab\x7d\xec\xbd\xcc\xd2\xee\x38\x5e\x24\x70\xb7\xb9\x63\x54\x1d\x32\x5e\x1a\x36\x1e\x51\x67\x90\x2a\xc6\xb7\x4d\x95\x4b\x63\xd3\xd6\xfd\x6f\xbf\x11\x65\x90\xac\x57\xea\xb4\xcf\x60\x77\xda\x6c\xf8\xe3\x8c\x5a\x5b\xa3\xd8\x3c\x1a\x82\x19\x3f\x79\xc2\x60\xb5\xe7\x55\xec\x78\x15\xe9\x16\xc3\xac\xa3\x27\x16\x7f\x75\xff\x04\x8c\xba\x20\xed\x23\x32\x08\x54\x75\x0e\x5f\xb6\x06\xf4\x51\xa5\xc7\xd9\x5b\x67\xe8\xb6\x39\x46\x15\x10\x42\x3a\x37\xc3\xf8\xd6\xab\xf3\x34\x32\xc1\x22\x4e\xfb\x1c\x85\x5c\xa8\x01\x8f\xf9\x17\x4c\x1f\xf3\xfa\x76\x32\xa0\x3b\x65\x87\x73\x6f\x09\xde\x4f\xf2\x41\x96\x57\xd3\x9b\xc3\xa4\xb7\x5b\x46\xef\x60\x09\xc1\xe4\x3e\x2c\x27\xb6\x44\xde\x90\x59\x01\x98\x5d\x00\x2d\xdc\x4d\xd9\x4e\x3f\x43\x53\x1e\xd4\x2d\xbb\x3b\xf2\x12\xb5\x97\x2f\x2b\x43\x42\xeb\xd2\x9c\x61\x4f\x6d\x47\x8b\xc2\x7a\xa5\xce\xee\x0a\x78\x40\x71\x1e\xe1\xc7\x0b\x43\x30\x33\xde\x19\x2e\xc7\xf6\xff\xb2\x4e\xf4\x61\xa5\x8c\x3a\xd1\x0b\x71\x6b\x80\xcb\xe8\xe9\x6d\xc2\xe2\x6f\xaa\xaf\x83\xa9\x9a\x33\xfa\xd2\xdd\xa2\xff\x88\xa8\xc4\x9f\x28\x21\xb5\x4d\x29\x21\xf9\x9e\xbc\x51\xc9\x41\xe5\xba\x6f\x23\x56\x02\x7e\x35\x5a\x07\x75\x71\x86\x96\x90\xec\x12\xff\x77\xe8\xa2\x3c\xcd\x96\xa3\x96\x4f\x7c\x89\x3c\xcb\x61\xfb\xfd\x98\xa6\x86\x2c\x35\x8d\x82\x7f\xff\x09\x33\x41\x8d\x43\xd6\x9a\x8f\x7c\x9e\xf9\xd2\x99\x62\x89\xe9\xfe\x8d\x5b\x1e\xe2\x21\xeb\x55\x36\xc1\x10\xcc\x7d\x41\x5b\xde\xba\xbd\x9b\x84\xe3\x2b\xa8\x90\x77\x76\xb2\x2c\x30\x94\x25\x96\x84\xf5\x6f\x95\xe9\x39\x73\x52\xee\x7e\x09\xc9\x1f\x83\xf7\x67\x40\x4a\xee\xbe\x6d\x7b\x6e\xea\xeb\x66\x91\x6d\xa8\x27\x08\xdd\x41\xbf\x50\xf5\x87\x64\xbd\x7a\x06\xca\xe3\x52\x30\xaa\x08\x21\xd9\x88\xbc\x86\x9b\x41\xff\xeb\x9f\x00\x00\x00\xff\xff\x15\xb4\xeb\x80\x89\x11\x00\x00") func templateBuilderSetterTmplBytes() ([]byte, error) { return bindataRead( @@ -216,12 +216,12 @@ func templateBuilderSetterTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/setter.tmpl", size: 4396, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/setter.tmpl", size: 4489, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templateBuilderUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x59\x6b\x6f\xe3\x36\xd6\xfe\x2c\xfd\x8a\x53\xc1\x33\xb0\x83\x58\x9e\x99\x6f\x6f\x5e\x78\x81\xee\x24\x03\x04\xd8\x9d\x2e\x26\xd3\x6e\xb1\x69\x50\xd0\xe2\x91\xcd\x46\x26\x35\x24\xe5\x24\xeb\xd5\x7f\x5f\xf0\x26\x4b\x96\xec\x38\x45\x80\x45\xfb\x29\x16\x2f\x0f\xcf\xe5\x39\x17\x32\xdb\xed\xec\x2c\xfe\x28\xca\x27\xc9\x96\x2b\x0d\x1f\xde\xbd\xff\xbf\x69\x29\x51\x21\xd7\xf0\x89\x64\xb8\x10\xe2\x1e\xae\x79\x96\xc2\xf7\x45\x01\x76\x91\x02\x33\x2f\x37\x48\xd3\xf8\xeb\x8a\x29\x50\xa2\x92\x19\x42\x26\x28\x02\x53\x50\xb0\x0c\xb9\x42\x0a\x15\xa7\x28\x41\xaf\x10\xbe\x2f\x49\xb6\x42\xf8\x90\xbe\x0b\xb3\x90\x8b\x8a\xd3\x98\x71\x3b\xff\xb7\xeb\x8f\x57\x9f\x6f\xae\x20\x67\x05\x82\x1f\x93\x42\x68\xa0\x4c\x62\xa6\x85\x7c\x02\x91\x83\x6e\x1d\xa6\x25\x62\x1a\x9f\xcd\xea\x3a\x8e\xb7\x5b\xa0\x98\x33\x8e\x90\x54\x25\x25\x1a\x13\xa8\x6b\x33\x3a\x2a\xef\x97\x70\x31\x87\x05\x51\x08\xa3\xf4\xa3\xe0\x39\x5b\xa6\xff\x20\xd9\x3d\x59\x22\xf8\xad\x1a\xd7\x65\x41\x34\x42\xb2\x42\x42\x51\x26\x30\xea\x4f\xb1\x75\x29\xa4\x6e\x4d\x8d\x16\x15\x2b\x8c\x7a\x17\x73\x28\x25\xe3\x1a\xc6\x25\x51\x19\x29\x60\x94\x7e\x26\x6b\x9c\x40\xf2\x63\x57\x16\x89\x19\xb2\x8d\xdb\xd1\xfc\x6e\x60\x0c\xec\x6c\x06\x6d\xe4\xba\x36\xd6\x34\xa6\x08\x23\xb9\x90\x60\x35\x64\x7c\x69\x97\xda\xa3\xcc\x42\xe4\x9a\x69\x86\x2a\x8d\xf5\x53\x89\xfb\x30\x4a\xcb\x2a\xd3\xb0\x8d\xa3\xcc\x9a\x20\x8e\xb6\xdb\x69\x4b\x3b\x67\xb5\x59\xce\xb0\xa0\xca\x28\x39\xad\xeb\x38\x2a\x25\x52\x96\x11\x8d\x0a\x6e\xef\x9a\x8f\xb4\x7d\x6e\xec\xa4\xfe\xe7\x0a\x25\x02\xa1\x54\x01\x01\x8e\x0f\xd0\xac\xb6\x22\xb7\x54\x48\xe3\xbc\xe2\x19\x8c\xdb\x06\xa9\x6b\x38\xeb\x0a\x3c\x71\x88\xe3\x52\x41\x9a\xa6\xc3\x47\x4f\xf6\x37\x19\xf5\xba\xb0\x69\x4b\x83\x39\x90\xb2\x44\x4e\xc7\x07\x97\x9c\x43\xa9\xd2\x34\x9d\xc4\x91\x44\x5d\x49\x0e\x1d\xa7\x39\x5d\xb7\x5b\x78\x60\x7a\x05\xf8\xa8\x91\x53\x18\x41\xf2\x57\x77\x7e\xd2\xf1\x64\xd4\xe1\x8e\x42\xad\xcd\x8a\xd4\x33\xc1\xec\xac\x7f\x2f\x98\x77\x15\xd2\x25\xaa\x3e\xe4\x6c\x06\x37\x64\x83\x80\x8f\x98\x55\x46\x6d\x63\xfa\x6f\x15\xca\x27\x20\x9c\x82\x53\xcc\x8d\xf2\x6a\xbd\x40\x69\xc2\x4a\x8a\x07\x35\xdb\xa0\xd4\x2c\x43\x05\x6b\xa2\xb3\x15\x52\x58\x3c\xb9\x78\x13\x25\x4a\xa2\x99\xe0\x43\xae\x83\x21\xdf\x19\x09\xc6\x99\x7e\x84\x4c\x70\x8d\x8f\xda\xc4\x9d\xf9\x3b\x81\x31\xe3\xfa\x1c\x50\x4a\x21\x27\xde\x5d\x7b\x16\xf8\xe2\x81\x93\xd6\x19\x89\x0f\xd8\xc4\xc5\x73\xf2\x2f\x94\xe2\x27\x52\x54\x98\xc0\x3b\xc7\xd4\x41\x13\x29\xb2\x41\x6f\x21\x4b\x77\x73\xc2\x34\x7c\xb0\x1c\x46\xe9\xdf\xab\x42\xb3\x1b\x2d\xa4\xc9\x06\x0e\x48\x3d\x30\x9d\xad\xf6\x5d\x9f\x52\x69\x7e\xa5\x97\x8c\x14\x98\xe9\xb1\x15\xde\xe2\x48\xc2\x97\x08\xa3\x5f\xcf\x61\xa4\x3c\xd0\xc5\x1c\x46\x69\x40\xb5\xa0\x99\x49\x3f\xdb\x2d\xfc\x26\x18\x6f\xd6\x05\x30\x05\xc9\x39\x98\x24\x71\x11\x47\xd1\x01\xea\x59\xe2\xab\x06\x32\x18\x78\xe2\x85\xf0\xde\x8f\x22\x8a\x39\xa9\x0a\xdd\x46\x7a\xe7\xed\xad\xd2\xcf\xf8\x30\x4e\x42\x52\xac\xeb\x0b\xa8\xb8\xaa\x4a\x93\xd6\x90\x02\x75\xc2\x24\x06\x32\xd8\xab\x50\xc1\x2a\x87\xa5\x62\x9c\xe2\x63\x4b\xdf\x77\x5d\xf1\x5a\xd2\xed\xd8\xf9\xb3\x2b\x12\xf7\x68\xbf\xce\x61\x51\x69\x28\x09\x67\x99\x32\x6e\x21\xdc\x09\x0c\x22\xcb\x2a\xa9\x5e\xc4\xba\x9f\x87\x69\x67\xb2\xf3\x36\x8e\x48\x9e\x63\xa6\x91\x5a\x8b\x18\x37\xed\xeb\xd3\x12\x9c\xe5\x76\xd1\x77\x73\xe0\xac\xb0\xde\xb6\x12\x8e\x51\xca\x49\x6c\x2c\xe4\x4d\x12\x30\xbd\x7a\x57\x8f\x98\x0d\x04\xdf\xc9\x4a\x98\xfd\xc3\x3a\x38\x9b\x6c\xe3\xe8\xd7\x53\xc4\xf7\xd2\xa1\x94\x2d\xc1\x76\x76\x37\x5f\xaf\x65\x77\x8b\x3c\x2c\xf3\xb6\xb1\xe3\x80\xb4\x41\xd5\xc9\xff\x1f\xb7\xb4\x4d\x94\xa7\x05\xda\x29\x09\x75\x2f\x99\x84\xec\x31\xd2\xeb\xb2\x68\x6a\x79\x0e\x89\x0f\x88\xd9\x1b\x35\x0b\x3d\x45\x2b\x02\xdd\xa6\xc7\x26\xe7\xb8\xed\x21\xd7\x04\xca\x77\x73\xfd\x48\x70\xdc\x6f\x1a\x72\x48\xde\xa8\x1f\x38\x76\x33\x7e\xc7\x54\xed\x66\xa1\x85\xd0\xea\x17\x3a\xa3\x47\x5b\x06\x02\x8a\xf1\x65\x81\x03\xbd\xc3\x53\xab\x73\xe8\x02\xf6\x9b\x07\x46\x1d\xc0\xf5\x65\xfa\xd5\xec\x09\x49\xf5\x48\x43\xf1\x7c\xf9\xec\xea\x76\x5a\x05\xfd\xdd\x80\xaf\x56\x45\x1d\x10\x6d\x6c\x78\x24\x68\xba\x56\x3d\x5a\x26\xcf\xda\xfe\x79\xd5\x82\x99\x70\x56\x24\xaf\x5c\x34\xff\x74\x35\x93\xb3\xe2\xcf\x5c\x35\x3b\x44\x3c\x5a\x38\x3b\x3c\x0c\xfd\x75\xfa\x65\x07\xf8\x9a\xa5\x74\x1f\xfb\x78\x49\x05\xe1\x6e\x89\x2f\x0d\xbc\x3f\x4c\x8d\x1d\x90\xfa\x0f\x50\x66\x5b\x52\xff\xef\x2a\xed\xee\xe7\xec\x0c\xd4\x8a\x48\xa4\xa1\x8a\xb9\x8a\x04\x0b\xd4\x0f\x88\x8e\x41\xfa\x41\xf8\x34\x2e\x15\xd8\x07\x85\xde\x7b\x42\x28\x64\x6e\xae\x65\xa3\xdc\x59\xe7\x93\x43\x6d\xe5\x49\x21\x61\xcc\x85\x86\x51\x9e\x5e\xaf\xd7\x95\x26\x8b\x02\x27\xe6\xcb\x3d\x0a\x5c\xba\xa4\x13\xf4\x9b\x9a\x19\x6f\x44\x8b\xd5\xb0\x20\xdf\x55\xd8\x26\x05\xbb\xb1\xf4\x73\xb5\x46\xc9\x32\x37\x17\x11\x4a\xdd\xfa\x93\x60\x42\xf6\xdb\xff\xed\xe0\x7f\x28\xcd\x7d\x8f\x14\x3e\x13\x17\x48\xe4\x30\xf6\x42\x88\xa2\x03\xd2\xf6\x48\x87\x4c\x9e\x46\x57\xa6\xe0\x36\xa7\x8d\xb0\x87\xb8\x26\xe5\xed\x5e\x6f\x71\xe7\x5c\xb7\x7d\x31\x7a\x69\x46\x13\x89\x6b\xb1\x41\x6a\xaa\x85\xc9\xbc\xb9\x39\xf5\x47\xce\xbe\x55\xe8\x46\x46\x25\xcc\x21\xb1\x4a\x36\xab\xda\x26\x71\x8f\x3b\xa3\xd2\xec\xbb\xb1\x92\x34\xc2\xf6\xf1\x8c\x41\xcc\x7e\x53\x04\xea\xfa\x98\x32\x3d\xee\x4e\xf7\x69\xbc\xe3\xae\x6d\x53\xc0\x2a\x42\x8a\x17\x73\xd7\x37\x39\xbe\xaf\x6c\x77\xa0\xee\xbd\x2a\xbd\xc9\x44\xd9\x78\xe2\xf4\xd7\xaa\x6e\x24\x0c\xb8\x60\xdf\x38\x3e\xfe\x6d\xce\x6b\x5e\xcd\x92\x8f\xc6\xf2\x49\xdf\xba\x71\x14\xf9\xfe\xd6\x6e\xa8\x6b\xb0\x3e\x72\x25\xc0\x0c\xe3\xae\x81\xa5\x4b\x04\x2d\xfc\xa8\x0b\x0e\x37\x95\xc6\x51\x74\xe2\x3d\xa6\x75\xd2\x78\xf0\x6d\x29\x8a\xf6\x73\xab\x27\x8d\x3b\x76\x8f\x1b\x73\xd0\xb2\xc2\xc3\xed\x49\xe8\x18\x02\x57\xbc\x71\x2c\x67\x0b\xf1\x80\x12\xc6\xcd\x0d\x21\x7d\xaf\x92\x8e\x66\x93\xb0\x61\x76\x66\x8c\x6c\x9f\x73\x8c\xc2\xc2\xfd\x2e\x89\x24\x6b\xd4\x28\x4d\xad\xc8\x0b\x66\x1a\x26\x9b\xb1\xed\xb3\x6a\x90\xc1\xee\xb0\x9c\x89\xbc\xb3\xf0\x9b\xe5\x79\xdb\x4c\x4d\x80\x6c\x12\xff\xd9\x34\x4e\x66\x8a\x51\xf5\xa9\xeb\xce\x2f\x36\xdc\x12\x18\x9b\x9b\x46\x55\x10\xd9\x38\xea\x3f\x9e\x70\x13\x48\xae\x2f\x1d\x21\x1b\x17\x07\x9c\xba\x76\x34\xc7\x97\xb9\x19\x16\x4f\xc0\xa8\x7a\xa1\xb7\x77\x87\x8e\x19\xb5\x2f\x8d\x7b\xc1\x7a\x80\x06\x2c\xef\x55\x59\x9f\x64\x86\x99\xb0\x2b\xb9\x7d\x0a\x1d\xdd\x08\x6b\x72\x8f\xe3\x63\x59\xc4\x34\x9e\x91\xcd\xff\xe6\x9e\xc7\x6c\xb0\xda\x98\x34\x0a\xbd\xf8\xc4\x5b\x46\xd5\x2d\xbb\xbb\x83\x39\x34\x69\xaa\x6e\x4e\x38\xc6\xe3\xa1\xc0\x0e\x4c\x38\x21\xb2\x83\xcf\xfb\xfe\x56\xaf\x1a\xd7\x8e\xcd\x75\x6d\x7c\x7d\xd6\x47\x3d\xe4\x6f\xaa\x8c\x5a\xd6\x19\xb7\x77\x7b\xae\x38\x87\x02\x79\x03\x3c\x99\x84\x3c\x61\x7d\x91\xb0\x5d\xd9\x31\xc1\xc5\xdc\x2a\x37\x3f\x87\xe4\xb7\x56\xbd\x71\x77\x06\xeb\x47\x37\x5f\xd7\x3b\x77\x36\x82\x3b\x9f\x1a\x3f\x85\x45\xc6\x5b\x61\x7a\x37\x98\x5e\x5f\x3e\xe3\xb8\xb4\x1f\x02\xee\xf5\x3b\x3a\xd0\x59\x1d\x28\x4e\x4d\x67\x16\x5e\xfa\xcd\x15\x12\xd6\xa8\x57\x82\x86\x84\xf4\x21\x3c\x47\x1c\x2c\x52\xee\xde\xe9\x2b\x7b\xf8\xb7\x8d\xaf\x4c\xe1\xff\x35\xd3\x30\xfd\x6f\x94\xa2\x35\xdf\x5c\x6f\x9b\xfd\xed\xe2\xe5\x17\x35\x17\x8b\x69\xbf\x7d\xe8\x76\x71\xd3\x6e\x33\xd4\x6d\xd8\x9c\x97\x06\x32\xc0\x70\x83\x14\x62\x7f\xdb\xef\xac\xe0\xed\x5b\xf8\x6e\xb0\xa2\x0c\x43\x35\xe6\x77\x1c\xd8\x84\x66\xbf\xf5\xef\x2c\x2f\x44\x47\x62\x4f\xed\x46\x82\x6b\xf5\x95\xd9\x91\xf1\xa4\x9d\xcc\x7b\x69\xe2\x80\x3e\xf0\x76\xd3\x61\xc8\xb4\x7d\x21\x20\x9c\xc2\x58\x48\xb3\xf1\x27\x52\x30\x4a\xb4\x90\xca\x1d\x7a\xc5\xab\xf5\x64\xa8\x25\x7e\xa1\x41\x5b\xf7\x97\xbd\x4b\x4f\xdf\x0e\x8d\x0c\x46\xdb\xb3\x93\xf0\xfb\xb7\xa4\x4e\xf8\x58\xe2\x99\x98\xcf\xd7\x3a\xbd\x32\x37\xb9\xbc\xfb\x38\xb0\x69\x8e\xcc\x09\x2b\x90\xda\xa0\xb0\x97\x07\xf8\x25\x71\x27\x7a\x87\xfc\x92\x5c\xc0\x9b\x4d\x62\x2f\x9a\x4d\x16\xef\xda\xb5\xf3\xf3\xf9\x7e\xb7\xd3\x6d\x35\x66\x0d\xd9\x69\x5f\xf5\x5e\xeb\x3d\x81\xbf\xc0\x7b\xa7\xf2\x90\xc6\x87\x9e\x43\xd6\x55\xa1\x59\x59\x20\x10\xa5\xd8\x92\xaf\x91\x6b\x65\xee\xe6\x04\x2a\x27\x89\xad\xda\x4e\x79\xdc\x29\x1f\x9e\x4c\x7c\xe7\x61\x79\x81\xbb\xf0\xf0\xc9\x70\x80\x16\xc7\x7a\xae\xb7\x6f\x07\x59\xd4\xbf\x65\xcc\x9f\xf3\xef\x21\x6d\xed\xe9\xee\x25\xf5\x79\xf5\x82\x7e\xed\x38\x19\xf4\x6d\x08\xc3\xff\x06\x00\x00\xff\xff\xb3\xae\x88\x18\x8c\x1f\x00\x00") +var _templateBuilderUpdateTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xdc\x59\x6d\x6f\xe3\x36\xf2\x7f\x2d\x7d\x8a\xa9\xe0\x5d\xd8\x41\x2c\xef\xee\xbb\x7f\xfe\xf0\x01\xbd\x4d\x16\x08\x70\xb7\x3d\x6c\xb6\xbd\xe2\xd2\xa0\xa0\xc5\x91\xcd\x46\x26\xb5\x24\xe5\x24\xe7\xd3\x77\x3f\xf0\x49\x96\x2c\xd9\x71\x8a\x00\x87\xf6\x95\x25\x91\x1c\xce\xfc\xe6\x37\x0f\xa4\xb7\xdb\xd9\x59\xfc\x51\x94\x4f\x92\x2d\x57\x1a\x3e\xbc\x7b\xff\x7f\xd3\x52\xa2\x42\xae\xe1\x13\xc9\x70\x21\xc4\x3d\x5c\xf3\x2c\x85\xef\x8b\x02\xec\x24\x05\x66\x5c\x6e\x90\xa6\xf1\xd7\x15\x53\xa0\x44\x25\x33\x84\x4c\x50\x04\xa6\xa0\x60\x19\x72\x85\x14\x2a\x4e\x51\x82\x5e\x21\x7c\x5f\x92\x6c\x85\xf0\x21\x7d\x17\x46\x21\x17\x15\xa7\x31\xe3\x76\xfc\x6f\xd7\x1f\xaf\x3e\xdf\x5c\x41\xce\x0a\x04\xff\x4d\x0a\xa1\x81\x32\x89\x99\x16\xf2\x09\x44\x0e\xba\xb5\x99\x96\x88\x69\x7c\x36\xab\xeb\x38\xde\x6e\x81\x62\xce\x38\x42\x52\x95\x94\x68\x4c\xa0\xae\xcd\xd7\x51\x79\xbf\x84\x8b\x39\x2c\x88\x42\x18\xa5\x1f\x05\xcf\xd9\x32\xfd\x07\xc9\xee\xc9\x12\xc1\x2f\xd5\xb8\x2e\x0b\xa2\x11\x92\x15\x12\x8a\x32\x81\x51\x7f\x88\xad\x4b\x21\x75\x6b\x68\xb4\xa8\x58\x61\xcc\xbb\x98\x43\x29\x19\xd7\x30\x2e\x89\xca\x48\x01\xa3\xf4\x33\x59\xe3\x04\x92\x1f\xbb\xba\x48\xcc\x90\x6d\xdc\x8a\xe6\xb9\x11\x63\xc4\xce\x66\xd0\x96\x5c\xd7\x06\x4d\x03\x45\xf8\x92\x0b\x09\xd6\x42\xc6\x97\x76\xaa\xdd\xca\x4c\x44\xae\x99\x66\xa8\xd2\x58\x3f\x95\xb8\x2f\x46\x69\x59\x65\x1a\xb6\x71\x94\x59\x08\xe2\x68\xbb\x9d\xb6\xac\x73\xa8\xcd\x72\x86\x05\x55\xc6\xc8\x69\x5d\xc7\x51\x29\x91\xb2\x8c\x68\x54\x70\x7b\xd7\xbc\xa4\xed\x7d\x63\xa7\xf5\x3f\x57\x28\x11\x08\xa5\x0a\x08\x70\x7c\x80\x66\xb6\x55\xb9\x65\x42\x1a\xe7\x15\xcf\x60\xdc\x06\xa4\xae\xe1\xac\xab\xf0\xc4\x49\x1c\x97\x0a\xd2\x34\x1d\xde\x7a\xb2\xbf\xc8\x98\xd7\x15\x9b\xb6\x2c\x98\x03\x29\x4b\xe4\x74\x7c\x70\xca\x39\x94\x2a\x4d\xd3\x49\x1c\x49\xd4\x95\xe4\xd0\x71\x9a\xb3\x75\xbb\x85\x07\xa6\x57\x80\x8f\x1a\x39\x85\x11\x24\x7f\x75\xfb\x27\x1d\x4f\x46\x1d\xee\x28\xd4\xda\xcc\x48\x3d\x13\xcc\xca\xfa\xf7\x0a\xf3\xae\x42\xba\x44\xd5\x17\x39\x9b\xc1\x0d\xd9\x20\xe0\x23\x66\x95\x31\xdb\x40\xff\xad\x42\xf9\x04\x84\x53\x70\x86\xb9\xaf\xbc\x5a\x2f\x50\x9a\xb0\x92\xe2\x41\xcd\x36\x28\x35\xcb\x50\xc1\x9a\xe8\x6c\x85\x14\x16\x4f\x2e\xde\x44\x89\x92\x68\x26\xf8\x90\xeb\x60\xc8\x77\x46\x83\x71\xa6\x1f\x21\x13\x5c\xe3\xa3\x36\x71\x67\x7e\x27\x30\x66\x5c\x9f\x03\x4a\x29\xe4\xc4\xbb\x6b\x0f\x81\x2f\x5e\x70\xd2\xda\x23\xf1\x01\x9b\xb8\x78\x4e\xfe\x85\x52\xfc\x44\x8a\x0a\x13\x78\xe7\x98\x3a\x08\x91\x22\x1b\xf4\x08\x59\xba\x9b\x1d\xa6\xe1\x85\xe5\x30\x4a\xff\x5e\x15\x9a\xdd\x68\x21\x4d\x36\x70\x82\xd4\x03\xd3\xd9\x6a\xdf\xf5\x29\x95\xe6\x29\xbd\x64\xa4\xc0\x4c\x8f\xad\xf2\x56\x8e\x24\x7c\x89\x30\xfa\xf5\x1c\x46\xca\x0b\xba\x98\xc3\x28\x0d\x52\xad\xd0\xcc\xa4\x9f\xed\x16\x7e\x13\x8c\x37\xf3\x82\x30\x05\xc9\x39\x98\x24\x71\x11\x47\xd1\x01\xea\x59\xe2\xab\x46\x64\x00\x78\xe2\x95\xf0\xde\x8f\x22\x8a\x39\xa9\x0a\xdd\x96\xf4\xce\xe3\xad\xd2\xcf\xf8\x30\x4e\x42\x52\xac\xeb\x0b\xa8\xb8\xaa\x4a\x93\xd6\x90\x02\x75\xca\x24\x46\x64\xc0\xab\x50\x01\x95\xc3\x5a\x31\x4e\xf1\xb1\x65\xef\xbb\xae\x7a\x2d\xed\x76\xec\xfc\xd9\x15\x89\x7b\xb4\x6f\xe7\xb0\xa8\x34\x94\x84\xb3\x4c\x19\xb7\x10\xee\x14\x06\x91\x65\x95\x54\x2f\x62\xdd\xcf\xc3\xb4\x33\xd9\x79\x1b\x47\x24\xcf\x31\xd3\x48\x2d\x22\xc6\x4d\xfb\xf6\xb4\x14\x67\xb9\x9d\xf4\xdd\x1c\x38\x2b\xac\xb7\xad\x86\x63\x94\x72\x12\x1b\x84\x3c\x24\x41\xa6\x37\xef\xea\x11\xb3\x81\xe0\x3b\xd9\x08\xb3\x7e\xd8\x06\x87\xc9\x36\x8e\x7e\x3d\x45\x7d\xaf\x1d\x4a\xd9\x52\x6c\x87\xbb\x79\x7b\x2d\xdc\xad\xe4\x61\x9d\xb7\x0d\x8e\x03\xda\x06\x53\x27\xff\x7f\x1c\x69\x9b\x28\x4f\x0b\xb4\x53\x12\xea\x5e\x32\x09\xd9\x63\xa4\xd7\x65\xd1\xd4\xf2\x1c\x12\x1f\x10\xb3\x37\x6a\x16\x7a\x8a\x56\x04\xba\x45\x8f\x4d\xce\x71\xcb\x43\xae\x09\x94\xef\xe6\xfa\x91\xe0\xb8\xdf\x34\xe4\x90\xbc\x51\x3f\x70\xec\x66\xfc\x0e\x54\xed\x66\xa1\x25\xa1\xd5\x2f\x74\xbe\x1e\x6d\x19\x08\x28\xc6\x97\x05\x0e\xf4\x0e\x4f\xad\xce\xa1\x2b\xb0\xdf\x3c\x30\xea\x04\x5c\x5f\xa6\x5f\xcd\x9a\x90\x54\x8f\x34\x14\xcf\x97\xcf\xae\x6d\xa7\x55\xd0\xdf\x2d\xf0\xd5\xaa\xa8\x13\x44\x1b\x0c\x8f\x04\x4d\x17\xd5\xa3\x65\xf2\xac\xed\x9f\x57\x2d\x98\x09\x67\x45\xf2\xca\x45\xf3\x4f\x57\x33\x39\x2b\xfe\xcc\x55\xb3\x43\xc4\xa3\x85\xb3\xc3\xc3\xd0\x5f\xa7\x5f\x76\x02\x5f\xb3\x94\xee\xcb\x3e\x5e\x52\x41\xb8\x53\xe2\x4b\x03\xef\x0f\x53\x63\x07\xb4\xfe\x03\x94\xd9\x96\xd6\xff\xbb\x4a\xbb\x7b\x9c\x9d\x81\x5a\x11\x89\x34\x54\x31\x57\x91\x60\x81\xfa\x01\xd1\x31\x48\x3f\x08\x9f\xc6\xa5\x02\x7b\xa1\xd0\xbb\x4f\x08\x85\xcc\x8d\xb5\x30\xca\x1d\x3a\x9f\x9c\xd4\x56\x9e\x14\x12\xc6\x5c\x68\x18\xe5\xe9\xf5\x7a\x5d\x69\xb2\x28\x70\x62\xde\xdc\xa5\xc0\xa5\x4b\x3a\xc1\xbe\xa9\x19\xf1\x20\x5a\x59\x0d\x0b\xf2\x5d\x85\x6d\x52\xb0\xfb\x96\x7e\xae\xd6\x28\x59\xe6\xc6\x22\x42\xa9\x9b\x7f\x92\x98\x90\xfd\xf6\x9f\x9d\xf8\x1f\x4a\x73\xde\x23\x85\xcf\xc4\x05\x12\x39\x2c\x7b\x21\x44\xd1\x11\xd2\xf6\x48\x87\x4c\x9e\x46\x57\xa6\xe0\x36\xbb\x8d\xb0\x27\x71\x4d\xca\x5b\xb3\x17\x3a\x1b\x77\x1d\xc6\x9d\x73\xe0\xf6\xc5\x7b\x94\xe6\x6b\x22\x71\x2d\x36\x48\x4d\xcd\x30\xf9\x37\x37\x3b\xfc\xc8\xd9\xb7\x0a\xdd\x97\x51\x09\x73\x48\xac\xa9\xcd\xac\x36\x30\xee\x8a\x67\x54\x9a\x75\x37\x56\x93\x46\xe5\xbe\x3c\x03\x8b\x59\x6f\x4a\x41\x5d\x3f\x6f\x52\x8f\xc7\xd3\x7d\x4a\xef\x78\x6c\x5b\x16\xb0\xe6\x90\xe2\xc5\x3c\xf6\x0d\x8f\xef\x31\xdb\xdd\xa8\xbb\xbb\x4a\x6f\x32\x51\x36\x5e\x39\xfd\xe6\xaa\x1b\x15\x03\x8e\xd8\x87\xc8\xe7\x02\x9b\xff\x9a\x1b\xb4\xe4\xa3\xc1\x3f\xe9\x63\x1c\x47\x91\xef\x75\xed\x82\xba\x06\xeb\x29\x57\x0e\x1c\xb6\x4d\x33\x4b\x97\x08\x5a\x40\x0b\x71\x3f\x94\xc6\x51\x74\xe2\x99\xa6\xb5\xd3\x78\xf0\x9e\x29\x8a\xf6\xf3\xac\xa7\x8e\xdb\x76\x8f\x21\x73\xd0\xb2\xc2\xc3\xad\x4a\xe8\x1e\x02\x63\x3c\x38\x96\xb9\x85\x78\x40\x09\xe3\xe6\xb4\x90\xbe\x57\x49\xc7\xb2\x49\x58\x30\x3b\x33\x20\xdb\xab\x1d\x63\xb0\x70\xcf\x25\x91\x64\x8d\x1a\xa5\xa9\x1b\x79\xc1\x4c\xf3\x64\xb3\xb7\xbd\x62\x0d\x3a\xd8\x15\x96\x33\x91\x77\x16\x7e\xb3\x6c\x6f\xc3\xd4\x84\xc9\x26\xf1\xaf\x4d\x13\x65\x86\x18\x55\x9f\xba\xee\xfc\x62\x83\x2e\x81\xb1\x39\x75\x54\x05\x91\x8d\xa3\xfe\xe3\x09\x37\x81\xe4\xfa\xd2\x11\xb2\x71\x71\x90\x53\xd7\x8e\xe6\xf8\x32\x37\xc3\xe2\x09\x18\x55\x2f\xf4\xf6\x6e\xd3\x31\xa3\xf6\xd6\x71\x30\x64\x0f\x90\x81\xe5\xbd\xba\xeb\x13\xce\x30\x1f\x76\x45\xb8\x4f\xa4\xa3\x0b\x61\x4d\xee\x71\xfc\x7c\x46\x31\x0d\x69\x64\xeb\x82\x39\xff\x31\x1b\xb8\x36\x3e\x8d\x71\x2f\xde\xf7\x96\x51\x75\xcb\xee\xee\x60\x0e\x4d\xca\xaa\x9b\x1d\x8e\x71\x7a\x28\xc8\x03\x2b\x4e\x88\xf2\xe0\xff\xbe\xef\xd5\xab\xc6\xb8\x63\x76\x5d\x1b\xbf\x9f\xf5\xa5\x1e\xf2\x3a\x55\xc6\x2c\xeb\x92\xdb\xbb\x41\x87\x9c\x43\x81\xbc\x11\x3f\x99\x84\xcc\x61\x3d\x92\xb0\x5d\x39\x32\xe1\xc6\xdc\x2c\x37\x3e\x87\xe4\xb7\x56\x1d\x72\x27\x0a\xeb\x4d\x37\x5e\xd7\x3b\xa7\x36\xea\x3b\xcf\x1a\x6f\x85\x49\xc6\x67\x61\x78\xf7\x31\xbd\xbe\x7c\xc6\x7d\x69\x3f\x28\xdc\xdd\x78\x74\xa0\xef\x3a\x50\xae\x9a\xbe\x2d\xfc\x0f\x60\x0e\x98\xb0\x46\xbd\x12\x34\xa4\xa8\x0f\xe1\xb2\xe2\x60\xd9\x72\xa7\x52\x5f\xf1\xc3\x9f\x3a\xbe\x56\x85\x7f\x73\xa6\x61\xf8\xdf\x28\x45\x6b\xbc\x39\xfc\x36\xeb\xdb\xe5\xcc\x4f\x6a\x8e\x1d\xd3\x7e\x5b\xd1\xed\xf1\xa6\xdd\x56\xa9\xdb\xce\x39\x2f\x0d\x64\x83\xe1\xf6\x29\xe4\x81\x6d\xbf\xef\x82\xb7\x6f\xe1\xbb\xc1\x1a\x33\x2c\xaa\x81\xdf\x71\x60\x13\x8e\x02\xad\x3f\xbb\xbc\x12\x1d\x8d\x3d\xc1\x1b\x0d\xae\xd5\x57\x66\xbf\x8c\x27\xed\xf4\xde\x4b\x16\x07\xec\x81\xb7\x9b\x0e\x43\xa6\xed\xe3\x02\xe1\x14\xc6\x42\x9a\x85\x3f\x91\x82\x51\xa2\x85\x54\x6e\xd3\x2b\x5e\xad\x27\x43\x0d\xf3\x0b\x01\x6d\x9d\x6e\xf6\x8e\x44\x7d\x1c\x1a\x1d\x8c\xb5\x67\x27\xc9\xef\x9f\xa1\x3a\xe1\x63\x89\x67\x62\x3e\x5f\xeb\xf4\xca\x9c\xf3\xf2\xee\xd5\xc1\xa6\xd9\x32\x27\xac\x40\x6a\x83\xc2\x1e\x2d\xe0\x97\xc4\xed\xe8\x1d\xf2\x4b\x72\x01\x6f\x36\x89\x3d\x86\x36\xb9\xbc\x8b\x6b\xe7\xf1\xf9\x3e\xb8\xd3\x7f\x35\xb0\x86\xec\xb4\x6f\x7a\xaf\x31\x9f\xc0\x5f\xe0\xbd\x33\x79\xc8\xe2\x43\x97\x25\xeb\xaa\xd0\xac\x2c\x10\x88\x52\x6c\xc9\xd7\xc8\xb5\x32\x27\x77\x02\x95\xd3\xc4\xd6\x71\x67\x3c\xee\x8c\x0f\x17\x2a\xbe\x17\xb1\xbc\xc0\x5d\x78\xf8\x64\x38\x40\x8b\x63\x5d\xd8\xdb\xb7\x83\x2c\xea\x9f\x41\xe6\xcf\xf9\xf7\x90\xb5\x76\x77\x77\xcf\xfa\xbc\x79\xc1\xbe\x76\x9c\x0c\xfa\x36\x84\xe1\x7f\x03\x00\x00\xff\xff\xf7\x4c\x7b\x8e\xaa\x1f\x00\x00") func templateBuilderUpdateTmplBytes() ([]byte, error) { return bindataRead( @@ -236,7 +236,7 @@ func templateBuilderUpdateTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/update.tmpl", size: 8076, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/builder/update.tmpl", size: 8106, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1001,7 +1001,7 @@ func templateTxTmpl() (*asset, error) { return a, nil } -var _templateWhereTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x57\x4d\x6f\x1b\x37\x10\x3d\x6b\x7f\xc5\x60\xa1\xa0\x52\x10\x73\xd3\xdc\x5a\xc0\x07\x23\x76\x10\x15\xad\x9d\xd6\x41\x7b\x08\x82\x82\x5e\xce\x4a\x84\x57\xe4\x86\xa4\xe4\x18\x8b\xfd\xef\xc5\x90\xdc\x0f\xeb\xc3\x91\x1b\x1b\x48\xda\x9b\x44\x0e\x87\x33\xef\xbd\x99\xe1\xd6\x75\xf6\x3c\x79\xad\xab\x5b\x23\xe7\x0b\x07\xaf\x5e\xfe\xf8\xd3\x51\x65\xd0\xa2\x72\xf0\x86\xe7\x78\xa5\xf5\x35\xcc\x54\xce\xe0\xa4\x2c\xc1\x1b\x59\xa0\x7d\xb3\x46\xc1\x92\xf7\x0b\x69\xc1\xea\x95\xc9\x11\x72\x2d\x10\xa4\x85\x52\xe6\xa8\x2c\x0a\x58\x29\x81\x06\xdc\x02\xe1\xa4\xe2\xf9\x02\xe1\x15\x7b\xd9\xee\x42\xa1\x57\x4a\x24\x52\xf9\xfd\x5f\x67\xaf\xcf\xce\x2f\xcf\xa0\x90\x25\x42\x5c\x33\x5a\x3b\x10\xd2\x60\xee\xb4\xb9\x05\x5d\x80\x1b\x5c\xe6\x0c\x22\x4b\x9e\x67\x4d\x93\x24\x75\x0d\x02\x0b\xa9\x10\xd2\x9b\x05\x1a\x4c\x21\xac\x1e\xc1\x8d\x74\x0b\xc0\xcf\x0e\x95\x80\x31\xa4\xef\x78\x7e\xcd\xe7\x98\xc2\x98\xc5\x9f\x70\xd4\x34\xc9\xa8\xae\xc1\xe1\xb2\x2a\xb9\x43\x48\x17\xc8\x05\x9a\x14\x18\x79\xa9\x6b\xa0\xb3\xf1\x96\xde\x48\x2e\x2b\x6d\x5c\x0a\x63\xbf\x95\x65\x30\x3b\xa5\xe0\x1d\x1a\x0b\x6b\x34\x4e\xe6\x68\xe1\x8a\x13\x0a\xda\xa7\x23\x0d\x48\x81\xca\xc9\x42\xa2\x61\x49\xb1\x52\x39\xcc\x4e\x27\x52\x40\x5d\xc3\x98\xcd\x4e\xd9\xfb\xdb\x0a\xa1\x69\xa6\x50\x19\x14\x32\xe7\x0e\x99\xdf\x3a\xe7\x4b\x5a\x87\x3a\x19\x19\x74\x2b\xa3\xf6\x18\xd4\x35\xc8\x02\xc6\xec\xb7\x55\xe9\xe4\xa5\xd3\x86\xd2\x6b\x9a\x77\x68\x4e\x25\x2f\x31\x77\x5d\x2e\x93\x64\x44\x29\x1b\xae\xe6\x08\xe3\xbf\x5f\xc0\xd8\x46\xf3\x9f\x8f\x61\xcc\xda\xb3\x1e\x1a\x6f\x39\x76\xcb\xaa\xa4\xcd\xca\x48\xe5\x0a\x48\x45\xf0\x98\x3d\xb3\x59\x17\x4c\x26\x45\xda\x7b\x6a\xcf\x1e\xc1\xe7\x0e\xb5\xe0\x86\x20\x7b\x11\x22\xa0\x70\xfc\x2d\xd3\x24\x00\x3c\x08\x49\x57\x74\xa1\xae\xac\x47\x07\x22\x4d\x63\x6e\xe6\xb4\x9e\xd2\x65\x5d\xce\xba\x62\x7f\x72\x23\xb9\x90\x79\x58\xf4\x66\xde\xca\x46\xb3\xc8\xa2\xf7\xe1\xc1\x1f\x64\x33\x3b\x7d\x66\x53\xef\x25\x42\x99\x8c\xb2\x0c\x3a\xcb\xa6\x01\x5e\x55\xa5\x44\xeb\x75\x49\xeb\xbd\x69\x4f\x46\x24\x3a\x28\x01\x4b\xc1\x92\x91\x3f\x3e\xf0\x33\x69\x43\x23\x3a\x77\x85\xce\x18\xeb\x62\x7d\x80\x2e\x1e\x53\x18\x0f\x50\xc6\x68\x47\x89\x9d\x98\x79\x1a\x72\x4c\x2f\x2a\x0f\x2a\xa4\xf1\xd8\x40\x1d\xad\x83\x87\x88\x2b\xd3\x95\xdd\x12\xd8\x6e\x89\xb1\x28\xb1\xbb\x22\xdb\xf8\x37\x4d\x46\x9b\xf5\x3d\xc8\xbb\x08\x19\xbf\x21\x26\x6d\x54\x4e\xf6\x1c\x7e\xb9\xbc\x38\x87\x9c\x2b\xa5\x1d\x5c\x51\xcb\x5b\x56\xdc\x50\xab\xb3\x52\xcd\x21\x3d\x4e\x81\x2b\x01\x67\x6a\xb5\x84\x05\xb7\xc0\xc1\x11\x7b\xa1\x3b\x89\x80\x15\x69\xc4\x0b\x04\x14\xf1\xe3\x5b\x98\xcf\x42\x16\x40\x6e\x27\xda\xc0\xb8\x60\x33\xeb\xef\xf2\xbf\xc8\xdf\x34\x64\x3c\xd4\xef\xb8\x60\x97\xce\xac\x72\xe7\xa3\x0c\xfb\x7b\x84\x8b\x9f\x56\xbc\x94\xee\x16\xf2\x05\xe6\xd7\xdb\xa2\xad\x6b\xf8\xb4\xd2\x04\x60\xd1\x09\x2b\xa8\x18\x66\xee\x07\x1b\x7b\x57\xce\x4b\x70\x7a\x78\xc1\xd9\xef\x2c\x19\x6d\xeb\x7c\x1d\xfe\x1d\xa4\xdd\x47\x15\xef\x43\xd4\xbb\x4b\xbe\x1e\xc9\x94\xe8\xef\xac\x0e\xd7\x68\x11\x0f\x6f\x4a\xf4\x0b\x1a\xdd\x10\xe9\xc6\xdf\x69\x32\x1a\x45\x81\x44\xa5\x3e\x48\xb3\x54\x81\xb6\xeb\xa4\x45\xaf\xe4\x36\x48\x5b\x61\x2e\x0b\x99\xf7\xf8\x5b\x10\xd2\xf2\xab\x12\x05\x14\xda\xc0\x92\x90\x3f\x6a\xcd\x69\xc8\xcf\x51\x75\xb2\x6d\x55\xbb\xc5\x50\xd4\xea\x80\x01\xa9\x04\x7e\x1e\xf0\xf0\xb2\xb7\xa2\xe0\x8e\x49\xac\x9e\x06\xfa\x37\xc9\x79\x59\x76\xc7\xd9\x85\x8f\x7e\xda\x26\x35\xe8\xe6\x5b\x23\xc3\x1f\xdf\x1c\x17\xeb\x43\xa6\xc5\xfa\x8b\xc3\x62\xb3\xe4\xee\xcc\x0c\xaf\x13\x12\x7c\x28\x4d\xd2\x3e\x19\x53\x63\xe8\xee\x6e\xab\x39\x5e\xec\xcd\x8f\xc1\x19\xb9\x6c\x1f\x24\x61\xad\x7f\xa0\xdc\x09\xe8\x2b\xc6\xd2\xfe\x0a\xdf\x3d\xa7\x5a\x5e\xc9\xa7\x2c\x37\xc0\x3a\x74\x7e\xb9\x50\xff\xdd\xda\xbd\x8d\x20\xf6\xc0\x0d\x97\x54\x03\x6b\x82\x74\xc9\xaf\x71\xf2\xe1\xa3\x54\x0e\x4d\xc1\x73\xac\x9b\x17\x50\xa2\x1a\xcc\xd4\x29\xd5\xca\x88\x34\x2b\xe9\x40\x50\xc6\x3a\x34\x99\xd1\xfa\x83\xfc\x08\xc7\xd0\x5b\x7f\x90\x1f\x69\xa3\x89\x37\xb7\x10\x7f\x9b\xb3\xb4\xef\x4b\x8f\x3b\x56\xbd\x02\x9e\x64\xb2\x0e\xca\x74\x6f\xc3\x8a\x50\x9c\x89\x39\xda\x3d\x05\x97\xbe\xe5\x14\x1b\x6e\x4d\xba\x7b\x4a\xe1\x2d\xb7\xe4\xf2\xbe\x1a\xc0\x4e\x79\x28\xe6\xb8\xab\x04\xbe\x93\xf7\x16\x25\x4a\xf8\xfc\x0b\xee\x29\xf3\x6c\xc1\x9f\x86\xfa\x80\x63\x1f\xc1\x33\xfb\x97\x74\x8b\xb4\xc3\xf7\x71\x09\x0c\xa8\x70\x98\xcb\x35\x2a\xc8\xb5\x12\xd2\x49\xad\x2c\x4c\xb4\x5b\xa0\x19\xcc\xb6\xe9\x2e\xae\x69\xdb\x02\x63\xec\x2e\xa1\x18\x7a\x78\xbc\xe8\xff\x23\x88\x9b\xc0\xd4\x93\xbd\xb4\xb3\x0c\x4e\x94\x80\xb9\xd1\xab\xca\x42\x29\xad\xa3\xaf\xfb\xc1\xfb\xa3\x7b\x27\x9f\x9c\x9f\x82\xae\xd0\x70\xa7\x0d\x5c\xa1\xbb\x41\xf4\x42\x58\xc6\x2f\xe8\x13\x25\x26\x83\x73\x5b\x0c\x1e\xc2\xdd\xb7\xfd\x51\xcd\xd5\x61\x5f\xd5\x6c\xdf\x57\x75\x96\xc1\x85\x39\x04\xeb\x8b\x3f\xee\x85\xfa\xc2\xfc\xc7\x91\xd6\xe6\xab\x81\x3e\xd7\xee\x4e\x1f\xa3\x07\x54\x87\x69\x6c\x61\xa1\x45\xf5\x18\x04\x74\xcf\xb5\x9b\x54\x7b\x90\xf9\x7e\x21\x55\xda\x7d\x1d\xa6\x7d\xd3\xf8\x27\x00\x00\xff\xff\xc8\x82\x92\x6e\xa8\x14\x00\x00") +var _templateWhereTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x57\xdd\x6f\xdb\x36\x10\x7f\xb6\xfe\x8a\x83\xe0\x62\x76\xd1\x50\x5d\xdf\x36\x20\x0f\x41\x93\xa2\x1e\xb6\xa4\x5b\x8a\xed\xa1\x28\x06\x46\x3c\xd9\x44\x64\x52\x25\x69\xa7\x81\xa0\xff\x7d\x38\x92\xfa\x88\x3f\x52\x67\x4d\x80\x76\x7b\x93\xc8\xe3\x7d\xfc\xee\x77\x77\x64\x5d\x67\xcf\x93\xd7\xba\xba\x35\x72\xbe\x70\xf0\xea\xe5\x8f\x3f\x1d\x55\x06\x2d\x2a\x07\x6f\x78\x8e\x57\x5a\x5f\xc3\x4c\xe5\x0c\x4e\xca\x12\xbc\x90\x05\xda\x37\x6b\x14\x2c\x79\xbf\x90\x16\xac\x5e\x99\x1c\x21\xd7\x02\x41\x5a\x28\x65\x8e\xca\xa2\x80\x95\x12\x68\xc0\x2d\x10\x4e\x2a\x9e\x2f\x10\x5e\xb1\x97\xed\x2e\x14\x7a\xa5\x44\x22\x95\xdf\xff\x75\xf6\xfa\xec\xfc\xf2\x0c\x0a\x59\x22\xc4\x35\xa3\xb5\x03\x21\x0d\xe6\x4e\x9b\x5b\xd0\x05\xb8\x81\x31\x67\x10\x59\xf2\x3c\x6b\x9a\x24\xa9\x6b\x10\x58\x48\x85\x90\xde\x2c\xd0\x60\x0a\x61\xf5\x08\x6e\xa4\x5b\x00\x7e\x76\xa8\x04\x8c\x21\x7d\xc7\xf3\x6b\x3e\xc7\x14\xc6\x2c\x7e\xc2\x51\xd3\x24\xa3\xba\x06\x87\xcb\xaa\xe4\x0e\x21\x5d\x20\x17\x68\x52\x60\xa4\xa5\xae\x81\xce\x46\x2b\xbd\x90\x5c\x56\xda\xb8\x14\xc6\x7e\x2b\xcb\x60\x76\x4a\xce\x3b\x34\x16\xd6\x68\x9c\xcc\xd1\xc2\x15\x27\x14\xb4\x0f\x47\x1a\x90\x02\x95\x93\x85\x44\xc3\x92\x62\xa5\x72\x98\x9d\x4e\xa4\x80\xba\x86\x31\x9b\x9d\xb2\xf7\xb7\x15\x42\xd3\x4c\xa1\x32\x28\x64\xce\x1d\x32\xbf\x75\xce\x97\xb4\x0e\x75\x32\x32\xe8\x56\x46\xed\x11\xa8\x6b\x90\x05\x8c\xd9\x6f\xab\xd2\xc9\x4b\xa7\x0d\x85\xd7\x34\xef\xd0\x9c\x4a\x5e\x62\xee\xba\x58\x26\xc9\x88\x42\x36\x5c\xcd\x11\xc6\x7f\xbf\x80\xb1\x8d\xe2\x3f\x1f\xc3\x98\xb5\x67\x3d\x34\x5e\x72\xec\x96\x55\x49\x9b\x95\x91\xca\x15\x90\x8a\xa0\x31\x7b\x66\xb3\xce\x99\x4c\x8a\xb4\xd7\xd4\x9e\x3d\x82\xcf\x1d\x6a\x41\x0d\x41\xf6\x22\x78\x40\xee\x78\x2b\xd3\x24\x00\x3c\x70\x49\x57\x64\x50\x57\xd6\xa3\x03\x31\x4d\x63\x6e\xe6\xb4\x9e\x92\xb1\x2e\x66\x5d\xb1\x3f\xb9\x91\x5c\xc8\x3c\x2c\x7a\x31\x2f\x65\xa3\x58\xcc\xa2\xd7\xe1\xc1\x1f\x44\x33\x3b\x7d\x66\x53\xaf\x25\x42\x99\x8c\xb2\x0c\x3a\xc9\xa6\x01\x5e\x55\xa5\x44\xeb\x79\x49\xeb\xbd\x68\x9f\x8c\x98\xe8\xc0\x04\x2c\x05\x4b\x46\xfe\xf8\x40\xcf\xa4\x75\x8d\xd2\xb9\xcb\x75\xc6\x58\xe7\xeb\x03\x78\xf1\x98\xc4\x78\x00\x33\x46\x3b\x4a\xec\xc4\xcc\xd3\x10\x63\x7a\x51\x79\x50\x21\x8d\xc7\x06\xec\x68\x15\x3c\x84\x5c\x99\xae\xec\x16\xc1\x76\x53\x8c\x45\x8a\xdd\x25\xd9\xc6\xdf\x34\x19\x6d\xd6\xf7\x20\xee\x22\x44\xfc\x86\x32\x69\x23\x73\xb2\xe7\xf0\xcb\xe5\xc5\x39\xe4\x5c\x29\xed\xe0\x8a\x5a\xde\xb2\xe2\x86\x5a\x9d\x95\x6a\x0e\xe9\x71\x0a\x5c\x09\x38\x53\xab\x25\x2c\xb8\x05\x0e\x8e\xb2\x17\xba\x93\x08\x58\x11\x47\x3c\x41\x40\x51\x7e\x7c\x0b\xf3\x51\xc8\x02\x48\xed\x44\x1b\x18\x17\x6c\x66\xbd\x2d\xff\x45\xfa\xa6\x21\xe2\x21\x7f\xc7\x05\xbb\x74\x66\x95\x3b\xef\x65\xd8\xdf\x43\x5c\xfc\xb4\xe2\xa5\x74\xb7\x90\x2f\x30\xbf\xde\x26\x6d\x5d\xc3\xa7\x95\x26\x00\x8b\x8e\x58\x81\xc5\x30\x73\x3f\xd8\xd8\xbb\x72\x5e\x82\xd3\x43\x03\x67\xbf\xb3\x64\xb4\xcd\xf3\x75\xf8\x3b\x88\xbb\x8f\x4a\xde\x87\xb0\x77\x17\x7d\x3d\x92\x29\xa5\xbf\x93\x3a\x9c\xa3\x45\x3c\xbc\x49\xd1\x2f\x70\x74\x83\xa4\x1b\xbf\xd3\x64\x34\x8a\x04\x89\x4c\x7d\x10\x67\xa9\x02\x6d\xd7\x49\x8b\x9e\xc9\xad\x93\xb6\xc2\x5c\x16\x32\xef\xf1\xb7\x20\xa4\xe5\x57\x25\x0a\x28\xb4\x81\x25\x21\x7f\xd4\x8a\xd3\x90\x9f\xa3\xea\x68\xdb\xb2\x76\x2b\x43\x91\xab\x83\x0c\x48\x25\xf0\xf3\x20\x0f\x2f\x7b\x29\x72\xee\x98\xc8\x8a\x4a\xd8\xf0\x3b\xc9\x79\x59\x76\xe7\xd9\x85\x77\x7f\xda\x46\x35\x68\xe7\x5b\x33\xc3\x1f\xdf\x9c\x17\xeb\x43\xc6\xc5\xfa\x8b\xd3\x62\xb3\xe6\xee\x0c\x0d\x4f\x14\x62\x7c\xa8\x4d\x22\x3f\x09\x53\x67\xe8\x6c\xb7\xe5\x1c\x0d\x7b\xf1\x63\x70\x46\x2e\xdb\x1b\x49\x58\xeb\x6f\x28\x77\x1c\xfa\x8a\xb9\xb4\xbf\xc4\x77\x0f\xaa\x36\xb1\xa4\x53\x96\x1b\x60\x1d\x3a\xc0\x5c\x68\x00\xdd\xda\xbd\x9d\x20\x36\xc1\x0d\x95\x54\x04\x6b\x82\x74\xc9\xaf\x71\xf2\xe1\xa3\x54\x0e\x4d\xc1\x73\xac\x9b\x17\x50\xa2\x1a\x0c\xd5\x29\x15\xcb\x88\x48\x2b\xe9\x40\x60\xc6\x3a\x74\x99\xd1\xfa\x83\xfc\x08\xc7\xd0\x4b\x7f\x90\x1f\x69\xa3\x89\x96\x5b\x88\xbf\xcd\x61\xda\x37\xa6\xc7\x9d\xab\x9e\x01\x4f\x32\x5a\x07\x65\xba\xb7\x63\x45\x28\xce\xc4\x1c\xed\x9e\x82\x4b\xdf\x72\xf2\x0d\xb7\x46\xdd\x3d\xa5\xf0\x96\x5b\x52\x79\x5f\x0d\x60\xc7\x3c\x14\x73\xdc\x55\x02\xdf\xc9\x85\x8b\x02\x25\x7c\xfe\x45\xee\x29\xf2\x6c\xc1\x9f\x26\xf5\x01\xc7\xde\x83\x67\xf6\x2f\xe9\x16\x69\x87\xef\xe3\x26\x30\xa0\xc2\x61\x2e\xd7\xa8\x20\xd7\x4a\x48\x27\xb5\xb2\x30\xd1\x6e\x81\x66\x30\xdc\xa6\xbb\x72\x4d\xdb\x16\x18\x63\x77\x13\x8a\xa1\x87\x47\x43\xff\x1f\x42\xdc\x84\x4c\x3d\xd9\x55\x3b\xcb\xe0\x44\x09\x98\x1b\xbd\xaa\x2c\x94\xd2\x3a\x7a\xde\x0f\x2e\x20\xdd\x45\xf9\xe4\xfc\x14\x74\x85\x86\x3b\x6d\xe0\x0a\xdd\x0d\xa2\x27\xc2\x32\x3e\xa1\x4f\x94\x98\x0c\xce\x6d\x65\xf0\x90\xdc\x7d\xdb\xaf\x6a\xae\x0e\x7b\x56\xb3\x7d\xcf\xea\x2c\x83\x0b\x73\x08\xd6\x17\x7f\xdc\x0b\xf5\x85\xf9\x8f\x23\xad\xcd\x57\x03\x7d\xae\xdd\x9d\x3e\x46\x17\xa8\x0e\xd3\xd8\xc2\x42\x8b\xea\x31\x08\xe8\x9e\x6b\x37\xa9\xf6\x20\xf3\xfd\x42\xaa\xb4\xfb\x3a\x4c\xfb\xa6\xf1\x4f\x00\x00\x00\xff\xff\x8e\xd2\x90\xe1\xa9\x14\x00\x00") func templateWhereTmplBytes() ([]byte, error) { return bindataRead( @@ -1016,7 +1016,7 @@ func templateWhereTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/where.tmpl", size: 5288, mode: os.FileMode(420), modTime: time.Unix(1, 0)} + info := bindataFileInfo{name: "template/where.tmpl", size: 5289, mode: os.FileMode(420), modTime: time.Unix(1, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/gen/template/builder/create.tmpl b/entc/gen/template/builder/create.tmpl index 243a4c0f1..8d967ab88 100644 --- a/entc/gen/template/builder/create.tmpl +++ b/entc/gen/template/builder/create.tmpl @@ -17,11 +17,14 @@ in the LICENSE file in the root directory of this source tree. // {{ $builder }} is the builder for creating a {{ $.Name }} entity. type {{ $builder }} struct { config + {{- if $.ID.UserDefined }} + {{ $.ID.BuilderField }} *{{ $.ID.Type }} + {{- end }} {{ range $_, $f := $.Fields }} {{- $f.BuilderField }} *{{ $f.Type }} {{ end }} {{- range $_, $e := $.Edges }} - {{- $e.BuilderField }} map[{{ $.ID.Type }}]struct{} + {{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} {{ end -}} } diff --git a/entc/gen/template/builder/setter.tmpl b/entc/gen/template/builder/setter.tmpl index 8464fcf50..caa49e4db 100644 --- a/entc/gen/template/builder/setter.tmpl +++ b/entc/gen/template/builder/setter.tmpl @@ -12,6 +12,8 @@ in the LICENSE file in the root directory of this source tree. {{- if or (hasSuffix $builder "Update") (hasSuffix $builder "UpdateOne") }} {{ $updater = true }} {{ $fields = $.MutableFields }} +{{- else if $.ID.UserDefined }} + {{ $fields = append $fields $.ID }} {{- end }} {{ range $_, $f := $fields }} @@ -67,9 +69,9 @@ in the LICENSE file in the root directory of this source tree. {{ $op := "add" }}{{ if $e.Unique }}{{ $op = "set" }}{{ end }} {{ $idsFunc := print (pascal $op) (singular $e.Name | pascal) "IDs" }}{{ if $e.Unique }}{{ $idsFunc = print (pascal $op) (pascal $e.Name) "ID" }}{{ end }} // {{ $idsFunc }} {{ $op }}s the {{ $e.Name }} edge to {{ $e.Type.Name }} by id{{ if not $e.Unique }}s{{ end }}. - func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $.ID.Type }}) *{{ $builder }} { + func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}({{ if $e.Unique }}id{{ else }}ids ...{{ end }} {{ $e.Type.ID.Type }}) *{{ $builder }} { if {{ $receiver }}.{{ $e.BuilderField }} == nil { - {{ $receiver }}.{{ $e.BuilderField }} = make(map[{{ $.ID.Type }}]struct{}) + {{ $receiver }}.{{ $e.BuilderField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) } {{ if $e.Unique -}} {{ $receiver }}.{{ $e.BuilderField }}[id] = struct{}{} @@ -83,7 +85,7 @@ in the LICENSE file in the root directory of this source tree. {{ if and $e.Unique $e.Optional }} {{ $nillableIDsFunc := print "SetNillable" $e.StructField "ID" }} // {{ $nillableIDsFunc }} sets the {{ $e.Name }} edge to {{ $e.Type.Name }} by id if the given value is not nil. - func ({{ $receiver }} *{{ $builder }}) {{ $nillableIDsFunc }}(id *{{ $.ID.Type }}) *{{ $builder }} { + func ({{ $receiver }} *{{ $builder }}) {{ $nillableIDsFunc }}(id *{{ $e.Type.ID.Type }}) *{{ $builder }} { if id != nil { {{ $receiver}} = {{ $receiver }}.{{ $idsFunc }}(*id) } @@ -98,7 +100,7 @@ in the LICENSE file in the root directory of this source tree. {{ if $e.Unique -}} return {{ $receiver }}.{{ $idsFunc }}({{ $p }}.ID) {{- else -}} - ids := make([]{{ $.ID.Type }}, len({{ $p }})) + ids := make([]{{ $e.Type.ID.Type }}, len({{ $p }})) {{ $i := "i" }}{{ if eq $i $p }}{{ $i = "j" }}{{ end -}} for {{ $i }} := range {{ $p }} { ids[{{ $i }}] = {{ $p }}[{{ $i }}].ID diff --git a/entc/gen/template/builder/update.tmpl b/entc/gen/template/builder/update.tmpl index 78373e8a3..0f0df645c 100644 --- a/entc/gen/template/builder/update.tmpl +++ b/entc/gen/template/builder/update.tmpl @@ -166,11 +166,11 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{- end }} {{ end }} {{- range $_, $e := $.Edges }} - {{- $e.BuilderField }} map[{{ $.ID.Type }}]struct{} + {{- $e.BuilderField }} map[{{ $e.Type.ID.Type }}]struct{} {{ end }} {{- range $_, $e := $.Edges }} {{- $p := "removed" }}{{ if $e.Unique }}{{ $p = "cleared" }}{{ end }} - {{- print $p $e.StructField }} {{ if $e.Unique }}bool{{ else }}map[{{ $.ID.Type }}]struct{}{{ end }} + {{- print $p $e.StructField }} {{ if $e.Unique }}bool{{ else }}map[{{ $e.Type.ID.Type }}]struct{}{{ end }} {{ end -}} {{ end }} @@ -193,9 +193,9 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{ if eq $p $receiver }} {{ $p = "v" }} {{ end }} {{ $idsFunc := print "Remove" (singular $e.Name | pascal) "IDs" }} // {{ $idsFunc }} removes the {{ $e.Name }} edge to {{ $e.Type.Name }} by ids. - func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}(ids ...{{ $.ID.Type }}) *{{ $builder }} { + func ({{ $receiver }} *{{ $builder }}) {{ $idsFunc }}(ids ...{{ $e.Type.ID.Type }}) *{{ $builder }} { if {{ $receiver }}.removed{{ $e.StructField }} == nil { - {{ $receiver }}.removed{{ $e.StructField }} = make(map[{{ $.ID.Type }}]struct{}) + {{ $receiver }}.removed{{ $e.StructField }} = make(map[{{ $e.Type.ID.Type }}]struct{}) } for i := range ids { {{ $receiver }}.removed{{ $e.StructField }}[ids[i]] = struct{}{} @@ -205,7 +205,7 @@ func ({{ $receiver }} *{{ $onebuilder }}) ExecX(ctx context.Context) { {{ $func := print "Remove" $e.StructField }} // {{ $func }} removes {{ $e.Name }} edges to {{ $e.Type.Name }}. func ({{ $receiver }} *{{ $builder }}) {{ $func }}({{ $p }} ...*{{ $e.Type.Name }}) *{{ $builder }} { - ids := make([]{{ $.ID.Type }}, len({{ $p }})) + ids := make([]{{ $e.Type.ID.Type }}, len({{ $p }})) {{ $i := "i" }}{{ if eq $i $p }}{{ $i = "j" }}{{ end -}} for {{ $i }} := range {{ $p }} { ids[{{ $i }}] = {{ $p }}[{{ $i }}].ID diff --git a/entc/gen/template/where.tmpl b/entc/gen/template/where.tmpl index 899b17e43..8b97bf320 100644 --- a/entc/gen/template/where.tmpl +++ b/entc/gen/template/where.tmpl @@ -61,7 +61,7 @@ func ID(id {{ $.ID.Type }}) predicate.{{ $.Name }} { {{/* storage specific predicates disabled for multi-storage codegen */}} {{ if not $.MultiStorage }} {{ $storage := index $.Storage 0 }} - {{ $ops = append $ops (call $storage.Ops $f) }} + {{ $ops = appends $ops (call $storage.Ops $f) }} {{ end }} {{ range $_, $op := $ops }} {{ $arg := "v" }}{{ if $op.Variadic }}{{ $arg = "vs" }}{{ end }} diff --git a/entc/gen/type.go b/entc/gen/type.go index 235d73c03..88d6fbd70 100644 --- a/entc/gen/type.go +++ b/entc/gen/type.go @@ -65,6 +65,9 @@ type ( Validators int // Position info of the field. Position *load.Position + // UserDefined indicates that this field was defined by the loaded schema. + // Unlike default id field, which is defined by the generator. + UserDefined bool } // Edge of a graph between two types. @@ -133,10 +136,10 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) { }, schema: schema, Name: schema.Name, - Fields: make([]*Field, len(schema.Fields)), + Fields: make([]*Field, 0, len(schema.Fields)), fields: make(map[string]*Field, len(schema.Fields)), } - for i, f := range schema.Fields { + for _, f := range schema.Fields { switch { case f.Info == nil || !f.Info.Valid(): return nil, fmt.Errorf("invalid type for field %s", f.Name) @@ -155,7 +158,7 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) { // enum types should be named as follows: typepkg.Field. f.Info.Ident = fmt.Sprintf("%s.%s", typ.Package(), pascal(f.Name)) } - typ.Fields[i] = &Field{ + tf := &Field{ def: f, Name: f.Name, Type: f.Info, @@ -168,8 +171,15 @@ func NewType(c *Config, schema *load.Schema) (*Type, error) { Immutable: f.Immutable, StructTag: structTag(f.Name, f.Tag), Validators: f.Validators, + UserDefined: true, + } + // user defined id field. + if tf.Name == typ.ID.Name { + typ.ID = tf + } else { + typ.Fields = append(typ.Fields, tf) + typ.fields[f.Name] = tf } - typ.fields[f.Name] = typ.Fields[i] } return typ, nil } diff --git a/entc/integration/customid/ent/client.go b/entc/integration/customid/ent/client.go new file mode 100644 index 000000000..000cb2bc8 --- /dev/null +++ b/entc/integration/customid/ent/client.go @@ -0,0 +1,265 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "log" + + "github.com/facebookincubator/ent/entc/integration/customid/ent/migrate" + + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" +) + +// Client is the client that holds all ent builders. +type Client struct { + config + // Schema is the client for creating, migrating and dropping schema. + Schema *migrate.Schema + // Group is the client for interacting with the Group builders. + Group *GroupClient + // User is the client for interacting with the User builders. + User *UserClient +} + +// NewClient creates a new client configured with the given options. +func NewClient(opts ...Option) *Client { + c := config{log: log.Println} + c.options(opts...) + return &Client{ + config: c, + Schema: migrate.NewSchema(c.driver), + Group: NewGroupClient(c), + User: NewUserClient(c), + } +} + +// Open opens a connection to the database specified by the driver name and a +// driver-specific data source name, and returns a new client attached to it. +// Optional parameters can be added for configuring the client. +func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { + switch driverName { + case dialect.MySQL, dialect.Postgres, dialect.SQLite: + drv, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return NewClient(append(options, Driver(drv))...), nil + + default: + return nil, fmt.Errorf("unsupported driver: %q", driverName) + } +} + +// Tx returns a new transactional client. +func (c *Client) Tx(ctx context.Context) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") + } + tx, err := newTx(ctx, c.driver) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %v", err) + } + cfg := config{driver: tx, log: c.log, debug: c.debug} + return &Tx{ + config: cfg, + Group: NewGroupClient(cfg), + User: NewUserClient(cfg), + }, nil +} + +// Debug returns a new debug-client. It's used to get verbose logging on specific operations. +// +// client.Debug(). +// Group. +// Query(). +// Count(ctx) +// +func (c *Client) Debug() *Client { + if c.debug { + return c + } + cfg := config{driver: dialect.Debug(c.driver, c.log), log: c.log, debug: true} + return &Client{ + config: cfg, + Schema: migrate.NewSchema(cfg.driver), + Group: NewGroupClient(cfg), + User: NewUserClient(cfg), + } +} + +// Close closes the database connection and prevents new queries from starting. +func (c *Client) Close() error { + return c.driver.Close() +} + +// GroupClient is a client for the Group schema. +type GroupClient struct { + config +} + +// NewGroupClient returns a client for the Group from the given config. +func NewGroupClient(c config) *GroupClient { + return &GroupClient{config: c} +} + +// Create returns a create builder for Group. +func (c *GroupClient) Create() *GroupCreate { + return &GroupCreate{config: c.config} +} + +// Update returns an update builder for Group. +func (c *GroupClient) Update() *GroupUpdate { + return &GroupUpdate{config: c.config} +} + +// UpdateOne returns an update builder for the given entity. +func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne { + return c.UpdateOneID(gr.ID) +} + +// UpdateOneID returns an update builder for the given id. +func (c *GroupClient) UpdateOneID(id string) *GroupUpdateOne { + return &GroupUpdateOne{config: c.config, id: id} +} + +// Delete returns a delete builder for Group. +func (c *GroupClient) Delete() *GroupDelete { + return &GroupDelete{config: c.config} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne { + return c.DeleteOneID(gr.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *GroupClient) DeleteOneID(id string) *GroupDeleteOne { + return &GroupDeleteOne{c.Delete().Where(group.ID(id))} +} + +// Create returns a query builder for Group. +func (c *GroupClient) Query() *GroupQuery { + return &GroupQuery{config: c.config} +} + +// Get returns a Group entity by its id. +func (c *GroupClient) Get(ctx context.Context, id string) (*Group, error) { + return c.Query().Where(group.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *GroupClient) GetX(ctx context.Context, id string) *Group { + gr, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return gr +} + +// QueryUsers queries the users edge of a Group. +func (c *GroupClient) QueryUsers(gr *Group) *UserQuery { + query := &UserQuery{config: c.config} + id := gr.id() + step := &sql.Step{} + step.From.V = id + step.From.Table = group.Table + step.From.Column = group.FieldID + step.To.Table = user.Table + step.To.Column = user.FieldID + step.Edge.Rel = sql.M2M + step.Edge.Inverse = false + step.Edge.Table = group.UsersTable + step.Edge.Columns = append(step.Edge.Columns, group.UsersPrimaryKey...) + query.sql = sql.Neighbors(gr.driver.Dialect(), step) + + return query +} + +// UserClient is a client for the User schema. +type UserClient struct { + config +} + +// NewUserClient returns a client for the User from the given config. +func NewUserClient(c config) *UserClient { + return &UserClient{config: c} +} + +// Create returns a create builder for User. +func (c *UserClient) Create() *UserCreate { + return &UserCreate{config: c.config} +} + +// Update returns an update builder for User. +func (c *UserClient) Update() *UserUpdate { + return &UserUpdate{config: c.config} +} + +// UpdateOne returns an update builder for the given entity. +func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { + return c.UpdateOneID(u.ID) +} + +// UpdateOneID returns an update builder for the given id. +func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { + return &UserUpdateOne{config: c.config, id: id} +} + +// Delete returns a delete builder for User. +func (c *UserClient) Delete() *UserDelete { + return &UserDelete{config: c.config} +} + +// DeleteOne returns a delete builder for the given entity. +func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { + return c.DeleteOneID(u.ID) +} + +// DeleteOneID returns a delete builder for the given id. +func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { + return &UserDeleteOne{c.Delete().Where(user.ID(id))} +} + +// Create returns a query builder for User. +func (c *UserClient) Query() *UserQuery { + return &UserQuery{config: c.config} +} + +// Get returns a User entity by its id. +func (c *UserClient) Get(ctx context.Context, id int) (*User, error) { + return c.Query().Where(user.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *UserClient) GetX(ctx context.Context, id int) *User { + u, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return u +} + +// QueryGroups queries the groups edge of a User. +func (c *UserClient) QueryGroups(u *User) *GroupQuery { + query := &GroupQuery{config: c.config} + id := u.ID + step := &sql.Step{} + step.From.V = id + step.From.Table = user.Table + step.From.Column = user.FieldID + step.To.Table = group.Table + step.To.Column = group.FieldID + step.Edge.Rel = sql.M2M + step.Edge.Inverse = true + step.Edge.Table = user.GroupsTable + step.Edge.Columns = append(step.Edge.Columns, user.GroupsPrimaryKey...) + query.sql = sql.Neighbors(u.driver.Dialect(), step) + + return query +} diff --git a/entc/integration/customid/ent/config.go b/entc/integration/customid/ent/config.go new file mode 100644 index 000000000..2200a84b2 --- /dev/null +++ b/entc/integration/customid/ent/config.go @@ -0,0 +1,51 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "github.com/facebookincubator/ent/dialect" +) + +// Option function to configure the client. +type Option func(*config) + +// Config is the configuration for the client and its builder. +type config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...interface{}) +} + +// Options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...interface{})) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} diff --git a/entc/integration/customid/ent/context.go b/entc/integration/customid/ent/context.go new file mode 100644 index 000000000..7f97cb6a6 --- /dev/null +++ b/entc/integration/customid/ent/context.go @@ -0,0 +1,20 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" +) + +type contextKey struct{} + +// FromContext returns the Client stored in a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(contextKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, contextKey{}, c) +} diff --git a/entc/integration/customid/ent/ent.go b/entc/integration/customid/ent/ent.go new file mode 100644 index 000000000..1a80c1610 --- /dev/null +++ b/entc/integration/customid/ent/ent.go @@ -0,0 +1,235 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "strings" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql" +) + +// Order applies an ordering on either graph traversal or sql selector. +type Order func(*sql.Selector) + +// Asc applies the given fields in ASC order. +func Asc(fields ...string) Order { + return Order( + func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Asc(f)) + } + }, + ) +} + +// Desc applies the given fields in DESC order. +func Desc(fields ...string) Order { + return Order( + func(s *sql.Selector) { + for _, f := range fields { + s.OrderBy(sql.Desc(f)) + } + }, + ) +} + +// Aggregate applies an aggregation step on the group-by traversal/selector. +type Aggregate struct { + // SQL the column wrapped with the aggregation function. + SQL func(*sql.Selector) string +} + +// As is a pseudo aggregation function for renaming another other functions with custom names. For example: +// +// GroupBy(field1, field2). +// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). +// Scan(ctx, &v) +// +func As(fn Aggregate, end string) Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.As(fn.SQL(s), end) + }, + } +} + +// Count applies the "count" aggregation function on each group. +func Count() Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.Count("*") + }, + } +} + +// Max applies the "max" aggregation function on the given field of each group. +func Max(field string) Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.Max(s.C(field)) + }, + } +} + +// Mean applies the "mean" aggregation function on the given field of each group. +func Mean(field string) Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.Avg(s.C(field)) + }, + } +} + +// Min applies the "min" aggregation function on the given field of each group. +func Min(field string) Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.Min(s.C(field)) + }, + } +} + +// Sum applies the "sum" aggregation function on the given field of each group. +func Sum(field string) Aggregate { + return Aggregate{ + SQL: func(s *sql.Selector) string { + return sql.Sum(s.C(field)) + }, + } +} + +// ErrNotFound returns when trying to fetch a specific entity and it was not found in the database. +type ErrNotFound struct { + label string +} + +// Error implements the error interface. +func (e *ErrNotFound) Error() string { + return fmt.Sprintf("ent: %s not found", e.label) +} + +// IsNotFound returns a boolean indicating whether the error is a not found error. +func IsNotFound(err error) bool { + _, ok := err.(*ErrNotFound) + return ok +} + +// MaskNotFound masks nor found error. +func MaskNotFound(err error) error { + if IsNotFound(err) { + return nil + } + return err +} + +// ErrNotSingular returns when trying to fetch a singular entity and more then one was found in the database. +type ErrNotSingular struct { + label string +} + +// Error implements the error interface. +func (e *ErrNotSingular) Error() string { + return fmt.Sprintf("ent: %s not singular", e.label) +} + +// IsNotSingular returns a boolean indicating whether the error is a not singular error. +func IsNotSingular(err error) bool { + _, ok := err.(*ErrNotSingular) + return ok +} + +// ErrConstraintFailed returns when trying to create/update one or more entities and +// one or more of their constraints failed. For example, violation of edge or field uniqueness. +type ErrConstraintFailed struct { + msg string + wrap error +} + +// Error implements the error interface. +func (e ErrConstraintFailed) Error() string { + return fmt.Sprintf("ent: unique constraint failed: %s", e.msg) +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ErrConstraintFailed) Unwrap() error { + return e.wrap +} + +// IsConstraintFailure returns a boolean indicating whether the error is a constraint failure. +func IsConstraintFailure(err error) bool { + _, ok := err.(*ErrConstraintFailed) + return ok +} + +func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) { + var ( + msg = err.Error() + // error format per dialect. + errors = [...]string{ + "Error 1062", // MySQL 1062 error (ER_DUP_ENTRY). + "UNIQUE constraint failed", // SQLite. + "duplicate key value violates unique constraint", // PostgreSQL. + } + ) + for i := range errors { + if strings.Contains(msg, errors[i]) { + return &ErrConstraintFailed{msg, err}, true + } + } + return nil, false +} + +// rollback calls to tx.Rollback and wraps the given error with the rollback error if occurred. +func rollback(tx dialect.Tx, err error) error { + if rerr := tx.Rollback(); rerr != nil { + err = fmt.Errorf("%s: %v", err.Error(), rerr) + } + if err, ok := isSQLConstraintError(err); ok { + return err + } + return err +} + +// insertLastID invokes the insert query on the transaction and returns the LastInsertID. +func insertLastID(ctx context.Context, tx dialect.Tx, insert *sql.InsertBuilder) (int64, error) { + query, args := insert.Query() + // PostgreSQL does not support the LastInsertId() method of sql.Result + // on Exec, and should be extracted manually using the `RETURNING` clause. + if insert.Dialect() == dialect.Postgres { + rows := &sql.Rows{} + if err := tx.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, fmt.Errorf("no rows found for query: %v", query) + } + var id int64 + if err := rows.Scan(&id); err != nil { + return 0, err + } + return id, nil + } + // MySQL, SQLite, etc. + var res sql.Result + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + id, err := res.LastInsertId() + if err != nil { + return 0, err + } + return id, nil +} + +// keys returns the keys/ids from the edge map. +func keys(m map[string]struct{}) []string { + s := make([]string, 0, len(m)) + for id := range m { + s = append(s, id) + } + return s +} diff --git a/entc/integration/customid/ent/example_test.go b/entc/integration/customid/ent/example_test.go new file mode 100644 index 000000000..847cb5dd5 --- /dev/null +++ b/entc/integration/customid/ent/example_test.go @@ -0,0 +1,73 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "log" + + "github.com/facebookincubator/ent/dialect/sql" +) + +// dsn for the database. In order to run the tests locally, run the following command: +// +// ENT_INTEGRATION_ENDPOINT="root:pass@tcp(localhost:3306)/test?parseTime=True" go test -v +// +var dsn string + +func ExampleGroup() { + if dsn == "" { + return + } + ctx := context.Background() + drv, err := sql.Open("mysql", dsn) + if err != nil { + log.Fatalf("failed creating database client: %v", err) + } + defer drv.Close() + client := NewClient(Driver(drv)) + // creating vertices for the group's edges. + u0 := client.User. + Create(). + SaveX(ctx) + log.Println("user created:", u0) + + // create group vertex with its edges. + gr := client.Group. + Create(). + AddUsers(u0). + SaveX(ctx) + log.Println("group created:", gr) + + // query edges. + u0, err = gr.QueryUsers().First(ctx) + if err != nil { + log.Fatalf("failed querying users: %v", err) + } + log.Println("users found:", u0) + + // Output: +} +func ExampleUser() { + if dsn == "" { + return + } + ctx := context.Background() + drv, err := sql.Open("mysql", dsn) + if err != nil { + log.Fatalf("failed creating database client: %v", err) + } + defer drv.Close() + client := NewClient(Driver(drv)) + // creating vertices for the user's edges. + + // create user vertex with its edges. + u := client.User. + Create(). + SaveX(ctx) + log.Println("user created:", u) + + // query edges. + + // Output: +} diff --git a/entc/integration/customid/ent/group.go b/entc/integration/customid/ent/group.go new file mode 100644 index 000000000..932e722bd --- /dev/null +++ b/entc/integration/customid/ent/group.go @@ -0,0 +1,92 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strconv" + "strings" + + "github.com/facebookincubator/ent/dialect/sql" +) + +// Group is the model entity for the Group schema. +type Group struct { + config + // ID of the ent. + ID string `json:"id,omitempty"` +} + +// FromRows scans the sql response data into Group. +func (gr *Group) FromRows(rows *sql.Rows) error { + var scangr struct { + ID int + } + // the order here should be the same as in the `group.Columns`. + if err := rows.Scan( + &scangr.ID, + ); err != nil { + return err + } + gr.ID = strconv.Itoa(scangr.ID) + return nil +} + +// QueryUsers queries the users edge of the Group. +func (gr *Group) QueryUsers() *UserQuery { + return (&GroupClient{gr.config}).QueryUsers(gr) +} + +// Update returns a builder for updating this Group. +// Note that, you need to call Group.Unwrap() before calling this method, if this Group +// was returned from a transaction, and the transaction was committed or rolled back. +func (gr *Group) Update() *GroupUpdateOne { + return (&GroupClient{gr.config}).UpdateOne(gr) +} + +// Unwrap unwraps the entity that was returned from a transaction after it was closed, +// so that all next queries will be executed through the driver which created the transaction. +func (gr *Group) Unwrap() *Group { + tx, ok := gr.config.driver.(*txDriver) + if !ok { + panic("ent: Group is not a transactional entity") + } + gr.config.driver = tx.drv + return gr +} + +// String implements the fmt.Stringer. +func (gr *Group) String() string { + var builder strings.Builder + builder.WriteString("Group(") + builder.WriteString(fmt.Sprintf("id=%v", gr.ID)) + builder.WriteByte(')') + return builder.String() +} + +// id returns the int representation of the ID field. +func (gr *Group) id() int { + id, _ := strconv.Atoi(gr.ID) + return id +} + +// Groups is a parsable slice of Group. +type Groups []*Group + +// FromRows scans the sql response data into Groups. +func (gr *Groups) FromRows(rows *sql.Rows) error { + for rows.Next() { + scangr := &Group{} + if err := scangr.FromRows(rows); err != nil { + return err + } + *gr = append(*gr, scangr) + } + return nil +} + +func (gr Groups) config(cfg config) { + for _i := range gr { + gr[_i].config = cfg + } +} diff --git a/entc/integration/customid/ent/group/group.go b/entc/integration/customid/ent/group/group.go new file mode 100644 index 000000000..f592c8feb --- /dev/null +++ b/entc/integration/customid/ent/group/group.go @@ -0,0 +1,29 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package group + +const ( + // Label holds the string label denoting the group type in the database. + Label = "group" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + + // Table holds the table name of the group in the database. + Table = "groups" + // UsersTable is the table the holds the users relation/edge. The primary key declared below. + UsersTable = "group_users" + // UsersInverseTable is the table name for the User entity. + // It exists in this package in order to avoid circular dependency with the "user" package. + UsersInverseTable = "users" +) + +// Columns holds all SQL columns are group fields. +var Columns = []string{ + FieldID, +} + +var ( + // UsersPrimaryKey and UsersColumn2 are the table columns denoting the + // primary key for the users relation (M2M). + UsersPrimaryKey = []string{"group_id", "user_id"} +) diff --git a/entc/integration/customid/ent/group/where.go b/entc/integration/customid/ent/group/where.go new file mode 100644 index 000000000..8710fd7d2 --- /dev/null +++ b/entc/integration/customid/ent/group/where.go @@ -0,0 +1,195 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package group + +import ( + "strconv" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" +) + +// ID filters vertices based on their identifier. +func ID(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.EQ(s.C(FieldID), id)) + }, + ) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.EQ(s.C(FieldID), id)) + }, + ) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.NEQ(s.C(FieldID), id)) + }, + ) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i], _ = strconv.Atoi(ids[i]) + } + s.Where(sql.In(s.C(FieldID), v...)) + }, + ) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i], _ = strconv.Atoi(ids[i]) + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }, + ) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.GT(s.C(FieldID), id)) + }, + ) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.GTE(s.C(FieldID), id)) + }, + ) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.LT(s.C(FieldID), id)) + }, + ) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id string) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + id, _ := strconv.Atoi(id) + s.Where(sql.LTE(s.C(FieldID), id)) + }, + ) +} + +// HasUsers applies the HasEdge predicate on the "users" edge. +func HasUsers() predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + t1 := s.Table() + builder := sql.Dialect(s.Dialect()) + s.Where( + sql.In( + t1.C(FieldID), + builder.Select(UsersPrimaryKey[0]). + From(builder.Table(UsersTable)), + ), + ) + }, + ) +} + +// HasUsersWith applies the HasEdge predicate on the "users" edge with a given conditions (other predicates). +func HasUsersWith(preds ...predicate.User) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + builder := sql.Dialect(s.Dialect()) + t1 := s.Table() + t2 := builder.Table(UsersInverseTable) + t3 := builder.Table(UsersTable) + t4 := builder.Select(t3.C(UsersPrimaryKey[0])). + From(t3). + Join(t2). + On(t3.C(UsersPrimaryKey[1]), t2.C(FieldID)) + t5 := builder.Select().From(t2) + for _, p := range preds { + p(t5) + } + t4.FromSelect(t5) + s.Where(sql.In(t1.C(FieldID), t4)) + }, + ) +} + +// And groups list of predicates with the AND operator between them. +func And(predicates ...predicate.Group) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }, + ) +} + +// Or groups list of predicates with the OR operator between them. +func Or(predicates ...predicate.Group) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }, + ) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Group) predicate.Group { + return predicate.Group( + func(s *sql.Selector) { + p(s.Not()) + }, + ) +} diff --git a/entc/integration/customid/ent/group_create.go b/entc/integration/customid/ent/group_create.go new file mode 100644 index 000000000..902388c56 --- /dev/null +++ b/entc/integration/customid/ent/group_create.go @@ -0,0 +1,92 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "strconv" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" +) + +// GroupCreate is the builder for creating a Group entity. +type GroupCreate struct { + config + id *string + users map[int]struct{} +} + +// SetID sets the id field. +func (gc *GroupCreate) SetID(s string) *GroupCreate { + gc.id = &s + return gc +} + +// AddUserIDs adds the users edge to User by ids. +func (gc *GroupCreate) AddUserIDs(ids ...int) *GroupCreate { + if gc.users == nil { + gc.users = make(map[int]struct{}) + } + for i := range ids { + gc.users[ids[i]] = struct{}{} + } + return gc +} + +// AddUsers adds the users edges to User. +func (gc *GroupCreate) AddUsers(u ...*User) *GroupCreate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return gc.AddUserIDs(ids...) +} + +// Save creates the Group in the database. +func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) { + return gc.sqlSave(ctx) +} + +// SaveX calls Save and panics if Save returns an error. +func (gc *GroupCreate) SaveX(ctx context.Context) *Group { + v, err := gc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) { + var ( + res sql.Result + builder = sql.Dialect(gc.driver.Dialect()) + gr = &Group{config: gc.config} + ) + tx, err := gc.driver.Tx(ctx) + if err != nil { + return nil, err + } + insert := builder.Insert(group.Table).Default() + id, err := insertLastID(ctx, tx, insert.Returning(group.FieldID)) + if err != nil { + return nil, rollback(tx, err) + } + gr.ID = strconv.FormatInt(id, 10) + if len(gc.users) > 0 { + for eid := range gc.users { + + query, args := builder.Insert(group.UsersTable). + Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]). + Values(id, eid). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + } + if err := tx.Commit(); err != nil { + return nil, err + } + return gr, nil +} diff --git a/entc/integration/customid/ent/group_delete.go b/entc/integration/customid/ent/group_delete.go new file mode 100644 index 000000000..14daad134 --- /dev/null +++ b/entc/integration/customid/ent/group_delete.go @@ -0,0 +1,80 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" +) + +// GroupDelete is the builder for deleting a Group entity. +type GroupDelete struct { + config + predicates []predicate.Group +} + +// Where adds a new predicate to the delete builder. +func (gd *GroupDelete) Where(ps ...predicate.Group) *GroupDelete { + gd.predicates = append(gd.predicates, ps...) + return gd +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (gd *GroupDelete) Exec(ctx context.Context) (int, error) { + return gd.sqlExec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (gd *GroupDelete) ExecX(ctx context.Context) int { + n, err := gd.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (gd *GroupDelete) sqlExec(ctx context.Context) (int, error) { + var ( + res sql.Result + builder = sql.Dialect(gd.driver.Dialect()) + ) + selector := builder.Select().From(sql.Table(group.Table)) + for _, p := range gd.predicates { + p(selector) + } + query, args := builder.Delete(group.Table).FromSelect(selector).Query() + if err := gd.driver.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + affected, err := res.RowsAffected() + if err != nil { + return 0, err + } + return int(affected), nil +} + +// GroupDeleteOne is the builder for deleting a single Group entity. +type GroupDeleteOne struct { + gd *GroupDelete +} + +// Exec executes the deletion query. +func (gdo *GroupDeleteOne) Exec(ctx context.Context) error { + n, err := gdo.gd.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &ErrNotFound{group.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (gdo *GroupDeleteOne) ExecX(ctx context.Context) { + gdo.gd.ExecX(ctx) +} diff --git a/entc/integration/customid/ent/group_query.go b/entc/integration/customid/ent/group_query.go new file mode 100644 index 000000000..80c0f9eff --- /dev/null +++ b/entc/integration/customid/ent/group_query.go @@ -0,0 +1,583 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "math" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" +) + +// GroupQuery is the builder for querying Group entities. +type GroupQuery struct { + config + limit *int + offset *int + order []Order + unique []string + predicates []predicate.Group + // intermediate queries. + sql *sql.Selector +} + +// Where adds a new predicate for the builder. +func (gq *GroupQuery) Where(ps ...predicate.Group) *GroupQuery { + gq.predicates = append(gq.predicates, ps...) + return gq +} + +// Limit adds a limit step to the query. +func (gq *GroupQuery) Limit(limit int) *GroupQuery { + gq.limit = &limit + return gq +} + +// Offset adds an offset step to the query. +func (gq *GroupQuery) Offset(offset int) *GroupQuery { + gq.offset = &offset + return gq +} + +// Order adds an order step to the query. +func (gq *GroupQuery) Order(o ...Order) *GroupQuery { + gq.order = append(gq.order, o...) + return gq +} + +// QueryUsers chains the current query on the users edge. +func (gq *GroupQuery) QueryUsers() *UserQuery { + query := &UserQuery{config: gq.config} + + builder := sql.Dialect(gq.driver.Dialect()) + t1 := builder.Table(user.Table) + t2 := gq.sqlQuery() + t2.Select(t2.C(group.FieldID)) + t3 := builder.Table(group.UsersTable) + t4 := builder.Select(t3.C(group.UsersPrimaryKey[1])). + From(t3). + Join(t2). + On(t3.C(group.UsersPrimaryKey[0]), t2.C(group.FieldID)) + query.sql = builder.Select(). + From(t1). + Join(t4). + On(t1.C(user.FieldID), t4.C(group.UsersPrimaryKey[1])) + return query +} + +// First returns the first Group entity in the query. Returns *ErrNotFound when no group was found. +func (gq *GroupQuery) First(ctx context.Context) (*Group, error) { + grs, err := gq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(grs) == 0 { + return nil, &ErrNotFound{group.Label} + } + return grs[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (gq *GroupQuery) FirstX(ctx context.Context) *Group { + gr, err := gq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return gr +} + +// FirstID returns the first Group id in the query. Returns *ErrNotFound when no id was found. +func (gq *GroupQuery) FirstID(ctx context.Context) (id string, err error) { + var ids []string + if ids, err = gq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &ErrNotFound{group.Label} + return + } + return ids[0], nil +} + +// FirstXID is like FirstID, but panics if an error occurs. +func (gq *GroupQuery) FirstXID(ctx context.Context) string { + id, err := gq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns the only Group entity in the query, returns an error if not exactly one entity was returned. +func (gq *GroupQuery) Only(ctx context.Context) (*Group, error) { + grs, err := gq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(grs) { + case 1: + return grs[0], nil + case 0: + return nil, &ErrNotFound{group.Label} + default: + return nil, &ErrNotSingular{group.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (gq *GroupQuery) OnlyX(ctx context.Context) *Group { + gr, err := gq.Only(ctx) + if err != nil { + panic(err) + } + return gr +} + +// OnlyID returns the only Group id in the query, returns an error if not exactly one id was returned. +func (gq *GroupQuery) OnlyID(ctx context.Context) (id string, err error) { + var ids []string + if ids, err = gq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &ErrNotFound{group.Label} + default: + err = &ErrNotSingular{group.Label} + } + return +} + +// OnlyXID is like OnlyID, but panics if an error occurs. +func (gq *GroupQuery) OnlyXID(ctx context.Context) string { + id, err := gq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Groups. +func (gq *GroupQuery) All(ctx context.Context) ([]*Group, error) { + return gq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (gq *GroupQuery) AllX(ctx context.Context) []*Group { + grs, err := gq.All(ctx) + if err != nil { + panic(err) + } + return grs +} + +// IDs executes the query and returns a list of Group ids. +func (gq *GroupQuery) IDs(ctx context.Context) ([]string, error) { + var ids []string + if err := gq.Select(group.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (gq *GroupQuery) IDsX(ctx context.Context) []string { + ids, err := gq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (gq *GroupQuery) Count(ctx context.Context) (int, error) { + return gq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (gq *GroupQuery) CountX(ctx context.Context) int { + count, err := gq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (gq *GroupQuery) Exist(ctx context.Context) (bool, error) { + return gq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (gq *GroupQuery) ExistX(ctx context.Context) bool { + exist, err := gq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the query builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (gq *GroupQuery) Clone() *GroupQuery { + return &GroupQuery{ + config: gq.config, + limit: gq.limit, + offset: gq.offset, + order: append([]Order{}, gq.order...), + unique: append([]string{}, gq.unique...), + predicates: append([]predicate.Group{}, gq.predicates...), + // clone intermediate queries. + sql: gq.sql.Clone(), + } +} + +// GroupBy used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +func (gq *GroupQuery) GroupBy(field string, fields ...string) *GroupGroupBy { + group := &GroupGroupBy{config: gq.config} + group.fields = append([]string{field}, fields...) + group.sql = gq.sqlQuery() + return group +} + +// Select one or more fields from the given query. +func (gq *GroupQuery) Select(field string, fields ...string) *GroupSelect { + selector := &GroupSelect{config: gq.config} + selector.fields = append([]string{field}, fields...) + selector.sql = gq.sqlQuery() + return selector +} + +func (gq *GroupQuery) sqlAll(ctx context.Context) ([]*Group, error) { + rows := &sql.Rows{} + selector := gq.sqlQuery() + if unique := gq.unique; len(unique) == 0 { + selector.Distinct() + } + query, args := selector.Query() + if err := gq.driver.Query(ctx, query, args, rows); err != nil { + return nil, err + } + defer rows.Close() + var grs Groups + if err := grs.FromRows(rows); err != nil { + return nil, err + } + grs.config(gq.config) + return grs, nil +} + +func (gq *GroupQuery) sqlCount(ctx context.Context) (int, error) { + rows := &sql.Rows{} + selector := gq.sqlQuery() + unique := []string{group.FieldID} + if len(gq.unique) > 0 { + unique = gq.unique + } + selector.Count(sql.Distinct(selector.Columns(unique...)...)) + query, args := selector.Query() + if err := gq.driver.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, errors.New("ent: no rows found") + } + var n int + if err := rows.Scan(&n); err != nil { + return 0, fmt.Errorf("ent: failed reading count: %v", err) + } + return n, nil +} + +func (gq *GroupQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := gq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %v", err) + } + return n > 0, nil +} + +func (gq *GroupQuery) sqlQuery() *sql.Selector { + builder := sql.Dialect(gq.driver.Dialect()) + t1 := builder.Table(group.Table) + selector := builder.Select(t1.Columns(group.Columns...)...).From(t1) + if gq.sql != nil { + selector = gq.sql + selector.Select(selector.Columns(group.Columns...)...) + } + for _, p := range gq.predicates { + p(selector) + } + for _, p := range gq.order { + p(selector) + } + if offset := gq.offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := gq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// GroupGroupBy is the builder for group-by Group entities. +type GroupGroupBy struct { + config + fields []string + fns []Aggregate + // intermediate queries. + sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (ggb *GroupGroupBy) Aggregate(fns ...Aggregate) *GroupGroupBy { + ggb.fns = append(ggb.fns, fns...) + return ggb +} + +// Scan applies the group-by query and scan the result into the given value. +func (ggb *GroupGroupBy) Scan(ctx context.Context, v interface{}) error { + return ggb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (ggb *GroupGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := ggb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field. +func (ggb *GroupGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(ggb.fields) > 1 { + return nil, errors.New("ent: GroupGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := ggb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (ggb *GroupGroupBy) StringsX(ctx context.Context) []string { + v, err := ggb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field. +func (ggb *GroupGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(ggb.fields) > 1 { + return nil, errors.New("ent: GroupGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := ggb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (ggb *GroupGroupBy) IntsX(ctx context.Context) []int { + v, err := ggb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field. +func (ggb *GroupGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(ggb.fields) > 1 { + return nil, errors.New("ent: GroupGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := ggb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (ggb *GroupGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := ggb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field. +func (ggb *GroupGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(ggb.fields) > 1 { + return nil, errors.New("ent: GroupGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := ggb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (ggb *GroupGroupBy) BoolsX(ctx context.Context) []bool { + v, err := ggb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (ggb *GroupGroupBy) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := ggb.sqlQuery().Query() + if err := ggb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (ggb *GroupGroupBy) sqlQuery() *sql.Selector { + selector := ggb.sql + columns := make([]string, 0, len(ggb.fields)+len(ggb.fns)) + columns = append(columns, ggb.fields...) + for _, fn := range ggb.fns { + columns = append(columns, fn.SQL(selector)) + } + return selector.Select(columns...).GroupBy(ggb.fields...) +} + +// GroupSelect is the builder for select fields of Group entities. +type GroupSelect struct { + config + fields []string + // intermediate queries. + sql *sql.Selector +} + +// Scan applies the selector query and scan the result into the given value. +func (gs *GroupSelect) Scan(ctx context.Context, v interface{}) error { + return gs.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (gs *GroupSelect) ScanX(ctx context.Context, v interface{}) { + if err := gs.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from selector. It is only allowed when selecting one field. +func (gs *GroupSelect) Strings(ctx context.Context) ([]string, error) { + if len(gs.fields) > 1 { + return nil, errors.New("ent: GroupSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := gs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (gs *GroupSelect) StringsX(ctx context.Context) []string { + v, err := gs.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from selector. It is only allowed when selecting one field. +func (gs *GroupSelect) Ints(ctx context.Context) ([]int, error) { + if len(gs.fields) > 1 { + return nil, errors.New("ent: GroupSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := gs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (gs *GroupSelect) IntsX(ctx context.Context) []int { + v, err := gs.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from selector. It is only allowed when selecting one field. +func (gs *GroupSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(gs.fields) > 1 { + return nil, errors.New("ent: GroupSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := gs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (gs *GroupSelect) Float64sX(ctx context.Context) []float64 { + v, err := gs.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from selector. It is only allowed when selecting one field. +func (gs *GroupSelect) Bools(ctx context.Context) ([]bool, error) { + if len(gs.fields) > 1 { + return nil, errors.New("ent: GroupSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := gs.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (gs *GroupSelect) BoolsX(ctx context.Context) []bool { + v, err := gs.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (gs *GroupSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := gs.sqlQuery().Query() + if err := gs.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (gs *GroupSelect) sqlQuery() sql.Querier { + view := "group_view" + return sql.Dialect(gs.driver.Dialect()). + Select(gs.fields...).From(gs.sql.As(view)) +} diff --git a/entc/integration/customid/ent/group_update.go b/entc/integration/customid/ent/group_update.go new file mode 100644 index 000000000..7441937a5 --- /dev/null +++ b/entc/integration/customid/ent/group_update.go @@ -0,0 +1,305 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" +) + +// GroupUpdate is the builder for updating Group entities. +type GroupUpdate struct { + config + users map[int]struct{} + removedUsers map[int]struct{} + predicates []predicate.Group +} + +// Where adds a new predicate for the builder. +func (gu *GroupUpdate) Where(ps ...predicate.Group) *GroupUpdate { + gu.predicates = append(gu.predicates, ps...) + return gu +} + +// AddUserIDs adds the users edge to User by ids. +func (gu *GroupUpdate) AddUserIDs(ids ...int) *GroupUpdate { + if gu.users == nil { + gu.users = make(map[int]struct{}) + } + for i := range ids { + gu.users[ids[i]] = struct{}{} + } + return gu +} + +// AddUsers adds the users edges to User. +func (gu *GroupUpdate) AddUsers(u ...*User) *GroupUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return gu.AddUserIDs(ids...) +} + +// RemoveUserIDs removes the users edge to User by ids. +func (gu *GroupUpdate) RemoveUserIDs(ids ...int) *GroupUpdate { + if gu.removedUsers == nil { + gu.removedUsers = make(map[int]struct{}) + } + for i := range ids { + gu.removedUsers[ids[i]] = struct{}{} + } + return gu +} + +// RemoveUsers removes users edges to User. +func (gu *GroupUpdate) RemoveUsers(u ...*User) *GroupUpdate { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return gu.RemoveUserIDs(ids...) +} + +// Save executes the query and returns the number of rows/vertices matched by this operation. +func (gu *GroupUpdate) Save(ctx context.Context) (int, error) { + return gu.sqlSave(ctx) +} + +// SaveX is like Save, but panics if an error occurs. +func (gu *GroupUpdate) SaveX(ctx context.Context) int { + affected, err := gu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (gu *GroupUpdate) Exec(ctx context.Context) error { + _, err := gu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (gu *GroupUpdate) ExecX(ctx context.Context) { + if err := gu.Exec(ctx); err != nil { + panic(err) + } +} + +func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) { + var ( + builder = sql.Dialect(gu.driver.Dialect()) + selector = builder.Select(group.FieldID).From(builder.Table(group.Table)) + ) + for _, p := range gu.predicates { + p(selector) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err = gu.driver.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + var ids []int + for rows.Next() { + var id int + if err := rows.Scan(&id); err != nil { + return 0, fmt.Errorf("ent: failed reading id: %v", err) + } + ids = append(ids, id) + } + if len(ids) == 0 { + return 0, nil + } + + tx, err := gu.driver.Tx(ctx) + if err != nil { + return 0, err + } + var res sql.Result + if len(gu.removedUsers) > 0 { + eids := make([]int, len(gu.removedUsers)) + for eid := range gu.removedUsers { + eids = append(eids, eid) + } + query, args := builder.Delete(group.UsersTable). + Where(sql.InInts(group.UsersPrimaryKey[0], ids...)). + Where(sql.InInts(group.UsersPrimaryKey[1], eids...)). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, rollback(tx, err) + } + } + if len(gu.users) > 0 { + values := make([][]int, 0, len(ids)) + for _, id := range ids { + for eid := range gu.users { + values = append(values, []int{id, eid}) + } + } + builder := builder.Insert(group.UsersTable). + Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]) + for _, v := range values { + builder.Values(v[0], v[1]) + } + query, args := builder.Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, rollback(tx, err) + } + } + if err = tx.Commit(); err != nil { + return 0, err + } + return len(ids), nil +} + +// GroupUpdateOne is the builder for updating a single Group entity. +type GroupUpdateOne struct { + config + id string + users map[int]struct{} + removedUsers map[int]struct{} +} + +// AddUserIDs adds the users edge to User by ids. +func (guo *GroupUpdateOne) AddUserIDs(ids ...int) *GroupUpdateOne { + if guo.users == nil { + guo.users = make(map[int]struct{}) + } + for i := range ids { + guo.users[ids[i]] = struct{}{} + } + return guo +} + +// AddUsers adds the users edges to User. +func (guo *GroupUpdateOne) AddUsers(u ...*User) *GroupUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return guo.AddUserIDs(ids...) +} + +// RemoveUserIDs removes the users edge to User by ids. +func (guo *GroupUpdateOne) RemoveUserIDs(ids ...int) *GroupUpdateOne { + if guo.removedUsers == nil { + guo.removedUsers = make(map[int]struct{}) + } + for i := range ids { + guo.removedUsers[ids[i]] = struct{}{} + } + return guo +} + +// RemoveUsers removes users edges to User. +func (guo *GroupUpdateOne) RemoveUsers(u ...*User) *GroupUpdateOne { + ids := make([]int, len(u)) + for i := range u { + ids[i] = u[i].ID + } + return guo.RemoveUserIDs(ids...) +} + +// Save executes the query and returns the updated entity. +func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) { + return guo.sqlSave(ctx) +} + +// SaveX is like Save, but panics if an error occurs. +func (guo *GroupUpdateOne) SaveX(ctx context.Context) *Group { + gr, err := guo.Save(ctx) + if err != nil { + panic(err) + } + return gr +} + +// Exec executes the query on the entity. +func (guo *GroupUpdateOne) Exec(ctx context.Context) error { + _, err := guo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (guo *GroupUpdateOne) ExecX(ctx context.Context) { + if err := guo.Exec(ctx); err != nil { + panic(err) + } +} + +func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) { + var ( + builder = sql.Dialect(guo.driver.Dialect()) + selector = builder.Select(group.Columns...).From(builder.Table(group.Table)) + ) + group.ID(guo.id)(selector) + rows := &sql.Rows{} + query, args := selector.Query() + if err = guo.driver.Query(ctx, query, args, rows); err != nil { + return nil, err + } + defer rows.Close() + var ids []int + for rows.Next() { + var id int + gr = &Group{config: guo.config} + if err := gr.FromRows(rows); err != nil { + return nil, fmt.Errorf("ent: failed scanning row into Group: %v", err) + } + id = gr.id() + ids = append(ids, id) + } + switch n := len(ids); { + case n == 0: + return nil, &ErrNotFound{fmt.Sprintf("Group with id: %v", guo.id)} + case n > 1: + return nil, fmt.Errorf("ent: more than one Group with the same id: %v", guo.id) + } + + tx, err := guo.driver.Tx(ctx) + if err != nil { + return nil, err + } + var res sql.Result + if len(guo.removedUsers) > 0 { + eids := make([]int, len(guo.removedUsers)) + for eid := range guo.removedUsers { + eids = append(eids, eid) + } + query, args := builder.Delete(group.UsersTable). + Where(sql.InInts(group.UsersPrimaryKey[0], ids...)). + Where(sql.InInts(group.UsersPrimaryKey[1], eids...)). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + if len(guo.users) > 0 { + values := make([][]int, 0, len(ids)) + for _, id := range ids { + for eid := range guo.users { + values = append(values, []int{id, eid}) + } + } + builder := builder.Insert(group.UsersTable). + Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]) + for _, v := range values { + builder.Values(v[0], v[1]) + } + query, args := builder.Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + if err = tx.Commit(); err != nil { + return nil, err + } + return gr, nil +} diff --git a/entc/integration/customid/ent/migrate/migrate.go b/entc/integration/customid/ent/migrate/migrate.go new file mode 100644 index 000000000..3afc279ab --- /dev/null +++ b/entc/integration/customid/ent/migrate/migrate.go @@ -0,0 +1,67 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package migrate + +import ( + "context" + "fmt" + "io" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/dialect/sql/schema" +) + +var ( + // WithGlobalUniqueID sets the universal ids options to the migration. + // If this option is enabled, ent migration will allocate a 1<<32 range + // for the ids of each entity (table). + // Note that this option cannot be applied on tables that already exist. + WithGlobalUniqueID = schema.WithGlobalUniqueID + // WithDropColumn sets the drop column option to the migration. + // If this option is enabled, ent migration will drop old columns + // that were used for both fields and edges. This defaults to false. + WithDropColumn = schema.WithDropColumn + // WithDropIndex sets the drop index option to the migration. + // If this option is enabled, ent migration will drop old indexes + // that were defined in the schema. This defaults to false. + // Note that unique constraints are defined using `UNIQUE INDEX`, + // and therefore, it's recommended to enable this option to get more + // flexibility in the schema changes. + WithDropIndex = schema.WithDropIndex +) + +// Schema is the API for creating, migrating and dropping a schema. +type Schema struct { + drv dialect.Driver + universalID bool +} + +// NewSchema creates a new schema client. +func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } + +// Create creates all schema resources. +func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { + migrate, err := schema.NewMigrate(s.drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} + +// WriteTo writes the schema changes to w instead of running them against the database. +// +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// log.Fatal(err) +// } +// +func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { + drv := &schema.WriteDriver{ + Writer: w, + Driver: s.drv, + } + migrate, err := schema.NewMigrate(drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %v", err) + } + return migrate.Create(ctx, Tables...) +} diff --git a/entc/integration/customid/ent/migrate/schema.go b/entc/integration/customid/ent/migrate/schema.go new file mode 100644 index 000000000..300e5060b --- /dev/null +++ b/entc/integration/customid/ent/migrate/schema.go @@ -0,0 +1,71 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package migrate + +import ( + "github.com/facebookincubator/ent/dialect/sql/schema" + "github.com/facebookincubator/ent/schema/field" +) + +var ( + // GroupsColumns holds the columns for the "groups" table. + GroupsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + } + // GroupsTable holds the schema information for the "groups" table. + GroupsTable = &schema.Table{ + Name: "groups", + Columns: GroupsColumns, + PrimaryKey: []*schema.Column{GroupsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{}, + } + // UsersColumns holds the columns for the "users" table. + UsersColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt, Increment: true}, + } + // UsersTable holds the schema information for the "users" table. + UsersTable = &schema.Table{ + Name: "users", + Columns: UsersColumns, + PrimaryKey: []*schema.Column{UsersColumns[0]}, + ForeignKeys: []*schema.ForeignKey{}, + } + // GroupUsersColumns holds the columns for the "group_users" table. + GroupUsersColumns = []*schema.Column{ + {Name: "group_id", Type: field.TypeString}, + {Name: "user_id", Type: field.TypeInt}, + } + // GroupUsersTable holds the schema information for the "group_users" table. + GroupUsersTable = &schema.Table{ + Name: "group_users", + Columns: GroupUsersColumns, + PrimaryKey: []*schema.Column{GroupUsersColumns[0], GroupUsersColumns[1]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "group_users_group_id", + Columns: []*schema.Column{GroupUsersColumns[0]}, + + RefColumns: []*schema.Column{GroupsColumns[0]}, + OnDelete: schema.Cascade, + }, + { + Symbol: "group_users_user_id", + Columns: []*schema.Column{GroupUsersColumns[1]}, + + RefColumns: []*schema.Column{UsersColumns[0]}, + OnDelete: schema.Cascade, + }, + }, + } + // Tables holds all the tables in the schema. + Tables = []*schema.Table{ + GroupsTable, + UsersTable, + GroupUsersTable, + } +) + +func init() { + GroupUsersTable.ForeignKeys[0].RefTable = GroupsTable + GroupUsersTable.ForeignKeys[1].RefTable = UsersTable +} diff --git a/entc/integration/customid/ent/predicate/predicate.go b/entc/integration/customid/ent/predicate/predicate.go new file mode 100644 index 000000000..8590a6ae4 --- /dev/null +++ b/entc/integration/customid/ent/predicate/predicate.go @@ -0,0 +1,13 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package predicate + +import ( + "github.com/facebookincubator/ent/dialect/sql" +) + +// Group is the predicate function for group builders. +type Group func(*sql.Selector) + +// User is the predicate function for user builders. +type User func(*sql.Selector) diff --git a/entc/integration/customid/ent/schema/group.go b/entc/integration/customid/ent/schema/group.go new file mode 100644 index 000000000..61d64ef17 --- /dev/null +++ b/entc/integration/customid/ent/schema/group.go @@ -0,0 +1,26 @@ +package schema + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/schema/edge" + "github.com/facebookincubator/ent/schema/field" +) + +// Group holds the schema definition for the Group entity. +type Group struct { + ent.Schema +} + +// Fields of the Group. +func (Group) Fields() []ent.Field { + return []ent.Field{ + field.String("id"), + } +} + +// Edges of the Group. +func (Group) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("users", User.Type), + } +} diff --git a/entc/integration/customid/ent/schema/user.go b/entc/integration/customid/ent/schema/user.go new file mode 100644 index 000000000..d71c4853c --- /dev/null +++ b/entc/integration/customid/ent/schema/user.go @@ -0,0 +1,27 @@ +package schema + +import ( + "github.com/facebookincubator/ent" + "github.com/facebookincubator/ent/schema/edge" + "github.com/facebookincubator/ent/schema/field" +) + +// User holds the schema definition for the User entity. +type User struct { + ent.Schema +} + +// Fields of the User. +func (User) Fields() []ent.Field { + return []ent.Field{ + field.Int("id"), + } +} + +// Edges of the User. +func (User) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("groups", Group.Type). + Ref("users"), + } +} diff --git a/entc/integration/customid/ent/tx.go b/entc/integration/customid/ent/tx.go new file mode 100644 index 000000000..5d9ed8f47 --- /dev/null +++ b/entc/integration/customid/ent/tx.go @@ -0,0 +1,96 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + + "github.com/facebookincubator/ent/dialect" + "github.com/facebookincubator/ent/entc/integration/customid/ent/migrate" +) + +// Tx is a transactional client that is created by calling Client.Tx(). +type Tx struct { + config + // Group is the client for interacting with the Group builders. + Group *GroupClient + // User is the client for interacting with the User builders. + User *UserClient +} + +// Commit commits the transaction. +func (tx *Tx) Commit() error { + return tx.config.driver.(*txDriver).tx.Commit() +} + +// Rollback rollbacks the transaction. +func (tx *Tx) Rollback() error { + return tx.config.driver.(*txDriver).tx.Rollback() +} + +// Client returns a Client that binds to current transaction. +func (tx *Tx) Client() *Client { + return &Client{ + config: tx.config, + Schema: migrate.NewSchema(tx.driver), + Group: NewGroupClient(tx.config), + User: NewUserClient(tx.config), + } +} + +// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. +// The idea is to support transactions without adding any extra code to the builders. +// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. +// Commit and Rollback are nop for the internal builders and the user must call one +// of them in order to commit or rollback the transaction. +// +// If a closed transaction is embedded in one of the generated entities, and the entity +// applies a query, for example: Group.QueryXXX(), the query will be executed +// through the driver which created this transaction. +// +// Note that txDriver is not goroutine safe. +type txDriver struct { + // the driver we started the transaction from. + drv dialect.Driver + // tx is the underlying transaction. + tx dialect.Tx +} + +// newTx creates a new transactional driver. +func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { + tx, err := drv.Tx(ctx) + if err != nil { + return nil, err + } + return &txDriver{tx: tx, drv: drv}, nil +} + +// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls +// from the internal builders. Should be called only by the internal builders. +func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } + +// Dialect returns the dialect of the driver we started the transaction from. +func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } + +// Close is a nop close. +func (*txDriver) Close() error { return nil } + +// Commit is a nop commit for the internal builders. +// User must call `Tx.Commit` in order to commit the transaction. +func (*txDriver) Commit() error { return nil } + +// Rollback is a nop rollback for the internal builders. +// User must call `Tx.Rollback` in order to rollback the transaction. +func (*txDriver) Rollback() error { return nil } + +// Exec calls tx.Exec. +func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Exec(ctx, query, args, v) +} + +// Query calls tx.Query. +func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { + return tx.tx.Query(ctx, query, args, v) +} + +var _ dialect.Driver = (*txDriver)(nil) diff --git a/entc/integration/customid/ent/user.go b/entc/integration/customid/ent/user.go new file mode 100644 index 000000000..20ef803c2 --- /dev/null +++ b/entc/integration/customid/ent/user.go @@ -0,0 +1,85 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + + "github.com/facebookincubator/ent/dialect/sql" +) + +// User is the model entity for the User schema. +type User struct { + config + // ID of the ent. + ID int `json:"id,omitempty"` +} + +// FromRows scans the sql response data into User. +func (u *User) FromRows(rows *sql.Rows) error { + var scanu struct { + ID int + } + // the order here should be the same as in the `user.Columns`. + if err := rows.Scan( + &scanu.ID, + ); err != nil { + return err + } + u.ID = scanu.ID + return nil +} + +// QueryGroups queries the groups edge of the User. +func (u *User) QueryGroups() *GroupQuery { + return (&UserClient{u.config}).QueryGroups(u) +} + +// Update returns a builder for updating this User. +// Note that, you need to call User.Unwrap() before calling this method, if this User +// was returned from a transaction, and the transaction was committed or rolled back. +func (u *User) Update() *UserUpdateOne { + return (&UserClient{u.config}).UpdateOne(u) +} + +// Unwrap unwraps the entity that was returned from a transaction after it was closed, +// so that all next queries will be executed through the driver which created the transaction. +func (u *User) Unwrap() *User { + tx, ok := u.config.driver.(*txDriver) + if !ok { + panic("ent: User is not a transactional entity") + } + u.config.driver = tx.drv + return u +} + +// String implements the fmt.Stringer. +func (u *User) String() string { + var builder strings.Builder + builder.WriteString("User(") + builder.WriteString(fmt.Sprintf("id=%v", u.ID)) + builder.WriteByte(')') + return builder.String() +} + +// Users is a parsable slice of User. +type Users []*User + +// FromRows scans the sql response data into Users. +func (u *Users) FromRows(rows *sql.Rows) error { + for rows.Next() { + scanu := &User{} + if err := scanu.FromRows(rows); err != nil { + return err + } + *u = append(*u, scanu) + } + return nil +} + +func (u Users) config(cfg config) { + for _i := range u { + u[_i].config = cfg + } +} diff --git a/entc/integration/customid/ent/user/user.go b/entc/integration/customid/ent/user/user.go new file mode 100644 index 000000000..cd3bf9428 --- /dev/null +++ b/entc/integration/customid/ent/user/user.go @@ -0,0 +1,29 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package user + +const ( + // Label holds the string label denoting the user type in the database. + Label = "user" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + + // Table holds the table name of the user in the database. + Table = "users" + // GroupsTable is the table the holds the groups relation/edge. The primary key declared below. + GroupsTable = "group_users" + // GroupsInverseTable is the table name for the Group entity. + // It exists in this package in order to avoid circular dependency with the "group" package. + GroupsInverseTable = "groups" +) + +// Columns holds all SQL columns are user fields. +var Columns = []string{ + FieldID, +} + +var ( + // GroupsPrimaryKey and GroupsColumn2 are the table columns denoting the + // primary key for the groups relation (M2M). + GroupsPrimaryKey = []string{"group_id", "user_id"} +) diff --git a/entc/integration/customid/ent/user/where.go b/entc/integration/customid/ent/user/where.go new file mode 100644 index 000000000..1eced1636 --- /dev/null +++ b/entc/integration/customid/ent/user/where.go @@ -0,0 +1,186 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package user + +import ( + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" +) + +// ID filters vertices based on their identifier. +func ID(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }, + ) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.EQ(s.C(FieldID), id)) + }, + ) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.NEQ(s.C(FieldID), id)) + }, + ) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.In(s.C(FieldID), v...)) + }, + ) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + // if not arguments were provided, append the FALSE constants, + // since we can't apply "IN ()". This will make this predicate falsy. + if len(ids) == 0 { + s.Where(sql.False()) + return + } + v := make([]interface{}, len(ids)) + for i := range v { + v[i] = ids[i] + } + s.Where(sql.NotIn(s.C(FieldID), v...)) + }, + ) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.GT(s.C(FieldID), id)) + }, + ) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.GTE(s.C(FieldID), id)) + }, + ) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.LT(s.C(FieldID), id)) + }, + ) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s.Where(sql.LTE(s.C(FieldID), id)) + }, + ) +} + +// HasGroups applies the HasEdge predicate on the "groups" edge. +func HasGroups() predicate.User { + return predicate.User( + func(s *sql.Selector) { + t1 := s.Table() + builder := sql.Dialect(s.Dialect()) + s.Where( + sql.In( + t1.C(FieldID), + builder.Select(GroupsPrimaryKey[1]). + From(builder.Table(GroupsTable)), + ), + ) + }, + ) +} + +// HasGroupsWith applies the HasEdge predicate on the "groups" edge with a given conditions (other predicates). +func HasGroupsWith(preds ...predicate.Group) predicate.User { + return predicate.User( + func(s *sql.Selector) { + builder := sql.Dialect(s.Dialect()) + t1 := s.Table() + t2 := builder.Table(GroupsInverseTable) + t3 := builder.Table(GroupsTable) + t4 := builder.Select(t3.C(GroupsPrimaryKey[1])). + From(t3). + Join(t2). + On(t3.C(GroupsPrimaryKey[0]), t2.C(FieldID)) + t5 := builder.Select().From(t2) + for _, p := range preds { + p(t5) + } + t4.FromSelect(t5) + s.Where(sql.In(t1.C(FieldID), t4)) + }, + ) +} + +// And groups list of predicates with the AND operator between them. +func And(predicates ...predicate.User) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for _, p := range predicates { + p(s1) + } + s.Where(s1.P()) + }, + ) +} + +// Or groups list of predicates with the OR operator between them. +func Or(predicates ...predicate.User) predicate.User { + return predicate.User( + func(s *sql.Selector) { + s1 := s.Clone().SetP(nil) + for i, p := range predicates { + if i > 0 { + s1.Or() + } + p(s1) + } + s.Where(s1.P()) + }, + ) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.User) predicate.User { + return predicate.User( + func(s *sql.Selector) { + p(s.Not()) + }, + ) +} diff --git a/entc/integration/customid/ent/user_create.go b/entc/integration/customid/ent/user_create.go new file mode 100644 index 000000000..83c640de1 --- /dev/null +++ b/entc/integration/customid/ent/user_create.go @@ -0,0 +1,96 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "strconv" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" +) + +// UserCreate is the builder for creating a User entity. +type UserCreate struct { + config + id *int + groups map[string]struct{} +} + +// SetID sets the id field. +func (uc *UserCreate) SetID(i int) *UserCreate { + uc.id = &i + return uc +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (uc *UserCreate) AddGroupIDs(ids ...string) *UserCreate { + if uc.groups == nil { + uc.groups = make(map[string]struct{}) + } + for i := range ids { + uc.groups[ids[i]] = struct{}{} + } + return uc +} + +// AddGroups adds the groups edges to Group. +func (uc *UserCreate) AddGroups(g ...*Group) *UserCreate { + ids := make([]string, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uc.AddGroupIDs(ids...) +} + +// Save creates the User in the database. +func (uc *UserCreate) Save(ctx context.Context) (*User, error) { + return uc.sqlSave(ctx) +} + +// SaveX calls Save and panics if Save returns an error. +func (uc *UserCreate) SaveX(ctx context.Context) *User { + v, err := uc.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { + var ( + res sql.Result + builder = sql.Dialect(uc.driver.Dialect()) + u = &User{config: uc.config} + ) + tx, err := uc.driver.Tx(ctx) + if err != nil { + return nil, err + } + insert := builder.Insert(user.Table).Default() + id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID)) + if err != nil { + return nil, rollback(tx, err) + } + u.ID = int(id) + if len(uc.groups) > 0 { + for eid := range uc.groups { + eid, err := strconv.Atoi(eid) + if err != nil { + return nil, rollback(tx, err) + } + + query, args := builder.Insert(user.GroupsTable). + Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]). + Values(id, eid). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + } + if err := tx.Commit(); err != nil { + return nil, err + } + return u, nil +} diff --git a/entc/integration/customid/ent/user_delete.go b/entc/integration/customid/ent/user_delete.go new file mode 100644 index 000000000..ee94459da --- /dev/null +++ b/entc/integration/customid/ent/user_delete.go @@ -0,0 +1,80 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" +) + +// UserDelete is the builder for deleting a User entity. +type UserDelete struct { + config + predicates []predicate.User +} + +// Where adds a new predicate to the delete builder. +func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { + ud.predicates = append(ud.predicates, ps...) + return ud +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (ud *UserDelete) Exec(ctx context.Context) (int, error) { + return ud.sqlExec(ctx) +} + +// ExecX is like Exec, but panics if an error occurs. +func (ud *UserDelete) ExecX(ctx context.Context) int { + n, err := ud.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (ud *UserDelete) sqlExec(ctx context.Context) (int, error) { + var ( + res sql.Result + builder = sql.Dialect(ud.driver.Dialect()) + ) + selector := builder.Select().From(sql.Table(user.Table)) + for _, p := range ud.predicates { + p(selector) + } + query, args := builder.Delete(user.Table).FromSelect(selector).Query() + if err := ud.driver.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + affected, err := res.RowsAffected() + if err != nil { + return 0, err + } + return int(affected), nil +} + +// UserDeleteOne is the builder for deleting a single User entity. +type UserDeleteOne struct { + ud *UserDelete +} + +// Exec executes the deletion query. +func (udo *UserDeleteOne) Exec(ctx context.Context) error { + n, err := udo.ud.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &ErrNotFound{user.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (udo *UserDeleteOne) ExecX(ctx context.Context) { + udo.ud.ExecX(ctx) +} diff --git a/entc/integration/customid/ent/user_query.go b/entc/integration/customid/ent/user_query.go new file mode 100644 index 000000000..aa2cc52a8 --- /dev/null +++ b/entc/integration/customid/ent/user_query.go @@ -0,0 +1,583 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "math" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/group" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" +) + +// UserQuery is the builder for querying User entities. +type UserQuery struct { + config + limit *int + offset *int + order []Order + unique []string + predicates []predicate.User + // intermediate queries. + sql *sql.Selector +} + +// Where adds a new predicate for the builder. +func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery { + uq.predicates = append(uq.predicates, ps...) + return uq +} + +// Limit adds a limit step to the query. +func (uq *UserQuery) Limit(limit int) *UserQuery { + uq.limit = &limit + return uq +} + +// Offset adds an offset step to the query. +func (uq *UserQuery) Offset(offset int) *UserQuery { + uq.offset = &offset + return uq +} + +// Order adds an order step to the query. +func (uq *UserQuery) Order(o ...Order) *UserQuery { + uq.order = append(uq.order, o...) + return uq +} + +// QueryGroups chains the current query on the groups edge. +func (uq *UserQuery) QueryGroups() *GroupQuery { + query := &GroupQuery{config: uq.config} + + builder := sql.Dialect(uq.driver.Dialect()) + t1 := builder.Table(group.Table) + t2 := uq.sqlQuery() + t2.Select(t2.C(user.FieldID)) + t3 := builder.Table(user.GroupsTable) + t4 := builder.Select(t3.C(user.GroupsPrimaryKey[0])). + From(t3). + Join(t2). + On(t3.C(user.GroupsPrimaryKey[1]), t2.C(user.FieldID)) + query.sql = builder.Select(). + From(t1). + Join(t4). + On(t1.C(group.FieldID), t4.C(user.GroupsPrimaryKey[0])) + return query +} + +// First returns the first User entity in the query. Returns *ErrNotFound when no user was found. +func (uq *UserQuery) First(ctx context.Context) (*User, error) { + us, err := uq.Limit(1).All(ctx) + if err != nil { + return nil, err + } + if len(us) == 0 { + return nil, &ErrNotFound{user.Label} + } + return us[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (uq *UserQuery) FirstX(ctx context.Context) *User { + u, err := uq.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return u +} + +// FirstID returns the first User id in the query. Returns *ErrNotFound when no id was found. +func (uq *UserQuery) FirstID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = uq.Limit(1).IDs(ctx); err != nil { + return + } + if len(ids) == 0 { + err = &ErrNotFound{user.Label} + return + } + return ids[0], nil +} + +// FirstXID is like FirstID, but panics if an error occurs. +func (uq *UserQuery) FirstXID(ctx context.Context) int { + id, err := uq.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns the only User entity in the query, returns an error if not exactly one entity was returned. +func (uq *UserQuery) Only(ctx context.Context) (*User, error) { + us, err := uq.Limit(2).All(ctx) + if err != nil { + return nil, err + } + switch len(us) { + case 1: + return us[0], nil + case 0: + return nil, &ErrNotFound{user.Label} + default: + return nil, &ErrNotSingular{user.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (uq *UserQuery) OnlyX(ctx context.Context) *User { + u, err := uq.Only(ctx) + if err != nil { + panic(err) + } + return u +} + +// OnlyID returns the only User id in the query, returns an error if not exactly one id was returned. +func (uq *UserQuery) OnlyID(ctx context.Context) (id int, err error) { + var ids []int + if ids, err = uq.Limit(2).IDs(ctx); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &ErrNotFound{user.Label} + default: + err = &ErrNotSingular{user.Label} + } + return +} + +// OnlyXID is like OnlyID, but panics if an error occurs. +func (uq *UserQuery) OnlyXID(ctx context.Context) int { + id, err := uq.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Users. +func (uq *UserQuery) All(ctx context.Context) ([]*User, error) { + return uq.sqlAll(ctx) +} + +// AllX is like All, but panics if an error occurs. +func (uq *UserQuery) AllX(ctx context.Context) []*User { + us, err := uq.All(ctx) + if err != nil { + panic(err) + } + return us +} + +// IDs executes the query and returns a list of User ids. +func (uq *UserQuery) IDs(ctx context.Context) ([]int, error) { + var ids []int + if err := uq.Select(user.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (uq *UserQuery) IDsX(ctx context.Context) []int { + ids, err := uq.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (uq *UserQuery) Count(ctx context.Context) (int, error) { + return uq.sqlCount(ctx) +} + +// CountX is like Count, but panics if an error occurs. +func (uq *UserQuery) CountX(ctx context.Context) int { + count, err := uq.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (uq *UserQuery) Exist(ctx context.Context) (bool, error) { + return uq.sqlExist(ctx) +} + +// ExistX is like Exist, but panics if an error occurs. +func (uq *UserQuery) ExistX(ctx context.Context) bool { + exist, err := uq.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the query builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (uq *UserQuery) Clone() *UserQuery { + return &UserQuery{ + config: uq.config, + limit: uq.limit, + offset: uq.offset, + order: append([]Order{}, uq.order...), + unique: append([]string{}, uq.unique...), + predicates: append([]predicate.User{}, uq.predicates...), + // clone intermediate queries. + sql: uq.sql.Clone(), + } +} + +// GroupBy used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy { + group := &UserGroupBy{config: uq.config} + group.fields = append([]string{field}, fields...) + group.sql = uq.sqlQuery() + return group +} + +// Select one or more fields from the given query. +func (uq *UserQuery) Select(field string, fields ...string) *UserSelect { + selector := &UserSelect{config: uq.config} + selector.fields = append([]string{field}, fields...) + selector.sql = uq.sqlQuery() + return selector +} + +func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) { + rows := &sql.Rows{} + selector := uq.sqlQuery() + if unique := uq.unique; len(unique) == 0 { + selector.Distinct() + } + query, args := selector.Query() + if err := uq.driver.Query(ctx, query, args, rows); err != nil { + return nil, err + } + defer rows.Close() + var us Users + if err := us.FromRows(rows); err != nil { + return nil, err + } + us.config(uq.config) + return us, nil +} + +func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { + rows := &sql.Rows{} + selector := uq.sqlQuery() + unique := []string{user.FieldID} + if len(uq.unique) > 0 { + unique = uq.unique + } + selector.Count(sql.Distinct(selector.Columns(unique...)...)) + query, args := selector.Query() + if err := uq.driver.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + if !rows.Next() { + return 0, errors.New("ent: no rows found") + } + var n int + if err := rows.Scan(&n); err != nil { + return 0, fmt.Errorf("ent: failed reading count: %v", err) + } + return n, nil +} + +func (uq *UserQuery) sqlExist(ctx context.Context) (bool, error) { + n, err := uq.sqlCount(ctx) + if err != nil { + return false, fmt.Errorf("ent: check existence: %v", err) + } + return n > 0, nil +} + +func (uq *UserQuery) sqlQuery() *sql.Selector { + builder := sql.Dialect(uq.driver.Dialect()) + t1 := builder.Table(user.Table) + selector := builder.Select(t1.Columns(user.Columns...)...).From(t1) + if uq.sql != nil { + selector = uq.sql + selector.Select(selector.Columns(user.Columns...)...) + } + for _, p := range uq.predicates { + p(selector) + } + for _, p := range uq.order { + p(selector) + } + if offset := uq.offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := uq.limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// UserGroupBy is the builder for group-by User entities. +type UserGroupBy struct { + config + fields []string + fns []Aggregate + // intermediate queries. + sql *sql.Selector +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (ugb *UserGroupBy) Aggregate(fns ...Aggregate) *UserGroupBy { + ugb.fns = append(ugb.fns, fns...) + return ugb +} + +// Scan applies the group-by query and scan the result into the given value. +func (ugb *UserGroupBy) Scan(ctx context.Context, v interface{}) error { + return ugb.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (ugb *UserGroupBy) ScanX(ctx context.Context, v interface{}) { + if err := ugb.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Strings(ctx context.Context) ([]string, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Strings is not achievable when grouping more than 1 field") + } + var v []string + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (ugb *UserGroupBy) StringsX(ctx context.Context) []string { + v, err := ugb.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Ints(ctx context.Context) ([]int, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Ints is not achievable when grouping more than 1 field") + } + var v []int + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (ugb *UserGroupBy) IntsX(ctx context.Context) []int { + v, err := ugb.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Float64s(ctx context.Context) ([]float64, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Float64s is not achievable when grouping more than 1 field") + } + var v []float64 + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (ugb *UserGroupBy) Float64sX(ctx context.Context) []float64 { + v, err := ugb.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field. +func (ugb *UserGroupBy) Bools(ctx context.Context) ([]bool, error) { + if len(ugb.fields) > 1 { + return nil, errors.New("ent: UserGroupBy.Bools is not achievable when grouping more than 1 field") + } + var v []bool + if err := ugb.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (ugb *UserGroupBy) BoolsX(ctx context.Context) []bool { + v, err := ugb.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (ugb *UserGroupBy) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := ugb.sqlQuery().Query() + if err := ugb.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (ugb *UserGroupBy) sqlQuery() *sql.Selector { + selector := ugb.sql + columns := make([]string, 0, len(ugb.fields)+len(ugb.fns)) + columns = append(columns, ugb.fields...) + for _, fn := range ugb.fns { + columns = append(columns, fn.SQL(selector)) + } + return selector.Select(columns...).GroupBy(ugb.fields...) +} + +// UserSelect is the builder for select fields of User entities. +type UserSelect struct { + config + fields []string + // intermediate queries. + sql *sql.Selector +} + +// Scan applies the selector query and scan the result into the given value. +func (us *UserSelect) Scan(ctx context.Context, v interface{}) error { + return us.sqlScan(ctx, v) +} + +// ScanX is like Scan, but panics if an error occurs. +func (us *UserSelect) ScanX(ctx context.Context, v interface{}) { + if err := us.Scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from selector. It is only allowed when selecting one field. +func (us *UserSelect) Strings(ctx context.Context) ([]string, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (us *UserSelect) StringsX(ctx context.Context) []string { + v, err := us.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from selector. It is only allowed when selecting one field. +func (us *UserSelect) Ints(ctx context.Context) ([]int, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (us *UserSelect) IntsX(ctx context.Context) []int { + v, err := us.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from selector. It is only allowed when selecting one field. +func (us *UserSelect) Float64s(ctx context.Context) ([]float64, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (us *UserSelect) Float64sX(ctx context.Context) []float64 { + v, err := us.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from selector. It is only allowed when selecting one field. +func (us *UserSelect) Bools(ctx context.Context) ([]bool, error) { + if len(us.fields) > 1 { + return nil, errors.New("ent: UserSelect.Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := us.Scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (us *UserSelect) BoolsX(ctx context.Context) []bool { + v, err := us.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +func (us *UserSelect) sqlScan(ctx context.Context, v interface{}) error { + rows := &sql.Rows{} + query, args := us.sqlQuery().Query() + if err := us.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +func (us *UserSelect) sqlQuery() sql.Querier { + view := "user_view" + return sql.Dialect(us.driver.Dialect()). + Select(us.fields...).From(us.sql.As(view)) +} diff --git a/entc/integration/customid/ent/user_update.go b/entc/integration/customid/ent/user_update.go new file mode 100644 index 000000000..295e87c5f --- /dev/null +++ b/entc/integration/customid/ent/user_update.go @@ -0,0 +1,326 @@ +// Code generated (@generated) by entc, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "strconv" + + "github.com/facebookincubator/ent/dialect/sql" + "github.com/facebookincubator/ent/entc/integration/customid/ent/predicate" + "github.com/facebookincubator/ent/entc/integration/customid/ent/user" +) + +// UserUpdate is the builder for updating User entities. +type UserUpdate struct { + config + groups map[string]struct{} + removedGroups map[string]struct{} + predicates []predicate.User +} + +// Where adds a new predicate for the builder. +func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { + uu.predicates = append(uu.predicates, ps...) + return uu +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (uu *UserUpdate) AddGroupIDs(ids ...string) *UserUpdate { + if uu.groups == nil { + uu.groups = make(map[string]struct{}) + } + for i := range ids { + uu.groups[ids[i]] = struct{}{} + } + return uu +} + +// AddGroups adds the groups edges to Group. +func (uu *UserUpdate) AddGroups(g ...*Group) *UserUpdate { + ids := make([]string, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uu.AddGroupIDs(ids...) +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (uu *UserUpdate) RemoveGroupIDs(ids ...string) *UserUpdate { + if uu.removedGroups == nil { + uu.removedGroups = make(map[string]struct{}) + } + for i := range ids { + uu.removedGroups[ids[i]] = struct{}{} + } + return uu +} + +// RemoveGroups removes groups edges to Group. +func (uu *UserUpdate) RemoveGroups(g ...*Group) *UserUpdate { + ids := make([]string, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uu.RemoveGroupIDs(ids...) +} + +// Save executes the query and returns the number of rows/vertices matched by this operation. +func (uu *UserUpdate) Save(ctx context.Context) (int, error) { + return uu.sqlSave(ctx) +} + +// SaveX is like Save, but panics if an error occurs. +func (uu *UserUpdate) SaveX(ctx context.Context) int { + affected, err := uu.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (uu *UserUpdate) Exec(ctx context.Context) error { + _, err := uu.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uu *UserUpdate) ExecX(ctx context.Context) { + if err := uu.Exec(ctx); err != nil { + panic(err) + } +} + +func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { + var ( + builder = sql.Dialect(uu.driver.Dialect()) + selector = builder.Select(user.FieldID).From(builder.Table(user.Table)) + ) + for _, p := range uu.predicates { + p(selector) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err = uu.driver.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + var ids []int + for rows.Next() { + var id int + if err := rows.Scan(&id); err != nil { + return 0, fmt.Errorf("ent: failed reading id: %v", err) + } + ids = append(ids, id) + } + if len(ids) == 0 { + return 0, nil + } + + tx, err := uu.driver.Tx(ctx) + if err != nil { + return 0, err + } + var res sql.Result + if len(uu.removedGroups) > 0 { + eids := make([]int, len(uu.removedGroups)) + for eid := range uu.removedGroups { + eid, serr := strconv.Atoi(eid) + if serr != nil { + err = rollback(tx, serr) + return + } + eids = append(eids, eid) + } + query, args := builder.Delete(user.GroupsTable). + Where(sql.InInts(user.GroupsPrimaryKey[1], ids...)). + Where(sql.InInts(user.GroupsPrimaryKey[0], eids...)). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, rollback(tx, err) + } + } + if len(uu.groups) > 0 { + values := make([][]int, 0, len(ids)) + for _, id := range ids { + for eid := range uu.groups { + eid, serr := strconv.Atoi(eid) + if serr != nil { + err = rollback(tx, serr) + return + } + values = append(values, []int{id, eid}) + } + } + builder := builder.Insert(user.GroupsTable). + Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]) + for _, v := range values { + builder.Values(v[0], v[1]) + } + query, args := builder.Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, rollback(tx, err) + } + } + if err = tx.Commit(); err != nil { + return 0, err + } + return len(ids), nil +} + +// UserUpdateOne is the builder for updating a single User entity. +type UserUpdateOne struct { + config + id int + groups map[string]struct{} + removedGroups map[string]struct{} +} + +// AddGroupIDs adds the groups edge to Group by ids. +func (uuo *UserUpdateOne) AddGroupIDs(ids ...string) *UserUpdateOne { + if uuo.groups == nil { + uuo.groups = make(map[string]struct{}) + } + for i := range ids { + uuo.groups[ids[i]] = struct{}{} + } + return uuo +} + +// AddGroups adds the groups edges to Group. +func (uuo *UserUpdateOne) AddGroups(g ...*Group) *UserUpdateOne { + ids := make([]string, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uuo.AddGroupIDs(ids...) +} + +// RemoveGroupIDs removes the groups edge to Group by ids. +func (uuo *UserUpdateOne) RemoveGroupIDs(ids ...string) *UserUpdateOne { + if uuo.removedGroups == nil { + uuo.removedGroups = make(map[string]struct{}) + } + for i := range ids { + uuo.removedGroups[ids[i]] = struct{}{} + } + return uuo +} + +// RemoveGroups removes groups edges to Group. +func (uuo *UserUpdateOne) RemoveGroups(g ...*Group) *UserUpdateOne { + ids := make([]string, len(g)) + for i := range g { + ids[i] = g[i].ID + } + return uuo.RemoveGroupIDs(ids...) +} + +// Save executes the query and returns the updated entity. +func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { + return uuo.sqlSave(ctx) +} + +// SaveX is like Save, but panics if an error occurs. +func (uuo *UserUpdateOne) SaveX(ctx context.Context) *User { + u, err := uuo.Save(ctx) + if err != nil { + panic(err) + } + return u +} + +// Exec executes the query on the entity. +func (uuo *UserUpdateOne) Exec(ctx context.Context) error { + _, err := uuo.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (uuo *UserUpdateOne) ExecX(ctx context.Context) { + if err := uuo.Exec(ctx); err != nil { + panic(err) + } +} + +func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) { + var ( + builder = sql.Dialect(uuo.driver.Dialect()) + selector = builder.Select(user.Columns...).From(builder.Table(user.Table)) + ) + user.ID(uuo.id)(selector) + rows := &sql.Rows{} + query, args := selector.Query() + if err = uuo.driver.Query(ctx, query, args, rows); err != nil { + return nil, err + } + defer rows.Close() + var ids []int + for rows.Next() { + var id int + u = &User{config: uuo.config} + if err := u.FromRows(rows); err != nil { + return nil, fmt.Errorf("ent: failed scanning row into User: %v", err) + } + id = u.ID + ids = append(ids, id) + } + switch n := len(ids); { + case n == 0: + return nil, &ErrNotFound{fmt.Sprintf("User with id: %v", uuo.id)} + case n > 1: + return nil, fmt.Errorf("ent: more than one User with the same id: %v", uuo.id) + } + + tx, err := uuo.driver.Tx(ctx) + if err != nil { + return nil, err + } + var res sql.Result + if len(uuo.removedGroups) > 0 { + eids := make([]int, len(uuo.removedGroups)) + for eid := range uuo.removedGroups { + eid, serr := strconv.Atoi(eid) + if serr != nil { + err = rollback(tx, serr) + return + } + eids = append(eids, eid) + } + query, args := builder.Delete(user.GroupsTable). + Where(sql.InInts(user.GroupsPrimaryKey[1], ids...)). + Where(sql.InInts(user.GroupsPrimaryKey[0], eids...)). + Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + if len(uuo.groups) > 0 { + values := make([][]int, 0, len(ids)) + for _, id := range ids { + for eid := range uuo.groups { + eid, serr := strconv.Atoi(eid) + if serr != nil { + err = rollback(tx, serr) + return + } + values = append(values, []int{id, eid}) + } + } + builder := builder.Insert(user.GroupsTable). + Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]) + for _, v := range values { + builder.Values(v[0], v[1]) + } + query, args := builder.Query() + if err := tx.Exec(ctx, query, args, &res); err != nil { + return nil, rollback(tx, err) + } + } + if err = tx.Commit(); err != nil { + return nil, err + } + return u, nil +}