entc/gen: move node creation to sqlgraph

This commit is contained in:
Ariel Mashraki
2019-12-16 16:55:20 +02:00
parent 5e9d13be97
commit c6800a3869
71 changed files with 2524 additions and 1838 deletions

View File

@@ -9,11 +9,11 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
"github.com/facebookincubator/ent/schema/field"
)
// CityCreate is the builder for creating a City entity.
@@ -68,47 +68,51 @@ func (cc *CityCreate) SaveX(ctx context.Context) *City {
func (cc *CityCreate) sqlSave(ctx context.Context) (*City, error) {
var (
res sql.Result
builder = sql.Dialect(cc.driver.Dialect())
c = &City{config: cc.config}
c = &City{config: cc.config}
spec = &sqlgraph.CreateSpec{
Table: city.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: city.FieldID,
},
}
)
tx, err := cc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(city.Table).Default()
if value := cc.name; value != nil {
insert.Set(city.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: city.FieldName,
})
c.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(city.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := cc.streets; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: city.StreetsTable,
Columns: []string{city.StreetsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: street.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
c.ID = int(id)
if len(cc.streets) > 0 {
p := sql.P()
for eid := range cc.streets {
p.Or().EQ(street.FieldID, eid)
if err := sqlgraph.CreateNode(ctx, cc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
query, args := builder.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
}
id := spec.ID.Value.(int64)
c.ID = int(id)
return c, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/edgeindex/ent/city"
"github.com/facebookincubator/ent/examples/edgeindex/ent/street"
"github.com/facebookincubator/ent/schema/field"
)
// StreetCreate is the builder for creating a Street entity.
@@ -71,38 +73,51 @@ func (sc *StreetCreate) SaveX(ctx context.Context) *Street {
func (sc *StreetCreate) sqlSave(ctx context.Context) (*Street, error) {
var (
res sql.Result
builder = sql.Dialect(sc.driver.Dialect())
s = &Street{config: sc.config}
s = &Street{config: sc.config}
spec = &sqlgraph.CreateSpec{
Table: street.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: street.FieldID,
},
}
)
tx, err := sc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(street.Table).Default()
if value := sc.name; value != nil {
insert.Set(street.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: street.FieldName,
})
s.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(street.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
s.ID = int(id)
if len(sc.city) > 0 {
for eid := range sc.city {
query, args := builder.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 nodes := sc.city; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: street.CityTable,
Columns: []string{street.CityColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: city.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if err := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, sc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
s.ID = int(id)
return s, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -9,8 +9,9 @@ package ent
import (
"context"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/entcpkg/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -34,22 +35,24 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
insert := builder.Insert(user.Table).Default()
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
id := spec.ID.Value.(int64)
u.ID = int(id)
if err := tx.Commit(); err != nil {
return nil, err
}
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/m2m2types/ent/group"
"github.com/facebookincubator/ent/examples/m2m2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// GroupCreate is the builder for creating a Group entity.
@@ -66,39 +68,51 @@ func (gc *GroupCreate) SaveX(ctx context.Context) *Group {
func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) {
var (
res sql.Result
builder = sql.Dialect(gc.driver.Dialect())
gr = &Group{config: gc.config}
gr = &Group{config: gc.config}
spec = &sqlgraph.CreateSpec{
Table: group.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
}
)
tx, err := gc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(group.Table).Default()
if value := gc.name; value != nil {
insert.Set(group.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: group.FieldName,
})
gr.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(group.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
gr.ID = int(id)
if len(gc.users) > 0 {
for eid := range gc.users {
query, args := builder.Insert(group.UsersTable).
Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := gc.users; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: group.UsersTable,
Columns: group.UsersPrimaryKey,
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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, gc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
gr.ID = int(id)
return gr, nil
}

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/m2m2types/ent/group"
"github.com/facebookincubator/ent/examples/m2m2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -76,43 +78,59 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
u.ID = int(id)
if len(uc.groups) > 0 {
for eid := range uc.groups {
query, args := builder.Insert(user.GroupsTable).
Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := uc.groups; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: user.GroupsTable,
Columns: user.GroupsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if err := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,9 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/m2mbidi/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -76,44 +77,59 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
u.ID = int(id)
if len(uc.friends) > 0 {
for eid := range uc.friends {
query, args := builder.Insert(user.FriendsTable).
Columns(user.FriendsPrimaryKey[0], user.FriendsPrimaryKey[1]).
Values(id, eid).
Values(eid, id).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := uc.friends; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: user.FriendsTable,
Columns: user.FriendsPrimaryKey,
Bidi: true,
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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,9 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/m2mrecur/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -97,55 +98,78 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
u.ID = int(id)
if len(uc.followers) > 0 {
for eid := range uc.followers {
query, args := builder.Insert(user.FollowersTable).
Columns(user.FollowersPrimaryKey[1], user.FollowersPrimaryKey[0]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := uc.followers; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: user.FollowersTable,
Columns: user.FollowersPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
}
if len(uc.following) > 0 {
for eid := range uc.following {
query, args := builder.Insert(user.FollowingTable).
Columns(user.FollowingPrimaryKey[0], user.FollowingPrimaryKey[1]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if err := tx.Commit(); err != nil {
if nodes := uc.following; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: user.FollowingTable,
Columns: user.FollowingPrimaryKey,
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, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2m2types/ent/pet"
"github.com/facebookincubator/ent/examples/o2m2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// PetCreate is the builder for creating a Pet entity.
@@ -71,38 +73,51 @@ func (pc *PetCreate) SaveX(ctx context.Context) *Pet {
func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) {
var (
res sql.Result
builder = sql.Dialect(pc.driver.Dialect())
pe = &Pet{config: pc.config}
pe = &Pet{config: pc.config}
spec = &sqlgraph.CreateSpec{
Table: pet.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: pet.FieldID,
},
}
)
tx, err := pc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(pet.Table).Default()
if value := pc.name; value != nil {
insert.Set(pet.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: pet.FieldName,
})
pe.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(pet.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
pe.ID = int(id)
if len(pc.owner) > 0 {
for eid := range pc.owner {
query, args := builder.Update(pet.OwnerTable).
Set(pet.OwnerColumn, eid).
Where(sql.EQ(pet.FieldID, id)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := pc.owner; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, pc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
pe.ID = int(id)
return pe, nil
}

View File

@@ -9,11 +9,11 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2m2types/ent/pet"
"github.com/facebookincubator/ent/examples/o2m2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -78,51 +78,59 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := uc.pets; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: pet.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
u.ID = int(id)
if len(uc.pets) > 0 {
p := sql.P()
for eid := range uc.pets {
p.Or().EQ(pet.FieldID, eid)
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
query, args := builder.Update(user.PetsTable).
Set(user.PetsColumn, id).
Where(sql.And(p, sql.IsNull(user.PetsColumn))).
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(uc.pets) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"pets\" %v already connected to a different \"User\"", keys(uc.pets))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -9,10 +9,10 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2mrecur/ent/node"
"github.com/facebookincubator/ent/schema/field"
)
// NodeCreate is the builder for creating a Node entity.
@@ -93,58 +93,70 @@ func (nc *NodeCreate) SaveX(ctx context.Context) *Node {
func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) {
var (
res sql.Result
builder = sql.Dialect(nc.driver.Dialect())
n = &Node{config: nc.config}
n = &Node{config: nc.config}
spec = &sqlgraph.CreateSpec{
Table: node.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
}
)
tx, err := nc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(node.Table).Default()
if value := nc.value; value != nil {
insert.Set(node.FieldValue, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: node.FieldValue,
})
n.Value = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(node.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := nc.parent; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: node.ParentTable,
Columns: []string{node.ParentColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
n.ID = int(id)
if len(nc.parent) > 0 {
for eid := range nc.parent {
query, args := builder.Update(node.ParentTable).
Set(node.ParentColumn, eid).
Where(sql.EQ(node.FieldID, id)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := nc.children; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: node.ChildrenTable,
Columns: []string{node.ChildrenColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(nc.children) > 0 {
p := sql.P()
for eid := range nc.children {
p.Or().EQ(node.FieldID, eid)
if err := sqlgraph.CreateNode(ctx, nc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
query, args := builder.Update(node.ChildrenTable).
Set(node.ChildrenColumn, id).
Where(sql.And(p, sql.IsNull(node.ChildrenColumn))).
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(nc.children) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"children\" %v already connected to a different \"Node\"", keys(nc.children))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
n.ID = int(id)
return n, nil
}

View File

@@ -9,11 +9,12 @@ package ent
import (
"context"
"errors"
"fmt"
"time"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2o2types/ent/card"
"github.com/facebookincubator/ent/examples/o2o2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// CardCreate is the builder for creating a Card entity.
@@ -78,48 +79,59 @@ func (cc *CardCreate) SaveX(ctx context.Context) *Card {
func (cc *CardCreate) sqlSave(ctx context.Context) (*Card, error) {
var (
res sql.Result
builder = sql.Dialect(cc.driver.Dialect())
c = &Card{config: cc.config}
c = &Card{config: cc.config}
spec = &sqlgraph.CreateSpec{
Table: card.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: card.FieldID,
},
}
)
tx, err := cc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(card.Table).Default()
if value := cc.expired; value != nil {
insert.Set(card.FieldExpired, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: *value,
Column: card.FieldExpired,
})
c.Expired = *value
}
if value := cc.number; value != nil {
insert.Set(card.FieldNumber, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: card.FieldNumber,
})
c.Number = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(card.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := cc.owner; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: card.OwnerTable,
Columns: []string{card.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)
}
c.ID = int(id)
if len(cc.owner) > 0 {
eid := keys(cc.owner)[0]
query, args := builder.Update(card.OwnerTable).
Set(card.OwnerColumn, eid).
Where(sql.EQ(card.FieldID, id).And().IsNull(card.OwnerColumn)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
if err := sqlgraph.CreateNode(ctx, cc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
affected, err := res.RowsAffected()
if err != nil {
return nil, rollback(tx, err)
}
if int(affected) < len(cc.owner) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"owner\" %v already connected to a different \"Card\"", keys(cc.owner))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
c.ID = int(id)
return c, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -9,11 +9,11 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2o2types/ent/card"
"github.com/facebookincubator/ent/examples/o2o2types/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -83,48 +83,59 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := uc.card; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.CardTable,
Columns: []string{user.CardColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: card.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
u.ID = int(id)
if len(uc.card) > 0 {
eid := keys(uc.card)[0]
query, args := builder.Update(user.CardTable).
Set(user.CardColumn, id).
Where(sql.EQ(card.FieldID, eid).And().IsNull(user.CardColumn)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
affected, err := res.RowsAffected()
if err != nil {
return nil, rollback(tx, err)
}
if int(affected) < len(uc.card) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"card\" %v already connected to a different \"User\"", keys(uc.card))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -9,10 +9,10 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2obidi/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -82,54 +82,59 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
u.ID = int(id)
if len(uc.spouse) > 0 {
for eid := range uc.spouse {
query, args := builder.Update(user.SpouseTable).
Set(user.SpouseColumn, eid).
Where(sql.EQ(user.FieldID, id)).Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
query, args = builder.Update(user.SpouseTable).
Set(user.SpouseColumn, id).
Where(sql.EQ(user.FieldID, eid).And().IsNull(user.SpouseColumn)).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(uc.spouse) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("\"spouse\" (%v) already connected to a different \"User\"", eid)})
}
if nodes := uc.spouse; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: user.SpouseTable,
Columns: []string{user.SpouseColumn},
Bidi: true,
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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -9,10 +9,10 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/o2orecur/ent/node"
"github.com/facebookincubator/ent/schema/field"
)
// NodeCreate is the builder for creating a Node entity.
@@ -98,61 +98,70 @@ func (nc *NodeCreate) SaveX(ctx context.Context) *Node {
func (nc *NodeCreate) sqlSave(ctx context.Context) (*Node, error) {
var (
res sql.Result
builder = sql.Dialect(nc.driver.Dialect())
n = &Node{config: nc.config}
n = &Node{config: nc.config}
spec = &sqlgraph.CreateSpec{
Table: node.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
}
)
tx, err := nc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(node.Table).Default()
if value := nc.value; value != nil {
insert.Set(node.FieldValue, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: node.FieldValue,
})
n.Value = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(node.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := nc.prev; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: true,
Table: node.PrevTable,
Columns: []string{node.PrevColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
n.ID = int(id)
if len(nc.prev) > 0 {
eid := keys(nc.prev)[0]
query, args := builder.Update(node.PrevTable).
Set(node.PrevColumn, eid).
Where(sql.EQ(node.FieldID, id).And().IsNull(node.PrevColumn)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
if nodes := nc.next; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2O,
Inverse: false,
Table: node.NextTable,
Columns: []string{node.NextColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: node.FieldID,
},
},
}
affected, err := res.RowsAffected()
if err != nil {
return nil, rollback(tx, err)
}
if int(affected) < len(nc.prev) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"prev\" %v already connected to a different \"Node\"", keys(nc.prev))})
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(nc.next) > 0 {
eid := keys(nc.next)[0]
query, args := builder.Update(node.NextTable).
Set(node.NextColumn, id).
Where(sql.EQ(node.FieldID, eid).And().IsNull(node.NextColumn)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
if err := sqlgraph.CreateNode(ctx, nc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
affected, err := res.RowsAffected()
if err != nil {
return nil, rollback(tx, err)
}
if int(affected) < len(nc.next) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"next\" %v already connected to a different \"Node\"", keys(nc.next))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
n.ID = int(id)
return n, nil
}

View File

@@ -11,8 +11,10 @@ import (
"errors"
"time"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/start/ent/car"
"github.com/facebookincubator/ent/examples/start/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// CarCreate is the builder for creating a Car entity.
@@ -82,42 +84,59 @@ func (cc *CarCreate) SaveX(ctx context.Context) *Car {
func (cc *CarCreate) sqlSave(ctx context.Context) (*Car, error) {
var (
res sql.Result
builder = sql.Dialect(cc.driver.Dialect())
c = &Car{config: cc.config}
c = &Car{config: cc.config}
spec = &sqlgraph.CreateSpec{
Table: car.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: car.FieldID,
},
}
)
tx, err := cc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(car.Table).Default()
if value := cc.model; value != nil {
insert.Set(car.FieldModel, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: car.FieldModel,
})
c.Model = *value
}
if value := cc.registered_at; value != nil {
insert.Set(car.FieldRegisteredAt, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeTime,
Value: *value,
Column: car.FieldRegisteredAt,
})
c.RegisteredAt = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(car.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
c.ID = int(id)
if len(cc.owner) > 0 {
for eid := range cc.owner {
query, args := builder.Update(car.OwnerTable).
Set(car.OwnerColumn, eid).
Where(sql.EQ(car.FieldID, id)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := cc.owner; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: car.OwnerTable,
Columns: []string{car.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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, cc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
c.ID = int(id)
return c, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -11,8 +11,10 @@ import (
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/start/ent/group"
"github.com/facebookincubator/ent/examples/start/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// GroupCreate is the builder for creating a Group entity.
@@ -70,39 +72,51 @@ func (gc *GroupCreate) SaveX(ctx context.Context) *Group {
func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) {
var (
res sql.Result
builder = sql.Dialect(gc.driver.Dialect())
gr = &Group{config: gc.config}
gr = &Group{config: gc.config}
spec = &sqlgraph.CreateSpec{
Table: group.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
}
)
tx, err := gc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(group.Table).Default()
if value := gc.name; value != nil {
insert.Set(group.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: group.FieldName,
})
gr.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(group.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
gr.ID = int(id)
if len(gc.users) > 0 {
for eid := range gc.users {
query, args := builder.Insert(group.UsersTable).
Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := gc.users; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: group.UsersTable,
Columns: group.UsersPrimaryKey,
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 := tx.Commit(); err != nil {
if err := sqlgraph.CreateNode(ctx, gc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
gr.ID = int(id)
return gr, nil
}

View File

@@ -11,9 +11,11 @@ import (
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/start/ent/car"
"github.com/facebookincubator/ent/examples/start/ent/group"
"github.com/facebookincubator/ent/examples/start/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -111,63 +113,78 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := uc.cars; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.CarsTable,
Columns: []string{user.CarsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: car.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
u.ID = int(id)
if len(uc.cars) > 0 {
p := sql.P()
for eid := range uc.cars {
p.Or().EQ(car.FieldID, eid)
if nodes := uc.groups; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: user.GroupsTable,
Columns: user.GroupsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
},
}
query, args := builder.Update(user.CarsTable).
Set(user.CarsColumn, id).
Where(sql.And(p, sql.IsNull(user.CarsColumn))).
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(uc.cars) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"cars\" %v already connected to a different \"User\"", keys(uc.cars))})
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(uc.groups) > 0 {
for eid := range uc.groups {
query, args := builder.Insert(user.GroupsTable).
Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/facebookincubator/ent/dialect"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
)
// Order applies an ordering on either graph traversal or sql selector.
@@ -159,6 +160,9 @@ func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
"duplicate key value violates unique constraint", // PostgreSQL.
}
)
if _, ok := err.(*sqlgraph.ConstraintError); ok {
return &ErrConstraintFailed{msg, err}, true
}
for i := range errors {
if strings.Contains(msg, errors[i]) {
return &ErrConstraintFailed{msg, err}, true

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/traversal/ent/group"
"github.com/facebookincubator/ent/examples/traversal/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// GroupCreate is the builder for creating a Group entity.
@@ -92,50 +94,70 @@ func (gc *GroupCreate) SaveX(ctx context.Context) *Group {
func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) {
var (
res sql.Result
builder = sql.Dialect(gc.driver.Dialect())
gr = &Group{config: gc.config}
gr = &Group{config: gc.config}
spec = &sqlgraph.CreateSpec{
Table: group.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
}
)
tx, err := gc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(group.Table).Default()
if value := gc.name; value != nil {
insert.Set(group.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: group.FieldName,
})
gr.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(group.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
gr.ID = int(id)
if len(gc.users) > 0 {
for eid := range gc.users {
query, args := builder.Insert(group.UsersTable).
Columns(group.UsersPrimaryKey[0], group.UsersPrimaryKey[1]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := gc.users; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: group.UsersTable,
Columns: group.UsersPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
}
if len(gc.admin) > 0 {
for eid := range gc.admin {
query, args := builder.Update(group.AdminTable).
Set(group.AdminColumn, eid).
Where(sql.EQ(group.FieldID, id)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if err := tx.Commit(); err != nil {
if nodes := gc.admin; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: false,
Table: group.AdminTable,
Columns: []string{group.AdminColumn},
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, gc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
return nil, err
}
id := spec.ID.Value.(int64)
gr.ID = int(id)
return gr, nil
}

View File

@@ -10,8 +10,10 @@ import (
"context"
"errors"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/traversal/ent/pet"
"github.com/facebookincubator/ent/examples/traversal/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// PetCreate is the builder for creating a Pet entity.
@@ -92,51 +94,70 @@ func (pc *PetCreate) SaveX(ctx context.Context) *Pet {
func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) {
var (
res sql.Result
builder = sql.Dialect(pc.driver.Dialect())
pe = &Pet{config: pc.config}
pe = &Pet{config: pc.config}
spec = &sqlgraph.CreateSpec{
Table: pet.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: pet.FieldID,
},
}
)
tx, err := pc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(pet.Table).Default()
if value := pc.name; value != nil {
insert.Set(pet.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: pet.FieldName,
})
pe.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(pet.FieldID))
if err != nil {
return nil, rollback(tx, err)
}
pe.ID = int(id)
if len(pc.friends) > 0 {
for eid := range pc.friends {
query, args := builder.Insert(pet.FriendsTable).
Columns(pet.FriendsPrimaryKey[0], pet.FriendsPrimaryKey[1]).
Values(id, eid).
Values(eid, id).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := pc.friends; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: pet.FriendsTable,
Columns: pet.FriendsPrimaryKey,
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: pet.FieldID,
},
},
}
}
if len(pc.owner) > 0 {
for eid := range pc.owner {
query, args := builder.Update(pet.OwnerTable).
Set(pet.OwnerColumn, eid).
Where(sql.EQ(pet.FieldID, id)).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if err := tx.Commit(); err != nil {
if nodes := pc.owner; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
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
}
return nil, err
}
id := spec.ID.Value.(int64)
pe.ID = int(id)
return pe, nil
}

View File

@@ -9,12 +9,12 @@ package ent
import (
"context"
"errors"
"fmt"
"github.com/facebookincubator/ent/dialect/sql"
"github.com/facebookincubator/ent/dialect/sql/sqlgraph"
"github.com/facebookincubator/ent/examples/traversal/ent/group"
"github.com/facebookincubator/ent/examples/traversal/ent/pet"
"github.com/facebookincubator/ent/examples/traversal/ent/user"
"github.com/facebookincubator/ent/schema/field"
)
// UserCreate is the builder for creating a User entity.
@@ -142,96 +142,116 @@ func (uc *UserCreate) SaveX(ctx context.Context) *User {
func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) {
var (
res sql.Result
builder = sql.Dialect(uc.driver.Dialect())
u = &User{config: uc.config}
u = &User{config: uc.config}
spec = &sqlgraph.CreateSpec{
Table: user.Table,
ID: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
}
)
tx, err := uc.driver.Tx(ctx)
if err != nil {
return nil, err
}
insert := builder.Insert(user.Table).Default()
if value := uc.age; value != nil {
insert.Set(user.FieldAge, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeInt,
Value: *value,
Column: user.FieldAge,
})
u.Age = *value
}
if value := uc.name; value != nil {
insert.Set(user.FieldName, *value)
spec.Fields = append(spec.Fields, &sqlgraph.FieldSpec{
Type: field.TypeString,
Value: *value,
Column: user.FieldName,
})
u.Name = *value
}
id, err := insertLastID(ctx, tx, insert.Returning(user.FieldID))
if err != nil {
return nil, rollback(tx, err)
if nodes := uc.pets; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: false,
Table: user.PetsTable,
Columns: []string{user.PetsColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: pet.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
u.ID = int(id)
if len(uc.pets) > 0 {
p := sql.P()
for eid := range uc.pets {
p.Or().EQ(pet.FieldID, eid)
if nodes := uc.friends; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: false,
Table: user.FriendsTable,
Columns: user.FriendsPrimaryKey,
Bidi: true,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: user.FieldID,
},
},
}
query, args := builder.Update(user.PetsTable).
Set(user.PetsColumn, id).
Where(sql.And(p, sql.IsNull(user.PetsColumn))).
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(uc.pets) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"pets\" %v already connected to a different \"User\"", keys(uc.pets))})
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(uc.friends) > 0 {
for eid := range uc.friends {
query, args := builder.Insert(user.FriendsTable).
Columns(user.FriendsPrimaryKey[0], user.FriendsPrimaryKey[1]).
Values(id, eid).
Values(eid, id).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := uc.groups; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2M,
Inverse: true,
Table: user.GroupsTable,
Columns: user.GroupsPrimaryKey,
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(uc.groups) > 0 {
for eid := range uc.groups {
query, args := builder.Insert(user.GroupsTable).
Columns(user.GroupsPrimaryKey[1], user.GroupsPrimaryKey[0]).
Values(id, eid).
Query()
if err := tx.Exec(ctx, query, args, &res); err != nil {
return nil, rollback(tx, err)
}
if nodes := uc.manage; len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.O2M,
Inverse: true,
Table: user.ManageTable,
Columns: []string{user.ManageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: &sqlgraph.FieldSpec{
Type: field.TypeInt,
Column: group.FieldID,
},
},
}
for k, _ := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
spec.Edges = append(spec.Edges, edge)
}
if len(uc.manage) > 0 {
p := sql.P()
for eid := range uc.manage {
p.Or().EQ(group.FieldID, eid)
if err := sqlgraph.CreateNode(ctx, uc.driver, spec); err != nil {
if cerr, ok := isSQLConstraintError(err); ok {
err = cerr
}
query, args := builder.Update(user.ManageTable).
Set(user.ManageColumn, id).
Where(sql.And(p, sql.IsNull(user.ManageColumn))).
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(uc.manage) {
return nil, rollback(tx, &ErrConstraintFailed{msg: fmt.Sprintf("one of \"manage\" %v already connected to a different \"User\"", keys(uc.manage))})
}
}
if err := tx.Commit(); err != nil {
return nil, err
}
id := spec.ID.Value.(int64)
u.ID = int(id)
return u, nil
}