entc/integration: fix issue with storage-key and inverse-edges (#556)

This commit is contained in:
Ariel Mashraki
2020-06-17 18:17:09 +03:00
committed by GitHub
parent b150cde478
commit c5503d76ad
17 changed files with 488 additions and 89 deletions

View File

@@ -400,6 +400,22 @@ func (c *PetClient) GetX(ctx context.Context, id int) *Pet {
return pe
}
// QueryOwner queries the owner edge of a Pet.
func (c *PetClient) QueryOwner(pe *Pet) *UserQuery {
query := &UserQuery{config: c.config}
query.path = func(ctx context.Context) (fromV *sql.Selector, _ error) {
id := pe.ID
step := sqlgraph.NewStep(
sqlgraph.From(pet.Table, pet.FieldID, id),
sqlgraph.To(user.Table, user.FieldID),
sqlgraph.Edge(sqlgraph.O2O, true, pet.OwnerTable, pet.OwnerColumn),
)
fromV = sqlgraph.Neighbors(pe.driver.Dialect(), step)
return fromV, nil
}
return query
}
// Hooks returns the client hooks.
func (c *PetClient) Hooks() []Hook {
return c.hooks.Pet
@@ -507,7 +523,7 @@ func (c *UserClient) QueryPets(u *User) *PetQuery {
step := sqlgraph.NewStep(
sqlgraph.From(user.Table, user.FieldID, id),
sqlgraph.To(pet.Table, pet.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, user.PetsTable, user.PetsColumn),
sqlgraph.Edge(sqlgraph.O2O, false, user.PetsTable, user.PetsColumn),
)
fromV = sqlgraph.Neighbors(u.driver.Dialect(), step)
return fromV, nil

View File

@@ -46,13 +46,22 @@ var (
// PetsColumns holds the columns for the "pets" table.
PetsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "owner_id", Type: field.TypeInt, Unique: true, Nullable: true},
}
// PetsTable holds the schema information for the "pets" table.
PetsTable = &schema.Table{
Name: "pets",
Columns: PetsColumns,
PrimaryKey: []*schema.Column{PetsColumns[0]},
ForeignKeys: []*schema.ForeignKey{},
Name: "pets",
Columns: PetsColumns,
PrimaryKey: []*schema.Column{PetsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "pets_users_pets",
Columns: []*schema.Column{PetsColumns[1]},
RefColumns: []*schema.Column{UsersColumns[0]},
OnDelete: schema.SetNull,
},
},
}
// UsersColumns holds the columns for the "users" table.
UsersColumns = []*schema.Column{
@@ -66,22 +75,13 @@ var (
{Name: "renamed", Type: field.TypeString, Nullable: true},
{Name: "blob", Type: field.TypeBytes, Nullable: true, Size: 1000},
{Name: "state", Type: field.TypeEnum, Nullable: true, Enums: []string{"logged_in", "logged_out", "online"}},
{Name: "owner_id", Type: field.TypeInt, Nullable: true},
}
// UsersTable holds the schema information for the "users" table.
UsersTable = &schema.Table{
Name: "users",
Columns: UsersColumns,
PrimaryKey: []*schema.Column{UsersColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "users_pets_pets",
Columns: []*schema.Column{UsersColumns[10]},
RefColumns: []*schema.Column{PetsColumns[0]},
OnDelete: schema.SetNull,
},
},
Name: "users",
Columns: UsersColumns,
PrimaryKey: []*schema.Column{UsersColumns[0]},
ForeignKeys: []*schema.ForeignKey{},
Indexes: []*schema.Index{
{
Name: "user_phone_age",
@@ -129,7 +129,7 @@ var (
func init() {
CarsTable.ForeignKeys[0].RefTable = UsersTable
UsersTable.ForeignKeys[0].RefTable = PetsTable
PetsTable.ForeignKeys[0].RefTable = UsersTable
FriendsTable.ForeignKeys[0].RefTable = UsersTable
FriendsTable.ForeignKeys[1].RefTable = UsersTable
}

View File

@@ -12,6 +12,7 @@ import (
"sync"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/car"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
"github.com/facebookincubator/ent"
@@ -569,6 +570,8 @@ type PetMutation struct {
typ string
id *int
clearedFields map[string]struct{}
owner *int
clearedowner bool
done bool
oldValue func(context.Context) (*Pet, error)
}
@@ -652,6 +655,45 @@ func (m *PetMutation) ID() (id int, exists bool) {
return *m.id, true
}
// SetOwnerID sets the owner edge to User by id.
func (m *PetMutation) SetOwnerID(id int) {
m.owner = &id
}
// ClearOwner clears the owner edge to User.
func (m *PetMutation) ClearOwner() {
m.clearedowner = true
}
// OwnerCleared returns if the edge owner was cleared.
func (m *PetMutation) OwnerCleared() bool {
return m.clearedowner
}
// OwnerID returns the owner id in the mutation.
func (m *PetMutation) OwnerID() (id int, exists bool) {
if m.owner != nil {
return *m.owner, true
}
return
}
// OwnerIDs returns the owner ids in the mutation.
// Note that ids always returns len(ids) <= 1 for unique edges, and you should use
// OwnerID instead. It exists only for internal usage by the builders.
func (m *PetMutation) OwnerIDs() (ids []int) {
if id := m.owner; id != nil {
ids = append(ids, *id)
}
return
}
// ResetOwner reset all changes of the "owner" edge.
func (m *PetMutation) ResetOwner() {
m.owner = nil
m.clearedowner = false
}
// Op returns the operation name.
func (m *PetMutation) Op() Op {
return m.op
@@ -742,45 +784,68 @@ func (m *PetMutation) ResetField(name string) error {
// AddedEdges returns all edge names that were set/added in this
// mutation.
func (m *PetMutation) AddedEdges() []string {
edges := make([]string, 0, 0)
edges := make([]string, 0, 1)
if m.owner != nil {
edges = append(edges, pet.EdgeOwner)
}
return edges
}
// AddedIDs returns all ids (to other nodes) that were added for
// the given edge name.
func (m *PetMutation) AddedIDs(name string) []ent.Value {
switch name {
case pet.EdgeOwner:
if id := m.owner; id != nil {
return []ent.Value{*id}
}
}
return nil
}
// RemovedEdges returns all edge names that were removed in this
// mutation.
func (m *PetMutation) RemovedEdges() []string {
edges := make([]string, 0, 0)
edges := make([]string, 0, 1)
return edges
}
// RemovedIDs returns all ids (to other nodes) that were removed for
// the given edge name.
func (m *PetMutation) RemovedIDs(name string) []ent.Value {
switch name {
}
return nil
}
// ClearedEdges returns all edge names that were cleared in this
// mutation.
func (m *PetMutation) ClearedEdges() []string {
edges := make([]string, 0, 0)
edges := make([]string, 0, 1)
if m.clearedowner {
edges = append(edges, pet.EdgeOwner)
}
return edges
}
// EdgeCleared returns a boolean indicates if this edge was
// cleared in this mutation.
func (m *PetMutation) EdgeCleared(name string) bool {
switch name {
case pet.EdgeOwner:
return m.clearedowner
}
return false
}
// ClearEdge clears the value for the given name. It returns an
// error if the edge name is not defined in the schema.
func (m *PetMutation) ClearEdge(name string) error {
switch name {
case pet.EdgeOwner:
m.ClearOwner()
return nil
}
return fmt.Errorf("unknown Pet unique edge %s", name)
}
@@ -788,6 +853,11 @@ func (m *PetMutation) ClearEdge(name string) error {
// given edge name. It returns an error if the edge is not
// defined in the schema.
func (m *PetMutation) ResetEdge(name string) error {
switch name {
case pet.EdgeOwner:
m.ResetOwner()
return nil
}
return fmt.Errorf("unknown Pet edge %s", name)
}

View File

@@ -12,6 +12,7 @@ import (
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
)
// Pet is the model entity for the Pet schema.
@@ -19,6 +20,33 @@ type Pet struct {
config
// ID of the ent.
ID int `json:"id,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the PetQuery when eager-loading is set.
Edges PetEdges `json:"edges"`
owner_id *int
}
// PetEdges holds the relations/edges for other nodes in the graph.
type PetEdges struct {
// Owner holds the value of the owner edge.
Owner *User
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// OwnerOrErr returns the Owner value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e PetEdges) OwnerOrErr() (*User, error) {
if e.loadedTypes[0] {
if e.Owner == nil {
// The edge owner was loaded in eager-loading,
// but was not found.
return nil, &NotFoundError{label: user.Label}
}
return e.Owner, nil
}
return nil, &NotLoadedError{edge: "owner"}
}
// scanValues returns the types for scanning values from sql.Rows.
@@ -28,6 +56,13 @@ func (*Pet) scanValues() []interface{} {
}
}
// fkValues returns the types for scanning foreign-keys values from sql.Rows.
func (*Pet) fkValues() []interface{} {
return []interface{}{
&sql.NullInt64{}, // owner_id
}
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the Pet fields.
func (pe *Pet) assignValues(values ...interface{}) error {
@@ -40,9 +75,23 @@ func (pe *Pet) assignValues(values ...interface{}) error {
}
pe.ID = int(value.Int64)
values = values[1:]
values = values[0:]
if len(values) == len(pet.ForeignKeys) {
if value, ok := values[0].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field owner_id", value)
} else if value.Valid {
pe.owner_id = new(int)
*pe.owner_id = int(value.Int64)
}
}
return nil
}
// QueryOwner queries the owner edge of the Pet.
func (pe *Pet) QueryOwner() *UserQuery {
return (&PetClient{config: pe.config}).QueryOwner(pe)
}
// Update returns a builder for updating this Pet.
// Note that, you need to call Pet.Unwrap() before calling this method, if this Pet
// was returned from a transaction, and the transaction was committed or rolled back.

View File

@@ -12,11 +12,26 @@ const (
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// EdgeOwner holds the string denoting the owner edge name in mutations.
EdgeOwner = "owner"
// Table holds the table name of the pet in the database.
Table = "pets"
// OwnerTable is the table the holds the owner relation/edge.
OwnerTable = "pets"
// OwnerInverseTable is the table name for the User entity.
// It exists in this package in order to avoid circular dependency with the "user" package.
OwnerInverseTable = "users"
// OwnerColumn is the table column denoting the owner relation/edge.
OwnerColumn = "owner_id"
)
// Columns holds all SQL columns for pet fields.
var Columns = []string{
FieldID,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the Pet type.
var ForeignKeys = []string{
"owner_id",
}

View File

@@ -8,6 +8,7 @@ package pet
import (
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/predicate"
)
@@ -94,6 +95,34 @@ func IDLTE(id int) predicate.Pet {
})
}
// HasOwner applies the HasEdge predicate on the "owner" edge.
func HasOwner() predicate.Pet {
return predicate.Pet(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(OwnerTable, FieldID),
sqlgraph.Edge(sqlgraph.O2O, true, OwnerTable, OwnerColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates).
func HasOwnerWith(preds ...predicate.User) predicate.Pet {
return predicate.Pet(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(OwnerInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.O2O, true, OwnerTable, OwnerColumn),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups list of predicates with the AND operator between them.
func And(predicates ...predicate.Pet) predicate.Pet {
return predicate.Pet(func(s *sql.Selector) {

View File

@@ -12,6 +12,7 @@ import (
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
"github.com/facebookincubator/ent/schema/field"
)
@@ -22,6 +23,25 @@ type PetCreate struct {
hooks []Hook
}
// SetOwnerID sets the owner edge to User by id.
func (pc *PetCreate) SetOwnerID(id int) *PetCreate {
pc.mutation.SetOwnerID(id)
return pc
}
// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil.
func (pc *PetCreate) SetNillableOwnerID(id *int) *PetCreate {
if id != nil {
pc = pc.SetOwnerID(*id)
}
return pc
}
// SetOwner sets the owner edge to User.
func (pc *PetCreate) SetOwner(u *User) *PetCreate {
return pc.SetOwnerID(u.ID)
}
// Mutation returns the PetMutation object of the builder.
func (pc *PetCreate) Mutation() *PetMutation {
return pc.mutation
@@ -76,6 +96,25 @@ func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) {
},
}
)
if nodes := pc.mutation.OwnerIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: pet.OwnerTable,
Columns: []string{pet.OwnerColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges = append(_spec.Edges, edge)
}
if err := sqlgraph.CreateNode(ctx, pc.driver, _spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr

View File

@@ -16,6 +16,7 @@ import (
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/predicate"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
"github.com/facebookincubator/ent/schema/field"
)
@@ -27,6 +28,9 @@ type PetQuery struct {
order []OrderFunc
unique []string
predicates []predicate.Pet
// eager-loading edges.
withOwner *UserQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
@@ -56,6 +60,24 @@ func (pq *PetQuery) Order(o ...OrderFunc) *PetQuery {
return pq
}
// QueryOwner chains the current query on the owner edge.
func (pq *PetQuery) QueryOwner() *UserQuery {
query := &UserQuery{config: pq.config}
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := pq.prepareQuery(ctx); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(pet.Table, pet.FieldID, pq.sqlQuery()),
sqlgraph.To(user.Table, user.FieldID),
sqlgraph.Edge(sqlgraph.O2O, true, pet.OwnerTable, pet.OwnerColumn),
)
fromU = sqlgraph.SetNeighbors(pq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first Pet entity in the query. Returns *NotFoundError when no pet was found.
func (pq *PetQuery) First(ctx context.Context) (*Pet, error) {
pes, err := pq.Limit(1).All(ctx)
@@ -235,6 +257,17 @@ func (pq *PetQuery) Clone() *PetQuery {
}
}
// WithOwner tells the query-builder to eager-loads the nodes that are connected to
// the "owner" edge. The optional arguments used to configure the query builder of the edge.
func (pq *PetQuery) WithOwner(opts ...func(*UserQuery)) *PetQuery {
query := &UserQuery{config: pq.config}
for _, opt := range opts {
opt(query)
}
pq.withOwner = query
return pq
}
// GroupBy used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
func (pq *PetQuery) GroupBy(field string, fields ...string) *PetGroupBy {
@@ -275,13 +308,26 @@ func (pq *PetQuery) prepareQuery(ctx context.Context) error {
func (pq *PetQuery) sqlAll(ctx context.Context) ([]*Pet, error) {
var (
nodes = []*Pet{}
_spec = pq.querySpec()
nodes = []*Pet{}
withFKs = pq.withFKs
_spec = pq.querySpec()
loadedTypes = [1]bool{
pq.withOwner != nil,
}
)
if pq.withOwner != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, pet.ForeignKeys...)
}
_spec.ScanValues = func() []interface{} {
node := &Pet{config: pq.config}
nodes = append(nodes, node)
values := node.scanValues()
if withFKs {
values = append(values, node.fkValues()...)
}
return values
}
_spec.Assign = func(values ...interface{}) error {
@@ -289,6 +335,7 @@ func (pq *PetQuery) sqlAll(ctx context.Context) ([]*Pet, error) {
return fmt.Errorf("entv2: Assign called without calling ScanValues")
}
node := nodes[len(nodes)-1]
node.Edges.loadedTypes = loadedTypes
return node.assignValues(values...)
}
if err := sqlgraph.QueryNodes(ctx, pq.driver, _spec); err != nil {
@@ -297,6 +344,32 @@ func (pq *PetQuery) sqlAll(ctx context.Context) ([]*Pet, error) {
if len(nodes) == 0 {
return nodes, nil
}
if query := pq.withOwner; query != nil {
ids := make([]int, 0, len(nodes))
nodeids := make(map[int][]*Pet)
for i := range nodes {
if fk := nodes[i].owner_id; fk != nil {
ids = append(ids, *fk)
nodeids[*fk] = append(nodeids[*fk], nodes[i])
}
}
query.Where(user.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return nil, err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return nil, fmt.Errorf(`unexpected foreign-key "owner_id" returned %v`, n.ID)
}
for i := range nodes {
nodes[i].Edges.Owner = n
}
}
}
return nodes, nil
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/pet"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/predicate"
"github.com/facebookincubator/ent/entc/integration/migrate/entv2/user"
"github.com/facebookincubator/ent/schema/field"
)
@@ -31,13 +32,39 @@ func (pu *PetUpdate) Where(ps ...predicate.Pet) *PetUpdate {
return pu
}
// SetOwnerID sets the owner edge to User by id.
func (pu *PetUpdate) SetOwnerID(id int) *PetUpdate {
pu.mutation.SetOwnerID(id)
return pu
}
// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil.
func (pu *PetUpdate) SetNillableOwnerID(id *int) *PetUpdate {
if id != nil {
pu = pu.SetOwnerID(*id)
}
return pu
}
// SetOwner sets the owner edge to User.
func (pu *PetUpdate) SetOwner(u *User) *PetUpdate {
return pu.SetOwnerID(u.ID)
}
// Mutation returns the PetMutation object of the builder.
func (pu *PetUpdate) Mutation() *PetMutation {
return pu.mutation
}
// ClearOwner clears the owner edge to User.
func (pu *PetUpdate) ClearOwner() *PetUpdate {
pu.mutation.ClearOwner()
return pu
}
// Save executes the query and returns the number of rows/vertices matched by this operation.
func (pu *PetUpdate) Save(ctx context.Context) (int, error) {
var (
err error
affected int
@@ -105,6 +132,41 @@ func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) {
}
}
}
if pu.mutation.OwnerCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: pet.OwnerTable,
Columns: []string{pet.OwnerColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := pu.mutation.OwnerIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: pet.OwnerTable,
Columns: []string{pet.OwnerColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, pu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{pet.Label}
@@ -123,13 +185,39 @@ type PetUpdateOne struct {
mutation *PetMutation
}
// SetOwnerID sets the owner edge to User by id.
func (puo *PetUpdateOne) SetOwnerID(id int) *PetUpdateOne {
puo.mutation.SetOwnerID(id)
return puo
}
// SetNillableOwnerID sets the owner edge to User by id if the given value is not nil.
func (puo *PetUpdateOne) SetNillableOwnerID(id *int) *PetUpdateOne {
if id != nil {
puo = puo.SetOwnerID(*id)
}
return puo
}
// SetOwner sets the owner edge to User.
func (puo *PetUpdateOne) SetOwner(u *User) *PetUpdateOne {
return puo.SetOwnerID(u.ID)
}
// Mutation returns the PetMutation object of the builder.
func (puo *PetUpdateOne) Mutation() *PetMutation {
return puo.mutation
}
// ClearOwner clears the owner edge to User.
func (puo *PetUpdateOne) ClearOwner() *PetUpdateOne {
puo.mutation.ClearOwner()
return puo
}
// Save executes the query and returns the updated entity.
func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) {
var (
err error
node *Pet
@@ -195,6 +283,41 @@ func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) {
return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing Pet.ID for update")}
}
_spec.Node.ID.Value = id
if puo.mutation.OwnerCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: pet.OwnerTable,
Columns: []string{pet.OwnerColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := puo.mutation.OwnerIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: pet.OwnerTable,
Columns: []string{pet.OwnerColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
pe = &Pet{config: puo.config}
_spec.Assign = pe.assignValues
_spec.ScanValues = pe.scanValues()

View File

@@ -90,10 +90,18 @@ func (Car) Edges() []ent.Edge {
}
}
// Additional types to be added to the schema.
type (
// Pet schema.
Pet struct{ ent.Schema }
// Group schema.
Group struct{ ent.Schema }
)
// Group schema.
type Group struct{ ent.Schema }
// Pet schema.
type Pet struct {
ent.Schema
}
func (Pet) Edges() []ent.Edge {
return []ent.Edge{
edge.From("owner", User.Type).
Ref("pets").
Unique(),
}
}

View File

@@ -40,8 +40,7 @@ type User struct {
State user.State `json:"state,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the UserQuery when eager-loading is set.
Edges UserEdges `json:"edges"`
owner_id *int
Edges UserEdges `json:"edges"`
}
// UserEdges holds the relations/edges for other nodes in the graph.
@@ -105,13 +104,6 @@ func (*User) scanValues() []interface{} {
}
}
// fkValues returns the types for scanning foreign-keys values from sql.Rows.
func (*User) fkValues() []interface{} {
return []interface{}{
&sql.NullInt64{}, // owner_id
}
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the User fields.
func (u *User) assignValues(values ...interface{}) error {
@@ -169,15 +161,6 @@ func (u *User) assignValues(values ...interface{}) error {
} else if value.Valid {
u.State = user.State(value.String)
}
values = values[9:]
if len(values) == len(user.ForeignKeys) {
if value, ok := values[0].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field owner_id", value)
} else if value.Valid {
u.owner_id = new(int)
*u.owner_id = int(value.Int64)
}
}
return nil
}

View File

@@ -51,7 +51,7 @@ const (
// CarColumn is the table column denoting the car relation/edge.
CarColumn = "user_car"
// PetsTable is the table the holds the pets relation/edge.
PetsTable = "users"
PetsTable = "pets"
// PetsInverseTable is the table name for the Pet entity.
// It exists in this package in order to avoid circular dependency with the "pet" package.
PetsInverseTable = "pets"
@@ -75,11 +75,6 @@ var Columns = []string{
FieldState,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the User type.
var ForeignKeys = []string{
"owner_id",
}
var (
// FriendsPrimaryKey and FriendsColumn2 are the table columns denoting the
// primary key for the friends relation (M2M).

View File

@@ -1072,7 +1072,7 @@ func HasPets() predicate.User {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PetsTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, PetsTable, PetsColumn),
sqlgraph.Edge(sqlgraph.O2O, false, PetsTable, PetsColumn),
)
sqlgraph.HasNeighbors(s, step)
})
@@ -1084,7 +1084,7 @@ func HasPetsWith(preds ...predicate.Pet) predicate.User {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PetsInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, PetsTable, PetsColumn),
sqlgraph.Edge(sqlgraph.O2O, false, PetsTable, PetsColumn),
)
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {

View File

@@ -339,7 +339,7 @@ func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
}
if nodes := uc.mutation.PetsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},

View File

@@ -34,7 +34,6 @@ type UserQuery struct {
withCar *CarQuery
withPets *PetQuery
withFriends *UserQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
@@ -92,7 +91,7 @@ func (uq *UserQuery) QueryPets() *PetQuery {
step := sqlgraph.NewStep(
sqlgraph.From(user.Table, user.FieldID, uq.sqlQuery()),
sqlgraph.To(pet.Table, pet.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, user.PetsTable, user.PetsColumn),
sqlgraph.Edge(sqlgraph.O2O, false, user.PetsTable, user.PetsColumn),
)
fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step)
return fromU, nil
@@ -395,7 +394,6 @@ func (uq *UserQuery) prepareQuery(ctx context.Context) error {
func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) {
var (
nodes = []*User{}
withFKs = uq.withFKs
_spec = uq.querySpec()
loadedTypes = [3]bool{
uq.withCar != nil,
@@ -403,19 +401,10 @@ func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) {
uq.withFriends != nil,
}
)
if uq.withPets != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, user.ForeignKeys...)
}
_spec.ScanValues = func() []interface{} {
node := &User{config: uq.config}
nodes = append(nodes, node)
values := node.scanValues()
if withFKs {
values = append(values, node.fkValues()...)
}
return values
}
_spec.Assign = func(values ...interface{}) error {
@@ -462,27 +451,30 @@ func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) {
}
if query := uq.withPets; query != nil {
ids := make([]int, 0, len(nodes))
nodeids := make(map[int][]*User)
fks := make([]driver.Value, 0, len(nodes))
nodeids := make(map[int]*User)
for i := range nodes {
if fk := nodes[i].owner_id; fk != nil {
ids = append(ids, *fk)
nodeids[*fk] = append(nodeids[*fk], nodes[i])
}
fks = append(fks, nodes[i].ID)
nodeids[nodes[i].ID] = nodes[i]
}
query.Where(pet.IDIn(ids...))
query.withFKs = true
query.Where(predicate.Pet(func(s *sql.Selector) {
s.Where(sql.InValues(user.PetsColumn, fks...))
}))
neighbors, err := query.All(ctx)
if err != nil {
return nil, err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
fk := n.owner_id
if fk == nil {
return nil, fmt.Errorf(`foreign-key "owner_id" is nil for node %v`, n.ID)
}
node, ok := nodeids[*fk]
if !ok {
return nil, fmt.Errorf(`unexpected foreign-key "owner_id" returned %v`, n.ID)
}
for i := range nodes {
nodes[i].Edges.Pets = n
return nil, fmt.Errorf(`unexpected foreign-key "owner_id" returned %v for node %v`, *fk, n.ID)
}
node.Edges.Pets = n
}
}

View File

@@ -449,7 +449,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
}
if uu.mutation.PetsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},
@@ -465,7 +465,7 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
}
if nodes := uu.mutation.PetsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},
@@ -952,7 +952,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) {
}
if uuo.mutation.PetsCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},
@@ -968,7 +968,7 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (u *User, err error) {
}
if nodes := uuo.mutation.PetsIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},