mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
entc/gen: generate sql builders with dialect option
Summary: Pull Request resolved: https://github.com/facebookincubator/ent/pull/130 Reviewed By: alexsn Differential Revision: D18164397 fbshipit-source-id: 2858d69d3ff85c06b51382c01c3d4369ee2c3bdb
This commit is contained in:
committed by
Facebook Github Bot
parent
ea479ea527
commit
c259aee24b
@@ -10,16 +10,15 @@ in the LICENSE file in the root directory of this source tree.
|
||||
|
||||
func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name }}, error) {
|
||||
var (
|
||||
res sql.Result
|
||||
{{ with $.Edges }}res sql.Result{{ end }}
|
||||
builder = sql.Dialect({{ $receiver }}.driver.Dialect())
|
||||
{{ $.Receiver }} = &{{ $.Name }}{config: {{ $receiver }}.config}
|
||||
)
|
||||
tx, err := {{ $receiver }}.driver.Tx(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder := sql.Dialect({{ $receiver }}.driver.Dialect()).
|
||||
Insert({{ $.Package }}.Table).
|
||||
Default()
|
||||
insert := builder.Insert({{ $.Package }}.Table).Default()
|
||||
{{- range $_, $f := $.Fields }}
|
||||
if value := {{ $receiver }}.{{- $f.BuilderField }}; value != nil {
|
||||
{{- if $f.IsJSON }}
|
||||
@@ -27,18 +26,14 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, buf)
|
||||
insert.Set({{ $.Package }}.{{ $f.Constant }}, buf)
|
||||
{{- else }}
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
insert.Set({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
{{- end }}
|
||||
{{ $.Receiver }}.{{ $f.StructField }} = {{ if not $f.Nillable }}*{{ end }}value
|
||||
}
|
||||
{{- end }}
|
||||
query, args := builder.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
id, err := insertLastID(ctx, tx, insert.Returning({{ $.Package }}.{{ $.ID.Constant }}))
|
||||
if err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
@@ -48,13 +43,13 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
{{- if and $e.Unique $e.SelfRef }}{{/* O2O with self reference */}}
|
||||
for eid := range {{ $receiver }}.{{ $e.BuilderField }} {
|
||||
{{- template "dialect/sql/create/convertid" $e -}}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.EQ({{ $.Package }}.{{ $.ID.Constant }}, id)).Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return nil, rollback(tx, err)
|
||||
}
|
||||
query, args = sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args = builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, id).
|
||||
Where(sql.EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
@@ -72,7 +67,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
for eid := range {{ $receiver }}.{{ $e.BuilderField }} {
|
||||
{{- template "dialect/sql/create/convertid" $e -}}
|
||||
{{ $a := 0 }}{{ $b := 1 }}{{- if $e.IsInverse }}{{ $a = 1 }}{{ $b = 0 }}{{ end }}
|
||||
query, args := sql.Insert({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Insert({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Columns({{ $.Package }}.{{ $e.PKConstant }}[{{ $a }}], {{ $.Package }}.{{ $e.PKConstant }}[{{ $b }}]).
|
||||
Values(id, eid).
|
||||
{{- if $e.SelfRef }}{{/* self-ref creates the edges in both ways. */}}
|
||||
@@ -86,7 +81,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
{{- else if $e.M2O }}
|
||||
for eid := range {{ $receiver }}.{{ $e.BuilderField }} {
|
||||
{{- template "dialect/sql/create/convertid" $e -}}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.EQ({{ $.Package }}.{{ $.ID.Constant }}, id)).
|
||||
Query()
|
||||
@@ -100,7 +95,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
{{- template "dialect/sql/create/convertid" $e -}}
|
||||
p.Or().EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid)
|
||||
}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, id).
|
||||
Where(sql.And(p, sql.IsNull({{ $.Package }}.{{ $e.ColumnConstant }}))).
|
||||
Query()
|
||||
@@ -124,12 +119,12 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (*{{ $.Name
|
||||
eid := keys({{ $receiver }}.{{ $e.BuilderField }})[0]
|
||||
{{- end }}
|
||||
{{- if $e.IsInverse }}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.EQ({{ $.Package }}.{{ $.ID.Constant }}, id).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).
|
||||
Query()
|
||||
{{- else }}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, id).
|
||||
Where(sql.EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).
|
||||
Query()
|
||||
|
||||
@@ -9,12 +9,15 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{ $receiver := receiver $builder }}
|
||||
|
||||
func ({{ $receiver}} *{{ $builder }}) sqlExec(ctx context.Context) (int, error) {
|
||||
var res sql.Result
|
||||
selector := sql.Select().From(sql.Table({{ $.Package }}.Table))
|
||||
var (
|
||||
res sql.Result
|
||||
builder = sql.Dialect({{ $receiver }}.driver.Dialect())
|
||||
)
|
||||
selector := builder.Select().From(sql.Table({{ $.Package }}.Table))
|
||||
for _, p := range {{ $receiver }}.predicates {
|
||||
p(selector)
|
||||
}
|
||||
query, args := sql.Delete({{ $.Package }}.Table).FromSelect(selector).Query()
|
||||
query, args := builder.Delete({{ $.Package }}.Table).FromSelect(selector).Query()
|
||||
if err := {{ $receiver }}.driver.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -4,12 +4,22 @@ This source code is licensed under the Apache 2.0 license found
|
||||
in the LICENSE file in the root directory of this source tree.
|
||||
*/}}
|
||||
|
||||
{{/* custom errors and errors handlers from sql dialects */}}
|
||||
{{/* custom errors and errors handlers for sql dialects */}}
|
||||
{{ define "dialect/sql/errors" }}
|
||||
func isSQLConstraintError(err error) (*ErrConstraintFailed, bool) {
|
||||
// Error number 1062 is ER_DUP_ENTRY in mysql, and "UNIQUE constraint failed" is SQLite prefix.
|
||||
if msg := err.Error(); strings.HasPrefix(msg, "Error 1062") || strings.HasPrefix(msg, "UNIQUE constraint failed") {
|
||||
return &ErrConstraintFailed{msg, err}, true
|
||||
var (
|
||||
msg = err.Error()
|
||||
// error format per dialect.
|
||||
errors = [...]string{
|
||||
"Error 1062", // MySQL 1062 error (ER_DUP_ENTRY).
|
||||
"UNIQUE constraint failed", // SQLite.
|
||||
"duplicate key value violates unique constraint", // PostgreSQL.
|
||||
}
|
||||
)
|
||||
for i := range errors {
|
||||
if strings.Contains(msg, errors[i]) {
|
||||
return &ErrConstraintFailed{msg, err}, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
40
entc/gen/template/dialect/sql/globals.tmpl
Normal file
40
entc/gen/template/dialect/sql/globals.tmpl
Normal file
@@ -0,0 +1,40 @@
|
||||
{{/*
|
||||
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.
|
||||
*/}}
|
||||
|
||||
{{/* custom globals and helpers for sql dialects */}}
|
||||
{{ define "dialect/sql/globals" }}
|
||||
// insertLastID invokes the insert query on the transaction and returns the LastInsertID.
|
||||
func insertLastID(ctx context.Context, tx dialect.Tx, insert *sql.InsertBuilder) (int64, error) {
|
||||
query, args := insert.Query()
|
||||
// PostgreSQL does not support the LastInsertId() method of sql.Result
|
||||
// on Exec, and should be extracted manually using the `RETURNING` clause.
|
||||
if insert.Dialect() == dialect.Postgres {
|
||||
rows := &sql.Rows{}
|
||||
if err := tx.Query(ctx, query, args, rows); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer rows.Close()
|
||||
if !rows.Next() {
|
||||
return 0, fmt.Errorf("no rows found for query: %v", query)
|
||||
}
|
||||
var id int64
|
||||
if err := rows.Scan(&id); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
// MySQL, SQLite, etc.
|
||||
var res sql.Result
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
{{ end }}
|
||||
@@ -64,10 +64,12 @@ in the LICENSE file in the root directory of this source tree.
|
||||
func(s *sql.Selector) {
|
||||
{{- if $e.M2M }}
|
||||
t1 := s.Table()
|
||||
builder := sql.Dialect(s.Dialect())
|
||||
s.Where(
|
||||
sql.In(
|
||||
t1.C({{ $.ID.Constant }}),
|
||||
sql.Select({{ $e.PKConstant }}[{{ if $e.IsInverse }}1{{ else }}0{{ end }}]).From(sql.Table({{ $e.TableConstant }})),
|
||||
builder.Select({{ $e.PKConstant }}[{{ if $e.IsInverse }}1{{ else }}0{{ end }}]).
|
||||
From(builder.Table({{ $e.TableConstant }})),
|
||||
),
|
||||
)
|
||||
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
||||
@@ -75,11 +77,12 @@ in the LICENSE file in the root directory of this source tree.
|
||||
s.Where(sql.NotNull(t1.C({{ $e.ColumnConstant }})))
|
||||
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
||||
t1 := s.Table()
|
||||
builder := sql.Dialect(s.Dialect())
|
||||
s.Where(
|
||||
sql.In(
|
||||
t1.C({{ $.ID.Constant }}),
|
||||
sql.Select({{ $e.ColumnConstant }}).
|
||||
From(sql.Table({{ $e.TableConstant }})).
|
||||
builder.Select({{ $e.ColumnConstant }}).
|
||||
From(builder.Table({{ $e.TableConstant }})).
|
||||
Where(sql.NotNull({{ $e.ColumnConstant }})),
|
||||
),
|
||||
)
|
||||
@@ -92,28 +95,30 @@ in the LICENSE file in the root directory of this source tree.
|
||||
func(s *sql.Selector) {
|
||||
{{- if $e.M2M }}
|
||||
{{ $i := 1 }}{{ $j := 0 }}{{- if $e.IsInverse }}{{ $i = 0 }}{{ $j = 1 }}{{ end -}}
|
||||
builder := sql.Dialect(s.Dialect())
|
||||
t1 := s.Table()
|
||||
t2 := sql.Table(
|
||||
t2 := builder.Table(
|
||||
{{- if ne $.Table $e.Type.Table -}}
|
||||
{{ $e.InverseTableConstant }}
|
||||
{{- else -}}
|
||||
Table
|
||||
{{- end -}}
|
||||
)
|
||||
t3 := sql.Table({{ $e.TableConstant }})
|
||||
t4 := sql.Select(t3.C({{ $e.PKConstant }}[{{ $j }}])).
|
||||
t3 := builder.Table({{ $e.TableConstant }})
|
||||
t4 := builder.Select(t3.C({{ $e.PKConstant }}[{{ $j }}])).
|
||||
From(t3).
|
||||
Join(t2).
|
||||
On(t3.C({{ $e.PKConstant }}[{{ $i }}]), t2.C({{ $e.Type.ID.Constant }}))
|
||||
t5 := sql.Select().From(t2)
|
||||
t5 := builder.Select().From(t2)
|
||||
for _, p := range preds {
|
||||
p(t5)
|
||||
}
|
||||
t4.FromSelect(t5)
|
||||
s.Where(sql.In(t1.C({{ $.ID.Constant }}), t4))
|
||||
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
||||
builder := sql.Dialect(s.Dialect())
|
||||
t1 := s.Table()
|
||||
t2 := sql.Select({{ $e.Type.ID.Constant }}).From(sql.Table(
|
||||
t2 := builder.Select({{ $e.Type.ID.Constant }}).From(builder.Table(
|
||||
{{- if ne $.Table $e.Type.Table -}}
|
||||
{{ $e.InverseTableConstant }}
|
||||
{{- else -}}
|
||||
@@ -125,8 +130,9 @@ in the LICENSE file in the root directory of this source tree.
|
||||
}
|
||||
s.Where(sql.In(t1.C({{ $e.ColumnConstant }}), t2))
|
||||
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
||||
builder := sql.Dialect(s.Dialect())
|
||||
t1 := s.Table()
|
||||
t2 := sql.Select({{ $e.ColumnConstant }}).From(sql.Table({{ $e.TableConstant }}))
|
||||
t2 := builder.Select({{ $e.ColumnConstant }}).From(builder.Table({{ $e.TableConstant }}))
|
||||
for _, p := range preds {
|
||||
p(t2)
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ func ({{ $receiver }} *{{ $builder }}) sqlExist(ctx context.Context) (bool, erro
|
||||
}
|
||||
|
||||
func ({{ $receiver }} *{{ $builder }}) sqlQuery() *sql.Selector {
|
||||
t1 := sql.Table({{ $.Package }}.Table)
|
||||
selector := sql.Select(t1.Columns({{ $.Package }}.Columns...)...).From(t1)
|
||||
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...)...)
|
||||
@@ -90,33 +91,34 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery() *sql.Selector {
|
||||
{{- $e := $.Scope.Edge }} {{/* the edge we need to genegrate the path to. */}}
|
||||
{{- $receiver := $.Scope.Receiver }}
|
||||
|
||||
builder := sql.Dialect({{ $receiver }}.driver.Dialect())
|
||||
{{- if $e.M2M }}
|
||||
{{ $i := 1 }}{{ $j := 0 }}{{- if $e.IsInverse }}{{ $i = 0 }}{{ $j = 1 }}{{ end -}}
|
||||
t1 := sql.Table({{ $e.Type.Package }}.Table)
|
||||
t1 := builder.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := {{ $receiver }}.sqlQuery()
|
||||
t2.Select(t2.C({{ $.Package }}.{{ $.ID.Constant }}))
|
||||
t3 := sql.Table({{ $.Package }}.{{ $e.TableConstant }})
|
||||
t4 := sql.Select(t3.C({{ $.Package }}.{{ $e.PKConstant }}[{{ $i }}])).
|
||||
t3 := builder.Table({{ $.Package }}.{{ $e.TableConstant }})
|
||||
t4 := builder.Select(t3.C({{ $.Package }}.{{ $e.PKConstant }}[{{ $i }}])).
|
||||
From(t3).
|
||||
Join(t2).
|
||||
On(t3.C({{ $.Package }}.{{ $e.PKConstant }}[{{ $j }}]), t2.C({{ $.Package }}.{{ $.ID.Constant }}))
|
||||
query.sql = sql.Select().
|
||||
query.sql = builder.Select().
|
||||
From(t1).
|
||||
Join(t4).
|
||||
On(t1.C({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), t4.C({{ $.Package }}.{{ $e.PKConstant }}[{{ $i }}]))
|
||||
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
||||
t1 := sql.Table({{ $e.Type.Package }}.Table)
|
||||
t1 := builder.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := {{ $receiver }}.sqlQuery()
|
||||
t2.Select(t2.C({{ $.Package }}.{{ $e.ColumnConstant }}))
|
||||
query.sql = sql.Select(t1.Columns({{ $e.Type.Package }}.Columns...)...).
|
||||
query.sql = builder.Select(t1.Columns({{ $e.Type.Package }}.Columns...)...).
|
||||
From(t1).
|
||||
Join(t2).
|
||||
On(t1.C({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), t2.C({{ $.Package }}.{{ $e.ColumnConstant }}))
|
||||
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
||||
t1 := sql.Table({{ $e.Type.Package }}.Table)
|
||||
t1 := builder.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := {{ $receiver }}.sqlQuery()
|
||||
t2.Select(t2.C({{ $.Package }}.{{ $.ID.Constant }}))
|
||||
query.sql = sql.Select().
|
||||
query.sql = builder.Select().
|
||||
From(t1).
|
||||
Join(t2).
|
||||
On(t1.C({{ $.Package }}.{{ $e.ColumnConstant }}), t2.C({{ $.Package }}.{{ $.ID.Constant }}))
|
||||
@@ -130,28 +132,29 @@ func ({{ $receiver }} *{{ $builder }}) sqlQuery() *sql.Selector {
|
||||
{{- $receiver := $.Scope.Receiver -}}
|
||||
|
||||
id := {{ $receiver }}.{{- if $n.ID.IsString }}id(){{ else }}ID{{ end }}
|
||||
builder := sql.Dialect({{ $receiver }}.driver.Dialect())
|
||||
{{- if $e.M2M }}
|
||||
{{ $i := 1 }}{{ $j := 0 }}{{- if $e.IsInverse }}{{ $i = 0 }}{{ $j = 1 }}{{ end -}}
|
||||
t1 := sql.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := sql.Table({{ $n.Package }}.Table)
|
||||
t3 := sql.Table({{ $n.Package }}.{{ $e.TableConstant }})
|
||||
t4 := sql.Select(t3.C({{ $n.Package }}.{{ $e.PKConstant }}[{{ $i }}])).
|
||||
t1 := builder.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := builder.Table({{ $n.Package }}.Table)
|
||||
t3 := builder.Table({{ $n.Package }}.{{ $e.TableConstant }})
|
||||
t4 := builder.Select(t3.C({{ $n.Package }}.{{ $e.PKConstant }}[{{ $i }}])).
|
||||
From(t3).
|
||||
Join(t2).
|
||||
On(t3.C({{ $n.Package }}.{{ $e.PKConstant }}[{{ $j }}]), t2.C({{ $n.Package }}.{{ $n.ID.Constant }})).
|
||||
Where(sql.EQ(t2.C({{ $n.Package }}.{{ $n.ID.Constant }}), id))
|
||||
query.sql = sql.Select().
|
||||
query.sql = builder.Select().
|
||||
From(t1).
|
||||
Join(t4).
|
||||
On(t1.C({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), t4.C({{ $n.Package }}.{{ $e.PKConstant }}[{{ $i }}]))
|
||||
{{- else if or $e.M2O (and $e.O2O $e.IsInverse) }}{{/* M2O || (O2O with inverse edge) */}}
|
||||
t1 := sql.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := sql.Select({{ $n.Package }}.{{ $e.ColumnConstant }}).
|
||||
From(sql.Table({{ $n.Package }}.{{ $e.TableConstant }})).
|
||||
t1 := builder.Table({{ $e.Type.Package }}.Table)
|
||||
t2 := builder.Select({{ $n.Package }}.{{ $e.ColumnConstant }}).
|
||||
From(builder.Table({{ $n.Package }}.{{ $e.TableConstant }})).
|
||||
Where(sql.EQ({{ $n.Package }}.{{ $n.ID.Constant }}, id))
|
||||
query.sql = sql.Select().From(t1).Join(t2).On(t1.C({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), t2.C({{ $n.Package }}.{{ $e.ColumnConstant }}))
|
||||
query.sql = builder.Select().From(t1).Join(t2).On(t1.C({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}), t2.C({{ $n.Package }}.{{ $e.ColumnConstant }}))
|
||||
{{- else }}{{/* O2M || (O2O with assoc edge) */}}
|
||||
query.sql = sql.Select().From(sql.Table({{ $e.Type.Package }}.Table)).
|
||||
query.sql = builder.Select().From(builder.Table({{ $e.Type.Package }}.Table)).
|
||||
Where(sql.EQ({{ $n.Package }}.{{ $e.ColumnConstant }}, id))
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -21,6 +21,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlScan(ctx context.Context, v interface{
|
||||
|
||||
func ({{ $receiver }} *{{ $builder }}) sqlQuery() sql.Querier {
|
||||
view := "{{ $.Package }}_view"
|
||||
return sql.Select({{ $receiver }}.fields...).From({{ $receiver }}.sql.As(view))
|
||||
return sql.Dialect({{ $receiver }}.driver.Dialect()).
|
||||
Select({{ $receiver }}.fields...).From({{ $receiver }}.sql.As(view))
|
||||
}
|
||||
{{ end }}
|
||||
@@ -13,7 +13,10 @@ in the LICENSE file in the root directory of this source tree.
|
||||
{{- $ret := "n" }}{{ if $one }}{{ $ret = $.Receiver }}{{ end }}
|
||||
|
||||
func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }} {{ if $one }}*{{ $.Name }}{{ else }}int{{ end }}, err error) {
|
||||
selector := sql.Select({{ $.Package }}.{{ if $one }}Columns...{{ else }}{{ $.ID.Constant }}{{ end }}).From(sql.Table({{ $.Package }}.Table))
|
||||
var (
|
||||
builder = sql.Dialect({{ $receiver }}.driver.Dialect())
|
||||
selector = builder.Select({{ $.Package }}.{{ if $one }}Columns...{{ else }}{{ $.ID.Constant }}{{ end }}).From(builder.Table({{ $.Package }}.Table))
|
||||
)
|
||||
{{- if $one }}
|
||||
{{ $.Package }}.ID({{ $receiver }}.id)(selector)
|
||||
{{- else }}
|
||||
@@ -63,7 +66,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{- if $.Fields }}
|
||||
var (
|
||||
res sql.Result
|
||||
builder = sql.Update({{ $.Package }}.Table).Where(sql.InInts({{ $.Package }}.{{ $.ID.Constant }}, ids...))
|
||||
updater = builder.Update({{ $.Package }}.Table).Where(sql.InInts({{ $.Package }}.{{ $.ID.Constant }}, ids...))
|
||||
)
|
||||
{{- range $_, $f := $.Fields }}
|
||||
{{- if or (not $f.Immutable) $f.UpdateDefault }}
|
||||
@@ -73,9 +76,9 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
if err != nil {
|
||||
return {{ $zero }}, err
|
||||
}
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, buf)
|
||||
updater.Set({{ $.Package }}.{{ $f.Constant }}, buf)
|
||||
{{- else }}
|
||||
builder.Set({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
updater.Set({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
{{- end }}
|
||||
{{- if $one }}
|
||||
{{ $.Receiver }}.{{ $f.StructField }} = {{ if not $f.Nillable }}*{{ end }}value
|
||||
@@ -83,7 +86,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
}
|
||||
{{- if $f.Type.Numeric }}
|
||||
if value := {{ $receiver }}.add{{ $f.BuilderField }}; value != nil {
|
||||
builder.Add({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
updater.Add({{ $.Package }}.{{ $f.Constant }}, *value)
|
||||
{{- if $one }}
|
||||
{{- if $f.Nillable }}
|
||||
if {{ $.Receiver }}.{{ $f.StructField }} != nil {
|
||||
@@ -108,12 +111,12 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{ $.Receiver }}.{{ $f.StructField }} = value
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
builder.SetNull({{ $.Package }}.{{ $f.Constant }})
|
||||
updater.SetNull({{ $.Package }}.{{ $f.Constant }})
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
if !builder.Empty() {
|
||||
query, args := builder.Query()
|
||||
if !updater.Empty() {
|
||||
query, args := updater.Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return {{ $zero }}, rollback(tx, err)
|
||||
}
|
||||
@@ -130,7 +133,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{- template "dialect/sql/update/convertid" $e -}}
|
||||
eids = append(eids, eid)
|
||||
}
|
||||
query, args := sql.Delete({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Delete({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.PKConstant }}[{{ $a }}], ids...)).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.PKConstant }}[{{ $b }}], eids...)).
|
||||
Query()
|
||||
@@ -138,7 +141,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
return {{ $zero }}, rollback(tx, err)
|
||||
}
|
||||
{{- if $e.SelfRef }}{{/* M2M with self reference */}}{{/* TODO: use OR in the case above. */}}
|
||||
query, args = sql.Delete({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args = builder.Delete({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.PKConstant }}[{{ $b }}], ids...)).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.PKConstant }}[{{ $a }}], eids...)).
|
||||
Query()
|
||||
@@ -154,7 +157,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{- template "dialect/sql/update/convertid" $e -}}
|
||||
eids = append(eids, eid)
|
||||
}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
SetNull({{ $.Package }}.{{ $e.ColumnConstant }}).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.ColumnConstant }}, ids...)).
|
||||
Where(sql.InInts({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eids...)).
|
||||
@@ -165,7 +168,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
}
|
||||
{{- else }}{{/* O2O or M2O */}}
|
||||
if {{ $receiver }}.cleared{{ $e.StructField }} {
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
SetNull({{ $.Package }}.{{ $e.ColumnConstant }}).
|
||||
Where(sql.InInts({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, ids...)).
|
||||
Query()
|
||||
@@ -173,7 +176,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
return {{ $zero }}, rollback(tx, err)
|
||||
}
|
||||
{{- if $e.SelfRef }}{{/* O2O with self reference */}}
|
||||
query, args = sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args = builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
SetNull({{ $.Package }}.{{ $e.ColumnConstant }}).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $e.ColumnConstant }}, ids...)).
|
||||
Query()
|
||||
@@ -190,13 +193,13 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
}
|
||||
for eid := range {{ $receiver }}.{{ $e.BuilderField }} {
|
||||
{{- template "dialect/sql/update/convertid" $e -}}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.EQ({{ $.Package }}.{{ $.ID.Constant }}, ids[0])).Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
return {{ $zero }}, rollback(tx, err)
|
||||
}
|
||||
query, args = sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args = builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, ids[0]).
|
||||
Where(sql.EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).Query()
|
||||
if err := tx.Exec(ctx, query, args, &res); err != nil {
|
||||
@@ -219,7 +222,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
}
|
||||
}
|
||||
{{- $a := 0 }}{{ $b := 1 }}{{ if $e.IsInverse }}{{ $a = 1 }}{{ $b = 0 }}{{ end }}
|
||||
builder := sql.Insert({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
builder := builder.Insert({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Columns({{ $.Package }}.{{ $e.PKConstant }}[{{ $a }}], {{ $.Package }}.{{ $e.PKConstant }}[{{ $b }}])
|
||||
for _, v := range values {
|
||||
builder.Values(v[0], v[1])
|
||||
@@ -231,7 +234,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{- else if $e.M2O }}
|
||||
for eid := range {{ $receiver }}.{{ $e.BuilderField }} {
|
||||
{{- template "dialect/sql/update/convertid" $e -}}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.InInts({{ $.Package }}.{{ $.ID.Constant }}, ids...)).
|
||||
Query()
|
||||
@@ -246,7 +249,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
{{- template "dialect/sql/update/convertid" $e -}}
|
||||
p.Or().EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid)
|
||||
}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, id).
|
||||
Where(sql.And(p, sql.IsNull({{ $.Package }}.{{ $e.ColumnConstant }}))).
|
||||
Query()
|
||||
@@ -272,12 +275,12 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) ({{ $ret }}
|
||||
eid := keys({{ $receiver }}.{{ $e.BuilderField }})[0]
|
||||
{{- end }}
|
||||
{{- if $e.IsInverse }}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, eid).
|
||||
Where(sql.EQ({{ $.Package }}.{{ $.ID.Constant }}, id).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).
|
||||
Query()
|
||||
{{- else }}
|
||||
query, args := sql.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
query, args := builder.Update({{ $.Package }}.{{ $e.TableConstant }}).
|
||||
Set({{ $.Package }}.{{ $e.ColumnConstant }}, id).
|
||||
Where(sql.EQ({{ $e.Type.Package }}.{{ $e.Type.ID.Constant }}, eid).And().IsNull({{ $.Package }}.{{ $e.ColumnConstant }})).
|
||||
Query()
|
||||
|
||||
Reference in New Issue
Block a user