{{/* 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. */}} {{ define "dialect/sql/query" }} {{ $pkg := $.Scope.Package }} {{ $builder := pascal $.Scope.Builder }} {{ $receiver := receiver $builder }} func ({{ $receiver }} *{{ $builder }}) sqlAll(ctx context.Context) ([]*{{ $.Name }}, error) { rows := &sql.Rows{} selector := {{ $receiver }}.sqlQuery() if unique := {{ $receiver }}.unique; len(unique) == 0 { selector.Distinct() } query, args := selector.Query() if err := {{ $receiver }}.driver.Query(ctx, query, args, rows); err != nil { return nil, err } defer rows.Close() {{- $ret := plural $.Receiver }} var {{ $ret }} {{ plural $.Name }} if err := {{ $ret }}.FromRows(rows); err != nil { return nil, err } {{ $ret }}.config({{ $receiver }}.config) return {{ $ret }}, nil } func ({{ $receiver }} *{{ $builder }}) sqlCount(ctx context.Context) (int, error) { rows := &sql.Rows{} selector := {{ $receiver }}.sqlQuery() unique := []string{ {{ $.Package }}.{{ $.ID.Constant }} } if len({{ $receiver }}.unique) > 0 { unique = {{ $receiver }}.unique } selector.Count(sql.Distinct(selector.Columns(unique...)...)) query, args := selector.Query() if err := {{ $receiver }}.driver.Query(ctx, query, args, rows); err != nil { return 0, err } defer rows.Close() if !rows.Next() { return 0, errors.New("{{ $pkg }}: no rows found") } var n int if err := rows.Scan(&n); err != nil { return 0, fmt.Errorf("{{ $pkg }}: failed reading count: %v", err) } return n, nil } func ({{ $receiver }} *{{ $builder }}) sqlExist(ctx context.Context) (bool, error) { n, err := {{ $receiver }}.sqlCount(ctx) if err != nil { return false, fmt.Errorf("{{ $pkg }}: check existence: %v", err) } return n > 0, nil } func ({{ $receiver }} *{{ $builder }}) sqlQuery() *sql.Selector { builder := sql.Dialect({{ $receiver }}.driver.Dialect()) t1 := builder.Table({{ $.Package }}.Table) selector := builder.Select(t1.Columns({{ $.Package }}.Columns...)...).From(t1) if {{ $receiver }}.sql != nil { selector = {{ $receiver }}.sql selector.Select(selector.Columns({{ $.Package }}.Columns...)...) } for _, p := range {{ $receiver }}.predicates { p(selector) } for _, p := range {{ $receiver }}.order { p(selector) } if offset := {{ $receiver }}.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 := {{ $receiver }}.limit; limit != nil { selector.Limit(*limit) } return selector } {{ end }} {{/* query/path defines the query generation for path of a given edge. */}} {{ define "dialect/sql/query/path" }} {{- $n := $ }} {{/* the node we start the query from. */}} {{- $e := $.Scope.Edge }} {{/* the edge we need to genegrate the path to. */}} {{- $receiver := $.Scope.Receiver }} step := sql.NewStep( sql.From({{ $n.Package }}.Table, {{ $n.Package }}.{{ $n.ID.Constant }}, {{ $receiver }}.sqlQuery()), sql.To({{ $e.Type.Package }}.Table, {{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), sql.Edge(sql.{{ $e.Rel.Type }}, {{ $e.IsInverse }}, {{ $n.Package }}.{{ $e.TableConstant }}, {{- if $e.M2M -}} {{ $n.Package }}.{{ $e.PKConstant }}... {{- else -}} {{ $n.Package }}.{{ $e.ColumnConstant }} {{- end -}} ), ) query.sql = sql.SetNeighbors({{ $receiver }}.driver.Dialect(), step) {{ end }} {{/* query/from defines the query generation for an edge query from a given node. */}} {{ define "dialect/sql/query/from" }} {{- $n := $ }} {{/* the node we start the query from. */}} {{- $e := $.Scope.Edge }} {{/* the edge we need to genegrate the path to. */}} {{- $receiver := $.Scope.Receiver -}} id := {{ $receiver }}.{{- if $n.ID.IsString }}id(){{ else }}ID{{ end }} step := sql.NewStep( sql.From({{ $n.Package }}.Table, {{ $n.Package }}.{{ $n.ID.Constant }}, id), sql.To({{ $e.Type.Package }}.Table, {{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), sql.Edge(sql.{{ $e.Rel.Type }}, {{ $e.IsInverse }}, {{ $n.Package }}.{{ $e.TableConstant }}, {{- if $e.M2M -}} {{ $n.Package }}.{{ $e.PKConstant }}... {{- else -}} {{ $n.Package }}.{{ $e.ColumnConstant }} {{- end -}} ), ) query.sql = sql.Neighbors({{ $receiver }}.driver.Dialect(), step) {{ end }}