diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go index df1e1e8e4..8e4c33144 100644 --- a/dialect/sql/builder.go +++ b/dialect/sql/builder.go @@ -9,17 +9,17 @@ import ( "fbc/ent/dialect" ) -// Node represents a builder step in the query. -type Node interface { +// Querier wraps the basic Query method. +type Querier interface { // Query returns the query representation of the element and its arguments (if any). Query() (string, []interface{}) } -// Nodes are list of queries join with space between them. -type Nodes []Node +// Queries are list of queries join with space between them. +type Queries []Querier -// Query returns query representation of Nodes. -func (n Nodes) Query() (string, []interface{}) { +// Query returns query representation of Queriers. +func (n Queries) Query() (string, []interface{}) { b := Builder{} for i := range n { if i > 0 { @@ -96,8 +96,8 @@ func (b *Builder) Pad() *Builder { return b } -// Join joins a list of Nodes to the builder. -func (b *Builder) Join(n ...Node) *Builder { +// Join joins a list of Queriers to the builder. +func (b *Builder) Join(n ...Querier) *Builder { for i := range n { query, args := n[i].Query() b.WriteString(query) @@ -106,8 +106,8 @@ func (b *Builder) Join(n ...Node) *Builder { return b } -// JoinComma joins a list of Nodes and adds comma between them. -func (b *Builder) JoinComma(n ...Node) *Builder { +// JoinComma joins a list of Queriers and adds comma between them. +func (b *Builder) JoinComma(n ...Querier) *Builder { for i := range n { if i > 0 { b.Comma() @@ -130,6 +130,13 @@ func (b *Builder) Nested(f func(*Builder)) *Builder { return b } +// clone returns a shallow clone of a builder. +func (b Builder) clone() Builder { + c := Builder{args: append([]interface{}{}, b.args...)} + c.Buffer.Write(c.Bytes()) + return c +} + // ColumnBuilder is a builder for column definition in table creation. type ColumnBuilder struct { b Builder @@ -177,7 +184,7 @@ type TableBuilder struct { collation string // table collation. columns []*ColumnBuilder // table columns. primary []string // primary key. - constraints []Node // foreign keys and indices. + constraints []Querier // foreign keys and indices. } // CreateTable returns a query builder for the `CREATE TABLE` statement. @@ -217,23 +224,23 @@ func (t *TableBuilder) PrimaryKey(column ...string) *TableBuilder { // ForeignKeys adds a list of foreign-keys to the statement (without constraints). func (t *TableBuilder) ForeignKeys(fks ...*ForeignKeyBuilder) *TableBuilder { - nodes := make([]Node, len(fks)) + Queriers := make([]Querier, len(fks)) for i := range fks { // erase the constraint symbol/name. fks[i].symbol = "" - nodes[i] = fks[i] + Queriers[i] = fks[i] } - t.constraints = append(t.constraints, nodes...) + t.constraints = append(t.constraints, Queriers...) return t } // Constraints adds a list of foreign-key constraints to the statement. func (t *TableBuilder) Constraints(fks ...*ForeignKeyBuilder) *TableBuilder { - nodes := make([]Node, len(fks)) + Queriers := make([]Querier, len(fks)) for i := range fks { - nodes[i] = &Wrapper{"CONSTRAINT %s", fks[i]} + Queriers[i] = &Wrapper{"CONSTRAINT %s", fks[i]} } - t.constraints = append(t.constraints, nodes...) + t.constraints = append(t.constraints, Queriers...) return t } @@ -303,9 +310,9 @@ func (t *DescribeBuilder) Query() (string, []interface{}) { // TableAlter is a query builder for `ALTER TABLE` statement. type TableAlter struct { - b Builder - name string // table to alter. - nodes []Node // columns and foreign-keys to add. + b Builder + name string // table to alter. + Queriers []Querier // columns and foreign-keys to add. } // AlterTable returns a query builder for the `ALTER TABLE` statement. @@ -318,19 +325,19 @@ func AlterTable(name string) *TableAlter { return &TableAlter{b: Builder{}, name // AddColumn appends the `ADD COLUMN` clause to the given `ALTER TABLE` statement. func (t *TableAlter) AddColumn(c *ColumnBuilder) *TableAlter { - t.nodes = append(t.nodes, &Wrapper{"ADD COLUMN %s", c}) + t.Queriers = append(t.Queriers, &Wrapper{"ADD COLUMN %s", c}) return t } // Modify appends the `MODIFY COLUMN` clause to the given `ALTER TABLE` statement. func (t *TableAlter) ModifyColumn(c *ColumnBuilder) *TableAlter { - t.nodes = append(t.nodes, &Wrapper{"MODIFY COLUMN %s", c}) + t.Queriers = append(t.Queriers, &Wrapper{"MODIFY COLUMN %s", c}) return t } // AddForeignKey adds a foreign key constraint to the `ALTER TABLE` statement. func (t *TableAlter) AddForeignKey(fk *ForeignKeyBuilder) *TableAlter { - t.nodes = append(t.nodes, &Wrapper{"ADD CONSTRAINT %s", fk}) + t.Queriers = append(t.Queriers, &Wrapper{"ADD CONSTRAINT %s", fk}) return t } @@ -339,7 +346,7 @@ func (t *TableAlter) Query() (string, []interface{}) { t.b.WriteString("ALTER TABLE ") t.b.Append(t.name) t.b.Pad() - t.b.JoinComma(t.nodes...) + t.b.JoinComma(t.Queriers...) return t.b.String(), t.b.args } @@ -921,6 +928,14 @@ func (p *Predicate) merge(pred *Predicate) *Predicate { return p } +// clone returns a shallow clone of p. +func (p *Predicate) clone() *Predicate { + if p == nil { + return p + } + return &Predicate{p.b.clone()} +} + // TableView is a view that returns a table view. Can ne a Table, Selector or a View (WITH statement). type TableView interface { view() @@ -1201,6 +1216,29 @@ func (s *Selector) Count(columns ...string) *Selector { return s } +// Clone returns a duplicate of the selector, including all associated steps. It can be +// used to prepare common SELECT statements and use them differently after the clone is made. +func (s *Selector) Clone() *Selector { + if s == nil { + return nil + } + return &Selector{ + as: s.as, + or: s.or, + not: s.not, + from: s.from, + limit: s.limit, + offset: s.offset, + distinct: s.distinct, + where: s.where.clone(), + having: s.having.clone(), + joins: append([]join{}, s.joins...), + group: append([]string{}, s.group...), + order: append([]string{}, s.order...), + columns: append([]string{}, s.columns...), + } +} + // Asc adds the ASC suffix for the given column. func Asc(column string) string { b := Builder{} @@ -1280,7 +1318,7 @@ func (s *Selector) Query() (string, []interface{}) { b.WriteString(query) b.args = append(b.args, args...) } - if s.order != nil { + if len(s.order) > 0 { b.WriteString(" ORDER BY ") b.AppendComma(s.order...) } @@ -1307,7 +1345,7 @@ type WithBuilder struct { // With returns a new builder for the `WITH` statement. // -// n := Nodes{With("users_view").As(Select().From(Table("users"))), Select().From(Table("users_view"))} +// n := Queriers{With("users_view").As(Select().From(Table("users"))), Select().From(Table("users_view"))} // return n.Query() // func With(name string) *WithBuilder { @@ -1336,21 +1374,21 @@ func (w *WithBuilder) Query() (string, []interface{}) { // implement the table view interface. func (*WithBuilder) view() {} -// Wrapper wraps a given node with different format. +// Wrapper wraps a given Querier with different format. // Used to prefix/suffix other queries. type Wrapper struct { format string - wrapped Node + wrapped Querier } -// Query returns query representation of a wrapped node. +// Query returns query representation of a wrapped Querier. func (w *Wrapper) Query() (string, []interface{}) { query, args := w.wrapped.Query() return fmt.Sprintf(w.format, query), args } -// Raw returns a raw sql node that is placed as-is in the query. -func Raw(s string) Node { return &raw{s} } +// Raw returns a raw sql Querier that is placed as-is in the query. +func Raw(s string) Querier { return &raw{s} } type raw struct{ s string } diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go index 7d2b166b4..901210e7a 100644 --- a/dialect/sql/builder_test.go +++ b/dialect/sql/builder_test.go @@ -9,7 +9,7 @@ import ( func TestBuilder(t *testing.T) { tests := []struct { - input Node + input Querier wantQuery string wantArgs []interface{} }{ @@ -230,7 +230,7 @@ func TestBuilder(t *testing.T) { wantQuery: "SELECT * FROM `users` AS `u`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") t2 := Table("groups").As("g") return Select(t1.C("id"), t2.C("name")).From(t1).Join(t2) @@ -238,7 +238,7 @@ func TestBuilder(t *testing.T) { wantQuery: "SELECT `u`.`id`, `g`.`name` FROM `users` AS `u` JOIN `groups` AS `g`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") t2 := Table("groups").As("g") return Select(t1.C("id"), t2.C("name")). @@ -249,7 +249,7 @@ func TestBuilder(t *testing.T) { wantQuery: "SELECT `u`.`id`, `g`.`name` FROM `users` AS `u` JOIN `groups` AS `g` ON `u`.`id` = `g`.`user_id`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") t2 := Table("groups").As("g") return Select(t1.C("id"), t2.C("name")). @@ -262,14 +262,14 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"bar"}, }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") return Select(t1.Columns("name", "age")...).From(t1) }(), wantQuery: "SELECT `u`.`name`, `u`.`age` FROM `users` AS `u`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") t2 := Select().From(Table("groups")).Where(EQ("user_id", 10)).As("g") return Select(t1.C("id"), t2.C("name")). @@ -281,7 +281,7 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{10}, }, { - input: func() Node { + input: func() Querier { selector := Select().Where(EQ("name", "foo").Or().EQ("name", "bar")) return Delete("users").FromSelect(selector) }(), @@ -289,14 +289,14 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"foo", "bar"}, }, { - input: func() Node { + input: func() Querier { selector := Select().From(Table("users")).As("t") return selector.Select(selector.C("name")) }(), wantQuery: "SELECT `t`.`name` FROM `users`", }, { - input: func() Node { + input: func() Querier { selector := Select().From(Table("groups")).Where(EQ("name", "foo")) return Delete("users").FromSelect(selector) }(), @@ -304,7 +304,7 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"foo"}, }, { - input: func() Node { + input: func() Querier { selector := Select() return Delete("users").FromSelect(selector) }(), @@ -316,7 +316,7 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"foo", "bar"}, }, { - input: func() Node { + input: func() Querier { t1 := Table("users") return Select(). From(t1). @@ -326,7 +326,7 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"pedro"}, }, { - input: func() Node { + input: func() Querier { t1 := Table("users") return Select(). From(t1). @@ -344,7 +344,7 @@ func TestBuilder(t *testing.T) { wantQuery: "SELECT COUNT(DISTINCT `id`) FROM `users`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users") t2 := Select().From(Table("groups")) t3 := Select().Count().From(t1).Join(t1).On(t2.C("id"), t1.C("blocked_id")) @@ -357,7 +357,7 @@ func TestBuilder(t *testing.T) { wantQuery: "SELECT SUM(`age`), MIN(`age`) FROM `users`", }, { - input: func() Node { + input: func() Querier { t1 := Table("users").As("u") return Select(As(Max(t1.C("age")), "max_age")).From(t1) }(), @@ -402,9 +402,17 @@ func TestBuilder(t *testing.T) { wantArgs: []interface{}{"foo", "bar"}, }, { - input: Nodes{With("users_view").As(Select().From(Table("users"))), Select().From(Table("users_view"))}, + input: Queries{With("users_view").As(Select().From(Table("users"))), Select().From(Table("users_view"))}, wantQuery: "WITH users_view AS (SELECT * FROM `users`) SELECT * FROM `users_view`", }, + { + input: func() Querier { + base := Select("*").From(Table("groups")) + return Queries{With("groups").As(base.Clone().Where(EQ("name", "bar"))), base.Select("age")} + }(), + wantQuery: "WITH groups AS (SELECT * FROM `groups` WHERE `name` = ?) SELECT `age` FROM `groups`", + wantArgs: []interface{}{"bar"}, + }, } for i, tt := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { diff --git a/entc/gen/bindata.go b/entc/gen/bindata.go index c139b9e28..68e67fdba 100644 --- a/entc/gen/bindata.go +++ b/entc/gen/bindata.go @@ -153,7 +153,7 @@ func templateBuilderDeleteTmpl() (*asset, error) { return a, nil } -var _templateBuilderQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5a\x6f\x6f\xdb\x38\xd2\x7f\x2d\x7f\x8a\x59\xc3\x4f\x60\x05\xae\xdc\x64\xf7\x55\x1e\xe4\x80\x6e\xd3\x16\xbe\x6b\x9b\xdd\xa6\xb8\x5b\x20\x08\x76\x15\x69\x64\xb3\xa5\x29\x47\xa4\x9c\x18\xae\xbf\xfb\x81\x43\xea\xaf\x25\x47\x76\x7d\xd7\x2b\x10\xd4\x94\x86\xc3\xe1\xcc\x8f\x3f\x8e\xc8\x59\xaf\x21\xc4\x88\x09\x84\xfe\x43\x8a\xc9\xaa\x0f\x9b\x4d\x6f\xbd\x86\xc1\xe2\xeb\x14\x2e\x2e\xe1\xde\x97\x08\x03\xef\x75\x2c\x22\x36\xf5\x7e\xf3\x83\xaf\xfe\x14\xad\x8c\xc2\xf9\x82\xfb\x0a\xa1\x3f\x43\x3f\xc4\xa4\x6f\x7a\x6d\x36\xbd\xea\x5b\x36\x5f\xc4\x89\xea\xc3\x20\x7b\x35\xb8\x4f\x19\x0f\x31\xd1\x03\x2c\x12\x26\x14\x0c\x17\xbe\x0c\x7c\x0e\x03\xef\xa3\x3f\x47\x17\xfa\xbf\x57\x8c\x49\x30\x40\xb6\x34\x1d\xf2\xdf\xb9\x16\xad\x75\x3c\x86\xb2\xe2\xcd\x06\x98\x04\x35\x43\xc8\x9e\x44\x71\x02\x34\x43\x26\xa6\x5a\xb4\x32\xa0\x96\x47\xa1\x98\x62\x28\xbd\x9e\x5a\x2d\xb0\xae\x4d\xaa\x24\x0d\x14\xac\x7b\x4e\x40\xae\xe8\x39\x9c\xcd\x99\x72\x9c\x53\x26\x54\xcf\x89\xa3\x48\x62\xd1\x4a\x42\x4c\x1c\xe7\xf6\xee\x5a\xff\xe8\x39\xa9\x60\x0f\x29\xea\x07\x52\x25\x4c\x4c\x7b\xce\x22\xc1\x90\x05\xbe\x42\x09\xce\xed\x1d\x0a\xe5\xfd\x96\x3d\xe9\x39\xe3\x31\x30\xa1\x30\x99\x63\xc8\xb4\x03\xb5\xd9\x64\x98\x23\x1f\x38\xe8\x7f\xa7\xf2\x81\x7b\x37\xc8\x31\x50\x71\xd2\x73\xa6\x09\xce\x39\x13\x70\x1a\x4a\xee\x7d\x4e\xfc\x25\x26\xd2\xe7\x3d\xe3\x96\x7f\xcd\x30\x41\xf0\xc3\x50\x82\x0f\x02\x1f\x21\x1f\x9b\x7c\x52\xf2\x91\xd7\x8b\x52\x11\xc0\xb0\xe2\xf1\xcd\x06\x4e\xab\xbe\x70\x8d\xca\xe1\x42\x82\xe7\x79\x15\xdb\xdd\xba\xac\x76\x58\x59\xdd\x66\xe3\x95\xa6\x7e\x09\xfe\x62\x81\x22\xac\x8f\x58\x92\x19\xc1\x42\x7a\x9e\xe7\xf6\x9c\x04\x55\x9a\x08\xa8\x89\xda\x49\xbe\xd7\xc1\xc8\x26\x49\x91\x01\xa9\x70\x01\x2a\xa6\x09\x52\xe0\x3b\x4f\x8f\x94\x0d\x8d\x16\x26\xd4\xb3\x93\xd2\x16\x1b\xe9\x4b\x38\xa1\x1f\xcf\x58\x7b\x4d\x68\xb1\xe6\x0a\x30\xe0\xf9\x0e\x83\x8d\xbe\xa1\xd5\xd3\xd5\x64\x2b\x7e\x09\x27\xe6\xd7\x73\x46\x6b\x2c\x17\x36\x53\xeb\x3b\x4c\xd6\xfd\x87\xb1\x46\x10\xfd\xec\x66\x31\x0d\xda\x8a\x1a\x7a\x3d\x82\xf8\x39\xbc\xac\xd7\xe3\x53\x50\x33\x26\x21\x88\x43\x84\x99\x2f\x41\xb2\x39\xe3\x7e\xc2\xd4\x0a\x1e\x99\x9a\x01\x86\xd3\x7c\xdd\x01\x13\x10\x70\xa6\x81\xae\xe6\x0b\x0e\xa7\x63\xc3\x4a\x89\x2f\xa6\x08\x83\x3f\x47\x30\x40\x4d\x4c\x03\xef\x4d\x38\x45\xa9\x07\x21\xcb\xb5\x8e\x3f\xdb\x99\x0e\xbd\xcf\xab\x05\x6e\xf3\x9d\x5e\xfe\xd4\x2a\x91\x14\xe6\x2c\x15\xcc\x7c\x26\x0c\xb3\x05\x69\x92\xa0\x50\xc6\xf1\x10\x0b\x7a\x48\x03\x17\x9c\x16\x4e\xd1\xeb\x39\x1d\x63\xd2\x3a\xea\xd0\x46\xa7\x32\x23\x13\x22\xc7\x8c\x7e\x71\x09\x27\x0d\x12\x6b\x43\x96\x17\xf5\x28\x78\xe6\xf9\xa6\xe7\x38\xf2\x91\xa9\x60\xb6\x25\x10\x26\xfa\x97\x77\xc5\x7c\x4d\x72\x43\x97\xc6\x0a\xf4\x66\x14\x9a\x47\xde\x87\xd5\xcd\xef\xef\x47\x79\xf3\xe6\xf7\xf7\x4c\xe1\x45\xcf\x71\x9c\xf5\xfa\x05\xb0\x48\xdb\xff\xe1\xfc\x03\x90\x4f\xe9\x29\x0c\x98\x36\xf4\x4c\x1b\xb6\x86\xc1\x17\xdd\x78\x49\x8d\x4c\x7e\x22\x27\x42\x93\x27\x5a\x11\x06\x99\x84\x16\xcf\xbb\xa2\x08\xe1\x85\x55\xab\xce\xb4\x1a\xcd\xc7\x9f\xfd\x7b\x8e\x43\x13\x00\x0a\x6d\xb1\x5b\x9a\x77\xae\xe9\x70\xae\x3b\xd4\xe7\x2b\x1f\x38\xb9\x7f\x98\x09\x59\x7a\x1f\xaa\x73\xef\x35\x29\x2d\xab\xa3\xf6\xe4\x4a\x6f\xcb\x52\xf9\x42\xe9\xf0\xd9\x8e\x3f\x6f\x9b\x53\xef\x89\xe6\x5d\xb9\xb3\xe9\xfb\x4b\xd6\x37\x1b\xfb\xe7\x96\xb1\xd1\xfb\xed\x1f\xa5\xee\xb7\xc6\x57\x9b\xcd\x9d\xeb\x7a\xa4\xca\x71\xde\x26\xf1\x7c\xa8\x7e\xce\xdb\x7f\x8f\x99\x18\xaa\xf3\xbc\x7d\x2d\xf6\x53\xff\x85\xd4\x8f\x60\x4f\x7f\x18\x56\xd2\xfb\x66\x65\x66\x99\x19\xc6\xca\xb3\xac\x69\x8c\xfc\x25\x6b\x6a\x1b\xcf\xec\x70\xdb\x31\x2d\x3d\xad\x0d\x3d\x02\xf5\xcb\xfe\x9e\xcb\xa0\x8b\x5c\xa2\xc6\x63\x9c\x18\x08\x5f\xc3\xd0\x17\xa1\xfe\x7d\x7d\x7e\x5d\x41\xa9\x4b\x70\x1c\x9f\x82\x16\xfa\xf6\x0d\x86\x5a\x80\xf8\x8b\x59\x18\xeb\xf5\xe8\x1a\xc6\xfa\xa1\x60\x45\xef\x75\xcc\xd3\xb9\xe8\x1c\x20\xed\x77\xea\x21\x5b\x8c\xb4\x6f\x35\xd7\xd3\xdf\x8e\x78\x9e\x1f\x21\x9e\x7b\x4f\x2c\x8f\xa4\x0d\xd1\xf5\xf9\x87\x6a\x88\x7c\x29\xe3\xe0\x7f\x26\x40\xc7\x5b\x3d\x8d\xde\xee\xe2\xb6\x7d\xd7\x36\x79\x58\x84\x86\xdf\x2b\x5b\xc3\x47\x5c\xa8\x54\x98\xcd\x20\xcb\x8d\x1b\xbc\x64\x5f\x95\x3c\x55\xec\x04\x37\xc8\xa3\x4f\x18\x65\x9b\x87\x71\x44\xa6\xeb\x12\xec\x2f\xef\xd7\x58\xcd\x5a\x27\x58\xa5\xd7\xf2\xd2\xae\x6d\x35\x3b\x87\x98\x88\x37\x3b\x01\x5b\x1e\xc7\xbb\x4e\xd5\x3f\x87\x75\xfc\xed\x54\x7f\x9d\xaa\x37\x1d\x66\xe0\x4d\x44\x59\x71\xe6\x76\xfd\x67\x13\x2d\x1a\xa0\xe7\x50\x6a\x64\xdf\x53\xde\xf8\x0e\x15\x18\x11\x9d\x9b\xd3\x48\x95\x4f\xae\x15\xdc\xaf\x80\x29\x09\x2c\xec\x9c\x3d\xbe\x43\x35\x0c\xd4\x13\x04\xb1\x50\xf8\xa4\xb4\xa5\xfa\xff\x11\xb0\x10\x32\xbc\x68\x6f\x91\xf0\xf0\xb4\x3c\xe8\x08\x30\x49\xe2\x84\x12\x8a\xe6\x14\xd1\x33\x9f\x37\x75\x9f\x4c\xae\x86\x2c\x74\x5d\xef\x5a\xf0\x95\x1e\xdc\xb5\x79\xf1\x3b\x54\x7f\xe8\x8f\x4d\xce\xbe\xa2\x6e\x8c\xe0\x3e\x55\xb0\xf0\x05\x0b\xa4\x8e\xb5\x2f\xcc\x88\x10\x07\x41\x9a\xc8\x7d\xe6\xf8\x47\xf7\x49\x56\xe6\x98\xe5\xce\xde\xa7\x62\x00\x9a\x77\xd3\x2a\xb0\xbe\xd4\x6a\xdd\x9e\xc3\x22\x92\xfb\xe9\x12\x04\xe3\x94\x74\xd1\x4c\x86\x98\x24\xae\x0e\x6e\xd9\x67\x65\xf5\xd6\x19\x6f\x59\x22\x8b\x70\xeb\x84\x34\xa2\x27\x4d\x61\x67\xa2\xf4\xdd\x00\x9f\x6c\x9f\xd3\x37\x49\xf2\x31\x56\x6f\xe3\x54\x84\xf0\x38\x43\x01\x22\xd6\xdd\x79\xfc\xa8\xbf\xf9\x73\x25\x8f\xbe\x84\x48\x0b\x75\x76\x28\xd9\xd6\xe4\xd1\x5d\x10\xd1\xe9\x30\x4f\x13\x3a\x29\xe8\xe2\x4d\xf3\xed\x78\xe6\x7a\xaf\x38\x37\x28\x69\x70\xa9\xf5\xa1\x60\x9c\xf4\x90\x5f\x59\x04\x1c\xc5\xb0\x65\x3c\x17\x2e\x75\x26\x5a\xef\x7c\x52\x72\xd6\x1a\xea\x88\x7d\xef\xdf\x23\xdf\xd4\xa2\xd6\xa4\xfd\xf6\xe5\xdd\x48\x2b\x2c\x07\xb1\xc0\x34\x35\x8f\x85\x6a\xa3\xbb\x39\x0a\x87\x63\x38\x0f\xed\x96\xbb\x4f\x4e\xe0\xa7\x89\xcc\x7c\x44\x30\x3e\x10\xd5\x93\xab\xe7\x70\xcd\xc2\x7d\x30\xcd\xc2\x43\x31\x3c\xb9\x6a\x41\xf1\x36\x31\x18\x8f\x15\x70\x5e\xfa\x09\xb0\x50\xc2\xed\x5d\x4d\x90\xfc\xc6\x42\x69\x3a\xec\xc0\xf5\xe4\x4a\x92\xa3\xff\xbf\x19\xd4\x65\x2c\xb3\x50\x96\x70\x6b\xf4\x76\x43\x6c\x59\x99\x0d\x0d\x0b\x65\x23\x4c\x27\x57\x55\xa0\x4e\xae\x8e\x0b\xd5\x36\x67\xd7\xfc\xa7\xa7\xc8\xc2\xdd\x00\x35\xaa\xbe\x13\xa2\x2c\xcc\xce\x63\x04\x5f\x55\x10\x19\xeb\x07\xcf\x11\xed\xa8\xd8\x8b\x33\xb7\xb0\x08\x44\xac\x00\x9f\xfc\x40\xf1\x15\xc4\x02\xb3\x8e\x1a\x9f\x46\x1c\xbb\x43\x34\xdb\x1f\xff\xf3\x2c\x7b\xbe\x3f\xcb\xda\xd3\x86\x9d\x4c\xbb\xee\x99\x6c\xf2\xec\xa2\x50\xf2\x1c\x71\x9a\x1e\x2f\x2f\x0e\xe2\xe7\x10\x23\x3f\xe5\xaa\xa5\xf3\x0d\x13\xd3\x94\xfb\xc9\x2e\x7e\x2f\x10\x51\xd0\xb6\x6e\x1d\x6b\x29\x90\xe6\x63\x93\x76\x91\x48\x7d\x6f\xd6\xa1\x35\xd5\xe8\x79\x7b\x31\xd4\xd8\xb9\xdb\x42\xb0\x24\x7d\xd0\x22\xf8\x71\x34\x7d\xde\x8d\xa6\x4b\x8b\x81\xa8\xba\x02\x7c\x16\xc2\xa5\x25\xdd\x32\xba\xf7\x61\xf1\x12\xae\x2b\xdd\xba\x20\x3a\xb3\xb3\x84\xec\x12\xd3\x1b\xf7\x1e\x15\xdd\xc7\xe1\xf9\x22\xee\x7b\xa0\x3a\xa7\xf4\x57\x9c\x03\x3e\x61\x90\x2a\x94\x05\x52\xc1\x17\x61\xe9\x0b\x8a\x33\xa9\x20\x8e\x2a\x94\x64\x31\xde\x79\xc6\x96\x36\x1b\xb0\x79\x7b\xd7\x4a\xd2\x7b\x9c\xd4\x76\x3b\xa8\x6d\xf9\xfc\x92\x0f\xbc\xa0\xf5\xb6\xef\xfa\x96\xbe\xf6\xab\xb6\xe8\xdf\xc2\xad\x34\x2b\xe9\x7d\xc4\xc7\x61\x7f\xbd\xce\xee\x2d\x2f\x20\x15\x32\x5d\x2c\xe2\x44\x61\x98\x8d\xda\x77\x0b\x86\x7d\xc5\x79\x41\xb0\xaf\x38\x3f\x16\x02\xb5\xde\xe6\x80\xd4\xe2\x71\xc8\x66\xb9\x6b\x8f\x6c\xa5\xd9\xa6\x11\xac\x13\x26\x57\x72\x2f\x94\x96\x29\xb8\xbb\x4b\x2c\x81\x35\x42\xb4\x89\x3d\xff\xfb\x20\xcd\x28\xf6\x50\x90\x16\xfd\x8f\x0b\xd2\xc9\x95\x2c\x40\x3a\xb9\x92\xc7\x02\xa9\xd6\xdb\x06\xd2\x46\x96\x94\xad\x90\x2c\xa6\xde\x9d\x23\xa5\x9d\xde\xeb\x38\x15\xd5\x23\x86\x80\x9e\xc4\x11\x35\xa6\x6c\x89\x62\xcf\xcb\x48\x52\xd9\xb6\x59\x0b\xf5\x83\xf0\x95\x5b\x75\x30\xc2\xca\x1a\xb6\x31\xf6\xf2\x60\x84\x91\xde\x02\x63\xd4\x3c\x16\xca\x8c\xee\xe6\x60\x30\x61\x2b\x30\x52\x1b\x94\x26\x6c\x95\x27\xdd\x15\x5d\xa4\xd1\x4e\xee\xcd\x13\x2b\x1f\x61\x25\x29\x9d\xd8\x16\x3c\x37\xf3\x25\x20\xc7\x39\x0a\x25\xb3\x8c\x72\x9a\xf8\x8b\x59\xe7\x29\xd2\x08\x2d\x70\xbb\x8f\x63\xfe\x83\xf0\x96\x9b\x75\x30\xde\xca\x1a\xb6\xf1\x16\xf9\x5c\xe2\xc1\x98\x23\xdd\x05\xe6\xa8\x79\x2c\xcc\x19\xdd\xcd\x11\xd1\x01\xd1\xde\x45\x33\x60\x0b\xe8\xca\x33\xef\x0a\x3a\xd2\xd8\xb3\x15\x51\xd3\x24\x4e\x17\xbf\x96\x8a\x05\x2a\xe5\x49\xdf\x4c\xf1\x40\x04\xfd\xff\x93\xef\x48\xd2\xd4\x0a\xd0\xf9\xb3\x69\x43\x2a\x31\x04\x15\x03\x69\x82\x25\x26\x8a\x05\x28\xe1\xde\x7c\xc8\xc4\x09\xcc\xe3\x04\x21\x62\xc8\x43\x39\x0e\xec\xed\x19\xed\x17\x4a\x7b\x35\x8e\x14\x0a\xa3\xc4\x5c\x4f\x4d\xa7\x09\x4e\xa9\x4a\x28\x15\x81\x62\xb1\x90\x23\x72\x3d\x5d\xe6\x7f\x89\x99\x80\xe1\x57\x5c\xc9\x42\xd0\x85\xfe\x08\xfa\x94\x86\xae\xd7\x2f\x8c\x16\x8e\x02\x06\xde\x5b\x1a\xd4\x14\x73\xbd\x80\x41\xa4\x27\xc8\x44\x88\x4f\xc5\xbb\x97\xfa\xed\x78\x6c\x22\xed\xcf\x17\x1c\x2f\x4c\x93\xbe\x85\x96\x40\xa5\x53\xa6\x02\x6b\x3c\xa6\xcb\xfc\xcc\x43\x51\x91\x1b\xad\x75\x2b\xdb\x82\xfe\x32\xcd\x1b\xea\xf6\xd9\xd7\x20\xfb\x8b\xfa\x9a\x0d\x44\x73\xc9\x5f\x5f\x64\x2c\x2e\xfa\x86\x4f\xe2\x39\x53\x38\x5f\xa8\x55\x9f\xc4\xac\x35\x8e\xad\xfc\x68\xa8\x18\xf3\xec\xc5\x91\x47\x5a\x6d\x18\x1a\xaf\x52\xa2\xea\x55\x0a\xc9\xbf\xca\xdc\x36\x2c\x16\x81\xe5\x2e\xd7\x8a\xdc\x04\xbe\x30\x47\xf3\x27\x4b\x57\x9b\x53\xba\x7a\xe9\x7a\x89\x60\xad\xa2\xb0\x83\xa9\x3e\x1b\x59\x10\x80\xe7\x79\xe6\x89\xfd\x8a\xaf\x60\xd0\x6c\xe2\x06\x4c\x59\x75\x47\x4d\xe0\xf9\xea\x0e\xea\xe0\xd9\xe1\xf2\xba\x9d\xac\x0c\x6e\x4d\x2f\x36\x99\x3d\xa6\x6c\xe7\xe8\x84\x67\x6c\x30\x77\x98\x0d\xac\x97\xdf\xfe\xb5\x51\x9e\xe9\x5f\x5c\x9c\x3d\x77\x8b\x58\x2c\x70\xea\xa9\x17\xb8\x5e\xe1\xa6\xac\xe8\x49\xe9\xf8\x0d\xa0\x6f\xbd\xd8\x2f\xc2\xd5\xb7\xa0\x29\xaa\x28\x9d\x4a\x15\xa5\x35\x6d\x2c\x1f\xf8\xd8\x96\x6a\x7a\xb6\x3e\x32\xbb\x6e\xeb\x32\x4c\xab\x5e\x3b\x8f\x36\xdd\x05\x4b\x7d\x6a\x2c\xc6\xac\x61\xa3\x63\x45\x26\xf5\x7a\x71\xbf\xea\x5a\x91\x59\x87\xe8\x76\x59\xa6\x05\x5b\x51\x6a\x19\x09\x09\x00\x70\x7b\x97\xaf\xb8\x2e\x15\x96\x7b\x95\x58\xe6\x9a\x4d\x79\x5c\x91\x86\x66\xdc\xc8\x62\x51\xd0\x68\x56\x30\x97\xcf\x7d\x2b\x59\xad\xba\x39\x5b\xd7\xb5\xb9\xbb\xc5\xb0\x43\x3d\x47\xcf\xf3\x5e\x15\x54\xdc\xb6\xa0\x9b\xd4\x7b\xba\x7b\xa5\xaa\xae\x49\x62\x04\x91\xd8\x2e\xc5\xac\x4b\x5a\x8f\x68\xea\xd2\x0a\x39\xb3\xdf\x88\xd5\xc9\xd2\xc7\xa2\xd4\x32\xfa\x5d\x82\x32\xe5\xc4\xc8\x71\xc9\x77\x4b\x9f\xa7\x78\x80\x57\x32\xd6\xdc\xbe\x37\x5d\x9a\xa0\x47\x7e\x80\xeb\x8d\x6b\x53\x85\x6a\x8e\xb5\x35\xf1\xa3\x24\x5a\x5b\x5a\xe5\x03\x2f\xc8\x7d\xd9\x2d\xdf\xda\x52\x62\x21\x59\x55\xb4\x9d\x76\xd5\xf3\xad\xba\x9e\x67\x33\x2f\x3d\x40\x91\x78\xe9\xd6\x1e\x79\xd7\x1e\x41\x6b\xb9\xed\xae\x45\x6d\x9d\x27\x58\x36\x0d\xdb\xf2\x4b\xd9\x21\x5b\xc7\x9f\xd5\x54\xcc\x70\x66\xa9\x90\x53\xd9\x42\xcd\x39\x53\x6c\x59\xaa\xe5\x8c\xca\x39\x99\xd2\xf9\x98\x39\x1f\xb1\xf5\x9a\x46\x64\xb3\xc9\x3f\x1b\x1a\x0e\xe9\xf4\xde\x0f\x51\x12\xcf\xf3\xb5\xe0\x65\xa9\x97\xe0\x2b\xf0\x39\x8f\x1f\xd1\x5e\x0f\xe6\x85\xea\xf9\xb2\x21\x5e\xd7\x89\x1c\xf1\x5b\xa5\xa6\xb3\xa3\x8b\x33\x1b\x77\x9e\xaa\xa8\xda\x71\x4a\xe9\x5a\xba\x81\x14\x88\x6a\x5d\xf8\x1b\x9c\x91\x6c\xa7\xc3\x8b\x06\xdb\xbc\xdc\x7d\x4c\xd2\x09\xbc\x1f\xcc\x18\x2e\xfd\x7b\x8e\xc6\x1d\x24\xaf\xdd\x41\x29\xac\x9a\xf9\x02\xce\x8c\x23\x34\x4e\xa9\x08\x25\xcb\x12\xb3\x49\x18\xd3\xbb\xc1\xe4\xa4\x01\x27\xdb\xb7\x47\xe5\x5a\x97\xa5\xbd\xf5\xd9\xf4\x2a\xe1\x2f\x56\x49\xf6\xe4\xd9\x95\x72\x78\x1c\x77\x9e\xc5\xa8\xac\x3c\x77\x39\xda\xe9\x84\x32\x28\xdc\xc2\x67\x65\x47\x94\x57\x4c\xc5\x07\xb5\x5a\x9f\x5d\xc9\x47\x3d\x39\x68\xcf\x6c\x48\x72\xbf\xcc\xa6\x9b\xf2\x2c\xbd\x69\x1f\xc0\xfe\xfc\x77\x00\x00\x00\xff\xff\x41\xd8\x55\x9d\x12\x33\x00\x00") +var _templateBuilderQueryTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5b\x6f\x6f\xdb\x38\xd2\x7f\x2d\x7f\x8a\x59\xc3\x4f\x60\x07\xae\xdc\x64\xf7\x55\x1e\xe4\x80\x6e\xd3\x16\xbe\x6b\x9b\xdd\xa6\xb8\x5b\x20\x08\x76\x15\x69\x64\xb3\xa5\x29\x87\xa4\x9c\x04\xae\xbf\xfb\x61\x48\xea\xaf\x25\x47\x4e\x7d\xd7\x5b\x20\x58\x53\x9a\x19\x0e\x67\x7e\xfc\x91\x14\xa7\xeb\x35\x44\x18\x33\x81\xd0\xbf\x4b\x51\x3e\xf6\x61\xb3\xe9\xad\xd7\x30\x58\x7e\x9d\xc1\xd9\x39\xdc\x06\x0a\x61\xe0\xbf\x4e\x44\xcc\x66\xfe\x6f\x41\xf8\x35\x98\xa1\x93\xd1\xb8\x58\xf2\x40\x23\xf4\xe7\x18\x44\x28\xfb\x56\x6b\xb3\xe9\x55\xdf\xb2\xc5\x32\x91\xba\x0f\x83\xec\xd5\xe0\x36\x65\x3c\x42\x49\x1d\x2c\x25\x13\x1a\x86\xcb\x40\x85\x01\x87\x81\xff\x31\x58\xe0\x08\xfa\xbf\x57\x9c\x91\x18\x22\x5b\x59\x85\xfc\x77\x6e\x85\xac\x4e\x26\x50\x36\xbc\xd9\x00\x53\xa0\xe7\x08\xd9\x93\x38\x91\x60\x46\xc8\xc4\x8c\x44\x2b\x1d\x92\x3c\x0a\xcd\x34\x43\xe5\xf7\xf4\xe3\x12\xeb\xd6\x94\x96\x69\xa8\x61\xdd\xf3\x42\x13\x8a\x9e\xc7\xd9\x82\x69\xcf\x3b\x66\x42\xf7\xbc\x24\x8e\x15\x16\x2d\x19\xa1\xf4\xbc\xeb\x9b\x4b\xfa\xd1\xf3\x52\xc1\xee\x52\xa4\x07\x4a\x4b\x26\x66\x3d\x6f\x29\x31\x62\x61\xa0\x51\x81\x77\x7d\x83\x42\xfb\xbf\x65\x4f\x7a\xde\x64\x02\x4c\x68\x94\x0b\x8c\x18\x05\x90\xdc\x36\x8e\x79\xea\x8e\x03\xfd\x77\xac\xee\xb8\x7f\x85\x1c\x43\x9d\xc8\x9e\x37\x93\xb8\xe0\x4c\xc0\x71\xa4\xb8\xff\x59\x06\x2b\x94\x2a\xe0\x3d\x1b\x96\x7f\xcd\x51\x22\x04\x51\xa4\x20\x00\x81\xf7\x90\xf7\x6d\x62\x52\x8a\x91\xdf\x8b\x53\x11\xc2\xb0\x12\xf1\xcd\x06\x8e\xab\xb1\x18\x59\x93\xc3\xa5\x02\xdf\xf7\x2b\xbe\x8f\xea\xb2\x14\xb0\xb2\xb9\xcd\xc6\x2f\x0d\xfd\x1c\x82\xe5\x12\x45\x54\xef\xb1\x24\x33\x86\xa5\xf2\x7d\x7f\xd4\xf3\x24\xea\x54\x0a\xa8\x89\xba\x41\xbe\xa7\x64\x64\x83\x34\x99\x01\xa5\x71\x09\x3a\x31\x03\x34\x89\xef\x3c\x3c\x63\x6c\x68\xad\x30\xa1\x9f\x1c\x14\x79\x6c\xa5\xcf\xe1\xc8\xfc\x78\xc2\xdb\x4b\x83\x16\xe7\xae\x00\x0b\x9e\xef\x70\xd8\xda\x1b\x3a\x3b\x5d\x5d\x76\xe2\xe7\x70\x64\x7f\x3d\xe5\x34\x61\xb9\xf0\xd9\xb4\xbe\xc3\x65\xd2\x1f\x26\x84\x20\xf3\xb3\x9b\xc7\xa6\xd3\x56\xd4\x98\xd7\x63\x48\x9e\xc2\xcb\x7a\x3d\x39\x06\x3d\x67\x0a\xc2\x24\x42\x98\x07\x0a\x14\x5b\x30\x1e\x48\xa6\x1f\xe1\x9e\xe9\x39\x60\x34\xcb\xe7\x1d\x30\x01\x21\x67\x04\x74\xbd\x58\x72\x38\x9e\x58\x56\x92\x81\x98\x21\x0c\xfe\x1c\xc3\x00\x89\x98\x06\xfe\x9b\x68\x86\x8a\x3a\x31\x9e\x93\x8d\x3f\xdb\x99\x0e\xfd\xcf\x8f\x4b\xdc\xe6\x3b\x9a\xfe\xa6\x55\x22\x29\xcc\x59\x2a\x9c\x07\x4c\x58\x66\x0b\x53\x29\x51\x68\x1b\x78\x48\x84\x79\x68\x3a\x2e\x38\x2d\x9a\xa1\xdf\xf3\x3a\xe6\xa4\xb5\xd7\xa1\xcb\x4e\x65\x44\x36\x45\x9e\xed\xfd\xec\x1c\x8e\x1a\x24\xd6\x96\x2c\xcf\xea\x59\xf0\xed\xf3\x4d\xcf\xf3\xd4\x3d\xd3\xe1\x7c\x4b\x20\x92\xf4\xcb\xbf\x60\x01\x91\xdc\x70\x64\xfa\x0a\x69\x31\x8a\xec\x23\xff\xc3\xe3\xd5\xef\xef\xc7\x79\xf3\xea\xf7\xf7\x4c\xe3\x59\xcf\xf3\xbc\xf5\xfa\x05\xb0\x98\xfc\xff\x70\xfa\x01\x4c\x4c\xcd\x53\x18\x30\x72\xf4\x84\x1c\x5b\xc3\xe0\x0b\x35\x5e\x9a\x46\x26\x3f\x55\x53\x41\xe4\x89\x4e\x84\x41\x26\x41\xe2\xb9\x2a\x8a\x08\x5e\x38\xb3\xfa\x84\xcc\x10\x1f\x7f\x0e\x6e\x39\x0e\x6d\x02\x4c\x6a\x8b\xd5\xd2\xbe\x1b\x59\x85\x53\x52\xa8\x8f\x57\xdd\x71\x13\xfe\x61\x26\xe4\xe8\x7d\xa8\x4f\xfd\xd7\xc6\x68\xd9\x9c\x69\x4f\x2f\x68\x59\x56\x3a\x10\x9a\xd2\xe7\x14\x7f\xde\x76\xa7\xae\x89\xf6\x5d\x59\xd9\xea\xfe\x92\xe9\x66\x7d\xff\xdc\xd2\x37\xfa\xbf\xfd\xa3\xa4\x7e\x6d\x63\xb5\xd9\xdc\x8c\x46\xbe\x31\xe5\x79\x6f\x65\xb2\x18\xea\x9f\xf3\xf6\xdf\x13\x26\x86\xfa\x34\x6f\x5f\x8a\xfd\xcc\x7f\x31\xe6\xc7\xb0\x67\x3c\x2c\x2b\xd1\xba\x59\x19\x59\xe6\x86\xf5\xf2\x24\x6b\x5a\x27\x7f\xc9\x9a\xe4\xe3\x89\xeb\x6e\x3b\xa7\xa5\xa7\xb5\xae\xc7\xa0\x7f\xd9\x3f\x72\x19\x74\x91\x2b\x24\x3c\x26\xd2\x42\xf8\x12\x86\x81\x88\xe8\xf7\xe5\xe9\x65\x05\xa5\x23\x03\xc7\xc9\x31\x90\xd0\xb7\x6f\x30\x24\x01\xc3\x5f\xcc\xc1\x98\xe6\xe3\xc8\x32\xd6\x0f\x05\x2b\xfa\xaf\x13\x9e\x2e\x44\xe7\x04\x51\xdc\x8d\x86\x6a\x71\xd2\xbd\x25\xae\x37\x7f\x3b\xf2\x79\x7a\x80\x7c\xee\x3d\xb0\x3c\x93\x2e\x45\x97\xa7\x1f\xaa\x29\x0a\x94\x4a\xc2\xff\x99\x04\x1d\x6e\xf6\x34\x46\xbb\x4b\xd8\xf6\x9d\xdb\x26\xc2\x22\xb2\xfc\x5e\x59\x1a\x3e\xe2\x52\xa7\xc2\x2e\x06\xd9\xde\xb8\x21\x4a\xee\x55\x29\x52\xc5\x4a\x70\x85\x3c\xfe\x84\x71\xb6\x78\xd8\x40\x64\xb6\xce\xc1\xfd\xf2\x7f\x4d\xf4\xbc\x75\x80\x55\x7a\x2d\x4f\xed\xda\x52\xb3\xb3\x8b\xa9\x78\xb3\x13\xb0\xe5\x7e\xfc\xcb\x54\xff\x73\x58\xc7\xdf\x4e\xf3\x97\xa9\x7e\xd3\x61\x04\xfe\x54\x94\x0d\x67\x61\xa7\x3f\xb7\xd1\x32\x1d\xf4\x3c\xb3\x35\x72\xef\xcd\xbe\xf1\x1d\x6a\xb0\x22\xb4\x37\x37\x3d\x55\x8e\x5c\x8f\x70\xfb\x08\x4c\x2b\x60\x51\xe7\xdd\xe3\x3b\xd4\xc3\x50\x3f\x40\x98\x08\x8d\x0f\x9a\x3c\xa5\xff\x8f\x81\x45\x90\xe1\x85\xa2\x65\x84\x87\xc7\xe5\x4e\xc7\x80\x52\x26\xd2\x6c\x28\x9a\xb7\x88\xbe\x3d\xde\xd4\x63\x32\xbd\x18\xb2\x68\x34\xf2\x2f\x05\x7f\xa4\xce\x47\x6e\x5f\xfc\x0e\xf5\x1f\x74\xd8\xe4\xec\x2b\x52\x63\x0c\xb7\xa9\x86\x65\x20\x58\xa8\x28\xd7\x81\xb0\x3d\x42\x12\x86\xa9\x54\xfb\x8c\xf1\x8f\xee\x83\xac\x8c\x31\xdb\x3b\xfb\x9f\x8a\x0e\xcc\xb8\x9b\x66\x81\x8b\x25\x99\x1d\xf5\x3c\x16\x1b\xb9\x9f\xce\x41\x30\x6e\x36\x5d\x66\x24\x43\x94\x72\x44\xc9\x2d\xc7\xac\x6c\xde\x05\xe3\x2d\x93\xaa\x48\x37\x6d\x48\x63\xf3\xa4\x29\xed\x4c\x94\xce\x0d\xf0\xc9\xe9\x1c\xbf\x91\xf2\x63\xa2\xdf\x26\xa9\x88\xe0\x7e\x8e\x02\x44\x42\xea\x3c\xb9\xa7\x33\x7f\x6e\xe4\x3e\x50\x10\x93\x50\xe7\x80\x1a\xdf\x9a\x22\xba\x0b\x22\xb4\x1d\xe6\xa9\x34\x5f\x0a\xba\x44\xd3\x9e\x1d\x4f\x46\xfe\x2b\xce\x2d\x4a\x1a\x42\xea\x62\x28\x18\x37\x76\x4c\x5c\x59\x0c\x1c\xc5\xb0\xa5\xbf\x11\x9c\xd3\x4e\xb4\xae\x7c\x54\x0a\xd6\x1a\xea\x88\x7d\x1f\xdc\x22\xdf\xd4\xb2\xd6\x64\xfd\xfa\xe5\xcd\x98\x0c\x96\x93\x58\x60\xda\x34\x0f\x85\x6a\x6b\xbb\x39\x0b\xcf\xc7\x70\x9e\xda\xad\x70\x1f\x1d\xc1\x4f\x53\x95\xc5\xc8\xc0\xf8\x99\xa8\x9e\x5e\x3c\x85\x6b\x16\xed\x83\x69\x16\x3d\x17\xc3\xd3\x8b\x16\x14\x6f\x13\x83\x8d\x58\x01\xe7\x55\x20\x81\x45\x0a\xae\x6f\x6a\x82\x26\x6e\x2c\x52\x56\x61\x07\xae\xa7\x17\xca\x04\xfa\xff\x9b\x41\x5d\xc6\x32\x8b\x54\x09\xb7\xd6\x6e\x37\xc4\x96\x8d\xb9\xd4\xb0\x48\x35\xc2\x74\x7a\x51\x05\xea\xf4\xe2\xb0\x50\x6d\x0b\x76\x2d\x7e\x34\x44\x16\xed\x06\xa8\x35\xf5\x9d\x10\x65\x51\xf6\x3d\x46\xf0\xc7\x0a\x22\x13\x7a\xf0\x14\xd1\x8e\x8b\xb5\x38\x0b\x0b\x8b\x41\x24\x1a\xf0\x21\x08\x35\x7f\x84\x44\x60\xa6\x48\xf8\xb4\xe2\xd8\x1d\xa2\xd9\xfa\xf8\x9f\x67\xd9\xd3\xfd\x59\xd6\x7d\x6d\xd8\xc9\xb4\xeb\x9e\xdd\x4d\x9e\x9c\x15\x46\x9e\x22\x4e\xab\xf1\xf2\xec\x59\xfc\x1c\x61\x1c\xa4\x5c\xb7\x28\x5f\x31\x31\x4b\x79\x20\x77\xf1\x7b\x81\x88\x82\xb6\xa9\x75\xa8\xa9\x60\x2c\x1f\x9a\xb4\x8b\x8d\xd4\xf7\xee\x3a\xc8\x52\x8d\x9e\xb7\x27\x43\x8d\x9d\xbb\x4d\x04\x47\xd2\xcf\x9a\x04\x3f\x8e\xa6\x4f\xbb\xd1\x74\x69\x32\x18\xaa\xae\x00\x9f\x45\x70\xee\x48\xb7\x8c\xee\x7d\x58\xbc\x84\xeb\x8a\x5a\x17\x44\x67\x7e\x96\x90\x5d\x62\x7a\x1b\xde\x83\xa2\xfb\x30\x3c\x5f\xe4\x7d\x0f\x54\xe7\x94\xfe\x8a\x73\xc0\x07\x0c\x53\x8d\xaa\x40\x2a\x04\x22\x2a\x9d\xa0\x38\x53\x1a\x92\xb8\x42\x49\x0e\xe3\x9d\x47\xec\x68\xb3\x01\x9b\xd7\x37\xad\x24\xbd\xc7\x97\xda\x6e\x1f\x6a\x5b\x8e\x5f\xea\x8e\x17\xb4\xde\x76\xae\x6f\xd1\x75\xa7\xda\x42\xbf\x85\x5b\xcd\xa8\x94\xff\x11\xef\x87\xfd\xf5\x3a\xbb\xb7\x3c\x83\x54\xa8\x74\xb9\x4c\xa4\xc6\x28\xeb\xb5\x3f\x2a\x18\xf6\x15\xe7\x05\xc1\xbe\xe2\xfc\x50\x08\x24\xbb\xcd\x09\xa9\xe5\xe3\x39\x8b\xe5\xae\x35\xb2\x95\x66\x9b\x7a\x70\x41\x98\x5e\xa8\xbd\x50\x5a\xa6\xe0\xee\x21\x71\x04\xd6\x08\xd1\x26\xf6\xfc\xef\x83\x34\xa3\xd8\xe7\x82\xb4\xd0\x3f\x2c\x48\xa7\x17\xaa\x00\xe9\xf4\x42\x1d\x0a\xa4\x64\xb7\x0d\xa4\x8d\x2c\xa9\x5a\x21\x59\x0c\xbd\x3b\x47\x2a\x37\xbc\xd7\x49\x2a\xaa\x9f\x18\x42\xf3\x24\x89\x4d\x63\xc6\x56\x28\xf6\xbc\x8c\x34\x26\xdb\x16\x6b\xa1\x7f\x10\xbe\x72\xaf\x9e\x8d\xb0\xb2\x85\x6d\x8c\xbd\x7c\x36\xc2\x8c\xdd\x02\x63\xa6\x79\x28\x94\x59\xdb\xcd\xc9\x60\xc2\x55\x60\xa4\x2e\x29\x4d\xd8\x2a\x0f\xba\x2b\xba\x8c\x45\x37\xb8\x37\x0f\xac\xfc\x09\x4b\xa6\xe6\x8b\x6d\xc1\x73\xf3\x40\x01\x72\x5c\xa0\xd0\x2a\xdb\x51\xce\x64\xb0\x9c\x77\x1e\xa2\xe9\xa1\x05\x6e\xb7\x49\xc2\x7f\x10\xde\x72\xb7\x9e\x8d\xb7\xb2\x85\x6d\xbc\xc5\x01\x57\xf8\x6c\xcc\x19\xdb\x05\xe6\x4c\xf3\x50\x98\xb3\xb6\x9b\x33\x42\x09\xa1\xe8\xa2\xed\xb0\x05\x74\xe5\x91\x77\x05\x9d\xb1\x98\xcd\x28\x4e\xa7\x8d\x62\xf9\x8c\xd2\x25\xb7\x35\x3a\x49\x19\x7b\xce\xe9\x31\x30\x11\xf2\x34\x62\x62\x06\x01\xe7\xf6\x2a\x89\x05\x14\x39\xa5\x71\xa9\x7c\x98\x6a\x08\x03\x01\xb7\x48\xc6\x53\x85\x11\xe8\x04\x96\x12\x97\x81\x24\xbe\x5c\x2c\x12\x51\x35\xa9\xcc\xfa\x9d\x2a\xa4\xde\x16\x10\xb1\x38\x46\x89\x82\xce\x41\x41\xac\xd1\xd6\x09\x85\xc6\x4b\xa6\x60\x11\x44\xd8\x7d\x46\x93\xd6\xb0\xb1\xc0\xc3\x45\xe2\xa8\xfa\xc6\x5c\xf5\xbb\xc2\x81\xad\x1a\x10\xfb\x62\xdc\xf3\x6c\x01\xd6\x19\x78\xcd\xb5\x38\x24\x61\xeb\x5a\x1a\x8c\xd8\x17\x46\x44\x46\x28\xc9\x88\xab\x29\x71\x35\x5b\xeb\xcd\x78\x2b\xc7\x46\xd4\xf7\xfd\x11\xe9\xd9\x92\xae\x33\x28\xf4\x6c\x69\x57\x93\xa2\x95\xcd\x34\x8b\xda\xa6\x33\xc8\x95\x2b\x55\x54\x4d\x36\x0a\xad\xcc\xce\x64\x92\xe5\xa3\xb9\x56\xcc\x53\x77\xbc\x29\x3a\xea\x8e\xfb\x2e\x25\x64\xc6\x4d\xdd\xb3\x7a\x99\x56\x76\x3f\x54\x88\xba\xda\x19\x18\xcc\x64\x92\x2e\x7f\x2d\x15\xb6\x54\x4a\xe9\xbe\xd9\x42\x97\x18\xfa\xff\xa7\xde\x19\x49\x5b\xd7\x62\xee\x4a\x6c\x3b\x47\xa4\xb1\x04\x2b\x94\x9a\x85\xa8\xe0\xd6\x1e\xba\x13\x09\x8b\x44\x22\xc4\x0c\x79\xa4\x26\xa1\xbb\xe9\x35\x7b\x1b\x4d\xf0\x4b\x62\x8d\xc2\x1a\xb1\x57\xa9\xb3\x99\xc4\x99\xa9\x68\x4b\x45\xa8\x59\x22\xd4\xd8\xd0\x84\x29\x3c\xf9\x92\x30\x01\xc3\xaf\xf8\xa8\x0a\xc1\x11\xf4\xc7\xd0\x37\x47\xa6\xf5\xfa\x85\xb5\xc2\x51\xc0\xc0\x7f\x6b\x3a\xb5\x85\x87\x2f\x60\x10\xd3\x00\x99\x88\xf0\xa1\x78\xf7\x92\xde\x4e\x26\x96\x95\x82\xc5\x92\xe3\x99\x6d\x9a\x73\xfb\x0a\x0c\x16\x6c\xb5\xe0\x64\x62\x12\x90\x45\x28\x2e\xf6\xf1\x6b\x6a\x65\xdb\xa5\xbf\x6c\xf3\xca\xa8\x7d\x0e\x88\x10\xff\x32\xba\x76\xb3\x43\xeb\xde\x5f\x5f\x54\x22\xce\xfa\x76\xed\x4b\x16\x4c\xe3\x62\xa9\x1f\xfb\x46\xcc\x79\xe3\xb9\x2a\xa5\x86\xea\x46\xdf\x5d\x72\xfa\xc6\xaa\x4b\x43\xe3\xb5\x5f\x5c\xbd\xf6\x33\xf2\xaf\xb2\xb0\x0d\x0b\xc2\x76\xeb\xec\xc8\x89\x5c\x85\x81\xb0\xd7\x48\x47\xab\x11\xb9\x53\xba\x26\xec\x7a\xe1\xe5\xbc\x32\x69\x07\x3b\x9d\xc6\x0e\x04\xe0\xfb\xbe\x7d\xe2\x78\xa4\x82\x41\x4b\x26\x16\x4c\x59\x25\x52\x4d\xe0\xe9\x4a\x24\xa3\xe0\xbb\xee\xce\xa1\x3e\xaf\xcd\x8b\x4d\xe6\x8f\x2d\x31\x3b\xf8\xe2\x6c\x7d\xb0\xf7\xed\x0d\xf3\x36\xbf\xa9\x6e\x5b\x9e\xad\x7e\x71\xc9\xdb\xb2\x4e\xe7\x76\x8a\xc5\xc8\x68\xd2\x04\xa7\x19\x6e\x4b\xe0\x1e\x34\xe5\x6f\x00\x7d\x17\xc5\x7e\x91\xae\xbe\x03\x4d\x51\xf1\xeb\x55\x2a\x7e\x9d\x6b\x13\x75\xc7\x27\xae\xac\xd8\x77\xb5\xbc\xd9\xd5\x70\x97\x6e\x5a\xed\xba\x71\xb4\xd9\x2e\x58\xea\x53\x63\xe1\x70\x0d\x1b\x1d\xab\x87\x8d\xd6\x8b\xdb\xc7\xae\xd5\xc3\x75\x88\x6e\x97\x10\x3b\xb0\x15\x65\xc1\xb1\x50\x00\x00\xd7\x37\xf9\x8c\xeb\x52\x0d\xbc\x57\x39\x70\x6e\xd9\x96\x72\x16\x47\xa6\x8c\x1b\x59\x22\x0a\x1a\xcd\x8a\x3b\xf3\xb1\x6f\x1d\xac\xaa\x61\xce\xe6\x75\x6d\xec\xa3\xa2\xdb\x21\x8d\xd1\xf7\xfd\x57\x05\x15\xb7\x4d\xe8\x26\xf3\x3e\xa9\x57\x2a\x40\x9b\x24\xc6\x10\x8b\xed\xb2\xe1\xba\xa4\x8b\x08\x51\x17\x19\xe4\xcc\x7d\xcf\xa8\x0e\xd6\x6c\x8c\x14\xc9\xd0\x3b\x89\x2a\xe5\x86\x91\x93\x52\xec\x56\x01\x4f\xf1\x19\x51\xc9\x58\x73\xfb\x8e\x7f\x65\x93\x1e\x07\x21\xae\x37\x23\xb7\xad\xad\x9e\x07\xb6\x06\x7e\x90\x43\xc1\x96\x55\x75\xc7\x0b\x72\x5f\x75\x3b\x1b\x6c\x19\x71\x90\xac\x1a\xda\x3e\x22\xd4\xcf\x06\x75\x3b\x4f\x9e\x12\xa8\x83\xe2\x90\x40\xad\x3d\xce\x08\x7b\x24\xad\xa5\x32\xa3\x96\xb5\x75\x7e\x18\x70\x47\x86\xad\xb8\x94\x03\xb2\xf5\xa9\xbe\x7a\x6c\xb0\x9c\x59\x2a\x3a\xd6\xae\xa8\x78\xc1\x34\x5b\x95\xea\x8e\xe3\xf2\x9e\x4c\xd3\x7e\xcc\x7e\xcb\x73\xb5\xc5\x56\x64\xb3\xc9\x4f\x1b\x0d\x1f\x94\x69\xed\x87\x58\x26\x8b\x7c\x2e\xf8\xd9\xd6\x4b\xd0\x89\x80\xf3\xe4\x1e\xdd\x55\x76\xfe\x8f\x2a\xf2\x69\x63\x78\x9d\x36\x72\x86\xdf\x2a\xf5\xc7\x1d\x43\x9c\xf9\xb8\xf3\x0b\xa0\xae\x7d\xfa\x2b\x95\x50\x34\x90\x82\xa1\xda\x11\xfc\x0d\x4e\x8c\x6c\xa7\x0f\x6d\x0d\xbe\xf9\x79\xf8\x98\x32\xb7\x45\x41\x38\x67\xb8\x0a\x6e\x39\xda\x70\x18\x79\x0a\x87\xd9\xc2\xea\x79\x20\xe0\xc4\x06\x82\x70\x6a\x0a\xa6\xb2\x5d\x62\x36\x08\xeb\x7a\x37\x98\x1c\x35\xe0\x64\xfb\xa6\xb3\x5c\x97\xb5\x72\x37\x94\x9b\x5e\x25\xfd\xc5\x2c\xc9\x9e\x3c\x39\x53\x9e\x9f\xc7\x9d\xdf\x0d\x75\x56\x4a\xbe\x1a\xef\x0c\x42\x19\x14\xa3\x22\x66\xe5\x40\x94\x67\x4c\x25\x06\xb5\xba\xb4\x5d\x9b\x8f\xfa\xe6\xa0\x7d\x67\x63\x24\xf7\xdb\xd9\x74\x33\x9e\x6d\x6f\xda\x3b\x70\x3f\xff\x1d\x00\x00\xff\xff\x85\xc3\xc2\x8d\xbe\x35\x00\x00") func templateBuilderQueryTmplBytes() ([]byte, error) { return bindataRead( @@ -168,7 +168,7 @@ func templateBuilderQueryTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "template/builder/query.tmpl", size: 13074, mode: os.FileMode(420), modTime: time.Unix(1561470397, 0)} + info := bindataFileInfo{name: "template/builder/query.tmpl", size: 13758, mode: os.FileMode(420), modTime: time.Unix(1563257934, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/entc/gen/template/builder/query.tmpl b/entc/gen/template/builder/query.tmpl index 0f384355c..d39757017 100644 --- a/entc/gen/template/builder/query.tmpl +++ b/entc/gen/template/builder/query.tmpl @@ -290,6 +290,22 @@ func ({{ $receiver }} *{{ $builder }}) ExistX(ctx context.Context) bool { 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 ({{ $receiver }} *{{ $builder }}) Clone() *{{ $builder }} { + return &{{ $builder }}{ + config: {{ $receiver }}.config, + limit: {{ $receiver }}.limit, + offset: {{ $receiver }}.offset, + order: append([]Order{}, {{ $receiver }}.order...), + unique: append([]string{}, {{ $receiver }}.unique...), + predicates: append([]ent.Predicate{}, {{ $receiver }}.predicates...), + // clone intermediate queries. + sql: {{ $receiver }}.sql.Clone(), + gremlin: {{ $receiver}}.gremlin.Clone(), + } +} + {{ $groupBuilder := pascal $.Name | printf "%sGroupBy" }} // GroupBy used to group vertices by one or more fields/columns. diff --git a/entc/integration/ent/card_query.go b/entc/integration/ent/card_query.go index 4caa0e09f..30a6e8dc7 100644 --- a/entc/integration/ent/card_query.go +++ b/entc/integration/ent/card_query.go @@ -269,6 +269,22 @@ func (cq *CardQuery) ExistX(ctx context.Context) bool { 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 (cq *CardQuery) Clone() *CardQuery { + return &CardQuery{ + config: cq.config, + limit: cq.limit, + offset: cq.offset, + order: append([]Order{}, cq.order...), + unique: append([]string{}, cq.unique...), + predicates: append([]ent.Predicate{}, cq.predicates...), + // clone intermediate queries. + sql: cq.sql.Clone(), + gremlin: cq.gremlin.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. // diff --git a/entc/integration/ent/comment_query.go b/entc/integration/ent/comment_query.go index 60b35c629..6d8a6215a 100644 --- a/entc/integration/ent/comment_query.go +++ b/entc/integration/ent/comment_query.go @@ -249,6 +249,22 @@ func (cq *CommentQuery) ExistX(ctx context.Context) bool { 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 (cq *CommentQuery) Clone() *CommentQuery { + return &CommentQuery{ + config: cq.config, + limit: cq.limit, + offset: cq.offset, + order: append([]Order{}, cq.order...), + unique: append([]string{}, cq.unique...), + predicates: append([]ent.Predicate{}, cq.predicates...), + // clone intermediate queries. + sql: cq.sql.Clone(), + gremlin: cq.gremlin.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 (cq *CommentQuery) GroupBy(field string, fields ...string) *CommentGroupBy { diff --git a/entc/integration/ent/fieldtype_query.go b/entc/integration/ent/fieldtype_query.go index 3dc5ddaa1..863d6ab18 100644 --- a/entc/integration/ent/fieldtype_query.go +++ b/entc/integration/ent/fieldtype_query.go @@ -249,6 +249,22 @@ func (ftq *FieldTypeQuery) ExistX(ctx context.Context) bool { 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 (ftq *FieldTypeQuery) Clone() *FieldTypeQuery { + return &FieldTypeQuery{ + config: ftq.config, + limit: ftq.limit, + offset: ftq.offset, + order: append([]Order{}, ftq.order...), + unique: append([]string{}, ftq.unique...), + predicates: append([]ent.Predicate{}, ftq.predicates...), + // clone intermediate queries. + sql: ftq.sql.Clone(), + gremlin: ftq.gremlin.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. // diff --git a/entc/integration/ent/file_query.go b/entc/integration/ent/file_query.go index b2a067831..f2ec4c505 100644 --- a/entc/integration/ent/file_query.go +++ b/entc/integration/ent/file_query.go @@ -249,6 +249,22 @@ func (fq *FileQuery) ExistX(ctx context.Context) bool { 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 (fq *FileQuery) Clone() *FileQuery { + return &FileQuery{ + config: fq.config, + limit: fq.limit, + offset: fq.offset, + order: append([]Order{}, fq.order...), + unique: append([]string{}, fq.unique...), + predicates: append([]ent.Predicate{}, fq.predicates...), + // clone intermediate queries. + sql: fq.sql.Clone(), + gremlin: fq.gremlin.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. // diff --git a/entc/integration/ent/group_query.go b/entc/integration/ent/group_query.go index 0b09a6c0e..1c0d70c08 100644 --- a/entc/integration/ent/group_query.go +++ b/entc/integration/ent/group_query.go @@ -333,6 +333,22 @@ func (gq *GroupQuery) ExistX(ctx context.Context) bool { 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([]ent.Predicate{}, gq.predicates...), + // clone intermediate queries. + sql: gq.sql.Clone(), + gremlin: gq.gremlin.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. // diff --git a/entc/integration/ent/groupinfo_query.go b/entc/integration/ent/groupinfo_query.go index de04461dd..13d865e31 100644 --- a/entc/integration/ent/groupinfo_query.go +++ b/entc/integration/ent/groupinfo_query.go @@ -269,6 +269,22 @@ func (giq *GroupInfoQuery) ExistX(ctx context.Context) bool { 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 (giq *GroupInfoQuery) Clone() *GroupInfoQuery { + return &GroupInfoQuery{ + config: giq.config, + limit: giq.limit, + offset: giq.offset, + order: append([]Order{}, giq.order...), + unique: append([]string{}, giq.unique...), + predicates: append([]ent.Predicate{}, giq.predicates...), + // clone intermediate queries. + sql: giq.sql.Clone(), + gremlin: giq.gremlin.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. // diff --git a/entc/integration/ent/node_query.go b/entc/integration/ent/node_query.go index 9924af317..e7294a6a4 100644 --- a/entc/integration/ent/node_query.go +++ b/entc/integration/ent/node_query.go @@ -287,6 +287,22 @@ func (nq *NodeQuery) ExistX(ctx context.Context) bool { 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 (nq *NodeQuery) Clone() *NodeQuery { + return &NodeQuery{ + config: nq.config, + limit: nq.limit, + offset: nq.offset, + order: append([]Order{}, nq.order...), + unique: append([]string{}, nq.unique...), + predicates: append([]ent.Predicate{}, nq.predicates...), + // clone intermediate queries. + sql: nq.sql.Clone(), + gremlin: nq.gremlin.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. // diff --git a/entc/integration/ent/pet_query.go b/entc/integration/ent/pet_query.go index 0f99868ad..e4834a5f5 100644 --- a/entc/integration/ent/pet_query.go +++ b/entc/integration/ent/pet_query.go @@ -288,6 +288,22 @@ func (pq *PetQuery) ExistX(ctx context.Context) bool { 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 (pq *PetQuery) Clone() *PetQuery { + return &PetQuery{ + config: pq.config, + limit: pq.limit, + offset: pq.offset, + order: append([]Order{}, pq.order...), + unique: append([]string{}, pq.unique...), + predicates: append([]ent.Predicate{}, pq.predicates...), + // clone intermediate queries. + sql: pq.sql.Clone(), + gremlin: pq.gremlin.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. // diff --git a/entc/integration/ent/user_query.go b/entc/integration/ent/user_query.go index 619125e8a..c5267f37d 100644 --- a/entc/integration/ent/user_query.go +++ b/entc/integration/ent/user_query.go @@ -482,6 +482,22 @@ func (uq *UserQuery) ExistX(ctx context.Context) bool { 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([]ent.Predicate{}, uq.predicates...), + // clone intermediate queries. + sql: uq.sql.Clone(), + gremlin: uq.gremlin.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. // diff --git a/entc/integration/integration_test.go b/entc/integration/integration_test.go index 661d6b3ca..88fc09637 100644 --- a/entc/integration/integration_test.go +++ b/entc/integration/integration_test.go @@ -15,6 +15,7 @@ import ( "fbc/ent/dialect/sql" "fbc/ent/entc/integration/ent" "fbc/ent/entc/integration/ent/card" + "fbc/ent/entc/integration/ent/file" "fbc/ent/entc/integration/ent/group" "fbc/ent/entc/integration/ent/groupinfo" "fbc/ent/entc/integration/ent/node" @@ -94,6 +95,7 @@ func TestGremlin(t *testing.T) { var tests = []func(*testing.T, *ent.Client){ Tx, Types, + Clone, Sanity, Paging, Charset, @@ -195,6 +197,15 @@ func Sanity(t *testing.T, client *ent.Client) { client.User.Delete().Where(user.IDIn(ids...)).ExecX(ctx) } +func Clone(t *testing.T, client *ent.Client) { + ctx := context.Background() + f1 := client.File.Create().SetName("foo").SetSize(10).SaveX(ctx) + f2 := client.File.Create().SetName("foo").SetSize(20).SaveX(ctx) + base := client.File.Query().Where(file.Name("foo")) + require.Equal(t, f1.Size, base.Clone().Where(file.Size(f1.Size)).OnlyX(ctx).Size) + require.Equal(t, f2.Size, base.Clone().Where(file.Size(f2.Size)).OnlyX(ctx).Size) +} + func Paging(t *testing.T, client *ent.Client) { require := require.New(t) ctx := context.Background() @@ -1747,6 +1758,7 @@ func drop(t *testing.T, client *ent.Client) { t.Log("drop data from database") ctx := context.Background() client.Pet.Delete().ExecX(ctx) + client.File.Delete().ExecX(ctx) client.Card.Delete().ExecX(ctx) client.Node.Delete().ExecX(ctx) client.User.Delete().ExecX(ctx) diff --git a/entc/integration/migrate/entv1/user_query.go b/entc/integration/migrate/entv1/user_query.go index 8d2acbef7..6197460d9 100644 --- a/entc/integration/migrate/entv1/user_query.go +++ b/entc/integration/migrate/entv1/user_query.go @@ -249,6 +249,22 @@ func (uq *UserQuery) ExistX(ctx context.Context) bool { 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([]ent.Predicate{}, uq.predicates...), + // clone intermediate queries. + sql: uq.sql.Clone(), + gremlin: uq.gremlin.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. // diff --git a/entc/integration/migrate/entv2/group_query.go b/entc/integration/migrate/entv2/group_query.go index 0e08f27fc..3009573fd 100644 --- a/entc/integration/migrate/entv2/group_query.go +++ b/entc/integration/migrate/entv2/group_query.go @@ -249,6 +249,22 @@ func (gq *GroupQuery) ExistX(ctx context.Context) bool { 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([]ent.Predicate{}, gq.predicates...), + // clone intermediate queries. + sql: gq.sql.Clone(), + gremlin: gq.gremlin.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 { diff --git a/entc/integration/migrate/entv2/pet_query.go b/entc/integration/migrate/entv2/pet_query.go index 8707c5c8b..b8e86b91e 100644 --- a/entc/integration/migrate/entv2/pet_query.go +++ b/entc/integration/migrate/entv2/pet_query.go @@ -249,6 +249,22 @@ func (pq *PetQuery) ExistX(ctx context.Context) bool { 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 (pq *PetQuery) Clone() *PetQuery { + return &PetQuery{ + config: pq.config, + limit: pq.limit, + offset: pq.offset, + order: append([]Order{}, pq.order...), + unique: append([]string{}, pq.unique...), + predicates: append([]ent.Predicate{}, pq.predicates...), + // clone intermediate queries. + sql: pq.sql.Clone(), + gremlin: pq.gremlin.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 (pq *PetQuery) GroupBy(field string, fields ...string) *PetGroupBy { diff --git a/entc/integration/migrate/entv2/user_query.go b/entc/integration/migrate/entv2/user_query.go index 8953cf8ec..e18540220 100644 --- a/entc/integration/migrate/entv2/user_query.go +++ b/entc/integration/migrate/entv2/user_query.go @@ -249,6 +249,22 @@ func (uq *UserQuery) ExistX(ctx context.Context) bool { 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([]ent.Predicate{}, uq.predicates...), + // clone intermediate queries. + sql: uq.sql.Clone(), + gremlin: uq.gremlin.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. // diff --git a/entc/integration/plugin/ent/boring_query.go b/entc/integration/plugin/ent/boring_query.go index 5634ee8c7..e5fc647fc 100644 --- a/entc/integration/plugin/ent/boring_query.go +++ b/entc/integration/plugin/ent/boring_query.go @@ -249,6 +249,22 @@ func (bq *BoringQuery) ExistX(ctx context.Context) bool { 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 (bq *BoringQuery) Clone() *BoringQuery { + return &BoringQuery{ + config: bq.config, + limit: bq.limit, + offset: bq.offset, + order: append([]Order{}, bq.order...), + unique: append([]string{}, bq.unique...), + predicates: append([]ent.Predicate{}, bq.predicates...), + // clone intermediate queries. + sql: bq.sql.Clone(), + gremlin: bq.gremlin.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 (bq *BoringQuery) GroupBy(field string, fields ...string) *BoringGroupBy {