mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
dialect/sql/schema: universl id allocation support
Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/9 Reviewed By: alexsn Differential Revision: D16252229 fbshipit-source-id: 795b6556d322e5c1ff5fb826c3b06ba5421ac857
This commit is contained in:
committed by
Facebook Github Bot
parent
ad051e6d72
commit
b5cdb810b8
20
entc/integration/migrate/entv1/context.go
Normal file
20
entc/integration/migrate/entv1/context.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv1
|
||||
|
||||
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)
|
||||
}
|
||||
@@ -3,31 +3,27 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql/schema"
|
||||
"fbc/ent/field"
|
||||
)
|
||||
|
||||
var (
|
||||
nullable = true
|
||||
// UsersColumns holds the columns for the "users" table.
|
||||
UsersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "age", Type: field.TypeInt32},
|
||||
{Name: "name", Type: field.TypeString, Size: 10},
|
||||
{Name: "address", Type: field.TypeString},
|
||||
}
|
||||
// UsersTable holds the schema information for the "users" table.
|
||||
UsersTable = &schema.Table{
|
||||
Name: "users",
|
||||
Columns: UsersColumns,
|
||||
PrimaryKey: []*schema.Column{UsersColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
UsersTable,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 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...)
|
||||
}
|
||||
|
||||
@@ -3,39 +3,31 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql/schema"
|
||||
"fbc/ent/field"
|
||||
)
|
||||
|
||||
// SQLDialect wraps the dialect.Driver with additional migration methods.
|
||||
type SQLDriver interface {
|
||||
Create(context.Context, ...*schema.Table) error
|
||||
}
|
||||
|
||||
// Schema is the API for creating, migrating and dropping a schema.
|
||||
type Schema struct {
|
||||
drv SQLDriver
|
||||
}
|
||||
|
||||
// NewSchema creates a new schema client.
|
||||
func NewSchema(drv dialect.Driver) *Schema {
|
||||
s := &Schema{}
|
||||
switch drv.Dialect() {
|
||||
case dialect.MySQL:
|
||||
s.drv = &schema.MySQL{Driver: drv}
|
||||
case dialect.SQLite:
|
||||
s.drv = &schema.SQLite{Driver: drv}
|
||||
var (
|
||||
nullable = true
|
||||
// UsersColumns holds the columns for the "users" table.
|
||||
UsersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "age", Type: field.TypeInt32},
|
||||
{Name: "name", Type: field.TypeString, Size: 10},
|
||||
{Name: "address", Type: field.TypeString},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Create creates all schema resources.
|
||||
func (s *Schema) Create(ctx context.Context) error {
|
||||
if s.drv == nil {
|
||||
return fmt.Errorf("entv1/migrate: dialect does not support migration")
|
||||
// UsersTable holds the schema information for the "users" table.
|
||||
UsersTable = &schema.Table{
|
||||
Name: "users",
|
||||
Columns: UsersColumns,
|
||||
PrimaryKey: []*schema.Column{UsersColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
return s.drv.Create(ctx, Tables...)
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
UsersTable,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ func (u *User) Unwrap() *User {
|
||||
func (u *User) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("User(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v,", u.ID))
|
||||
buf.WriteString(fmt.Sprintf("age=%v", u.Age))
|
||||
buf.WriteString(fmt.Sprintf("id=%v", u.ID))
|
||||
buf.WriteString(fmt.Sprintf(", age=%v", u.Age))
|
||||
buf.WriteString(fmt.Sprintf(", name=%v", u.Name))
|
||||
buf.WriteString(fmt.Sprintf(", address=%v", u.Address))
|
||||
buf.WriteString(")")
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/migrate"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/group"
|
||||
"fbc/ent/entc/integration/migrate/entv2/pet"
|
||||
"fbc/ent/entc/integration/migrate/entv2/user"
|
||||
)
|
||||
|
||||
@@ -17,6 +19,10 @@ type Client struct {
|
||||
config
|
||||
// Schema is the client for creating, migrating and dropping schema.
|
||||
Schema *migrate.Schema
|
||||
// Group is the client for interacting with the Group builders.
|
||||
Group *GroupClient
|
||||
// Pet is the client for interacting with the Pet builders.
|
||||
Pet *PetClient
|
||||
// User is the client for interacting with the User builders.
|
||||
User *UserClient
|
||||
}
|
||||
@@ -28,6 +34,8 @@ func NewClient(opts ...Option) *Client {
|
||||
return &Client{
|
||||
config: c,
|
||||
Schema: migrate.NewSchema(c.driver),
|
||||
Group: NewGroupClient(c),
|
||||
Pet: NewPetClient(c),
|
||||
User: NewUserClient(c),
|
||||
}
|
||||
}
|
||||
@@ -44,10 +52,112 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
||||
cfg := config{driver: tx, log: c.log, verbose: c.verbose}
|
||||
return &Tx{
|
||||
config: cfg,
|
||||
Group: NewGroupClient(cfg),
|
||||
Pet: NewPetClient(cfg),
|
||||
User: NewUserClient(cfg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GroupClient is a client for the Group schema.
|
||||
type GroupClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewGroupClient returns a client for the Group from the given config.
|
||||
func NewGroupClient(c config) *GroupClient {
|
||||
return &GroupClient{config: c}
|
||||
}
|
||||
|
||||
// Create returns a create builder for Group.
|
||||
func (c *GroupClient) Create() *GroupCreate {
|
||||
return &GroupCreate{config: c.config}
|
||||
}
|
||||
|
||||
// Update returns an update builder for Group.
|
||||
func (c *GroupClient) Update() *GroupUpdate {
|
||||
return &GroupUpdate{config: c.config}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *GroupClient) UpdateOne(gr *Group) *GroupUpdateOne {
|
||||
return c.UpdateOneID(gr.ID)
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *GroupClient) UpdateOneID(id string) *GroupUpdateOne {
|
||||
return &GroupUpdateOne{config: c.config, id: id}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for Group.
|
||||
func (c *GroupClient) Delete() *GroupDelete {
|
||||
return &GroupDelete{config: c.config}
|
||||
}
|
||||
|
||||
// DeleteOne returns a delete builder for the given entity.
|
||||
func (c *GroupClient) DeleteOne(gr *Group) *GroupDeleteOne {
|
||||
return c.DeleteOneID(gr.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a delete builder for the given id.
|
||||
func (c *GroupClient) DeleteOneID(id string) *GroupDeleteOne {
|
||||
return &GroupDeleteOne{c.Delete().Where(group.ID(id))}
|
||||
}
|
||||
|
||||
// Create returns a query builder for Group.
|
||||
func (c *GroupClient) Query() *GroupQuery {
|
||||
return &GroupQuery{config: c.config}
|
||||
}
|
||||
|
||||
// PetClient is a client for the Pet schema.
|
||||
type PetClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewPetClient returns a client for the Pet from the given config.
|
||||
func NewPetClient(c config) *PetClient {
|
||||
return &PetClient{config: c}
|
||||
}
|
||||
|
||||
// Create returns a create builder for Pet.
|
||||
func (c *PetClient) Create() *PetCreate {
|
||||
return &PetCreate{config: c.config}
|
||||
}
|
||||
|
||||
// Update returns an update builder for Pet.
|
||||
func (c *PetClient) Update() *PetUpdate {
|
||||
return &PetUpdate{config: c.config}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *PetClient) UpdateOne(pe *Pet) *PetUpdateOne {
|
||||
return c.UpdateOneID(pe.ID)
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *PetClient) UpdateOneID(id string) *PetUpdateOne {
|
||||
return &PetUpdateOne{config: c.config, id: id}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for Pet.
|
||||
func (c *PetClient) Delete() *PetDelete {
|
||||
return &PetDelete{config: c.config}
|
||||
}
|
||||
|
||||
// DeleteOne returns a delete builder for the given entity.
|
||||
func (c *PetClient) DeleteOne(pe *Pet) *PetDeleteOne {
|
||||
return c.DeleteOneID(pe.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a delete builder for the given id.
|
||||
func (c *PetClient) DeleteOneID(id string) *PetDeleteOne {
|
||||
return &PetDeleteOne{c.Delete().Where(pet.ID(id))}
|
||||
}
|
||||
|
||||
// Create returns a query builder for Pet.
|
||||
func (c *PetClient) Query() *PetQuery {
|
||||
return &PetQuery{config: c.config}
|
||||
}
|
||||
|
||||
// UserClient is a client for the User schema.
|
||||
type UserClient struct {
|
||||
config
|
||||
|
||||
20
entc/integration/migrate/entv2/context.go
Normal file
20
entc/integration/migrate/entv2/context.go
Normal file
@@ -0,0 +1,20 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
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)
|
||||
}
|
||||
@@ -26,6 +26,52 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleGroup() {
|
||||
if endpoint == nil {
|
||||
return
|
||||
}
|
||||
ctx := context.Background()
|
||||
conn, err := gremlin.NewClient(gremlin.Config{Endpoint: *endpoint})
|
||||
if err != nil {
|
||||
log.Fatalf("failed creating database client: %v", err)
|
||||
}
|
||||
client := NewClient(Driver(dialect.NewGremlin(conn)))
|
||||
|
||||
// creating vertices for the group's edges.
|
||||
|
||||
// create group vertex with its edges.
|
||||
gr := client.Group.
|
||||
Create().
|
||||
SaveX(ctx)
|
||||
log.Println("group created:", gr)
|
||||
|
||||
// query edges.
|
||||
|
||||
// Output:
|
||||
}
|
||||
func ExamplePet() {
|
||||
if endpoint == nil {
|
||||
return
|
||||
}
|
||||
ctx := context.Background()
|
||||
conn, err := gremlin.NewClient(gremlin.Config{Endpoint: *endpoint})
|
||||
if err != nil {
|
||||
log.Fatalf("failed creating database client: %v", err)
|
||||
}
|
||||
client := NewClient(Driver(dialect.NewGremlin(conn)))
|
||||
|
||||
// creating vertices for the pet's edges.
|
||||
|
||||
// create pet vertex with its edges.
|
||||
pe := client.Pet.
|
||||
Create().
|
||||
SaveX(ctx)
|
||||
log.Println("pet created:", pe)
|
||||
|
||||
// query edges.
|
||||
|
||||
// Output:
|
||||
}
|
||||
func ExampleUser() {
|
||||
if endpoint == nil {
|
||||
return
|
||||
|
||||
125
entc/integration/migrate/entv2/group.go
Normal file
125
entc/integration/migrate/entv2/group.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
)
|
||||
|
||||
// Group is the model entity for the Group schema.
|
||||
type Group struct {
|
||||
config
|
||||
// ID of the ent.
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// FromResponse scans the gremlin response data into Group.
|
||||
func (gr *Group) FromResponse(res *gremlin.Response) error {
|
||||
vmap, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var vgr struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
if err := vmap.Decode(&vgr); err != nil {
|
||||
return err
|
||||
}
|
||||
gr.ID = vgr.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into Group.
|
||||
func (gr *Group) FromRows(rows *sql.Rows) error {
|
||||
var vgr struct {
|
||||
ID int
|
||||
}
|
||||
// the order here should be the same as in the `group.Columns`.
|
||||
if err := rows.Scan(
|
||||
&vgr.ID,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
gr.ID = strconv.Itoa(vgr.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Group.
|
||||
// Note that, you need to call Group.Unwrap() before calling this method, if this Group
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (gr *Group) Update() *GroupUpdateOne {
|
||||
return (&GroupClient{gr.config}).UpdateOne(gr)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the entity that was returned from a transaction after it was closed,
|
||||
// so that all next queries will be executed through the driver which created the transaction.
|
||||
func (gr *Group) Unwrap() *Group {
|
||||
tx, ok := gr.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("entv2: Group is not a transactional entity")
|
||||
}
|
||||
gr.config.driver = tx.drv
|
||||
return gr
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (gr *Group) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("Group(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v", gr.ID))
|
||||
buf.WriteString(")")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// id returns the int representation of the ID field.
|
||||
func (gr *Group) id() int {
|
||||
id, _ := strconv.Atoi(gr.ID)
|
||||
return id
|
||||
}
|
||||
|
||||
// Groups is a parsable slice of Group.
|
||||
type Groups []*Group
|
||||
|
||||
// FromResponse scans the gremlin response data into Groups.
|
||||
func (gr *Groups) FromResponse(res *gremlin.Response) error {
|
||||
vmap, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var vgr []struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
if err := vmap.Decode(&vgr); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range vgr {
|
||||
*gr = append(*gr, &Group{
|
||||
ID: v.ID,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into Groups.
|
||||
func (gr *Groups) FromRows(rows *sql.Rows) error {
|
||||
for rows.Next() {
|
||||
vgr := &Group{}
|
||||
if err := vgr.FromRows(rows); err != nil {
|
||||
return err
|
||||
}
|
||||
*gr = append(*gr, vgr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gr Groups) config(cfg config) {
|
||||
for i := range gr {
|
||||
gr[i].config = cfg
|
||||
}
|
||||
}
|
||||
17
entc/integration/migrate/entv2/group/group.go
Normal file
17
entc/integration/migrate/entv2/group/group.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package group
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the group type in the database.
|
||||
Label = "group"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// Table holds the table name of the group in the database.
|
||||
Table = "groups"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns are group fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
}
|
||||
156
entc/integration/migrate/entv2/group/where.go
Normal file
156
entc/integration/migrate/entv2/group/where.go
Normal file
@@ -0,0 +1,156 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package group
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/p"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their identifier.
|
||||
func ID(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
id, _ := strconv.Atoi(id)
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(id)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.EQ(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.EQ(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.NEQ(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.NEQ(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.GT(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.GT(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.GTE(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.GTE(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.LT(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.LT(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.LTE(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.LTE(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
// if not arguments were provided, append the FALSE constants,
|
||||
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||
if len(ids) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i], _ = strconv.Atoi(ids[i])
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
t.HasID(p.Within(v...))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
// if not arguments were provided, append the FALSE constants,
|
||||
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||
if len(ids) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i], _ = strconv.Atoi(ids[i])
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
t.HasID(p.Without(v...))
|
||||
},
|
||||
}
|
||||
}
|
||||
90
entc/integration/migrate/entv2/group_create.go
Normal file
90
entc/integration/migrate/entv2/group_create.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/group"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// GroupCreate is the builder for creating a Group entity.
|
||||
type GroupCreate struct {
|
||||
config
|
||||
}
|
||||
|
||||
// Save creates the Group in the database.
|
||||
func (gc *GroupCreate) Save(ctx context.Context) (*Group, error) {
|
||||
switch gc.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gc.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
return gc.gremlinSave(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (gc *GroupCreate) SaveX(ctx context.Context) *Group {
|
||||
v, err := gc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (gc *GroupCreate) sqlSave(ctx context.Context) (*Group, error) {
|
||||
var (
|
||||
res sql.Result
|
||||
gr = &Group{config: gc.config}
|
||||
)
|
||||
tx, err := gc.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := sql.Insert(group.Table).Default(gc.driver.Dialect())
|
||||
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)
|
||||
}
|
||||
gr.ID = strconv.FormatInt(id, 10)
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gr, nil
|
||||
}
|
||||
|
||||
func (gc *GroupCreate) gremlinSave(ctx context.Context) (*Group, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gc.gremlin().Query()
|
||||
if err := gc.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
gr := &Group{config: gc.config}
|
||||
if err := gr.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gr, nil
|
||||
}
|
||||
|
||||
func (gc *GroupCreate) gremlin() *dsl.Traversal {
|
||||
v := g.AddV(group.Label)
|
||||
return v.ValueMap(true)
|
||||
}
|
||||
88
entc/integration/migrate/entv2/group_delete.go
Normal file
88
entc/integration/migrate/entv2/group_delete.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/group"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// GroupDelete is the builder for deleting a Group entity.
|
||||
type GroupDelete struct {
|
||||
config
|
||||
predicates []ent.Predicate
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (gd *GroupDelete) Where(ps ...ent.Predicate) *GroupDelete {
|
||||
gd.predicates = append(gd.predicates, ps...)
|
||||
return gd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (gd *GroupDelete) Exec(ctx context.Context) error {
|
||||
switch gd.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gd.sqlExec(ctx)
|
||||
case dialect.Neptune:
|
||||
return gd.gremlinExec(ctx)
|
||||
default:
|
||||
return errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (gd *GroupDelete) ExecX(ctx context.Context) {
|
||||
if err := gd.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (gd *GroupDelete) sqlExec(ctx context.Context) error {
|
||||
var res sql.Result
|
||||
selector := sql.Select().From(sql.Table(group.Table))
|
||||
for _, p := range gd.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
query, args := sql.Delete(group.Table).FromSelect(selector).Query()
|
||||
return gd.driver.Exec(ctx, query, args, &res)
|
||||
}
|
||||
|
||||
func (gd *GroupDelete) gremlinExec(ctx context.Context) error {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gd.gremlin().Query()
|
||||
return gd.driver.Exec(ctx, query, bindings, res)
|
||||
}
|
||||
|
||||
func (gd *GroupDelete) gremlin() *dsl.Traversal {
|
||||
t := g.V().HasLabel(group.Label)
|
||||
for _, p := range gd.predicates {
|
||||
p.Gremlin(t)
|
||||
}
|
||||
return t.Drop()
|
||||
}
|
||||
|
||||
// GroupDeleteOne is the builder for deleting a single Group entity.
|
||||
type GroupDeleteOne struct {
|
||||
gd *GroupDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (gdo *GroupDeleteOne) Exec(ctx context.Context) error {
|
||||
return gdo.gd.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (gdo *GroupDeleteOne) ExecX(ctx context.Context) {
|
||||
gdo.gd.ExecX(ctx)
|
||||
}
|
||||
603
entc/integration/migrate/entv2/group_query.go
Normal file
603
entc/integration/migrate/entv2/group_query.go
Normal file
@@ -0,0 +1,603 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/group"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/__"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// GroupQuery is the builder for querying Group entities.
|
||||
type GroupQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
order []Order
|
||||
unique []string
|
||||
predicates []ent.Predicate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
gremlin *dsl.Traversal
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (gq *GroupQuery) Where(ps ...ent.Predicate) *GroupQuery {
|
||||
gq.predicates = append(gq.predicates, ps...)
|
||||
return gq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (gq *GroupQuery) Limit(limit int) *GroupQuery {
|
||||
gq.limit = &limit
|
||||
return gq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (gq *GroupQuery) Offset(offset int) *GroupQuery {
|
||||
gq.offset = &offset
|
||||
return gq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (gq *GroupQuery) Order(o ...Order) *GroupQuery {
|
||||
gq.order = append(gq.order, o...)
|
||||
return gq
|
||||
}
|
||||
|
||||
// Get returns a Group entity by its id.
|
||||
func (gq *GroupQuery) Get(ctx context.Context, id string) (*Group, error) {
|
||||
return gq.Where(group.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (gq *GroupQuery) GetX(ctx context.Context, id string) *Group {
|
||||
gr, err := gq.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gr
|
||||
}
|
||||
|
||||
// First returns the first Group entity in the query. Returns *ErrNotFound when no group was found.
|
||||
func (gq *GroupQuery) First(ctx context.Context) (*Group, error) {
|
||||
grs, err := gq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(grs) == 0 {
|
||||
return nil, &ErrNotFound{group.Label}
|
||||
}
|
||||
return grs[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (gq *GroupQuery) FirstX(ctx context.Context) *Group {
|
||||
gr, err := gq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return gr
|
||||
}
|
||||
|
||||
// FirstID returns the first Group id in the query. Returns *ErrNotFound when no id was found.
|
||||
func (gq *GroupQuery) FirstID(ctx context.Context) (id string, err error) {
|
||||
var ids []string
|
||||
if ids, err = gq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &ErrNotFound{group.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstXID is like FirstID, but panics if an error occurs.
|
||||
func (gq *GroupQuery) FirstXID(ctx context.Context) string {
|
||||
id, err := gq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns the only Group entity in the query, returns an error if not exactly one entity was returned.
|
||||
func (gq *GroupQuery) Only(ctx context.Context) (*Group, error) {
|
||||
grs, err := gq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(grs) {
|
||||
case 1:
|
||||
return grs[0], nil
|
||||
case 0:
|
||||
return nil, &ErrNotFound{group.Label}
|
||||
default:
|
||||
return nil, &ErrNotSingular{group.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (gq *GroupQuery) OnlyX(ctx context.Context) *Group {
|
||||
gr, err := gq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gr
|
||||
}
|
||||
|
||||
// OnlyID returns the only Group id in the query, returns an error if not exactly one id was returned.
|
||||
func (gq *GroupQuery) OnlyID(ctx context.Context) (id string, err error) {
|
||||
var ids []string
|
||||
if ids, err = gq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &ErrNotFound{group.Label}
|
||||
default:
|
||||
err = &ErrNotSingular{group.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyXID is like OnlyID, but panics if an error occurs.
|
||||
func (gq *GroupQuery) OnlyXID(ctx context.Context) string {
|
||||
id, err := gq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of Groups.
|
||||
func (gq *GroupQuery) All(ctx context.Context) ([]*Group, error) {
|
||||
switch gq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gq.sqlAll(ctx)
|
||||
case dialect.Neptune:
|
||||
return gq.gremlinAll(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (gq *GroupQuery) AllX(ctx context.Context) []*Group {
|
||||
grs, err := gq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return grs
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of Group ids.
|
||||
func (gq *GroupQuery) IDs(ctx context.Context) ([]string, error) {
|
||||
switch gq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gq.sqlIDs(ctx)
|
||||
case dialect.Neptune:
|
||||
return gq.gremlinIDs(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (gq *GroupQuery) IDsX(ctx context.Context) []string {
|
||||
ids, err := gq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (gq *GroupQuery) Count(ctx context.Context) (int, error) {
|
||||
switch gq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gq.sqlCount(ctx)
|
||||
case dialect.Neptune:
|
||||
return gq.gremlinCount(ctx)
|
||||
default:
|
||||
return 0, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (gq *GroupQuery) CountX(ctx context.Context) int {
|
||||
count, err := gq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (gq *GroupQuery) Exist(ctx context.Context) (bool, error) {
|
||||
switch gq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gq.sqlExist(ctx)
|
||||
case dialect.Neptune:
|
||||
return gq.gremlinExist(ctx)
|
||||
default:
|
||||
return false, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (gq *GroupQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := gq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// GroupBy used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
func (gq *GroupQuery) GroupBy(field string, fields ...string) *GroupGroupBy {
|
||||
group := &GroupGroupBy{config: gq.config}
|
||||
group.fields = append([]string{field}, fields...)
|
||||
switch gq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
group.sql = gq.sqlQuery()
|
||||
case dialect.Neptune:
|
||||
group.gremlin = gq.gremlinQuery()
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) sqlAll(ctx context.Context) ([]*Group, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := gq.sqlQuery()
|
||||
if unique := gq.unique; len(unique) == 0 {
|
||||
selector.Distinct()
|
||||
}
|
||||
query, args := selector.Query()
|
||||
if err := gq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var grs Groups
|
||||
if err := grs.FromRows(rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grs.config(gq.config)
|
||||
return grs, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := gq.sqlQuery()
|
||||
unique := []string{group.FieldID}
|
||||
if len(gq.unique) > 0 {
|
||||
unique = gq.unique
|
||||
}
|
||||
selector.Count(sql.Distinct(selector.Columns(unique...)...))
|
||||
query, args := selector.Query()
|
||||
if err := gq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
return 0, errors.New("entv2: no rows found")
|
||||
}
|
||||
var n int
|
||||
if err := rows.Scan(&n); err != nil {
|
||||
return 0, fmt.Errorf("entv2: failed reading count: %v", err)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
n, err := gq.sqlCount(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("entv2: check existence: %v", err)
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) sqlIDs(ctx context.Context) ([]string, error) {
|
||||
vs, err := gq.sqlAll(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []string
|
||||
for _, v := range vs {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) sqlQuery() *sql.Selector {
|
||||
t1 := sql.Table(group.Table)
|
||||
selector := sql.Select(t1.Columns(group.Columns...)...).From(t1)
|
||||
if gq.sql != nil {
|
||||
selector = gq.sql
|
||||
selector.Select(selector.Columns(group.Columns...)...)
|
||||
}
|
||||
for _, p := range gq.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
for _, p := range gq.order {
|
||||
p.SQL(selector)
|
||||
}
|
||||
if offset := gq.offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt64)
|
||||
}
|
||||
if limit := gq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) gremlinIDs(ctx context.Context) ([]string, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gq.gremlinQuery().Query()
|
||||
if err := gq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vertices, err := res.ReadVertices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]string, 0, len(vertices))
|
||||
for _, vertex := range vertices {
|
||||
ids = append(ids, vertex.ID.(string))
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) gremlinAll(ctx context.Context) ([]*Group, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gq.gremlinQuery().ValueMap(true).Query()
|
||||
if err := gq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var grs Groups
|
||||
if err := grs.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grs.config(gq.config)
|
||||
return grs, nil
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) gremlinCount(ctx context.Context) (int, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gq.gremlinQuery().Count().Query()
|
||||
if err := gq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.ReadInt()
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) gremlinExist(ctx context.Context) (bool, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gq.gremlinQuery().HasNext().Query()
|
||||
if err := gq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res.ReadBool()
|
||||
}
|
||||
|
||||
func (gq *GroupQuery) gremlinQuery() *dsl.Traversal {
|
||||
v := g.V().HasLabel(group.Label)
|
||||
if gq.gremlin != nil {
|
||||
v = gq.gremlin.Clone()
|
||||
}
|
||||
for _, p := range gq.predicates {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
if len(gq.order) > 0 {
|
||||
v.Order()
|
||||
for _, p := range gq.order {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
}
|
||||
switch limit, offset := gq.limit, gq.offset; {
|
||||
case limit != nil && offset != nil:
|
||||
v.Range(*offset, *offset+*limit)
|
||||
case offset != nil:
|
||||
v.Range(*offset, math.MaxInt64)
|
||||
case limit != nil:
|
||||
v.Limit(*limit)
|
||||
}
|
||||
if unique := gq.unique; len(unique) == 0 {
|
||||
v.Dedup()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// GroupQuery is the builder for group-by Group entities.
|
||||
type GroupGroupBy struct {
|
||||
config
|
||||
fields []string
|
||||
fns []Aggregate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
gremlin *dsl.Traversal
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (ggb *GroupGroupBy) Aggregate(fns ...Aggregate) *GroupGroupBy {
|
||||
ggb.fns = append(ggb.fns, fns...)
|
||||
return ggb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scan the result into the given value.
|
||||
func (ggb *GroupGroupBy) Scan(ctx context.Context, v interface{}) error {
|
||||
switch ggb.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return ggb.sqlScan(ctx, v)
|
||||
case dialect.Neptune:
|
||||
return ggb.gremlinScan(ctx, v)
|
||||
default:
|
||||
return errors.New("ggb: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ScanX is like Scan, but panics if an error occurs.
|
||||
func (ggb *GroupGroupBy) ScanX(ctx context.Context, v interface{}) {
|
||||
if err := ggb.Scan(ctx, v); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Strings returns list of strings from group-by. It is only allowed when querying group-by with one field.
|
||||
func (ggb *GroupGroupBy) Strings(ctx context.Context) ([]string, error) {
|
||||
if len(ggb.fields) > 1 {
|
||||
return nil, errors.New("entv2: GroupGroupBy.Strings is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []string
|
||||
if err := ggb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// StringsX is like Strings, but panics if an error occurs.
|
||||
func (ggb *GroupGroupBy) StringsX(ctx context.Context) []string {
|
||||
v, err := ggb.Strings(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Ints returns list of ints from group-by. It is only allowed when querying group-by with one field.
|
||||
func (ggb *GroupGroupBy) Ints(ctx context.Context) ([]int, error) {
|
||||
if len(ggb.fields) > 1 {
|
||||
return nil, errors.New("entv2: GroupGroupBy.Ints is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []int
|
||||
if err := ggb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IntsX is like Ints, but panics if an error occurs.
|
||||
func (ggb *GroupGroupBy) IntsX(ctx context.Context) []int {
|
||||
v, err := ggb.Ints(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Float64s returns list of float64s from group-by. It is only allowed when querying group-by with one field.
|
||||
func (ggb *GroupGroupBy) Float64s(ctx context.Context) ([]float64, error) {
|
||||
if len(ggb.fields) > 1 {
|
||||
return nil, errors.New("entv2: GroupGroupBy.Float64s is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []float64
|
||||
if err := ggb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Float64sX is like Float64s, but panics if an error occurs.
|
||||
func (ggb *GroupGroupBy) Float64sX(ctx context.Context) []float64 {
|
||||
v, err := ggb.Float64s(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Bools returns list of bools from group-by. It is only allowed when querying group-by with one field.
|
||||
func (ggb *GroupGroupBy) Bools(ctx context.Context) ([]bool, error) {
|
||||
if len(ggb.fields) > 1 {
|
||||
return nil, errors.New("entv2: GroupGroupBy.Bools is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []bool
|
||||
if err := ggb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// BoolsX is like Bools, but panics if an error occurs.
|
||||
func (ggb *GroupGroupBy) BoolsX(ctx context.Context) []bool {
|
||||
v, err := ggb.Bools(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (ggb *GroupGroupBy) sqlScan(ctx context.Context, v interface{}) error {
|
||||
rows := &sql.Rows{}
|
||||
query, args := ggb.sqlQuery().Query()
|
||||
if err := ggb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (ggb *GroupGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := ggb.sql
|
||||
columns := make([]string, 0, len(ggb.fields)+len(ggb.fns))
|
||||
columns = append(columns, ggb.fields...)
|
||||
for _, fn := range ggb.fns {
|
||||
columns = append(columns, fn.SQL(selector))
|
||||
}
|
||||
return selector.Select(columns...).GroupBy(ggb.fields...)
|
||||
}
|
||||
|
||||
func (ggb *GroupGroupBy) gremlinScan(ctx context.Context, v interface{}) error {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := ggb.gremlinQuery().Query()
|
||||
if err := ggb.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(ggb.fields)+len(ggb.fns) == 1 {
|
||||
return res.ReadVal(v)
|
||||
}
|
||||
vm, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.Decode(v)
|
||||
}
|
||||
|
||||
func (ggb *GroupGroupBy) gremlinQuery() *dsl.Traversal {
|
||||
var (
|
||||
trs []interface{}
|
||||
names []interface{}
|
||||
)
|
||||
for _, fn := range ggb.fns {
|
||||
name, tr := fn.Gremlin("p", "")
|
||||
trs = append(trs, tr)
|
||||
names = append(names, name)
|
||||
}
|
||||
for _, f := range ggb.fields {
|
||||
names = append(names, f)
|
||||
trs = append(trs, __.As("p").Unfold().Values(f).As(f))
|
||||
}
|
||||
return ggb.gremlin.Group().
|
||||
By(__.Values(ggb.fields...).Fold()).
|
||||
By(__.Fold().Match(trs...).Select(names...)).
|
||||
Select(dsl.Values).
|
||||
Next()
|
||||
}
|
||||
231
entc/integration/migrate/entv2/group_update.go
Normal file
231
entc/integration/migrate/entv2/group_update.go
Normal file
@@ -0,0 +1,231 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/group"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// GroupUpdate is the builder for updating Group entities.
|
||||
type GroupUpdate struct {
|
||||
config
|
||||
predicates []ent.Predicate
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (gu *GroupUpdate) Where(ps ...ent.Predicate) *GroupUpdate {
|
||||
gu.predicates = append(gu.predicates, ps...)
|
||||
return gu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of rows/vertices matched by this operation.
|
||||
func (gu *GroupUpdate) Save(ctx context.Context) (int, error) {
|
||||
switch gu.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return gu.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
vertices, err := gu.gremlinSave(ctx)
|
||||
return len(vertices), err
|
||||
default:
|
||||
return 0, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (gu *GroupUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := gu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (gu *GroupUpdate) Exec(ctx context.Context) error {
|
||||
_, err := gu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (gu *GroupUpdate) ExecX(ctx context.Context) {
|
||||
if err := gu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (gu *GroupUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
selector := sql.Select(group.FieldID).From(sql.Table(group.Table))
|
||||
for _, p := range gu.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = gu.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var ids []int
|
||||
for rows.Next() {
|
||||
var id int
|
||||
if err := rows.Scan(&id); err != nil {
|
||||
return 0, fmt.Errorf("entv2: failed reading id: %v", err)
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
tx, err := gu.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(ids), nil
|
||||
}
|
||||
|
||||
func (gu *GroupUpdate) gremlinSave(ctx context.Context) ([]*Group, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := gu.gremlin().Query()
|
||||
if err := gu.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
var grs Groups
|
||||
grs.config(gu.config)
|
||||
if err := grs.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return grs, nil
|
||||
}
|
||||
|
||||
func (gu *GroupUpdate) gremlin() *dsl.Traversal {
|
||||
v := g.V().HasLabel(group.Label)
|
||||
for _, p := range gu.predicates {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
var (
|
||||
trs []*dsl.Traversal
|
||||
)
|
||||
v.ValueMap(true)
|
||||
trs = append(trs, v)
|
||||
return dsl.Join(trs...)
|
||||
}
|
||||
|
||||
// GroupUpdateOne is the builder for updating a single Group entity.
|
||||
type GroupUpdateOne struct {
|
||||
config
|
||||
id string
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated entity.
|
||||
func (guo *GroupUpdateOne) Save(ctx context.Context) (*Group, error) {
|
||||
switch guo.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return guo.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
return guo.gremlinSave(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (guo *GroupUpdateOne) SaveX(ctx context.Context) *Group {
|
||||
gr, err := guo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gr
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (guo *GroupUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := guo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (guo *GroupUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := guo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (guo *GroupUpdateOne) sqlSave(ctx context.Context) (gr *Group, err error) {
|
||||
selector := sql.Select(group.Columns...).From(sql.Table(group.Table))
|
||||
group.ID(guo.id).SQL(selector)
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = guo.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var ids []int
|
||||
for rows.Next() {
|
||||
var id int
|
||||
gr = &Group{config: guo.config}
|
||||
if err := gr.FromRows(rows); err != nil {
|
||||
return nil, fmt.Errorf("entv2: failed scanning row into Group: %v", err)
|
||||
}
|
||||
id = gr.id()
|
||||
ids = append(ids, id)
|
||||
}
|
||||
switch n := len(ids); {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("entv2: Group not found with id: %v", guo.id)
|
||||
case n > 1:
|
||||
return nil, fmt.Errorf("entv2: more than one Group with the same id: %v", guo.id)
|
||||
}
|
||||
|
||||
tx, err := guo.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gr, nil
|
||||
}
|
||||
|
||||
func (guo *GroupUpdateOne) gremlinSave(ctx context.Context) (*Group, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := guo.gremlin(guo.id).Query()
|
||||
if err := guo.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
gr := &Group{config: guo.config}
|
||||
if err := gr.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gr, nil
|
||||
}
|
||||
|
||||
func (guo *GroupUpdateOne) gremlin(id string) *dsl.Traversal {
|
||||
v := g.V(id)
|
||||
var (
|
||||
trs []*dsl.Traversal
|
||||
)
|
||||
v.ValueMap(true)
|
||||
trs = append(trs, v)
|
||||
return dsl.Join(trs...)
|
||||
}
|
||||
@@ -3,31 +3,27 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql/schema"
|
||||
"fbc/ent/field"
|
||||
)
|
||||
|
||||
var (
|
||||
nullable = true
|
||||
// UsersColumns holds the columns for the "users" table.
|
||||
UsersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "age", Type: field.TypeInt},
|
||||
{Name: "name", Type: field.TypeString, Size: 2147483647},
|
||||
{Name: "phone", Type: field.TypeString},
|
||||
}
|
||||
// UsersTable holds the schema information for the "users" table.
|
||||
UsersTable = &schema.Table{
|
||||
Name: "users",
|
||||
Columns: UsersColumns,
|
||||
PrimaryKey: []*schema.Column{UsersColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
UsersTable,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 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...)
|
||||
}
|
||||
|
||||
@@ -3,39 +3,55 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql/schema"
|
||||
"fbc/ent/field"
|
||||
)
|
||||
|
||||
// SQLDialect wraps the dialect.Driver with additional migration methods.
|
||||
type SQLDriver interface {
|
||||
Create(context.Context, ...*schema.Table) error
|
||||
}
|
||||
|
||||
// Schema is the API for creating, migrating and dropping a schema.
|
||||
type Schema struct {
|
||||
drv SQLDriver
|
||||
}
|
||||
|
||||
// NewSchema creates a new schema client.
|
||||
func NewSchema(drv dialect.Driver) *Schema {
|
||||
s := &Schema{}
|
||||
switch drv.Dialect() {
|
||||
case dialect.MySQL:
|
||||
s.drv = &schema.MySQL{Driver: drv}
|
||||
case dialect.SQLite:
|
||||
s.drv = &schema.SQLite{Driver: drv}
|
||||
var (
|
||||
nullable = true
|
||||
// GroupsColumns holds the columns for the "groups" table.
|
||||
GroupsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Create creates all schema resources.
|
||||
func (s *Schema) Create(ctx context.Context) error {
|
||||
if s.drv == nil {
|
||||
return fmt.Errorf("entv2/migrate: dialect does not support migration")
|
||||
// GroupsTable holds the schema information for the "groups" table.
|
||||
GroupsTable = &schema.Table{
|
||||
Name: "groups",
|
||||
Columns: GroupsColumns,
|
||||
PrimaryKey: []*schema.Column{GroupsColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
return s.drv.Create(ctx, Tables...)
|
||||
// PetsColumns holds the columns for the "pets" table.
|
||||
PetsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: 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{},
|
||||
}
|
||||
// UsersColumns holds the columns for the "users" table.
|
||||
UsersColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||
{Name: "age", Type: field.TypeInt},
|
||||
{Name: "name", Type: field.TypeString, Size: 2147483647},
|
||||
{Name: "phone", Type: field.TypeString},
|
||||
}
|
||||
// UsersTable holds the schema information for the "users" table.
|
||||
UsersTable = &schema.Table{
|
||||
Name: "users",
|
||||
Columns: UsersColumns,
|
||||
PrimaryKey: []*schema.Column{UsersColumns[0]},
|
||||
ForeignKeys: []*schema.ForeignKey{},
|
||||
}
|
||||
// Tables holds all the tables in the schema.
|
||||
Tables = []*schema.Table{
|
||||
GroupsTable,
|
||||
PetsTable,
|
||||
UsersTable,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
}
|
||||
|
||||
125
entc/integration/migrate/entv2/pet.go
Normal file
125
entc/integration/migrate/entv2/pet.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
)
|
||||
|
||||
// Pet is the model entity for the Pet schema.
|
||||
type Pet struct {
|
||||
config
|
||||
// ID of the ent.
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// FromResponse scans the gremlin response data into Pet.
|
||||
func (pe *Pet) FromResponse(res *gremlin.Response) error {
|
||||
vmap, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var vpe struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
if err := vmap.Decode(&vpe); err != nil {
|
||||
return err
|
||||
}
|
||||
pe.ID = vpe.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into Pet.
|
||||
func (pe *Pet) FromRows(rows *sql.Rows) error {
|
||||
var vpe struct {
|
||||
ID int
|
||||
}
|
||||
// the order here should be the same as in the `pet.Columns`.
|
||||
if err := rows.Scan(
|
||||
&vpe.ID,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
pe.ID = strconv.Itoa(vpe.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (pe *Pet) Update() *PetUpdateOne {
|
||||
return (&PetClient{pe.config}).UpdateOne(pe)
|
||||
}
|
||||
|
||||
// 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 (pe *Pet) Unwrap() *Pet {
|
||||
tx, ok := pe.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("entv2: Pet is not a transactional entity")
|
||||
}
|
||||
pe.config.driver = tx.drv
|
||||
return pe
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (pe *Pet) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("Pet(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v", pe.ID))
|
||||
buf.WriteString(")")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// id returns the int representation of the ID field.
|
||||
func (pe *Pet) id() int {
|
||||
id, _ := strconv.Atoi(pe.ID)
|
||||
return id
|
||||
}
|
||||
|
||||
// Pets is a parsable slice of Pet.
|
||||
type Pets []*Pet
|
||||
|
||||
// FromResponse scans the gremlin response data into Pets.
|
||||
func (pe *Pets) FromResponse(res *gremlin.Response) error {
|
||||
vmap, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var vpe []struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
if err := vmap.Decode(&vpe); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range vpe {
|
||||
*pe = append(*pe, &Pet{
|
||||
ID: v.ID,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromRows scans the sql response data into Pets.
|
||||
func (pe *Pets) FromRows(rows *sql.Rows) error {
|
||||
for rows.Next() {
|
||||
vpe := &Pet{}
|
||||
if err := vpe.FromRows(rows); err != nil {
|
||||
return err
|
||||
}
|
||||
*pe = append(*pe, vpe)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pe Pets) config(cfg config) {
|
||||
for i := range pe {
|
||||
pe[i].config = cfg
|
||||
}
|
||||
}
|
||||
17
entc/integration/migrate/entv2/pet/pet.go
Normal file
17
entc/integration/migrate/entv2/pet/pet.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package pet
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the pet type in the database.
|
||||
Label = "pet"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// Table holds the table name of the pet in the database.
|
||||
Table = "pets"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns are pet fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
}
|
||||
156
entc/integration/migrate/entv2/pet/where.go
Normal file
156
entc/integration/migrate/entv2/pet/where.go
Normal file
@@ -0,0 +1,156 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package pet
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/p"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their identifier.
|
||||
func ID(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
id, _ := strconv.Atoi(id)
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(id)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.EQ(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.EQ(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.NEQ(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.NEQ(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.GT(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.GT(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.GTE(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.GTE(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.LT(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.LT(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
v, _ := strconv.Atoi(id)
|
||||
s.Where(sql.LTE(s.C(FieldID), v))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
t.HasID(p.LTE(id))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
// if not arguments were provided, append the FALSE constants,
|
||||
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||
if len(ids) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i], _ = strconv.Atoi(ids[i])
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
t.HasID(p.Within(v...))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...string) ent.Predicate {
|
||||
return ent.Predicate{
|
||||
SQL: func(s *sql.Selector) {
|
||||
// if not arguments were provided, append the FALSE constants,
|
||||
// since we can't apply "IN ()". This will make this predicate falsy.
|
||||
if len(ids) == 0 {
|
||||
s.Where(sql.False())
|
||||
return
|
||||
}
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i], _ = strconv.Atoi(ids[i])
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
},
|
||||
Gremlin: func(t *dsl.Traversal) {
|
||||
v := make([]interface{}, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
t.HasID(p.Without(v...))
|
||||
},
|
||||
}
|
||||
}
|
||||
90
entc/integration/migrate/entv2/pet_create.go
Normal file
90
entc/integration/migrate/entv2/pet_create.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/pet"
|
||||
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// PetCreate is the builder for creating a Pet entity.
|
||||
type PetCreate struct {
|
||||
config
|
||||
}
|
||||
|
||||
// Save creates the Pet in the database.
|
||||
func (pc *PetCreate) Save(ctx context.Context) (*Pet, error) {
|
||||
switch pc.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pc.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
return pc.gremlinSave(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (pc *PetCreate) SaveX(ctx context.Context) *Pet {
|
||||
v, err := pc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (pc *PetCreate) sqlSave(ctx context.Context) (*Pet, error) {
|
||||
var (
|
||||
res sql.Result
|
||||
pe = &Pet{config: pc.config}
|
||||
)
|
||||
tx, err := pc.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := sql.Insert(pet.Table).Default(pc.driver.Dialect())
|
||||
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)
|
||||
}
|
||||
pe.ID = strconv.FormatInt(id, 10)
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pe, nil
|
||||
}
|
||||
|
||||
func (pc *PetCreate) gremlinSave(ctx context.Context) (*Pet, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pc.gremlin().Query()
|
||||
if err := pc.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
pe := &Pet{config: pc.config}
|
||||
if err := pe.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pe, nil
|
||||
}
|
||||
|
||||
func (pc *PetCreate) gremlin() *dsl.Traversal {
|
||||
v := g.AddV(pet.Label)
|
||||
return v.ValueMap(true)
|
||||
}
|
||||
88
entc/integration/migrate/entv2/pet_delete.go
Normal file
88
entc/integration/migrate/entv2/pet_delete.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/pet"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// PetDelete is the builder for deleting a Pet entity.
|
||||
type PetDelete struct {
|
||||
config
|
||||
predicates []ent.Predicate
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (pd *PetDelete) Where(ps ...ent.Predicate) *PetDelete {
|
||||
pd.predicates = append(pd.predicates, ps...)
|
||||
return pd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (pd *PetDelete) Exec(ctx context.Context) error {
|
||||
switch pd.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pd.sqlExec(ctx)
|
||||
case dialect.Neptune:
|
||||
return pd.gremlinExec(ctx)
|
||||
default:
|
||||
return errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (pd *PetDelete) ExecX(ctx context.Context) {
|
||||
if err := pd.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (pd *PetDelete) sqlExec(ctx context.Context) error {
|
||||
var res sql.Result
|
||||
selector := sql.Select().From(sql.Table(pet.Table))
|
||||
for _, p := range pd.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
query, args := sql.Delete(pet.Table).FromSelect(selector).Query()
|
||||
return pd.driver.Exec(ctx, query, args, &res)
|
||||
}
|
||||
|
||||
func (pd *PetDelete) gremlinExec(ctx context.Context) error {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pd.gremlin().Query()
|
||||
return pd.driver.Exec(ctx, query, bindings, res)
|
||||
}
|
||||
|
||||
func (pd *PetDelete) gremlin() *dsl.Traversal {
|
||||
t := g.V().HasLabel(pet.Label)
|
||||
for _, p := range pd.predicates {
|
||||
p.Gremlin(t)
|
||||
}
|
||||
return t.Drop()
|
||||
}
|
||||
|
||||
// PetDeleteOne is the builder for deleting a single Pet entity.
|
||||
type PetDeleteOne struct {
|
||||
pd *PetDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (pdo *PetDeleteOne) Exec(ctx context.Context) error {
|
||||
return pdo.pd.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (pdo *PetDeleteOne) ExecX(ctx context.Context) {
|
||||
pdo.pd.ExecX(ctx)
|
||||
}
|
||||
603
entc/integration/migrate/entv2/pet_query.go
Normal file
603
entc/integration/migrate/entv2/pet_query.go
Normal file
@@ -0,0 +1,603 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/pet"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/__"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// PetQuery is the builder for querying Pet entities.
|
||||
type PetQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
order []Order
|
||||
unique []string
|
||||
predicates []ent.Predicate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
gremlin *dsl.Traversal
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (pq *PetQuery) Where(ps ...ent.Predicate) *PetQuery {
|
||||
pq.predicates = append(pq.predicates, ps...)
|
||||
return pq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (pq *PetQuery) Limit(limit int) *PetQuery {
|
||||
pq.limit = &limit
|
||||
return pq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (pq *PetQuery) Offset(offset int) *PetQuery {
|
||||
pq.offset = &offset
|
||||
return pq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (pq *PetQuery) Order(o ...Order) *PetQuery {
|
||||
pq.order = append(pq.order, o...)
|
||||
return pq
|
||||
}
|
||||
|
||||
// Get returns a Pet entity by its id.
|
||||
func (pq *PetQuery) Get(ctx context.Context, id string) (*Pet, error) {
|
||||
return pq.Where(pet.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (pq *PetQuery) GetX(ctx context.Context, id string) *Pet {
|
||||
pe, err := pq.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pe
|
||||
}
|
||||
|
||||
// First returns the first Pet entity in the query. Returns *ErrNotFound when no pet was found.
|
||||
func (pq *PetQuery) First(ctx context.Context) (*Pet, error) {
|
||||
pes, err := pq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(pes) == 0 {
|
||||
return nil, &ErrNotFound{pet.Label}
|
||||
}
|
||||
return pes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (pq *PetQuery) FirstX(ctx context.Context) *Pet {
|
||||
pe, err := pq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return pe
|
||||
}
|
||||
|
||||
// FirstID returns the first Pet id in the query. Returns *ErrNotFound when no id was found.
|
||||
func (pq *PetQuery) FirstID(ctx context.Context) (id string, err error) {
|
||||
var ids []string
|
||||
if ids, err = pq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &ErrNotFound{pet.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstXID is like FirstID, but panics if an error occurs.
|
||||
func (pq *PetQuery) FirstXID(ctx context.Context) string {
|
||||
id, err := pq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns the only Pet entity in the query, returns an error if not exactly one entity was returned.
|
||||
func (pq *PetQuery) Only(ctx context.Context) (*Pet, error) {
|
||||
pes, err := pq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(pes) {
|
||||
case 1:
|
||||
return pes[0], nil
|
||||
case 0:
|
||||
return nil, &ErrNotFound{pet.Label}
|
||||
default:
|
||||
return nil, &ErrNotSingular{pet.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (pq *PetQuery) OnlyX(ctx context.Context) *Pet {
|
||||
pe, err := pq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pe
|
||||
}
|
||||
|
||||
// OnlyID returns the only Pet id in the query, returns an error if not exactly one id was returned.
|
||||
func (pq *PetQuery) OnlyID(ctx context.Context) (id string, err error) {
|
||||
var ids []string
|
||||
if ids, err = pq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &ErrNotFound{pet.Label}
|
||||
default:
|
||||
err = &ErrNotSingular{pet.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyXID is like OnlyID, but panics if an error occurs.
|
||||
func (pq *PetQuery) OnlyXID(ctx context.Context) string {
|
||||
id, err := pq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of Pets.
|
||||
func (pq *PetQuery) All(ctx context.Context) ([]*Pet, error) {
|
||||
switch pq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pq.sqlAll(ctx)
|
||||
case dialect.Neptune:
|
||||
return pq.gremlinAll(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (pq *PetQuery) AllX(ctx context.Context) []*Pet {
|
||||
pes, err := pq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of Pet ids.
|
||||
func (pq *PetQuery) IDs(ctx context.Context) ([]string, error) {
|
||||
switch pq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pq.sqlIDs(ctx)
|
||||
case dialect.Neptune:
|
||||
return pq.gremlinIDs(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (pq *PetQuery) IDsX(ctx context.Context) []string {
|
||||
ids, err := pq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (pq *PetQuery) Count(ctx context.Context) (int, error) {
|
||||
switch pq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pq.sqlCount(ctx)
|
||||
case dialect.Neptune:
|
||||
return pq.gremlinCount(ctx)
|
||||
default:
|
||||
return 0, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (pq *PetQuery) CountX(ctx context.Context) int {
|
||||
count, err := pq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (pq *PetQuery) Exist(ctx context.Context) (bool, error) {
|
||||
switch pq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pq.sqlExist(ctx)
|
||||
case dialect.Neptune:
|
||||
return pq.gremlinExist(ctx)
|
||||
default:
|
||||
return false, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (pq *PetQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := pq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// 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 {
|
||||
group := &PetGroupBy{config: pq.config}
|
||||
group.fields = append([]string{field}, fields...)
|
||||
switch pq.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
group.sql = pq.sqlQuery()
|
||||
case dialect.Neptune:
|
||||
group.gremlin = pq.gremlinQuery()
|
||||
}
|
||||
return group
|
||||
}
|
||||
|
||||
func (pq *PetQuery) sqlAll(ctx context.Context) ([]*Pet, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := pq.sqlQuery()
|
||||
if unique := pq.unique; len(unique) == 0 {
|
||||
selector.Distinct()
|
||||
}
|
||||
query, args := selector.Query()
|
||||
if err := pq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var pes Pets
|
||||
if err := pes.FromRows(rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pes.config(pq.config)
|
||||
return pes, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
rows := &sql.Rows{}
|
||||
selector := pq.sqlQuery()
|
||||
unique := []string{pet.FieldID}
|
||||
if len(pq.unique) > 0 {
|
||||
unique = pq.unique
|
||||
}
|
||||
selector.Count(sql.Distinct(selector.Columns(unique...)...))
|
||||
query, args := selector.Query()
|
||||
if err := pq.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
return 0, errors.New("entv2: no rows found")
|
||||
}
|
||||
var n int
|
||||
if err := rows.Scan(&n); err != nil {
|
||||
return 0, fmt.Errorf("entv2: failed reading count: %v", err)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
n, err := pq.sqlCount(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("entv2: check existence: %v", err)
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) sqlIDs(ctx context.Context) ([]string, error) {
|
||||
vs, err := pq.sqlAll(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ids []string
|
||||
for _, v := range vs {
|
||||
ids = append(ids, v.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) sqlQuery() *sql.Selector {
|
||||
t1 := sql.Table(pet.Table)
|
||||
selector := sql.Select(t1.Columns(pet.Columns...)...).From(t1)
|
||||
if pq.sql != nil {
|
||||
selector = pq.sql
|
||||
selector.Select(selector.Columns(pet.Columns...)...)
|
||||
}
|
||||
for _, p := range pq.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
for _, p := range pq.order {
|
||||
p.SQL(selector)
|
||||
}
|
||||
if offset := pq.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 := pq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
func (pq *PetQuery) gremlinIDs(ctx context.Context) ([]string, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pq.gremlinQuery().Query()
|
||||
if err := pq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vertices, err := res.ReadVertices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]string, 0, len(vertices))
|
||||
for _, vertex := range vertices {
|
||||
ids = append(ids, vertex.ID.(string))
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) gremlinAll(ctx context.Context) ([]*Pet, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pq.gremlinQuery().ValueMap(true).Query()
|
||||
if err := pq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pes Pets
|
||||
if err := pes.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pes.config(pq.config)
|
||||
return pes, nil
|
||||
}
|
||||
|
||||
func (pq *PetQuery) gremlinCount(ctx context.Context) (int, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pq.gremlinQuery().Count().Query()
|
||||
if err := pq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res.ReadInt()
|
||||
}
|
||||
|
||||
func (pq *PetQuery) gremlinExist(ctx context.Context) (bool, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pq.gremlinQuery().HasNext().Query()
|
||||
if err := pq.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return res.ReadBool()
|
||||
}
|
||||
|
||||
func (pq *PetQuery) gremlinQuery() *dsl.Traversal {
|
||||
v := g.V().HasLabel(pet.Label)
|
||||
if pq.gremlin != nil {
|
||||
v = pq.gremlin.Clone()
|
||||
}
|
||||
for _, p := range pq.predicates {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
if len(pq.order) > 0 {
|
||||
v.Order()
|
||||
for _, p := range pq.order {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
}
|
||||
switch limit, offset := pq.limit, pq.offset; {
|
||||
case limit != nil && offset != nil:
|
||||
v.Range(*offset, *offset+*limit)
|
||||
case offset != nil:
|
||||
v.Range(*offset, math.MaxInt64)
|
||||
case limit != nil:
|
||||
v.Limit(*limit)
|
||||
}
|
||||
if unique := pq.unique; len(unique) == 0 {
|
||||
v.Dedup()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// PetQuery is the builder for group-by Pet entities.
|
||||
type PetGroupBy struct {
|
||||
config
|
||||
fields []string
|
||||
fns []Aggregate
|
||||
// intermediate queries.
|
||||
sql *sql.Selector
|
||||
gremlin *dsl.Traversal
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (pgb *PetGroupBy) Aggregate(fns ...Aggregate) *PetGroupBy {
|
||||
pgb.fns = append(pgb.fns, fns...)
|
||||
return pgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scan the result into the given value.
|
||||
func (pgb *PetGroupBy) Scan(ctx context.Context, v interface{}) error {
|
||||
switch pgb.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pgb.sqlScan(ctx, v)
|
||||
case dialect.Neptune:
|
||||
return pgb.gremlinScan(ctx, v)
|
||||
default:
|
||||
return errors.New("pgb: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// ScanX is like Scan, but panics if an error occurs.
|
||||
func (pgb *PetGroupBy) ScanX(ctx context.Context, v interface{}) {
|
||||
if err := pgb.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 (pgb *PetGroupBy) Strings(ctx context.Context) ([]string, error) {
|
||||
if len(pgb.fields) > 1 {
|
||||
return nil, errors.New("entv2: PetGroupBy.Strings is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []string
|
||||
if err := pgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// StringsX is like Strings, but panics if an error occurs.
|
||||
func (pgb *PetGroupBy) StringsX(ctx context.Context) []string {
|
||||
v, err := pgb.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 (pgb *PetGroupBy) Ints(ctx context.Context) ([]int, error) {
|
||||
if len(pgb.fields) > 1 {
|
||||
return nil, errors.New("entv2: PetGroupBy.Ints is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []int
|
||||
if err := pgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IntsX is like Ints, but panics if an error occurs.
|
||||
func (pgb *PetGroupBy) IntsX(ctx context.Context) []int {
|
||||
v, err := pgb.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 (pgb *PetGroupBy) Float64s(ctx context.Context) ([]float64, error) {
|
||||
if len(pgb.fields) > 1 {
|
||||
return nil, errors.New("entv2: PetGroupBy.Float64s is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []float64
|
||||
if err := pgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Float64sX is like Float64s, but panics if an error occurs.
|
||||
func (pgb *PetGroupBy) Float64sX(ctx context.Context) []float64 {
|
||||
v, err := pgb.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 (pgb *PetGroupBy) Bools(ctx context.Context) ([]bool, error) {
|
||||
if len(pgb.fields) > 1 {
|
||||
return nil, errors.New("entv2: PetGroupBy.Bools is not achievable when grouping more than 1 field")
|
||||
}
|
||||
var v []bool
|
||||
if err := pgb.Scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// BoolsX is like Bools, but panics if an error occurs.
|
||||
func (pgb *PetGroupBy) BoolsX(ctx context.Context) []bool {
|
||||
v, err := pgb.Bools(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (pgb *PetGroupBy) sqlScan(ctx context.Context, v interface{}) error {
|
||||
rows := &sql.Rows{}
|
||||
query, args := pgb.sqlQuery().Query()
|
||||
if err := pgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (pgb *PetGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := pgb.sql
|
||||
columns := make([]string, 0, len(pgb.fields)+len(pgb.fns))
|
||||
columns = append(columns, pgb.fields...)
|
||||
for _, fn := range pgb.fns {
|
||||
columns = append(columns, fn.SQL(selector))
|
||||
}
|
||||
return selector.Select(columns...).GroupBy(pgb.fields...)
|
||||
}
|
||||
|
||||
func (pgb *PetGroupBy) gremlinScan(ctx context.Context, v interface{}) error {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pgb.gremlinQuery().Query()
|
||||
if err := pgb.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(pgb.fields)+len(pgb.fns) == 1 {
|
||||
return res.ReadVal(v)
|
||||
}
|
||||
vm, err := res.ReadValueMap()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return vm.Decode(v)
|
||||
}
|
||||
|
||||
func (pgb *PetGroupBy) gremlinQuery() *dsl.Traversal {
|
||||
var (
|
||||
trs []interface{}
|
||||
names []interface{}
|
||||
)
|
||||
for _, fn := range pgb.fns {
|
||||
name, tr := fn.Gremlin("p", "")
|
||||
trs = append(trs, tr)
|
||||
names = append(names, name)
|
||||
}
|
||||
for _, f := range pgb.fields {
|
||||
names = append(names, f)
|
||||
trs = append(trs, __.As("p").Unfold().Values(f).As(f))
|
||||
}
|
||||
return pgb.gremlin.Group().
|
||||
By(__.Values(pgb.fields...).Fold()).
|
||||
By(__.Fold().Match(trs...).Select(names...)).
|
||||
Select(dsl.Values).
|
||||
Next()
|
||||
}
|
||||
231
entc/integration/migrate/entv2/pet_update.go
Normal file
231
entc/integration/migrate/entv2/pet_update.go
Normal file
@@ -0,0 +1,231 @@
|
||||
// Code generated (@generated) by entc, DO NOT EDIT.
|
||||
|
||||
package entv2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"fbc/ent/entc/integration/migrate/entv2/pet"
|
||||
|
||||
"fbc/ent"
|
||||
"fbc/ent/dialect"
|
||||
"fbc/ent/dialect/sql"
|
||||
|
||||
"fbc/lib/go/gremlin"
|
||||
"fbc/lib/go/gremlin/graph/dsl"
|
||||
"fbc/lib/go/gremlin/graph/dsl/g"
|
||||
)
|
||||
|
||||
// PetUpdate is the builder for updating Pet entities.
|
||||
type PetUpdate struct {
|
||||
config
|
||||
predicates []ent.Predicate
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the builder.
|
||||
func (pu *PetUpdate) Where(ps ...ent.Predicate) *PetUpdate {
|
||||
pu.predicates = append(pu.predicates, ps...)
|
||||
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) {
|
||||
switch pu.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return pu.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
vertices, err := pu.gremlinSave(ctx)
|
||||
return len(vertices), err
|
||||
default:
|
||||
return 0, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (pu *PetUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := pu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (pu *PetUpdate) Exec(ctx context.Context) error {
|
||||
_, err := pu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (pu *PetUpdate) ExecX(ctx context.Context) {
|
||||
if err := pu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (pu *PetUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
selector := sql.Select(pet.FieldID).From(sql.Table(pet.Table))
|
||||
for _, p := range pu.predicates {
|
||||
p.SQL(selector)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = pu.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("entv2: failed reading id: %v", err)
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
tx, err := pu.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(ids), nil
|
||||
}
|
||||
|
||||
func (pu *PetUpdate) gremlinSave(ctx context.Context) ([]*Pet, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := pu.gremlin().Query()
|
||||
if err := pu.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
var pes Pets
|
||||
pes.config(pu.config)
|
||||
if err := pes.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pes, nil
|
||||
}
|
||||
|
||||
func (pu *PetUpdate) gremlin() *dsl.Traversal {
|
||||
v := g.V().HasLabel(pet.Label)
|
||||
for _, p := range pu.predicates {
|
||||
p.Gremlin(v)
|
||||
}
|
||||
var (
|
||||
trs []*dsl.Traversal
|
||||
)
|
||||
v.ValueMap(true)
|
||||
trs = append(trs, v)
|
||||
return dsl.Join(trs...)
|
||||
}
|
||||
|
||||
// PetUpdateOne is the builder for updating a single Pet entity.
|
||||
type PetUpdateOne struct {
|
||||
config
|
||||
id string
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated entity.
|
||||
func (puo *PetUpdateOne) Save(ctx context.Context) (*Pet, error) {
|
||||
switch puo.driver.Dialect() {
|
||||
case dialect.MySQL, dialect.SQLite:
|
||||
return puo.sqlSave(ctx)
|
||||
case dialect.Neptune:
|
||||
return puo.gremlinSave(ctx)
|
||||
default:
|
||||
return nil, errors.New("entv2: unsupported dialect")
|
||||
}
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (puo *PetUpdateOne) SaveX(ctx context.Context) *Pet {
|
||||
pe, err := puo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return pe
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (puo *PetUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := puo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (puo *PetUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := puo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (puo *PetUpdateOne) sqlSave(ctx context.Context) (pe *Pet, err error) {
|
||||
selector := sql.Select(pet.Columns...).From(sql.Table(pet.Table))
|
||||
pet.ID(puo.id).SQL(selector)
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err = puo.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var ids []int
|
||||
for rows.Next() {
|
||||
var id int
|
||||
pe = &Pet{config: puo.config}
|
||||
if err := pe.FromRows(rows); err != nil {
|
||||
return nil, fmt.Errorf("entv2: failed scanning row into Pet: %v", err)
|
||||
}
|
||||
id = pe.id()
|
||||
ids = append(ids, id)
|
||||
}
|
||||
switch n := len(ids); {
|
||||
case n == 0:
|
||||
return nil, fmt.Errorf("entv2: Pet not found with id: %v", puo.id)
|
||||
case n > 1:
|
||||
return nil, fmt.Errorf("entv2: more than one Pet with the same id: %v", puo.id)
|
||||
}
|
||||
|
||||
tx, err := puo.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pe, nil
|
||||
}
|
||||
|
||||
func (puo *PetUpdateOne) gremlinSave(ctx context.Context) (*Pet, error) {
|
||||
res := &gremlin.Response{}
|
||||
query, bindings := puo.gremlin(puo.id).Query()
|
||||
if err := puo.driver.Exec(ctx, query, bindings, res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err, ok := isConstantError(res); ok {
|
||||
return nil, err
|
||||
}
|
||||
pe := &Pet{config: puo.config}
|
||||
if err := pe.FromResponse(res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return pe, nil
|
||||
}
|
||||
|
||||
func (puo *PetUpdateOne) gremlin(id string) *dsl.Traversal {
|
||||
v := g.V(id)
|
||||
var (
|
||||
trs []*dsl.Traversal
|
||||
)
|
||||
v.ValueMap(true)
|
||||
trs = append(trs, v)
|
||||
return dsl.Join(trs...)
|
||||
}
|
||||
@@ -22,3 +22,11 @@ func (User) Fields() []ent.Field {
|
||||
// deleting the address column.
|
||||
}
|
||||
}
|
||||
|
||||
// Additional types to be added to the schema.
|
||||
type (
|
||||
// Pet schema.
|
||||
Pet struct{ ent.Schema }
|
||||
// Group schema.
|
||||
Group struct{ ent.Schema }
|
||||
)
|
||||
|
||||
@@ -13,6 +13,10 @@ import (
|
||||
// Tx is a transactional client that is created by calling Client.Tx().
|
||||
type Tx struct {
|
||||
config
|
||||
// Group is the client for interacting with the Group builders.
|
||||
Group *GroupClient
|
||||
// Pet is the client for interacting with the Pet builders.
|
||||
Pet *PetClient
|
||||
// User is the client for interacting with the User builders.
|
||||
User *UserClient
|
||||
}
|
||||
@@ -32,6 +36,8 @@ func (tx *Tx) Client() *Client {
|
||||
return &Client{
|
||||
config: tx.config,
|
||||
Schema: migrate.NewSchema(tx.driver),
|
||||
Group: NewGroupClient(tx.config),
|
||||
Pet: NewPetClient(tx.config),
|
||||
User: NewUserClient(tx.config),
|
||||
}
|
||||
}
|
||||
@@ -43,7 +49,7 @@ func (tx *Tx) Client() *Client {
|
||||
// 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: User.QueryXXX(), the query will be executed
|
||||
// applies a query, for example: Group.QueryXXX(), the query will be executed
|
||||
// through the driver which created this transaction.
|
||||
//
|
||||
// Note that this driver is safe for concurrent usage, however, it executes only one query
|
||||
|
||||
@@ -93,8 +93,8 @@ func (u *User) Unwrap() *User {
|
||||
func (u *User) String() string {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
buf.WriteString("User(")
|
||||
buf.WriteString(fmt.Sprintf("id=%v,", u.ID))
|
||||
buf.WriteString(fmt.Sprintf("age=%v", u.Age))
|
||||
buf.WriteString(fmt.Sprintf("id=%v", u.ID))
|
||||
buf.WriteString(fmt.Sprintf(", age=%v", u.Age))
|
||||
buf.WriteString(fmt.Sprintf(", name=%v", u.Name))
|
||||
buf.WriteString(fmt.Sprintf(", phone=%v", u.Phone))
|
||||
buf.WriteString(")")
|
||||
|
||||
@@ -2,9 +2,11 @@ package migrate
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"fbc/ent/dialect/sql"
|
||||
"fbc/ent/dialect/sql/schema"
|
||||
"fbc/ent/entc/integration/migrate/entv1"
|
||||
"fbc/ent/entc/integration/migrate/entv2"
|
||||
|
||||
@@ -27,13 +29,34 @@ func TestMySQL(t *testing.T) {
|
||||
|
||||
// run migration and execute queries on v1.
|
||||
clientv1 := entv1.NewClient(entv1.Driver(drv))
|
||||
require.NoError(t, clientv1.Schema.Create(ctx))
|
||||
require.NoError(t, clientv1.Schema.Create(ctx, schema.WithGlobalUniqueID(true)))
|
||||
SanityV1(t, clientv1)
|
||||
|
||||
// run migration and execute queries on v2.
|
||||
clientv2 := entv2.NewClient(entv2.Driver(drv))
|
||||
require.NoError(t, clientv2.Schema.Create(ctx))
|
||||
require.NoError(t, clientv2.Schema.Create(ctx, schema.WithGlobalUniqueID(true)))
|
||||
SanityV2(t, clientv2)
|
||||
|
||||
// since "users" created in the migration of v1, it will occupy the range of 0 ... 1<<32-1,
|
||||
// even though they are ordered differently in the migration of v2 (groups, pets, users).
|
||||
idRange(t, clientv2.User.Create().SetAge(1).SetName("foo").SetPhone("100").SaveX(ctx).ID, 0, 1<<32)
|
||||
idRange(t, clientv2.Group.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
|
||||
idRange(t, clientv2.Pet.Create().SaveX(ctx).ID, 2<<32-1, 3<<32)
|
||||
}
|
||||
|
||||
func TestSQLite(t *testing.T) {
|
||||
drv, err := sql.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
|
||||
require.NoError(t, err)
|
||||
defer drv.Close()
|
||||
|
||||
ctx := context.Background()
|
||||
client := entv2.NewClient(entv2.Driver(drv))
|
||||
require.NoError(t, client.Schema.Create(ctx, schema.WithGlobalUniqueID(true)))
|
||||
|
||||
SanityV2(t, client)
|
||||
idRange(t, client.Group.Create().SaveX(ctx).ID, 0, 1<<32)
|
||||
idRange(t, client.Pet.Create().SaveX(ctx).ID, 1<<32-1, 2<<32)
|
||||
idRange(t, client.User.Create().SetAge(1).SetName("x").SetPhone("y").SaveX(ctx).ID, 2<<32, 3<<32-1)
|
||||
}
|
||||
|
||||
func SanityV1(t *testing.T, client *entv1.Client) {
|
||||
@@ -55,3 +78,9 @@ func SanityV2(t *testing.T, client *entv2.Client) {
|
||||
_, err := client.User.Create().SetAge(1).SetName("foobarbazqux").SetPhone("100").Save(ctx)
|
||||
require.NoError(t, err, "name is not limited to 10 chars")
|
||||
}
|
||||
|
||||
func idRange(t *testing.T, s string, l, h int) {
|
||||
id, err := strconv.Atoi(s)
|
||||
require.NoError(t, err)
|
||||
require.Truef(t, id > l && id < h, "id %s should be between %d to %d", s, l, h)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user