mirror of
https://github.com/ent/ent.git
synced 2026-05-22 09:31:45 +03:00
ent/doc: add indexes doc and example
Summary: Pull Request resolved: https://github.com/facebookexternal/fbc/pull/1380 Reviewed By: alexsn Differential Revision: D17075317 fbshipit-source-id: 021cb0bde3849af5a5d842b715a7b7dbd861c54f
This commit is contained in:
committed by
Facebook Github Bot
parent
373769dfaf
commit
e00a7d96a4
10
examples/edgeindex/README.md
Normal file
10
examples/edgeindex/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# City-Street Unique Index Example
|
||||
|
||||
In this example, we have a `City` with many `Street`s, and we want to set the
|
||||
street name to be unique under each city.
|
||||
|
||||
### Generate Assets
|
||||
|
||||
```console
|
||||
go generate ./...
|
||||
```
|
||||
68
examples/edgeindex/edgeindex.go
Normal file
68
examples/edgeindex/edgeindex.go
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("sqlite3", "file:o2o2types?mode=memory&cache=shared&_fk=1")
|
||||
if err != nil {
|
||||
log.Fatalf("failed opening connection to sqlite: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
client := ent.NewClient(ent.Driver(db))
|
||||
ctx := context.Background()
|
||||
// run the auto migration tool.
|
||||
if err := client.Schema.Create(ctx); err != nil {
|
||||
log.Fatalf("failed creating schema resources: %v", err)
|
||||
}
|
||||
if err := Do(ctx, client); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Do(ctx context.Context, client *ent.Client) error {
|
||||
// Unlike `Save`, `SaveX` panics if an error occurs.
|
||||
tlv := client.City.
|
||||
Create().
|
||||
SetName("TLV").
|
||||
SaveX(ctx)
|
||||
nyc := client.City.
|
||||
Create().
|
||||
SetName("NYC").
|
||||
SaveX(ctx)
|
||||
// Add a street "ST" to "TLV".
|
||||
client.Street.
|
||||
Create().
|
||||
SetName("ST").
|
||||
SetCity(tlv).
|
||||
SaveX(ctx)
|
||||
// This operation will fail because "ST"
|
||||
// is already created under "TLV".
|
||||
_, err := client.Street.
|
||||
Create().
|
||||
SetName("ST").
|
||||
SetCity(tlv).
|
||||
Save(ctx)
|
||||
if err == nil {
|
||||
return fmt.Errorf("expecting creation to fail")
|
||||
}
|
||||
// Add a street "ST" to "NYC".
|
||||
client.Street.
|
||||
Create().
|
||||
SetName("ST").
|
||||
SetCity(nyc).
|
||||
SaveX(ctx)
|
||||
return nil
|
||||
}
|
||||
95
examples/edgeindex/ent/city.go
Normal file
95
examples/edgeindex/ent/city.go
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// City is the model entity for the City schema.
|
||||
type City struct {
|
||||
config
|
||||
// ID of the ent.
|
||||
ID int `json:"id,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into City.
|
||||
func (c *City) FromRows(rows *sql.Rows) error {
|
||||
var vc struct {
|
||||
ID int
|
||||
Name sql.NullString
|
||||
}
|
||||
// the order here should be the same as in the `city.Columns`.
|
||||
if err := rows.Scan(
|
||||
&vc.ID,
|
||||
&vc.Name,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
c.ID = vc.ID
|
||||
c.Name = vc.Name.String
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryStreets queries the streets edge of the City.
|
||||
func (c *City) QueryStreets() *StreetQuery {
|
||||
return (&CityClient{c.config}).QueryStreets(c)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this City.
|
||||
// Note that, you need to call City.Unwrap() before calling this method, if this City
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (c *City) Update() *CityUpdateOne {
|
||||
return (&CityClient{c.config}).UpdateOne(c)
|
||||
}
|
||||
|
||||
// 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 (c *City) Unwrap() *City {
|
||||
tx, ok := c.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: City is not a transactional entity")
|
||||
}
|
||||
c.config.driver = tx.drv
|
||||
return c
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (c *City) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("City(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v", c.ID))
|
||||
buf.WriteString(fmt.Sprintf(", name=%v", c.Name))
|
||||
buf.WriteString(")")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Cities is a parsable slice of City.
|
||||
type Cities []*City
|
||||
|
||||
// FromRows scans the sql response data into Cities.
|
||||
func (c *Cities) FromRows(rows *sql.Rows) error {
|
||||
for rows.Next() {
|
||||
vc := &City{}
|
||||
if err := vc.FromRows(rows); err != nil {
|
||||
return err
|
||||
}
|
||||
*c = append(*c, vc)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Cities) config(cfg config) {
|
||||
for i := range c {
|
||||
c[i].config = cfg
|
||||
}
|
||||
}
|
||||
32
examples/edgeindex/ent/city/city.go
Normal file
32
examples/edgeindex/ent/city/city.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package city
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the city type in the database.
|
||||
Label = "city"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldName holds the string denoting the name vertex property in the database.
|
||||
FieldName = "name"
|
||||
|
||||
// Table holds the table name of the city in the database.
|
||||
Table = "cities"
|
||||
// StreetsTable is the table the holds the streets relation/edge.
|
||||
StreetsTable = "streets"
|
||||
// StreetsInverseTable is the table name for the Street entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "street" package.
|
||||
StreetsInverseTable = "streets"
|
||||
// StreetsColumn is the table column denoting the streets relation/edge.
|
||||
StreetsColumn = "city_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns are city fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldName,
|
||||
}
|
||||
316
examples/edgeindex/ent/city/where.go
Normal file
316
examples/edgeindex/ent/city/where.go
Normal file
@@ -0,0 +1,316 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package city
|
||||
|
||||
import (
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their identifier.
|
||||
func ID(id int) predicate.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.City {
|
||||
return predicate.City(
|
||||
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.City {
|
||||
return predicate.City(
|
||||
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...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.City {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.City(
|
||||
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(vs) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldName), v...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.City {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.City(
|
||||
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(vs) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldName), v...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// HasStreets applies the HasEdge predicate on the "streets" edge.
|
||||
func HasStreets() predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
t1 := s.Table()
|
||||
s.Where(
|
||||
sql.In(
|
||||
t1.C(FieldID),
|
||||
sql.Select(StreetsColumn).
|
||||
From(sql.Table(StreetsTable)).
|
||||
Where(sql.NotNull(StreetsColumn)),
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// HasStreetsWith applies the HasEdge predicate on the "streets" edge with a given conditions (other predicates).
|
||||
func HasStreetsWith(preds ...predicate.Street) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
t1 := s.Table()
|
||||
t2 := sql.Select(StreetsColumn).From(sql.Table(StreetsTable))
|
||||
for _, p := range preds {
|
||||
p(t2)
|
||||
}
|
||||
s.Where(sql.In(t1.C(FieldID), t2))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// And groups list of predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.City) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
for _, p := range predicates {
|
||||
p(s)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Or groups list of predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.City) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
for i, p := range predicates {
|
||||
if i > 0 {
|
||||
s.Or()
|
||||
}
|
||||
p(s)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.City) predicate.City {
|
||||
return predicate.City(
|
||||
func(s *sql.Selector) {
|
||||
p(s.Not())
|
||||
},
|
||||
)
|
||||
}
|
||||
117
examples/edgeindex/ent/city_create.go
Normal file
117
examples/edgeindex/ent/city_create.go
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// CityCreate is the builder for creating a City entity.
|
||||
type CityCreate struct {
|
||||
config
|
||||
name *string
|
||||
streets map[int]struct{}
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (cc *CityCreate) SetName(s string) *CityCreate {
|
||||
cc.name = &s
|
||||
return cc
|
||||
}
|
||||
|
||||
// AddStreetIDs adds the streets edge to Street by ids.
|
||||
func (cc *CityCreate) AddStreetIDs(ids ...int) *CityCreate {
|
||||
if cc.streets == nil {
|
||||
cc.streets = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
cc.streets[ids[i]] = struct{}{}
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// AddStreets adds the streets edges to Street.
|
||||
func (cc *CityCreate) AddStreets(s ...*Street) *CityCreate {
|
||||
ids := make([]int, len(s))
|
||||
for i := range s {
|
||||
ids[i] = s[i].ID
|
||||
}
|
||||
return cc.AddStreetIDs(ids...)
|
||||
}
|
||||
|
||||
// Save creates the City in the database.
|
||||
func (cc *CityCreate) Save(ctx context.Context) (*City, error) {
|
||||
if cc.name == nil {
|
||||
return nil, errors.New("ent: missing required field \"name\"")
|
||||
}
|
||||
return cc.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (cc *CityCreate) SaveX(ctx context.Context) *City {
|
||||
v, err := cc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (cc *CityCreate) sqlSave(ctx context.Context) (*City, error) {
|
||||
var (
|
||||
res sql.Result
|
||||
c = &City{config: cc.config}
|
||||
)
|
||||
tx, err := cc.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := sql.Insert(city.Table).Default(cc.driver.Dialect())
|
||||
if cc.name != nil {
|
||||
builder.Set(city.FieldName, *cc.name)
|
||||
c.Name = *cc.name
|
||||
}
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
c.ID = int(id)
|
||||
if len(cc.streets) > 0 {
|
||||
p := sql.P()
|
||||
for eid := range cc.streets {
|
||||
p.Or().EQ(street.FieldID, eid)
|
||||
}
|
||||
query, args := sql.Update(city.StreetsTable).
|
||||
Set(city.StreetsColumn, id).
|
||||
Where(sql.And(p, sql.IsNull(city.StreetsColumn))).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
if int(affected) < len(cc.streets) {
|
||||
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"streets\" %v already connected to a different \"City\"", keys(cc.streets))})
|
||||
}
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
65
examples/edgeindex/ent/city_delete.go
Normal file
65
examples/edgeindex/ent/city_delete.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// CityDelete is the builder for deleting a City entity.
|
||||
type CityDelete struct {
|
||||
config
|
||||
predicates []predicate.City
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (cd *CityDelete) Where(ps ...predicate.City) *CityDelete {
|
||||
cd.predicates = append(cd.predicates, ps...)
|
||||
return cd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (cd *CityDelete) Exec(ctx context.Context) error {
|
||||
return cd.sqlExec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (cd *CityDelete) ExecX(ctx context.Context) {
|
||||
if err := cd.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cd *CityDelete) sqlExec(ctx context.Context) error {
|
||||
var res sql.Result
|
||||
selector := sql.Select().From(sql.Table(city.Table))
|
||||
for _, p := range cd.predicates {
|
||||
p(selector)
|
||||
}
|
||||
query, args := sql.Delete(city.Table).FromSelect(selector).Query()
|
||||
return cd.driver.Exec(ctx, query, args, &res)
|
||||
}
|
||||
|
||||
// CityDeleteOne is the builder for deleting a single City entity.
|
||||
type CityDeleteOne struct {
|
||||
cd *CityDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (cdo *CityDeleteOne) Exec(ctx context.Context) error {
|
||||
return cdo.cd.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (cdo *CityDeleteOne) ExecX(ctx context.Context) {
|
||||
cdo.cd.ExecX(ctx)
|
||||
}
|
||||
487
examples/edgeindex/ent/city_query.go
Normal file
487
examples/edgeindex/ent/city_query.go
Normal file
@@ -0,0 +1,487 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// CityQuery is the builder for querying City entities.
|
||||
type CityQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
order []Order
|
||||
unique []string
|
||||
predicates []predicate.City
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (cq *CityQuery) Where(ps ...predicate.City) *CityQuery {
|
||||
cq.predicates = append(cq.predicates, ps...)
|
||||
return cq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (cq *CityQuery) Limit(limit int) *CityQuery {
|
||||
cq.limit = &limit
|
||||
return cq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (cq *CityQuery) Offset(offset int) *CityQuery {
|
||||
cq.offset = &offset
|
||||
return cq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (cq *CityQuery) Order(o ...Order) *CityQuery {
|
||||
cq.order = append(cq.order, o...)
|
||||
return cq
|
||||
}
|
||||
|
||||
// QueryStreets chains the current query on the streets edge.
|
||||
func (cq *CityQuery) QueryStreets() *StreetQuery {
|
||||
query := &StreetQuery{config: cq.config}
|
||||
t1 := sql.Table(street.Table)
|
||||
t2 := cq.sqlQuery()
|
||||
t2.Select(t2.C(city.FieldID))
|
||||
query.sql = sql.Select().
|
||||
From(t1).
|
||||
Join(t2).
|
||||
On(t1.C(city.StreetsColumn), t2.C(city.FieldID))
|
||||
return query
|
||||
}
|
||||
|
||||
// Get returns a City entity by its id.
|
||||
func (cq *CityQuery) Get(ctx context.Context, id int) (*City, error) {
|
||||
return cq.Where(city.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (cq *CityQuery) GetX(ctx context.Context, id int) *City {
|
||||
c, err := cq.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// First returns the first City entity in the query. Returns *ErrNotFound when no city was found.
|
||||
func (cq *CityQuery) First(ctx context.Context) (*City, error) {
|
||||
cs, err := cq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(cs) == 0 {
|
||||
return nil, &ErrNotFound{city.Label}
|
||||
}
|
||||
return cs[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (cq *CityQuery) FirstX(ctx context.Context) *City {
|
||||
c, err := cq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// FirstID returns the first City id in the query. Returns *ErrNotFound when no id was found.
|
||||
func (cq *CityQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = cq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &ErrNotFound{city.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstXID is like FirstID, but panics if an error occurs.
|
||||
func (cq *CityQuery) FirstXID(ctx context.Context) int {
|
||||
id, err := cq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns the only City entity in the query, returns an error if not exactly one entity was returned.
|
||||
func (cq *CityQuery) Only(ctx context.Context) (*City, error) {
|
||||
cs, err := cq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(cs) {
|
||||
case 1:
|
||||
return cs[0], nil
|
||||
case 0:
|
||||
return nil, &ErrNotFound{city.Label}
|
||||
default:
|
||||
return nil, &ErrNotSingular{city.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (cq *CityQuery) OnlyX(ctx context.Context) *City {
|
||||
c, err := cq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// OnlyID returns the only City id in the query, returns an error if not exactly one id was returned.
|
||||
func (cq *CityQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = cq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &ErrNotFound{city.Label}
|
||||
default:
|
||||
err = &ErrNotSingular{city.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyXID is like OnlyID, but panics if an error occurs.
|
||||
func (cq *CityQuery) OnlyXID(ctx context.Context) int {
|
||||
id, err := cq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of Cities.
|
||||
func (cq *CityQuery) All(ctx context.Context) ([]*City, error) {
|
||||
return cq.sqlAll(ctx)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (cq *CityQuery) AllX(ctx context.Context) []*City {
|
||||
cs, err := cq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return cs
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of City ids.
|
||||
func (cq *CityQuery) IDs(ctx context.Context) ([]int, error) {
|
||||
return cq.sqlIDs(ctx)
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (cq *CityQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := cq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (cq *CityQuery) Count(ctx context.Context) (int, error) {
|
||||
return cq.sqlCount(ctx)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (cq *CityQuery) CountX(ctx context.Context) int {
|
||||
count, err := cq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (cq *CityQuery) Exist(ctx context.Context) (bool, error) {
|
||||
return cq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (cq *CityQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := cq.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 (cq *CityQuery) Clone() *CityQuery {
|
||||
return &CityQuery{
|
||||
config: cq.config,
|
||||
limit: cq.limit,
|
||||
offset: cq.offset,
|
||||
order: append([]Order{}, cq.order...),
|
||||
unique: append([]string{}, cq.unique...),
|
||||
predicates: append([]predicate.City{}, cq.predicates...),
|
||||
// clone intermediate queries.
|
||||
sql: cq.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.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Name string `json:"name,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.City.Query().
|
||||
// GroupBy(city.FieldName).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
//
|
||||
func (cq *CityQuery) GroupBy(field string, fields ...string) *CityGroupBy {
|
||||
group := &CityGroupBy{config: cq.config}
|
||||
group.fields = append([]string{field}, fields...)
|
||||
group.sql = cq.sqlQuery()
|
||||
return group
|
||||
}
|
||||
|
||||
func (cq *CityQuery) sqlAll(ctx context.Context) ([]*City, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := cq.sqlQuery()
|
||||
if unique := cq.unique; len(unique) == 0 {
|
||||
selector.Distinct()
|
||||
}
|
||||
query, args := selector.Query()
|
||||
if err := cq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var cs Cities
|
||||
if err := cs.FromRows(rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.config(cq.config)
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
func (cq *CityQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := cq.sqlQuery()
|
||||
unique := []string{city.FieldID}
|
||||
if len(cq.unique) > 0 {
|
||||
unique = cq.unique
|
||||
}
|
||||
selector.Count(sql.Distinct(selector.Columns(unique...)...))
|
||||
query, args := selector.Query()
|
||||
if err := cq.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 (cq *CityQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
n, err := cq.sqlCount(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("ent: check existence: %v", err)
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
func (cq *CityQuery) sqlIDs(ctx context.Context) ([]int, error) {
|
||||
vs, err := cq.sqlAll(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []int
|
||||
for _, v := range vs {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (cq *CityQuery) sqlQuery() *sql.Selector {
|
||||
t1 := sql.Table(city.Table)
|
||||
selector := sql.Select(t1.Columns(city.Columns...)...).From(t1)
|
||||
if cq.sql != nil {
|
||||
selector = cq.sql
|
||||
selector.Select(selector.Columns(city.Columns...)...)
|
||||
}
|
||||
for _, p := range cq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range cq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := cq.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.MaxInt64)
|
||||
}
|
||||
if limit := cq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// CityQuery is the builder for group-by City entities.
|
||||
type CityGroupBy struct {
|
||||
config
|
||||
fields []string
|
||||
fns []Aggregate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (cgb *CityGroupBy) Aggregate(fns ...Aggregate) *CityGroupBy {
|
||||
cgb.fns = append(cgb.fns, fns...)
|
||||
return cgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scan the result into the given value.
|
||||
func (cgb *CityGroupBy) Scan(ctx context.Context, v interface{}) error {
|
||||
return cgb.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
// ScanX is like Scan, but panics if an error occurs.
|
||||
func (cgb *CityGroupBy) ScanX(ctx context.Context, v interface{}) {
|
||||
if err := cgb.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 (cgb *CityGroupBy) Strings(ctx context.Context) ([]string, error) {
|
||||
if len(cgb.fields) > 1 {
|
||||
return nil, errors.New("ent: CityGroupBy.Strings is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []string
|
||||
if err := cgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// StringsX is like Strings, but panics if an error occurs.
|
||||
func (cgb *CityGroupBy) StringsX(ctx context.Context) []string {
|
||||
v, err := cgb.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 (cgb *CityGroupBy) Ints(ctx context.Context) ([]int, error) {
|
||||
if len(cgb.fields) > 1 {
|
||||
return nil, errors.New("ent: CityGroupBy.Ints is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []int
|
||||
if err := cgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IntsX is like Ints, but panics if an error occurs.
|
||||
func (cgb *CityGroupBy) IntsX(ctx context.Context) []int {
|
||||
v, err := cgb.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 (cgb *CityGroupBy) Float64s(ctx context.Context) ([]float64, error) {
|
||||
if len(cgb.fields) > 1 {
|
||||
return nil, errors.New("ent: CityGroupBy.Float64s is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []float64
|
||||
if err := cgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Float64sX is like Float64s, but panics if an error occurs.
|
||||
func (cgb *CityGroupBy) Float64sX(ctx context.Context) []float64 {
|
||||
v, err := cgb.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 (cgb *CityGroupBy) Bools(ctx context.Context) ([]bool, error) {
|
||||
if len(cgb.fields) > 1 {
|
||||
return nil, errors.New("ent: CityGroupBy.Bools is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []bool
|
||||
if err := cgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// BoolsX is like Bools, but panics if an error occurs.
|
||||
func (cgb *CityGroupBy) BoolsX(ctx context.Context) []bool {
|
||||
v, err := cgb.Bools(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (cgb *CityGroupBy) sqlScan(ctx context.Context, v interface{}) error {
|
||||
rows := &sql.Rows{}
|
||||
query, args := cgb.sqlQuery().Query()
|
||||
if err := cgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (cgb *CityGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := cgb.sql
|
||||
columns := make([]string, 0, len(cgb.fields)+len(cgb.fns))
|
||||
columns = append(columns, cgb.fields...)
|
||||
for _, fn := range cgb.fns {
|
||||
columns = append(columns, fn.SQL(selector))
|
||||
}
|
||||
return selector.Select(columns...).GroupBy(cgb.fields...)
|
||||
}
|
||||
360
examples/edgeindex/ent/city_update.go
Normal file
360
examples/edgeindex/ent/city_update.go
Normal file
@@ -0,0 +1,360 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// CityUpdate is the builder for updating City entities.
|
||||
type CityUpdate struct {
|
||||
config
|
||||
name *string
|
||||
streets map[int]struct{}
|
||||
removedStreets map[int]struct{}
|
||||
predicates []predicate.City
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (cu *CityUpdate) Where(ps ...predicate.City) *CityUpdate {
|
||||
cu.predicates = append(cu.predicates, ps...)
|
||||
return cu
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (cu *CityUpdate) SetName(s string) *CityUpdate {
|
||||
cu.name = &s
|
||||
return cu
|
||||
}
|
||||
|
||||
// AddStreetIDs adds the streets edge to Street by ids.
|
||||
func (cu *CityUpdate) AddStreetIDs(ids ...int) *CityUpdate {
|
||||
if cu.streets == nil {
|
||||
cu.streets = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
cu.streets[ids[i]] = struct{}{}
|
||||
}
|
||||
return cu
|
||||
}
|
||||
|
||||
// AddStreets adds the streets edges to Street.
|
||||
func (cu *CityUpdate) AddStreets(s ...*Street) *CityUpdate {
|
||||
ids := make([]int, len(s))
|
||||
for i := range s {
|
||||
ids[i] = s[i].ID
|
||||
}
|
||||
return cu.AddStreetIDs(ids...)
|
||||
}
|
||||
|
||||
// RemoveStreetIDs removes the streets edge to Street by ids.
|
||||
func (cu *CityUpdate) RemoveStreetIDs(ids ...int) *CityUpdate {
|
||||
if cu.removedStreets == nil {
|
||||
cu.removedStreets = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
cu.removedStreets[ids[i]] = struct{}{}
|
||||
}
|
||||
return cu
|
||||
}
|
||||
|
||||
// RemoveStreets removes streets edges to Street.
|
||||
func (cu *CityUpdate) RemoveStreets(s ...*Street) *CityUpdate {
|
||||
ids := make([]int, len(s))
|
||||
for i := range s {
|
||||
ids[i] = s[i].ID
|
||||
}
|
||||
return cu.RemoveStreetIDs(ids...)
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of rows/vertices matched by this operation.
|
||||
func (cu *CityUpdate) Save(ctx context.Context) (int, error) {
|
||||
return cu.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (cu *CityUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := cu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (cu *CityUpdate) Exec(ctx context.Context) error {
|
||||
_, err := cu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (cu *CityUpdate) ExecX(ctx context.Context) {
|
||||
if err := cu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cu *CityUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
selector := sql.Select(city.FieldID).From(sql.Table(city.Table))
|
||||
for _, p := range cu.predicates {
|
||||
p(selector)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = cu.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 := cu.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var (
|
||||
update bool
|
||||
res sql.Result
|
||||
builder = sql.Update(city.Table).Where(sql.InInts(city.FieldID, ids...))
|
||||
)
|
||||
if cu.name != nil {
|
||||
update = true
|
||||
builder.Set(city.FieldName, *cu.name)
|
||||
}
|
||||
if update {
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(cu.removedStreets) > 0 {
|
||||
eids := make([]int, len(cu.removedStreets))
|
||||
for eid := range cu.removedStreets {
|
||||
eids = append(eids, eid)
|
||||
}
|
||||
query, args := sql.Update(city.StreetsTable).
|
||||
SetNull(city.StreetsColumn).
|
||||
Where(sql.InInts(city.StreetsColumn, ids...)).
|
||||
Where(sql.InInts(street.FieldID, eids...)).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(cu.streets) > 0 {
|
||||
for _, id := range ids {
|
||||
p := sql.P()
|
||||
for eid := range cu.streets {
|
||||
p.Or().EQ(street.FieldID, eid)
|
||||
}
|
||||
query, args := sql.Update(city.StreetsTable).
|
||||
Set(city.StreetsColumn, id).
|
||||
Where(sql.And(p, sql.IsNull(city.StreetsColumn))).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
if int(affected) < len(cu.streets) {
|
||||
return 0, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"streets\" %v already connected to a different \"City\"", keys(cu.streets))})
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(ids), nil
|
||||
}
|
||||
|
||||
// CityUpdateOne is the builder for updating a single City entity.
|
||||
type CityUpdateOne struct {
|
||||
config
|
||||
id int
|
||||
name *string
|
||||
streets map[int]struct{}
|
||||
removedStreets map[int]struct{}
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (cuo *CityUpdateOne) SetName(s string) *CityUpdateOne {
|
||||
cuo.name = &s
|
||||
return cuo
|
||||
}
|
||||
|
||||
// AddStreetIDs adds the streets edge to Street by ids.
|
||||
func (cuo *CityUpdateOne) AddStreetIDs(ids ...int) *CityUpdateOne {
|
||||
if cuo.streets == nil {
|
||||
cuo.streets = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
cuo.streets[ids[i]] = struct{}{}
|
||||
}
|
||||
return cuo
|
||||
}
|
||||
|
||||
// AddStreets adds the streets edges to Street.
|
||||
func (cuo *CityUpdateOne) AddStreets(s ...*Street) *CityUpdateOne {
|
||||
ids := make([]int, len(s))
|
||||
for i := range s {
|
||||
ids[i] = s[i].ID
|
||||
}
|
||||
return cuo.AddStreetIDs(ids...)
|
||||
}
|
||||
|
||||
// RemoveStreetIDs removes the streets edge to Street by ids.
|
||||
func (cuo *CityUpdateOne) RemoveStreetIDs(ids ...int) *CityUpdateOne {
|
||||
if cuo.removedStreets == nil {
|
||||
cuo.removedStreets = make(map[int]struct{})
|
||||
}
|
||||
for i := range ids {
|
||||
cuo.removedStreets[ids[i]] = struct{}{}
|
||||
}
|
||||
return cuo
|
||||
}
|
||||
|
||||
// RemoveStreets removes streets edges to Street.
|
||||
func (cuo *CityUpdateOne) RemoveStreets(s ...*Street) *CityUpdateOne {
|
||||
ids := make([]int, len(s))
|
||||
for i := range s {
|
||||
ids[i] = s[i].ID
|
||||
}
|
||||
return cuo.RemoveStreetIDs(ids...)
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated entity.
|
||||
func (cuo *CityUpdateOne) Save(ctx context.Context) (*City, error) {
|
||||
return cuo.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (cuo *CityUpdateOne) SaveX(ctx context.Context) *City {
|
||||
c, err := cuo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (cuo *CityUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := cuo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (cuo *CityUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := cuo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (cuo *CityUpdateOne) sqlSave(ctx context.Context) (c *City, err error) {
|
||||
selector := sql.Select(city.Columns...).From(sql.Table(city.Table))
|
||||
city.ID(cuo.id)(selector)
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = cuo.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var ids []int
|
||||
for rows.Next() {
|
||||
var id int
|
||||
c = &City{config: cuo.config}
|
||||
if err := c.FromRows(rows); err != nil {
|
||||
return nil, fmt.Errorf("ent: failed scanning row into City: %v", err)
|
||||
}
|
||||
id = c.ID
|
||||
ids = append(ids, id)
|
||||
}
|
||||
switch n := len(ids); {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("ent: City not found with id: %v", cuo.id)
|
||||
case n > 1:
|
||||
return nil, fmt.Errorf("ent: more than one City with the same id: %v", cuo.id)
|
||||
}
|
||||
|
||||
tx, err := cuo.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
update bool
|
||||
res sql.Result
|
||||
builder = sql.Update(city.Table).Where(sql.InInts(city.FieldID, ids...))
|
||||
)
|
||||
if cuo.name != nil {
|
||||
update = true
|
||||
builder.Set(city.FieldName, *cuo.name)
|
||||
c.Name = *cuo.name
|
||||
}
|
||||
if update {
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(cuo.removedStreets) > 0 {
|
||||
eids := make([]int, len(cuo.removedStreets))
|
||||
for eid := range cuo.removedStreets {
|
||||
eids = append(eids, eid)
|
||||
}
|
||||
query, args := sql.Update(city.StreetsTable).
|
||||
SetNull(city.StreetsColumn).
|
||||
Where(sql.InInts(city.StreetsColumn, ids...)).
|
||||
Where(sql.InInts(street.FieldID, eids...)).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(cuo.streets) > 0 {
|
||||
for _, id := range ids {
|
||||
p := sql.P()
|
||||
for eid := range cuo.streets {
|
||||
p.Or().EQ(street.FieldID, eid)
|
||||
}
|
||||
query, args := sql.Update(city.StreetsTable).
|
||||
Set(city.StreetsColumn, id).
|
||||
Where(sql.And(p, sql.IsNull(city.StreetsColumn))).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
if int(affected) < len(cuo.streets) {
|
||||
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"streets\" %v already connected to a different \"City\"", keys(cuo.streets))})
|
||||
}
|
||||
}
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
183
examples/edgeindex/ent/client.go
Normal file
183
examples/edgeindex/ent/client.go
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/migrate"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"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
|
||||
// City is the client for interacting with the City builders.
|
||||
City *CityClient
|
||||
// Street is the client for interacting with the Street builders.
|
||||
Street *StreetClient
|
||||
}
|
||||
|
||||
// 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),
|
||||
City: NewCityClient(c),
|
||||
Street: NewStreetClient(c),
|
||||
}
|
||||
}
|
||||
|
||||
// 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, verbose: c.verbose}
|
||||
return &Tx{
|
||||
config: cfg,
|
||||
City: NewCityClient(cfg),
|
||||
Street: NewStreetClient(cfg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CityClient is a client for the City schema.
|
||||
type CityClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewCityClient returns a client for the City from the given config.
|
||||
func NewCityClient(c config) *CityClient {
|
||||
return &CityClient{config: c}
|
||||
}
|
||||
|
||||
// Create returns a create builder for City.
|
||||
func (c *CityClient) Create() *CityCreate {
|
||||
return &CityCreate{config: c.config}
|
||||
}
|
||||
|
||||
// Update returns an update builder for City.
|
||||
func (c *CityClient) Update() *CityUpdate {
|
||||
return &CityUpdate{config: c.config}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *CityClient) UpdateOne(ci *City) *CityUpdateOne {
|
||||
return c.UpdateOneID(ci.ID)
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *CityClient) UpdateOneID(id int) *CityUpdateOne {
|
||||
return &CityUpdateOne{config: c.config, id: id}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for City.
|
||||
func (c *CityClient) Delete() *CityDelete {
|
||||
return &CityDelete{config: c.config}
|
||||
}
|
||||
|
||||
// DeleteOne returns a delete builder for the given entity.
|
||||
func (c *CityClient) DeleteOne(ci *City) *CityDeleteOne {
|
||||
return c.DeleteOneID(ci.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a delete builder for the given id.
|
||||
func (c *CityClient) DeleteOneID(id int) *CityDeleteOne {
|
||||
return &CityDeleteOne{c.Delete().Where(city.ID(id))}
|
||||
}
|
||||
|
||||
// Create returns a query builder for City.
|
||||
func (c *CityClient) Query() *CityQuery {
|
||||
return &CityQuery{config: c.config}
|
||||
}
|
||||
|
||||
// QueryStreets queries the streets edge of a City.
|
||||
func (c *CityClient) QueryStreets(ci *City) *StreetQuery {
|
||||
query := &StreetQuery{config: c.config}
|
||||
id := ci.ID
|
||||
query.sql = sql.Select().From(sql.Table(street.Table)).
|
||||
Where(sql.EQ(city.StreetsColumn, id))
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
// StreetClient is a client for the Street schema.
|
||||
type StreetClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewStreetClient returns a client for the Street from the given config.
|
||||
func NewStreetClient(c config) *StreetClient {
|
||||
return &StreetClient{config: c}
|
||||
}
|
||||
|
||||
// Create returns a create builder for Street.
|
||||
func (c *StreetClient) Create() *StreetCreate {
|
||||
return &StreetCreate{config: c.config}
|
||||
}
|
||||
|
||||
// Update returns an update builder for Street.
|
||||
func (c *StreetClient) Update() *StreetUpdate {
|
||||
return &StreetUpdate{config: c.config}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *StreetClient) UpdateOne(s *Street) *StreetUpdateOne {
|
||||
return c.UpdateOneID(s.ID)
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *StreetClient) UpdateOneID(id int) *StreetUpdateOne {
|
||||
return &StreetUpdateOne{config: c.config, id: id}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for Street.
|
||||
func (c *StreetClient) Delete() *StreetDelete {
|
||||
return &StreetDelete{config: c.config}
|
||||
}
|
||||
|
||||
// DeleteOne returns a delete builder for the given entity.
|
||||
func (c *StreetClient) DeleteOne(s *Street) *StreetDeleteOne {
|
||||
return c.DeleteOneID(s.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a delete builder for the given id.
|
||||
func (c *StreetClient) DeleteOneID(id int) *StreetDeleteOne {
|
||||
return &StreetDeleteOne{c.Delete().Where(street.ID(id))}
|
||||
}
|
||||
|
||||
// Create returns a query builder for Street.
|
||||
func (c *StreetClient) Query() *StreetQuery {
|
||||
return &StreetQuery{config: c.config}
|
||||
}
|
||||
|
||||
// QueryCity queries the city edge of a Street.
|
||||
func (c *StreetClient) QueryCity(s *Street) *CityQuery {
|
||||
query := &CityQuery{config: c.config}
|
||||
id := s.ID
|
||||
t1 := sql.Table(city.Table)
|
||||
t2 := sql.Select(street.CityColumn).
|
||||
From(sql.Table(street.CityTable)).
|
||||
Where(sql.EQ(street.FieldID, id))
|
||||
query.sql = sql.Select().From(t1).Join(t2).On(t1.C(city.FieldID), t2.C(street.CityColumn))
|
||||
|
||||
return query
|
||||
}
|
||||
55
examples/edgeindex/ent/config.go
Normal file
55
examples/edgeindex/ent/config.go
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// 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 is the driver used for execute database requests.
|
||||
driver dialect.Driver
|
||||
// verbose enable a verbosity logging.
|
||||
verbose bool
|
||||
// log used for logging on verbose 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.verbose {
|
||||
c.driver = dialect.Debug(c.driver, c.log)
|
||||
}
|
||||
}
|
||||
|
||||
// Verbose sets the client logging to verbose.
|
||||
func Verbose() Option {
|
||||
return func(c *config) {
|
||||
c.verbose = true
|
||||
}
|
||||
}
|
||||
|
||||
// Log sets the client logging to verbose.
|
||||
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
|
||||
}
|
||||
}
|
||||
24
examples/edgeindex/ent/context.go
Normal file
24
examples/edgeindex/ent/context.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// 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)
|
||||
}
|
||||
196
examples/edgeindex/ent/ent.go
Normal file
196
examples/edgeindex/ent/ent.go
Normal file
@@ -0,0 +1,196 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"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) {
|
||||
// Error number 1062 is ER_DUP_ENTRY in mysql, and "UNIQUE constraint failed" is SQLite prefix.
|
||||
if msg := err.Error(); strings.HasPrefix(msg, "Error 1062") || strings.HasPrefix(msg, "UNIQUE constraint failed") {
|
||||
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
|
||||
}
|
||||
|
||||
// keys returns the keys/ids from the edge map.
|
||||
func keys(m map[int]struct{}) []int {
|
||||
s := make([]int, 0, len(m))
|
||||
for id, _ := range m {
|
||||
s = append(s, id)
|
||||
}
|
||||
return s
|
||||
}
|
||||
80
examples/edgeindex/ent/example_test.go
Normal file
80
examples/edgeindex/ent/example_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// 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 ExampleCity() {
|
||||
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 city's edges.
|
||||
s0 := client.Street.
|
||||
Create().
|
||||
SetName("string").
|
||||
SaveX(ctx)
|
||||
log.Println("street created:", s0)
|
||||
|
||||
// create city vertex with its edges.
|
||||
c := client.City.
|
||||
Create().
|
||||
SetName("string").
|
||||
AddStreets(s0).
|
||||
SaveX(ctx)
|
||||
log.Println("city created:", c)
|
||||
|
||||
// query edges.
|
||||
s0, err = c.QueryStreets().First(ctx)
|
||||
if err != nil {
|
||||
log.Fatalf("failed querying streets: %v", err)
|
||||
}
|
||||
log.Println("streets found:", s0)
|
||||
|
||||
// Output:
|
||||
}
|
||||
func ExampleStreet() {
|
||||
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 street's edges.
|
||||
|
||||
// create street vertex with its edges.
|
||||
s := client.Street.
|
||||
Create().
|
||||
SetName("string").
|
||||
SaveX(ctx)
|
||||
log.Println("street created:", s)
|
||||
|
||||
// query edges.
|
||||
|
||||
// Output:
|
||||
}
|
||||
7
examples/edgeindex/ent/generate.go
Normal file
7
examples/edgeindex/ent/generate.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
package ent
|
||||
|
||||
//go:generate go run ../../../entc/cmd/entc/entc.go generate --header "Code generated (@generated) by entc, DO NOT EDIT." ./schema
|
||||
52
examples/edgeindex/ent/migrate/migrate.go
Normal file
52
examples/edgeindex/ent/migrate/migrate.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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...)
|
||||
}
|
||||
64
examples/edgeindex/ent/migrate/schema.go
Normal file
64
examples/edgeindex/ent/migrate/schema.go
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// 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 (
|
||||
// CitiesColumns holds the columns for the "cities" table.
|
||||
CitiesColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "name", Type: field.TypeString},
|
||||
}
|
||||
// CitiesTable holds the schema information for the "cities" table.
|
||||
CitiesTable = &schema.Table{
|
||||
Name: "cities",
|
||||
Columns: CitiesColumns,
|
||||
PrimaryKey: []*schema.Column{CitiesColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
// StreetsColumns holds the columns for the "streets" table.
|
||||
StreetsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "name", Type: field.TypeString},
|
||||
{Name: "city_id", Type: field.TypeInt, Nullable: true},
|
||||
}
|
||||
// StreetsTable holds the schema information for the "streets" table.
|
||||
StreetsTable = &schema.Table{
|
||||
Name: "streets",
|
||||
Columns: StreetsColumns,
|
||||
PrimaryKey: []*schema.Column{StreetsColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "streets_cities_streets",
|
||||
Columns: []*schema.Column{StreetsColumns[2]},
|
||||
|
||||
RefColumns: []*schema.Column{CitiesColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "name_city_id",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{StreetsColumns[1], StreetsColumns[2]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
CitiesTable,
|
||||
StreetsTable,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
StreetsTable.ForeignKeys[0].RefTable = CitiesTable
|
||||
}
|
||||
17
examples/edgeindex/ent/predicate/predicate.go
Normal file
17
examples/edgeindex/ent/predicate/predicate.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package predicate
|
||||
|
||||
import (
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// City is the predicate function for city builders.
|
||||
type City func(*sql.Selector)
|
||||
|
||||
// Street is the predicate function for street builders.
|
||||
type Street func(*sql.Selector)
|
||||
30
examples/edgeindex/ent/schema/city.go
Normal file
30
examples/edgeindex/ent/schema/city.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/facebookincubator/ent"
|
||||
"github.com/facebookincubator/ent/schema/edge"
|
||||
"github.com/facebookincubator/ent/schema/field"
|
||||
)
|
||||
|
||||
// City holds the schema definition for the City entity.
|
||||
type City struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
// Fields of the City.
|
||||
func (City) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name"),
|
||||
}
|
||||
}
|
||||
|
||||
// Edges of the City.
|
||||
func (City) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.To("streets", Street.Type),
|
||||
}
|
||||
}
|
||||
42
examples/edgeindex/ent/schema/street.go
Normal file
42
examples/edgeindex/ent/schema/street.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"github.com/facebookincubator/ent"
|
||||
"github.com/facebookincubator/ent/schema/edge"
|
||||
"github.com/facebookincubator/ent/schema/field"
|
||||
"github.com/facebookincubator/ent/schema/index"
|
||||
)
|
||||
|
||||
// Street holds the schema definition for the Street entity.
|
||||
type Street struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
// Fields of the Street.
|
||||
func (Street) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name"),
|
||||
}
|
||||
}
|
||||
|
||||
// Edges of the Street.
|
||||
func (Street) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
edge.From("city", City.Type).
|
||||
Ref("streets").
|
||||
Unique(),
|
||||
}
|
||||
}
|
||||
|
||||
// Indexes of the Street.
|
||||
func (Street) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("name").
|
||||
Edges("city").
|
||||
Unique(),
|
||||
}
|
||||
}
|
||||
95
examples/edgeindex/ent/street.go
Normal file
95
examples/edgeindex/ent/street.go
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// Street is the model entity for the Street schema.
|
||||
type Street struct {
|
||||
config
|
||||
// ID of the ent.
|
||||
ID int `json:"id,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into Street.
|
||||
func (s *Street) FromRows(rows *sql.Rows) error {
|
||||
var vs struct {
|
||||
ID int
|
||||
Name sql.NullString
|
||||
}
|
||||
// the order here should be the same as in the `street.Columns`.
|
||||
if err := rows.Scan(
|
||||
&vs.ID,
|
||||
&vs.Name,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
s.ID = vs.ID
|
||||
s.Name = vs.Name.String
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryCity queries the city edge of the Street.
|
||||
func (s *Street) QueryCity() *CityQuery {
|
||||
return (&StreetClient{s.config}).QueryCity(s)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Street.
|
||||
// Note that, you need to call Street.Unwrap() before calling this method, if this Street
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (s *Street) Update() *StreetUpdateOne {
|
||||
return (&StreetClient{s.config}).UpdateOne(s)
|
||||
}
|
||||
|
||||
// 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 (s *Street) Unwrap() *Street {
|
||||
tx, ok := s.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: Street is not a transactional entity")
|
||||
}
|
||||
s.config.driver = tx.drv
|
||||
return s
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (s *Street) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("Street(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v", s.ID))
|
||||
buf.WriteString(fmt.Sprintf(", name=%v", s.Name))
|
||||
buf.WriteString(")")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Streets is a parsable slice of Street.
|
||||
type Streets []*Street
|
||||
|
||||
// FromRows scans the sql response data into Streets.
|
||||
func (s *Streets) FromRows(rows *sql.Rows) error {
|
||||
for rows.Next() {
|
||||
vs := &Street{}
|
||||
if err := vs.FromRows(rows); err != nil {
|
||||
return err
|
||||
}
|
||||
*s = append(*s, vs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s Streets) config(cfg config) {
|
||||
for i := range s {
|
||||
s[i].config = cfg
|
||||
}
|
||||
}
|
||||
32
examples/edgeindex/ent/street/street.go
Normal file
32
examples/edgeindex/ent/street/street.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package street
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the street type in the database.
|
||||
Label = "street"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldName holds the string denoting the name vertex property in the database.
|
||||
FieldName = "name"
|
||||
|
||||
// Table holds the table name of the street in the database.
|
||||
Table = "streets"
|
||||
// CityTable is the table the holds the city relation/edge.
|
||||
CityTable = "streets"
|
||||
// CityInverseTable is the table name for the City entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "city" package.
|
||||
CityInverseTable = "cities"
|
||||
// CityColumn is the table column denoting the city relation/edge.
|
||||
CityColumn = "city_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns are street fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldName,
|
||||
}
|
||||
309
examples/edgeindex/ent/street/where.go
Normal file
309
examples/edgeindex/ent/street/where.go
Normal file
@@ -0,0 +1,309 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package street
|
||||
|
||||
import (
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their identifier.
|
||||
func ID(id int) predicate.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.Street {
|
||||
return predicate.Street(
|
||||
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.Street {
|
||||
return predicate.Street(
|
||||
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...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.Street {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Street(
|
||||
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(vs) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldName), v...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.Street {
|
||||
v := make([]interface{}, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Street(
|
||||
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(vs) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldName), v...))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldName), v))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// HasCity applies the HasEdge predicate on the "city" edge.
|
||||
func HasCity() predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
t1 := s.Table()
|
||||
s.Where(sql.NotNull(t1.C(CityColumn)))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// HasCityWith applies the HasEdge predicate on the "city" edge with a given conditions (other predicates).
|
||||
func HasCityWith(preds ...predicate.City) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
t1 := s.Table()
|
||||
t2 := sql.Select(FieldID).From(sql.Table(CityInverseTable))
|
||||
for _, p := range preds {
|
||||
p(t2)
|
||||
}
|
||||
s.Where(sql.In(t1.C(CityColumn), t2))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// And groups list of predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.Street) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
for _, p := range predicates {
|
||||
p(s)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Or groups list of predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.Street) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
for i, p := range predicates {
|
||||
if i > 0 {
|
||||
s.Or()
|
||||
}
|
||||
p(s)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.Street) predicate.Street {
|
||||
return predicate.Street(
|
||||
func(s *sql.Selector) {
|
||||
p(s.Not())
|
||||
},
|
||||
)
|
||||
}
|
||||
111
examples/edgeindex/ent/street_create.go
Normal file
111
examples/edgeindex/ent/street_create.go
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// StreetCreate is the builder for creating a Street entity.
|
||||
type StreetCreate struct {
|
||||
config
|
||||
name *string
|
||||
city map[int]struct{}
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (sc *StreetCreate) SetName(s string) *StreetCreate {
|
||||
sc.name = &s
|
||||
return sc
|
||||
}
|
||||
|
||||
// SetCityID sets the city edge to City by id.
|
||||
func (sc *StreetCreate) SetCityID(id int) *StreetCreate {
|
||||
if sc.city == nil {
|
||||
sc.city = make(map[int]struct{})
|
||||
}
|
||||
sc.city[id] = struct{}{}
|
||||
return sc
|
||||
}
|
||||
|
||||
// SetNillableCityID sets the city edge to City by id if the given value is not nil.
|
||||
func (sc *StreetCreate) SetNillableCityID(id *int) *StreetCreate {
|
||||
if id != nil {
|
||||
sc = sc.SetCityID(*id)
|
||||
}
|
||||
return sc
|
||||
}
|
||||
|
||||
// SetCity sets the city edge to City.
|
||||
func (sc *StreetCreate) SetCity(c *City) *StreetCreate {
|
||||
return sc.SetCityID(c.ID)
|
||||
}
|
||||
|
||||
// Save creates the Street in the database.
|
||||
func (sc *StreetCreate) Save(ctx context.Context) (*Street, error) {
|
||||
if sc.name == nil {
|
||||
return nil, errors.New("ent: missing required field \"name\"")
|
||||
}
|
||||
if len(sc.city) > 1 {
|
||||
return nil, errors.New("ent: multiple assignments on a unique edge \"city\"")
|
||||
}
|
||||
return sc.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (sc *StreetCreate) SaveX(ctx context.Context) *Street {
|
||||
v, err := sc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (sc *StreetCreate) sqlSave(ctx context.Context) (*Street, error) {
|
||||
var (
|
||||
res sql.Result
|
||||
s = &Street{config: sc.config}
|
||||
)
|
||||
tx, err := sc.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := sql.Insert(street.Table).Default(sc.driver.Dialect())
|
||||
if sc.name != nil {
|
||||
builder.Set(street.FieldName, *sc.name)
|
||||
s.Name = *sc.name
|
||||
}
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
s.ID = int(id)
|
||||
if len(sc.city) > 0 {
|
||||
for eid := range sc.city {
|
||||
query, args := sql.Update(street.CityTable).
|
||||
Set(street.CityColumn, eid).
|
||||
Where(sql.EQ(street.FieldID, id)).
|
||||
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 s, nil
|
||||
}
|
||||
65
examples/edgeindex/ent/street_delete.go
Normal file
65
examples/edgeindex/ent/street_delete.go
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// StreetDelete is the builder for deleting a Street entity.
|
||||
type StreetDelete struct {
|
||||
config
|
||||
predicates []predicate.Street
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (sd *StreetDelete) Where(ps ...predicate.Street) *StreetDelete {
|
||||
sd.predicates = append(sd.predicates, ps...)
|
||||
return sd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (sd *StreetDelete) Exec(ctx context.Context) error {
|
||||
return sd.sqlExec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (sd *StreetDelete) ExecX(ctx context.Context) {
|
||||
if err := sd.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (sd *StreetDelete) sqlExec(ctx context.Context) error {
|
||||
var res sql.Result
|
||||
selector := sql.Select().From(sql.Table(street.Table))
|
||||
for _, p := range sd.predicates {
|
||||
p(selector)
|
||||
}
|
||||
query, args := sql.Delete(street.Table).FromSelect(selector).Query()
|
||||
return sd.driver.Exec(ctx, query, args, &res)
|
||||
}
|
||||
|
||||
// StreetDeleteOne is the builder for deleting a single Street entity.
|
||||
type StreetDeleteOne struct {
|
||||
sd *StreetDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (sdo *StreetDeleteOne) Exec(ctx context.Context) error {
|
||||
return sdo.sd.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (sdo *StreetDeleteOne) ExecX(ctx context.Context) {
|
||||
sdo.sd.ExecX(ctx)
|
||||
}
|
||||
487
examples/edgeindex/ent/street_query.go
Normal file
487
examples/edgeindex/ent/street_query.go
Normal file
@@ -0,0 +1,487 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// StreetQuery is the builder for querying Street entities.
|
||||
type StreetQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
order []Order
|
||||
unique []string
|
||||
predicates []predicate.Street
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (sq *StreetQuery) Where(ps ...predicate.Street) *StreetQuery {
|
||||
sq.predicates = append(sq.predicates, ps...)
|
||||
return sq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (sq *StreetQuery) Limit(limit int) *StreetQuery {
|
||||
sq.limit = &limit
|
||||
return sq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (sq *StreetQuery) Offset(offset int) *StreetQuery {
|
||||
sq.offset = &offset
|
||||
return sq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (sq *StreetQuery) Order(o ...Order) *StreetQuery {
|
||||
sq.order = append(sq.order, o...)
|
||||
return sq
|
||||
}
|
||||
|
||||
// QueryCity chains the current query on the city edge.
|
||||
func (sq *StreetQuery) QueryCity() *CityQuery {
|
||||
query := &CityQuery{config: sq.config}
|
||||
t1 := sql.Table(city.Table)
|
||||
t2 := sq.sqlQuery()
|
||||
t2.Select(t2.C(street.CityColumn))
|
||||
query.sql = sql.Select(t1.Columns(city.Columns...)...).
|
||||
From(t1).
|
||||
Join(t2).
|
||||
On(t1.C(city.FieldID), t2.C(street.CityColumn))
|
||||
return query
|
||||
}
|
||||
|
||||
// Get returns a Street entity by its id.
|
||||
func (sq *StreetQuery) Get(ctx context.Context, id int) (*Street, error) {
|
||||
return sq.Where(street.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (sq *StreetQuery) GetX(ctx context.Context, id int) *Street {
|
||||
s, err := sq.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// First returns the first Street entity in the query. Returns *ErrNotFound when no street was found.
|
||||
func (sq *StreetQuery) First(ctx context.Context) (*Street, error) {
|
||||
sSlice, err := sq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(sSlice) == 0 {
|
||||
return nil, &ErrNotFound{street.Label}
|
||||
}
|
||||
return sSlice[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (sq *StreetQuery) FirstX(ctx context.Context) *Street {
|
||||
s, err := sq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// FirstID returns the first Street id in the query. Returns *ErrNotFound when no id was found.
|
||||
func (sq *StreetQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = sq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &ErrNotFound{street.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstXID is like FirstID, but panics if an error occurs.
|
||||
func (sq *StreetQuery) FirstXID(ctx context.Context) int {
|
||||
id, err := sq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns the only Street entity in the query, returns an error if not exactly one entity was returned.
|
||||
func (sq *StreetQuery) Only(ctx context.Context) (*Street, error) {
|
||||
sSlice, err := sq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(sSlice) {
|
||||
case 1:
|
||||
return sSlice[0], nil
|
||||
case 0:
|
||||
return nil, &ErrNotFound{street.Label}
|
||||
default:
|
||||
return nil, &ErrNotSingular{street.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (sq *StreetQuery) OnlyX(ctx context.Context) *Street {
|
||||
s, err := sq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// OnlyID returns the only Street id in the query, returns an error if not exactly one id was returned.
|
||||
func (sq *StreetQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = sq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &ErrNotFound{street.Label}
|
||||
default:
|
||||
err = &ErrNotSingular{street.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyXID is like OnlyID, but panics if an error occurs.
|
||||
func (sq *StreetQuery) OnlyXID(ctx context.Context) int {
|
||||
id, err := sq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of Streets.
|
||||
func (sq *StreetQuery) All(ctx context.Context) ([]*Street, error) {
|
||||
return sq.sqlAll(ctx)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (sq *StreetQuery) AllX(ctx context.Context) []*Street {
|
||||
sSlice, err := sq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sSlice
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of Street ids.
|
||||
func (sq *StreetQuery) IDs(ctx context.Context) ([]int, error) {
|
||||
return sq.sqlIDs(ctx)
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (sq *StreetQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := sq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (sq *StreetQuery) Count(ctx context.Context) (int, error) {
|
||||
return sq.sqlCount(ctx)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (sq *StreetQuery) CountX(ctx context.Context) int {
|
||||
count, err := sq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (sq *StreetQuery) Exist(ctx context.Context) (bool, error) {
|
||||
return sq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (sq *StreetQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := sq.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 (sq *StreetQuery) Clone() *StreetQuery {
|
||||
return &StreetQuery{
|
||||
config: sq.config,
|
||||
limit: sq.limit,
|
||||
offset: sq.offset,
|
||||
order: append([]Order{}, sq.order...),
|
||||
unique: append([]string{}, sq.unique...),
|
||||
predicates: append([]predicate.Street{}, sq.predicates...),
|
||||
// clone intermediate queries.
|
||||
sql: sq.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.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Name string `json:"name,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.Street.Query().
|
||||
// GroupBy(street.FieldName).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
//
|
||||
func (sq *StreetQuery) GroupBy(field string, fields ...string) *StreetGroupBy {
|
||||
group := &StreetGroupBy{config: sq.config}
|
||||
group.fields = append([]string{field}, fields...)
|
||||
group.sql = sq.sqlQuery()
|
||||
return group
|
||||
}
|
||||
|
||||
func (sq *StreetQuery) sqlAll(ctx context.Context) ([]*Street, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := sq.sqlQuery()
|
||||
if unique := sq.unique; len(unique) == 0 {
|
||||
selector.Distinct()
|
||||
}
|
||||
query, args := selector.Query()
|
||||
if err := sq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var sSlice Streets
|
||||
if err := sSlice.FromRows(rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sSlice.config(sq.config)
|
||||
return sSlice, nil
|
||||
}
|
||||
|
||||
func (sq *StreetQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := sq.sqlQuery()
|
||||
unique := []string{street.FieldID}
|
||||
if len(sq.unique) > 0 {
|
||||
unique = sq.unique
|
||||
}
|
||||
selector.Count(sql.Distinct(selector.Columns(unique...)...))
|
||||
query, args := selector.Query()
|
||||
if err := sq.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 (sq *StreetQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
n, err := sq.sqlCount(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("ent: check existence: %v", err)
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
func (sq *StreetQuery) sqlIDs(ctx context.Context) ([]int, error) {
|
||||
vs, err := sq.sqlAll(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []int
|
||||
for _, v := range vs {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (sq *StreetQuery) sqlQuery() *sql.Selector {
|
||||
t1 := sql.Table(street.Table)
|
||||
selector := sql.Select(t1.Columns(street.Columns...)...).From(t1)
|
||||
if sq.sql != nil {
|
||||
selector = sq.sql
|
||||
selector.Select(selector.Columns(street.Columns...)...)
|
||||
}
|
||||
for _, p := range sq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range sq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := sq.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.MaxInt64)
|
||||
}
|
||||
if limit := sq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// StreetQuery is the builder for group-by Street entities.
|
||||
type StreetGroupBy struct {
|
||||
config
|
||||
fields []string
|
||||
fns []Aggregate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (sgb *StreetGroupBy) Aggregate(fns ...Aggregate) *StreetGroupBy {
|
||||
sgb.fns = append(sgb.fns, fns...)
|
||||
return sgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scan the result into the given value.
|
||||
func (sgb *StreetGroupBy) Scan(ctx context.Context, v interface{}) error {
|
||||
return sgb.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
// ScanX is like Scan, but panics if an error occurs.
|
||||
func (sgb *StreetGroupBy) ScanX(ctx context.Context, v interface{}) {
|
||||
if err := sgb.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 (sgb *StreetGroupBy) Strings(ctx context.Context) ([]string, error) {
|
||||
if len(sgb.fields) > 1 {
|
||||
return nil, errors.New("ent: StreetGroupBy.Strings is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []string
|
||||
if err := sgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// StringsX is like Strings, but panics if an error occurs.
|
||||
func (sgb *StreetGroupBy) StringsX(ctx context.Context) []string {
|
||||
v, err := sgb.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 (sgb *StreetGroupBy) Ints(ctx context.Context) ([]int, error) {
|
||||
if len(sgb.fields) > 1 {
|
||||
return nil, errors.New("ent: StreetGroupBy.Ints is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []int
|
||||
if err := sgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IntsX is like Ints, but panics if an error occurs.
|
||||
func (sgb *StreetGroupBy) IntsX(ctx context.Context) []int {
|
||||
v, err := sgb.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 (sgb *StreetGroupBy) Float64s(ctx context.Context) ([]float64, error) {
|
||||
if len(sgb.fields) > 1 {
|
||||
return nil, errors.New("ent: StreetGroupBy.Float64s is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []float64
|
||||
if err := sgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Float64sX is like Float64s, but panics if an error occurs.
|
||||
func (sgb *StreetGroupBy) Float64sX(ctx context.Context) []float64 {
|
||||
v, err := sgb.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 (sgb *StreetGroupBy) Bools(ctx context.Context) ([]bool, error) {
|
||||
if len(sgb.fields) > 1 {
|
||||
return nil, errors.New("ent: StreetGroupBy.Bools is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []bool
|
||||
if err := sgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// BoolsX is like Bools, but panics if an error occurs.
|
||||
func (sgb *StreetGroupBy) BoolsX(ctx context.Context) []bool {
|
||||
v, err := sgb.Bools(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (sgb *StreetGroupBy) sqlScan(ctx context.Context, v interface{}) error {
|
||||
rows := &sql.Rows{}
|
||||
query, args := sgb.sqlQuery().Query()
|
||||
if err := sgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (sgb *StreetGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := sgb.sql
|
||||
columns := make([]string, 0, len(sgb.fields)+len(sgb.fns))
|
||||
columns = append(columns, sgb.fields...)
|
||||
for _, fn := range sgb.fns {
|
||||
columns = append(columns, fn.SQL(selector))
|
||||
}
|
||||
return selector.Select(columns...).GroupBy(sgb.fields...)
|
||||
}
|
||||
311
examples/edgeindex/ent/street_update.go
Normal file
311
examples/edgeindex/ent/street_update.go
Normal file
@@ -0,0 +1,311 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/predicate"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// StreetUpdate is the builder for updating Street entities.
|
||||
type StreetUpdate struct {
|
||||
config
|
||||
name *string
|
||||
city map[int]struct{}
|
||||
clearedCity bool
|
||||
predicates []predicate.Street
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (su *StreetUpdate) Where(ps ...predicate.Street) *StreetUpdate {
|
||||
su.predicates = append(su.predicates, ps...)
|
||||
return su
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (su *StreetUpdate) SetName(s string) *StreetUpdate {
|
||||
su.name = &s
|
||||
return su
|
||||
}
|
||||
|
||||
// SetCityID sets the city edge to City by id.
|
||||
func (su *StreetUpdate) SetCityID(id int) *StreetUpdate {
|
||||
if su.city == nil {
|
||||
su.city = make(map[int]struct{})
|
||||
}
|
||||
su.city[id] = struct{}{}
|
||||
return su
|
||||
}
|
||||
|
||||
// SetNillableCityID sets the city edge to City by id if the given value is not nil.
|
||||
func (su *StreetUpdate) SetNillableCityID(id *int) *StreetUpdate {
|
||||
if id != nil {
|
||||
su = su.SetCityID(*id)
|
||||
}
|
||||
return su
|
||||
}
|
||||
|
||||
// SetCity sets the city edge to City.
|
||||
func (su *StreetUpdate) SetCity(c *City) *StreetUpdate {
|
||||
return su.SetCityID(c.ID)
|
||||
}
|
||||
|
||||
// ClearCity clears the city edge to City.
|
||||
func (su *StreetUpdate) ClearCity() *StreetUpdate {
|
||||
su.clearedCity = true
|
||||
return su
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of rows/vertices matched by this operation.
|
||||
func (su *StreetUpdate) Save(ctx context.Context) (int, error) {
|
||||
if len(su.city) > 1 {
|
||||
return 0, errors.New("ent: multiple assignments on a unique edge \"city\"")
|
||||
}
|
||||
return su.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (su *StreetUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := su.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (su *StreetUpdate) Exec(ctx context.Context) error {
|
||||
_, err := su.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (su *StreetUpdate) ExecX(ctx context.Context) {
|
||||
if err := su.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (su *StreetUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
selector := sql.Select(street.FieldID).From(sql.Table(street.Table))
|
||||
for _, p := range su.predicates {
|
||||
p(selector)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = su.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 := su.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var (
|
||||
update bool
|
||||
res sql.Result
|
||||
builder = sql.Update(street.Table).Where(sql.InInts(street.FieldID, ids...))
|
||||
)
|
||||
if su.name != nil {
|
||||
update = true
|
||||
builder.Set(street.FieldName, *su.name)
|
||||
}
|
||||
if update {
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if su.clearedCity {
|
||||
query, args := sql.Update(street.CityTable).
|
||||
SetNull(street.CityColumn).
|
||||
Where(sql.InInts(city.FieldID, ids...)).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(su.city) > 0 {
|
||||
for eid := range su.city {
|
||||
query, args := sql.Update(street.CityTable).
|
||||
Set(street.CityColumn, eid).
|
||||
Where(sql.InInts(street.FieldID, ids...)).
|
||||
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
|
||||
}
|
||||
|
||||
// StreetUpdateOne is the builder for updating a single Street entity.
|
||||
type StreetUpdateOne struct {
|
||||
config
|
||||
id int
|
||||
name *string
|
||||
city map[int]struct{}
|
||||
clearedCity bool
|
||||
}
|
||||
|
||||
// SetName sets the name field.
|
||||
func (suo *StreetUpdateOne) SetName(s string) *StreetUpdateOne {
|
||||
suo.name = &s
|
||||
return suo
|
||||
}
|
||||
|
||||
// SetCityID sets the city edge to City by id.
|
||||
func (suo *StreetUpdateOne) SetCityID(id int) *StreetUpdateOne {
|
||||
if suo.city == nil {
|
||||
suo.city = make(map[int]struct{})
|
||||
}
|
||||
suo.city[id] = struct{}{}
|
||||
return suo
|
||||
}
|
||||
|
||||
// SetNillableCityID sets the city edge to City by id if the given value is not nil.
|
||||
func (suo *StreetUpdateOne) SetNillableCityID(id *int) *StreetUpdateOne {
|
||||
if id != nil {
|
||||
suo = suo.SetCityID(*id)
|
||||
}
|
||||
return suo
|
||||
}
|
||||
|
||||
// SetCity sets the city edge to City.
|
||||
func (suo *StreetUpdateOne) SetCity(c *City) *StreetUpdateOne {
|
||||
return suo.SetCityID(c.ID)
|
||||
}
|
||||
|
||||
// ClearCity clears the city edge to City.
|
||||
func (suo *StreetUpdateOne) ClearCity() *StreetUpdateOne {
|
||||
suo.clearedCity = true
|
||||
return suo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated entity.
|
||||
func (suo *StreetUpdateOne) Save(ctx context.Context) (*Street, error) {
|
||||
if len(suo.city) > 1 {
|
||||
return nil, errors.New("ent: multiple assignments on a unique edge \"city\"")
|
||||
}
|
||||
return suo.sqlSave(ctx)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (suo *StreetUpdateOne) SaveX(ctx context.Context) *Street {
|
||||
s, err := suo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (suo *StreetUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := suo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (suo *StreetUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := suo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (suo *StreetUpdateOne) sqlSave(ctx context.Context) (s *Street, err error) {
|
||||
selector := sql.Select(street.Columns...).From(sql.Table(street.Table))
|
||||
street.ID(suo.id)(selector)
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = suo.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var ids []int
|
||||
for rows.Next() {
|
||||
var id int
|
||||
s = &Street{config: suo.config}
|
||||
if err := s.FromRows(rows); err != nil {
|
||||
return nil, fmt.Errorf("ent: failed scanning row into Street: %v", err)
|
||||
}
|
||||
id = s.ID
|
||||
ids = append(ids, id)
|
||||
}
|
||||
switch n := len(ids); {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("ent: Street not found with id: %v", suo.id)
|
||||
case n > 1:
|
||||
return nil, fmt.Errorf("ent: more than one Street with the same id: %v", suo.id)
|
||||
}
|
||||
|
||||
tx, err := suo.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
update bool
|
||||
res sql.Result
|
||||
builder = sql.Update(street.Table).Where(sql.InInts(street.FieldID, ids...))
|
||||
)
|
||||
if suo.name != nil {
|
||||
update = true
|
||||
builder.Set(street.FieldName, *suo.name)
|
||||
s.Name = *suo.name
|
||||
}
|
||||
if update {
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if suo.clearedCity {
|
||||
query, args := sql.Update(street.CityTable).
|
||||
SetNull(street.CityColumn).
|
||||
Where(sql.InInts(city.FieldID, ids...)).
|
||||
Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
}
|
||||
if len(suo.city) > 0 {
|
||||
for eid := range suo.city {
|
||||
query, args := sql.Update(street.CityTable).
|
||||
Set(street.CityColumn, eid).
|
||||
Where(sql.InInts(street.FieldID, ids...)).
|
||||
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 s, nil
|
||||
}
|
||||
100
examples/edgeindex/ent/tx.go
Normal file
100
examples/edgeindex/ent/tx.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// Copyright 2019-present Facebook Inc. All rights reserved.
|
||||
// This source code is licensed under the Apache 2.0 license found
|
||||
// in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/facebookincubator/ent/dialect"
|
||||
"github.com/facebookincubator/ent/examples/edgeindex/ent/migrate"
|
||||
)
|
||||
|
||||
// Tx is a transactional client that is created by calling Client.Tx().
|
||||
type Tx struct {
|
||||
config
|
||||
// City is the client for interacting with the City builders.
|
||||
City *CityClient
|
||||
// Street is the client for interacting with the Street builders.
|
||||
Street *StreetClient
|
||||
}
|
||||
|
||||
// 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),
|
||||
City: NewCityClient(tx.config),
|
||||
Street: NewStreetClient(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: City.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)
|
||||
Reference in New Issue
Block a user