Files
ent/entc/integration/customid/ent/intsid_query.go
Ariel Mashraki 939c7cff1a entc/gen: reduce the usage of DISTINCT in queries (#3305)
Most queries are not graph traversals but rather regular table scans,
in which case the DISTINCT clause is not needed as duplicates cannot be
returned (unless query was modified by the user).
2023-02-06 22:40:50 +02:00

671 lines
19 KiB
Go

// 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 ent, DO NOT EDIT.
package ent
import (
"context"
"database/sql/driver"
"fmt"
"math"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/entc/integration/customid/ent/intsid"
"entgo.io/ent/entc/integration/customid/ent/predicate"
"entgo.io/ent/entc/integration/customid/sid"
"entgo.io/ent/schema/field"
)
// IntSIDQuery is the builder for querying IntSID entities.
type IntSIDQuery struct {
config
ctx *QueryContext
order []OrderFunc
inters []Interceptor
predicates []predicate.IntSID
withParent *IntSIDQuery
withChildren *IntSIDQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the IntSIDQuery builder.
func (isq *IntSIDQuery) Where(ps ...predicate.IntSID) *IntSIDQuery {
isq.predicates = append(isq.predicates, ps...)
return isq
}
// Limit the number of records to be returned by this query.
func (isq *IntSIDQuery) Limit(limit int) *IntSIDQuery {
isq.ctx.Limit = &limit
return isq
}
// Offset to start from.
func (isq *IntSIDQuery) Offset(offset int) *IntSIDQuery {
isq.ctx.Offset = &offset
return isq
}
// 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 (isq *IntSIDQuery) Unique(unique bool) *IntSIDQuery {
isq.ctx.Unique = &unique
return isq
}
// Order specifies how the records should be ordered.
func (isq *IntSIDQuery) Order(o ...OrderFunc) *IntSIDQuery {
isq.order = append(isq.order, o...)
return isq
}
// QueryParent chains the current query on the "parent" edge.
func (isq *IntSIDQuery) QueryParent() *IntSIDQuery {
query := (&IntSIDClient{config: isq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := isq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := isq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(intsid.Table, intsid.FieldID, selector),
sqlgraph.To(intsid.Table, intsid.FieldID),
sqlgraph.Edge(sqlgraph.M2O, false, intsid.ParentTable, intsid.ParentColumn),
)
fromU = sqlgraph.SetNeighbors(isq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// QueryChildren chains the current query on the "children" edge.
func (isq *IntSIDQuery) QueryChildren() *IntSIDQuery {
query := (&IntSIDClient{config: isq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := isq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := isq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(intsid.Table, intsid.FieldID, selector),
sqlgraph.To(intsid.Table, intsid.FieldID),
sqlgraph.Edge(sqlgraph.O2M, true, intsid.ChildrenTable, intsid.ChildrenColumn),
)
fromU = sqlgraph.SetNeighbors(isq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first IntSID entity from the query.
// Returns a *NotFoundError when no IntSID was found.
func (isq *IntSIDQuery) First(ctx context.Context) (*IntSID, error) {
nodes, err := isq.Limit(1).All(setContextOp(ctx, isq.ctx, "First"))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{intsid.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (isq *IntSIDQuery) FirstX(ctx context.Context) *IntSID {
node, err := isq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first IntSID ID from the query.
// Returns a *NotFoundError when no IntSID ID was found.
func (isq *IntSIDQuery) FirstID(ctx context.Context) (id sid.ID, err error) {
var ids []sid.ID
if ids, err = isq.Limit(1).IDs(setContextOp(ctx, isq.ctx, "FirstID")); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{intsid.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (isq *IntSIDQuery) FirstIDX(ctx context.Context) sid.ID {
id, err := isq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single IntSID entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one IntSID entity is found.
// Returns a *NotFoundError when no IntSID entities are found.
func (isq *IntSIDQuery) Only(ctx context.Context) (*IntSID, error) {
nodes, err := isq.Limit(2).All(setContextOp(ctx, isq.ctx, "Only"))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{intsid.Label}
default:
return nil, &NotSingularError{intsid.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (isq *IntSIDQuery) OnlyX(ctx context.Context) *IntSID {
node, err := isq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only IntSID ID in the query.
// Returns a *NotSingularError when more than one IntSID ID is found.
// Returns a *NotFoundError when no entities are found.
func (isq *IntSIDQuery) OnlyID(ctx context.Context) (id sid.ID, err error) {
var ids []sid.ID
if ids, err = isq.Limit(2).IDs(setContextOp(ctx, isq.ctx, "OnlyID")); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{intsid.Label}
default:
err = &NotSingularError{intsid.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (isq *IntSIDQuery) OnlyIDX(ctx context.Context) sid.ID {
id, err := isq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of IntSIDs.
func (isq *IntSIDQuery) All(ctx context.Context) ([]*IntSID, error) {
ctx = setContextOp(ctx, isq.ctx, "All")
if err := isq.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*IntSID, *IntSIDQuery]()
return withInterceptors[[]*IntSID](ctx, isq, qr, isq.inters)
}
// AllX is like All, but panics if an error occurs.
func (isq *IntSIDQuery) AllX(ctx context.Context) []*IntSID {
nodes, err := isq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of IntSID IDs.
func (isq *IntSIDQuery) IDs(ctx context.Context) (ids []sid.ID, err error) {
if isq.ctx.Unique == nil && isq.path != nil {
isq.Unique(true)
}
ctx = setContextOp(ctx, isq.ctx, "IDs")
if err = isq.Select(intsid.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (isq *IntSIDQuery) IDsX(ctx context.Context) []sid.ID {
ids, err := isq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (isq *IntSIDQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, isq.ctx, "Count")
if err := isq.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, isq, querierCount[*IntSIDQuery](), isq.inters)
}
// CountX is like Count, but panics if an error occurs.
func (isq *IntSIDQuery) CountX(ctx context.Context) int {
count, err := isq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (isq *IntSIDQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, isq.ctx, "Exist")
switch _, err := isq.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (isq *IntSIDQuery) ExistX(ctx context.Context) bool {
exist, err := isq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the IntSIDQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (isq *IntSIDQuery) Clone() *IntSIDQuery {
if isq == nil {
return nil
}
return &IntSIDQuery{
config: isq.config,
ctx: isq.ctx.Clone(),
order: append([]OrderFunc{}, isq.order...),
inters: append([]Interceptor{}, isq.inters...),
predicates: append([]predicate.IntSID{}, isq.predicates...),
withParent: isq.withParent.Clone(),
withChildren: isq.withChildren.Clone(),
// clone intermediate query.
sql: isq.sql.Clone(),
path: isq.path,
}
}
// WithParent tells the query-builder to eager-load the nodes that are connected to
// the "parent" edge. The optional arguments are used to configure the query builder of the edge.
func (isq *IntSIDQuery) WithParent(opts ...func(*IntSIDQuery)) *IntSIDQuery {
query := (&IntSIDClient{config: isq.config}).Query()
for _, opt := range opts {
opt(query)
}
isq.withParent = query
return isq
}
// WithChildren tells the query-builder to eager-load the nodes that are connected to
// the "children" edge. The optional arguments are used to configure the query builder of the edge.
func (isq *IntSIDQuery) WithChildren(opts ...func(*IntSIDQuery)) *IntSIDQuery {
query := (&IntSIDClient{config: isq.config}).Query()
for _, opt := range opts {
opt(query)
}
isq.withChildren = query
return isq
}
// 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.
func (isq *IntSIDQuery) GroupBy(field string, fields ...string) *IntSIDGroupBy {
isq.ctx.Fields = append([]string{field}, fields...)
grbuild := &IntSIDGroupBy{build: isq}
grbuild.flds = &isq.ctx.Fields
grbuild.label = intsid.Label
grbuild.scan = 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.
func (isq *IntSIDQuery) Select(fields ...string) *IntSIDSelect {
isq.ctx.Fields = append(isq.ctx.Fields, fields...)
sbuild := &IntSIDSelect{IntSIDQuery: isq}
sbuild.label = intsid.Label
sbuild.flds, sbuild.scan = &isq.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a IntSIDSelect configured with the given aggregations.
func (isq *IntSIDQuery) Aggregate(fns ...AggregateFunc) *IntSIDSelect {
return isq.Select().Aggregate(fns...)
}
func (isq *IntSIDQuery) prepareQuery(ctx context.Context) error {
for _, inter := range isq.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, isq); err != nil {
return err
}
}
}
for _, f := range isq.ctx.Fields {
if !intsid.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if isq.path != nil {
prev, err := isq.path(ctx)
if err != nil {
return err
}
isq.sql = prev
}
return nil
}
func (isq *IntSIDQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*IntSID, error) {
var (
nodes = []*IntSID{}
withFKs = isq.withFKs
_spec = isq.querySpec()
loadedTypes = [2]bool{
isq.withParent != nil,
isq.withChildren != nil,
}
)
if isq.withParent != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, intsid.ForeignKeys...)
}
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*IntSID).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &IntSID{config: isq.config}
nodes = append(nodes, node)
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, isq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := isq.withParent; query != nil {
if err := isq.loadParent(ctx, query, nodes, nil,
func(n *IntSID, e *IntSID) { n.Edges.Parent = e }); err != nil {
return nil, err
}
}
if query := isq.withChildren; query != nil {
if err := isq.loadChildren(ctx, query, nodes,
func(n *IntSID) { n.Edges.Children = []*IntSID{} },
func(n *IntSID, e *IntSID) { n.Edges.Children = append(n.Edges.Children, e) }); err != nil {
return nil, err
}
}
return nodes, nil
}
func (isq *IntSIDQuery) loadParent(ctx context.Context, query *IntSIDQuery, nodes []*IntSID, init func(*IntSID), assign func(*IntSID, *IntSID)) error {
ids := make([]sid.ID, 0, len(nodes))
nodeids := make(map[sid.ID][]*IntSID)
for i := range nodes {
if nodes[i].int_sid_parent == nil {
continue
}
fk := *nodes[i].int_sid_parent
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(intsid.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "int_sid_parent" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (isq *IntSIDQuery) loadChildren(ctx context.Context, query *IntSIDQuery, nodes []*IntSID, init func(*IntSID), assign func(*IntSID, *IntSID)) error {
fks := make([]driver.Value, 0, len(nodes))
nodeids := make(map[sid.ID]*IntSID)
for i := range nodes {
fks = append(fks, nodes[i].ID)
nodeids[nodes[i].ID] = nodes[i]
if init != nil {
init(nodes[i])
}
}
query.withFKs = true
query.Where(predicate.IntSID(func(s *sql.Selector) {
s.Where(sql.InValues(intsid.ChildrenColumn, fks...))
}))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
fk := n.int_sid_parent
if fk == nil {
return fmt.Errorf(`foreign-key "int_sid_parent" is nil for node %v`, n.ID)
}
node, ok := nodeids[*fk]
if !ok {
return fmt.Errorf(`unexpected foreign-key "int_sid_parent" returned %v for node %v`, *fk, n.ID)
}
assign(node, n)
}
return nil
}
func (isq *IntSIDQuery) sqlCount(ctx context.Context) (int, error) {
_spec := isq.querySpec()
_spec.Node.Columns = isq.ctx.Fields
if len(isq.ctx.Fields) > 0 {
_spec.Unique = isq.ctx.Unique != nil && *isq.ctx.Unique
}
return sqlgraph.CountNodes(ctx, isq.driver, _spec)
}
func (isq *IntSIDQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(intsid.Table, intsid.Columns, sqlgraph.NewFieldSpec(intsid.FieldID, field.TypeInt64))
_spec.From = isq.sql
if unique := isq.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if isq.path != nil {
_spec.Unique = true
}
if fields := isq.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, intsid.FieldID)
for i := range fields {
if fields[i] != intsid.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := isq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := isq.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := isq.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := isq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (isq *IntSIDQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(isq.driver.Dialect())
t1 := builder.Table(intsid.Table)
columns := isq.ctx.Fields
if len(columns) == 0 {
columns = intsid.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if isq.sql != nil {
selector = isq.sql
selector.Select(selector.Columns(columns...)...)
}
if isq.ctx.Unique != nil && *isq.ctx.Unique {
selector.Distinct()
}
for _, p := range isq.predicates {
p(selector)
}
for _, p := range isq.order {
p(selector)
}
if offset := isq.ctx.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.MaxInt32)
}
if limit := isq.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// IntSIDGroupBy is the group-by builder for IntSID entities.
type IntSIDGroupBy struct {
selector
build *IntSIDQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (isgb *IntSIDGroupBy) Aggregate(fns ...AggregateFunc) *IntSIDGroupBy {
isgb.fns = append(isgb.fns, fns...)
return isgb
}
// Scan applies the selector query and scans the result into the given value.
func (isgb *IntSIDGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, isgb.build.ctx, "GroupBy")
if err := isgb.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*IntSIDQuery, *IntSIDGroupBy](ctx, isgb.build, isgb, isgb.build.inters, v)
}
func (isgb *IntSIDGroupBy) sqlScan(ctx context.Context, root *IntSIDQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(isgb.fns))
for _, fn := range isgb.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*isgb.flds)+len(isgb.fns))
for _, f := range *isgb.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*isgb.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := isgb.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// IntSIDSelect is the builder for selecting fields of IntSID entities.
type IntSIDSelect struct {
*IntSIDQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (iss *IntSIDSelect) Aggregate(fns ...AggregateFunc) *IntSIDSelect {
iss.fns = append(iss.fns, fns...)
return iss
}
// Scan applies the selector query and scans the result into the given value.
func (iss *IntSIDSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, iss.ctx, "Select")
if err := iss.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*IntSIDQuery, *IntSIDSelect](ctx, iss.IntSIDQuery, iss, iss.inters, v)
}
func (iss *IntSIDSelect) sqlScan(ctx context.Context, root *IntSIDQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(iss.fns))
for _, fn := range iss.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*iss.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := iss.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}