// Copyright 2019-present Facebook Inc. All rights reserved. // This source code is licensed under the Apache 2.0 license found // in the LICENSE file in the root directory of this source tree. // Code generated by entc, DO NOT EDIT. package ent import ( "context" "math" "entgo.io/ent/dialect/gremlin" "entgo.io/ent/dialect/gremlin/graph/dsl" "entgo.io/ent/dialect/gremlin/graph/dsl/__" "entgo.io/ent/dialect/gremlin/graph/dsl/g" "entgo.io/ent/entc/integration/gremlin/ent/item" "entgo.io/ent/entc/integration/gremlin/ent/predicate" ) // ItemQuery is the builder for querying Item entities. type ItemQuery struct { config limit *int offset *int unique *bool order []OrderFunc fields []string predicates []predicate.Item // intermediate query (i.e. traversal path). gremlin *dsl.Traversal path func(context.Context) (*dsl.Traversal, error) } // Where adds a new predicate for the ItemQuery builder. func (iq *ItemQuery) Where(ps ...predicate.Item) *ItemQuery { iq.predicates = append(iq.predicates, ps...) return iq } // Limit adds a limit step to the query. func (iq *ItemQuery) Limit(limit int) *ItemQuery { iq.limit = &limit return iq } // Offset adds an offset step to the query. func (iq *ItemQuery) Offset(offset int) *ItemQuery { iq.offset = &offset return iq } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. func (iq *ItemQuery) Unique(unique bool) *ItemQuery { iq.unique = &unique return iq } // Order adds an order step to the query. func (iq *ItemQuery) Order(o ...OrderFunc) *ItemQuery { iq.order = append(iq.order, o...) return iq } // First returns the first Item entity from the query. // Returns a *NotFoundError when no Item was found. func (iq *ItemQuery) First(ctx context.Context) (*Item, error) { nodes, err := iq.Limit(1).All(ctx) if err != nil { return nil, err } if len(nodes) == 0 { return nil, &NotFoundError{item.Label} } return nodes[0], nil } // FirstX is like First, but panics if an error occurs. func (iq *ItemQuery) FirstX(ctx context.Context) *Item { node, err := iq.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } return node } // FirstID returns the first Item ID from the query. // Returns a *NotFoundError when no Item ID was found. func (iq *ItemQuery) FirstID(ctx context.Context) (id string, err error) { var ids []string if ids, err = iq.Limit(1).IDs(ctx); err != nil { return } if len(ids) == 0 { err = &NotFoundError{item.Label} return } return ids[0], nil } // FirstIDX is like FirstID, but panics if an error occurs. func (iq *ItemQuery) FirstIDX(ctx context.Context) string { id, err := iq.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } return id } // Only returns a single Item entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when more than one Item entity is found. // Returns a *NotFoundError when no Item entities are found. func (iq *ItemQuery) Only(ctx context.Context) (*Item, error) { nodes, err := iq.Limit(2).All(ctx) if err != nil { return nil, err } switch len(nodes) { case 1: return nodes[0], nil case 0: return nil, &NotFoundError{item.Label} default: return nil, &NotSingularError{item.Label} } } // OnlyX is like Only, but panics if an error occurs. func (iq *ItemQuery) OnlyX(ctx context.Context) *Item { node, err := iq.Only(ctx) if err != nil { panic(err) } return node } // OnlyID is like Only, but returns the only Item ID in the query. // Returns a *NotSingularError when more than one Item ID is found. // Returns a *NotFoundError when no entities are found. func (iq *ItemQuery) OnlyID(ctx context.Context) (id string, err error) { var ids []string if ids, err = iq.Limit(2).IDs(ctx); err != nil { return } switch len(ids) { case 1: id = ids[0] case 0: err = &NotFoundError{item.Label} default: err = &NotSingularError{item.Label} } return } // OnlyIDX is like OnlyID, but panics if an error occurs. func (iq *ItemQuery) OnlyIDX(ctx context.Context) string { id, err := iq.OnlyID(ctx) if err != nil { panic(err) } return id } // All executes the query and returns a list of Items. func (iq *ItemQuery) All(ctx context.Context) ([]*Item, error) { if err := iq.prepareQuery(ctx); err != nil { return nil, err } return iq.gremlinAll(ctx) } // AllX is like All, but panics if an error occurs. func (iq *ItemQuery) AllX(ctx context.Context) []*Item { nodes, err := iq.All(ctx) if err != nil { panic(err) } return nodes } // IDs executes the query and returns a list of Item IDs. func (iq *ItemQuery) IDs(ctx context.Context) ([]string, error) { var ids []string if err := iq.Select(item.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. func (iq *ItemQuery) IDsX(ctx context.Context) []string { ids, err := iq.IDs(ctx) if err != nil { panic(err) } return ids } // Count returns the count of the given query. func (iq *ItemQuery) Count(ctx context.Context) (int, error) { if err := iq.prepareQuery(ctx); err != nil { return 0, err } return iq.gremlinCount(ctx) } // CountX is like Count, but panics if an error occurs. func (iq *ItemQuery) CountX(ctx context.Context) int { count, err := iq.Count(ctx) if err != nil { panic(err) } return count } // Exist returns true if the query has elements in the graph. func (iq *ItemQuery) Exist(ctx context.Context) (bool, error) { if err := iq.prepareQuery(ctx); err != nil { return false, err } return iq.gremlinExist(ctx) } // ExistX is like Exist, but panics if an error occurs. func (iq *ItemQuery) ExistX(ctx context.Context) bool { exist, err := iq.Exist(ctx) if err != nil { panic(err) } return exist } // Clone returns a duplicate of the ItemQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. func (iq *ItemQuery) Clone() *ItemQuery { if iq == nil { return nil } return &ItemQuery{ config: iq.config, limit: iq.limit, offset: iq.offset, order: append([]OrderFunc{}, iq.order...), predicates: append([]predicate.Item{}, iq.predicates...), // clone intermediate query. gremlin: iq.gremlin.Clone(), path: iq.path, unique: iq.unique, } } // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. // // Example: // // var v []struct { // Text string `json:"text,omitempty"` // Count int `json:"count,omitempty"` // } // // client.Item.Query(). // GroupBy(item.FieldText). // Aggregate(ent.Count()). // Scan(ctx, &v) // func (iq *ItemQuery) GroupBy(field string, fields ...string) *ItemGroupBy { grbuild := &ItemGroupBy{config: iq.config} grbuild.fields = append([]string{field}, fields...) grbuild.path = func(ctx context.Context) (prev *dsl.Traversal, err error) { if err := iq.prepareQuery(ctx); err != nil { return nil, err } return iq.gremlinQuery(ctx), nil } grbuild.label = item.Label grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan return grbuild } // Select allows the selection one or more fields/columns for the given query, // instead of selecting all fields in the entity. // // Example: // // var v []struct { // Text string `json:"text,omitempty"` // } // // client.Item.Query(). // Select(item.FieldText). // Scan(ctx, &v) // func (iq *ItemQuery) Select(fields ...string) *ItemSelect { iq.fields = append(iq.fields, fields...) selbuild := &ItemSelect{ItemQuery: iq} selbuild.label = item.Label selbuild.flds, selbuild.scan = &iq.fields, selbuild.Scan return selbuild } func (iq *ItemQuery) prepareQuery(ctx context.Context) error { if iq.path != nil { prev, err := iq.path(ctx) if err != nil { return err } iq.gremlin = prev } return nil } func (iq *ItemQuery) gremlinAll(ctx context.Context) ([]*Item, error) { res := &gremlin.Response{} traversal := iq.gremlinQuery(ctx) if len(iq.fields) > 0 { fields := make([]interface{}, len(iq.fields)) for i, f := range iq.fields { fields[i] = f } traversal.ValueMap(fields...) } else { traversal.ValueMap(true) } query, bindings := traversal.Query() if err := iq.driver.Exec(ctx, query, bindings, res); err != nil { return nil, err } var is Items if err := is.FromResponse(res); err != nil { return nil, err } is.config(iq.config) return is, nil } func (iq *ItemQuery) gremlinCount(ctx context.Context) (int, error) { res := &gremlin.Response{} query, bindings := iq.gremlinQuery(ctx).Count().Query() if err := iq.driver.Exec(ctx, query, bindings, res); err != nil { return 0, err } return res.ReadInt() } func (iq *ItemQuery) gremlinExist(ctx context.Context) (bool, error) { res := &gremlin.Response{} query, bindings := iq.gremlinQuery(ctx).HasNext().Query() if err := iq.driver.Exec(ctx, query, bindings, res); err != nil { return false, err } return res.ReadBool() } func (iq *ItemQuery) gremlinQuery(context.Context) *dsl.Traversal { v := g.V().HasLabel(item.Label) if iq.gremlin != nil { v = iq.gremlin.Clone() } for _, p := range iq.predicates { p(v) } if len(iq.order) > 0 { v.Order() for _, p := range iq.order { p(v) } } switch limit, offset := iq.limit, iq.offset; { case limit != nil && offset != nil: v.Range(*offset, *offset+*limit) case offset != nil: v.Range(*offset, math.MaxInt32) case limit != nil: v.Limit(*limit) } if unique := iq.unique; unique == nil || *unique { v.Dedup() } return v } // ItemGroupBy is the group-by builder for Item entities. type ItemGroupBy struct { config selector fields []string fns []AggregateFunc // intermediate query (i.e. traversal path). gremlin *dsl.Traversal path func(context.Context) (*dsl.Traversal, error) } // Aggregate adds the given aggregation functions to the group-by query. func (igb *ItemGroupBy) Aggregate(fns ...AggregateFunc) *ItemGroupBy { igb.fns = append(igb.fns, fns...) return igb } // Scan applies the group-by query and scans the result into the given value. func (igb *ItemGroupBy) Scan(ctx context.Context, v interface{}) error { query, err := igb.path(ctx) if err != nil { return err } igb.gremlin = query return igb.gremlinScan(ctx, v) } func (igb *ItemGroupBy) gremlinScan(ctx context.Context, v interface{}) error { res := &gremlin.Response{} query, bindings := igb.gremlinQuery().Query() if err := igb.driver.Exec(ctx, query, bindings, res); err != nil { return err } if len(igb.fields)+len(igb.fns) == 1 { return res.ReadVal(v) } vm, err := res.ReadValueMap() if err != nil { return err } return vm.Decode(v) } func (igb *ItemGroupBy) gremlinQuery() *dsl.Traversal { var ( trs []interface{} names []interface{} ) for _, fn := range igb.fns { name, tr := fn("p", "") trs = append(trs, tr) names = append(names, name) } for _, f := range igb.fields { names = append(names, f) trs = append(trs, __.As("p").Unfold().Values(f).As(f)) } return igb.gremlin.Group(). By(__.Values(igb.fields...).Fold()). By(__.Fold().Match(trs...).Select(names...)). Select(dsl.Values). Next() } // ItemSelect is the builder for selecting fields of Item entities. type ItemSelect struct { *ItemQuery selector // intermediate query (i.e. traversal path). gremlin *dsl.Traversal } // Scan applies the selector query and scans the result into the given value. func (is *ItemSelect) Scan(ctx context.Context, v interface{}) error { if err := is.prepareQuery(ctx); err != nil { return err } is.gremlin = is.ItemQuery.gremlinQuery(ctx) return is.gremlinScan(ctx, v) } func (is *ItemSelect) gremlinScan(ctx context.Context, v interface{}) error { var ( traversal *dsl.Traversal res = &gremlin.Response{} ) if len(is.fields) == 1 { if is.fields[0] != item.FieldID { traversal = is.gremlin.Values(is.fields...) } else { traversal = is.gremlin.ID() } } else { fields := make([]interface{}, len(is.fields)) for i, f := range is.fields { fields[i] = f } traversal = is.gremlin.ValueMap(fields...) } query, bindings := traversal.Query() if err := is.driver.Exec(ctx, query, bindings, res); err != nil { return err } if len(is.fields) == 1 { return res.ReadVal(v) } vm, err := res.ReadValueMap() if err != nil { return err } return vm.Decode(v) }