Skip to content

Commit 6c91199

Browse files
authored
Merge pull request #1317 from atzedus/upsert-options-feature
Ability to extend upsert expression with options
2 parents 63485f5 + 01d864f commit 6c91199

File tree

2 files changed

+52
-21
lines changed

2 files changed

+52
-21
lines changed

drivers/sqlboiler-psql/driver/override/main/17_upsert.go.tpl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
{{- $schemaTable := .Table.Name | .SchemaTable}}
44
{{if .AddGlobal -}}
55
// UpsertG attempts an insert, and does an update or ignore on conflict.
6-
func (o *{{$alias.UpSingular}}) UpsertG({{if not .NoContext}}ctx context.Context, {{end -}} updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
7-
return o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateOnConflict, conflictColumns, updateColumns, insertColumns)
6+
func (o *{{$alias.UpSingular}}) UpsertG({{if not .NoContext}}ctx context.Context, {{end -}} updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns, opts ...UpsertOptionFunc) error {
7+
return o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateOnConflict, conflictColumns, updateColumns, insertColumns, opts...)
88
}
99

1010
{{end -}}
1111

1212
{{if and .AddGlobal .AddPanic -}}
1313
// UpsertGP attempts an insert, and does an update or ignore on conflict. Panics on error.
14-
func (o *{{$alias.UpSingular}}) UpsertGP({{if not .NoContext}}ctx context.Context, {{end -}} updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) {
15-
if err := o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateOnConflict, conflictColumns, updateColumns, insertColumns); err != nil {
14+
func (o *{{$alias.UpSingular}}) UpsertGP({{if not .NoContext}}ctx context.Context, {{end -}} updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns, opts ...UpsertOptionFunc) {
15+
if err := o.Upsert({{if .NoContext}}boil.GetDB(){{else}}ctx, boil.GetContextDB(){{end}}, updateOnConflict, conflictColumns, updateColumns, insertColumns, opts...); err != nil {
1616
panic(boil.WrapErr(err))
1717
}
1818
}
@@ -22,8 +22,8 @@ func (o *{{$alias.UpSingular}}) UpsertGP({{if not .NoContext}}ctx context.Contex
2222
{{if .AddPanic -}}
2323
// UpsertP attempts an insert using an executor, and does an update or ignore on conflict.
2424
// UpsertP panics on error.
25-
func (o *{{$alias.UpSingular}}) UpsertP({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) {
26-
if err := o.Upsert({{if not .NoContext}}ctx, {{end -}} exec, updateOnConflict, conflictColumns, updateColumns, insertColumns); err != nil {
25+
func (o *{{$alias.UpSingular}}) UpsertP({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns, opts ...UpsertOptionFunc) {
26+
if err := o.Upsert({{if not .NoContext}}ctx, {{end -}} exec, updateOnConflict, conflictColumns, updateColumns, insertColumns, opts...); err != nil {
2727
panic(boil.WrapErr(err))
2828
}
2929
}
@@ -32,7 +32,7 @@ func (o *{{$alias.UpSingular}}) UpsertP({{if .NoContext}}exec boil.Executor{{els
3232

3333
// Upsert attempts an insert using an executor, and does an update or ignore on conflict.
3434
// See boil.Columns documentation for how to properly use updateColumns and insertColumns.
35-
func (o *{{$alias.UpSingular}}) Upsert({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns) error {
35+
func (o *{{$alias.UpSingular}}) Upsert({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, updateOnConflict bool, conflictColumns []string, updateColumns, insertColumns boil.Columns, opts ...UpsertOptionFunc) error {
3636
if o == nil {
3737
return errors.New("{{.PkgName}}: no {{.Table.Name}} provided for upsert")
3838
}
@@ -111,7 +111,7 @@ func (o *{{$alias.UpSingular}}) Upsert({{if .NoContext}}exec boil.Executor{{else
111111
conflict = make([]string, len({{$alias.DownSingular}}PrimaryKeyColumns))
112112
copy(conflict, {{$alias.DownSingular}}PrimaryKeyColumns)
113113
}
114-
cache.query = buildUpsertQueryPostgres(dialect, "{{$schemaTable}}", updateOnConflict, ret, update, conflict, insert)
114+
cache.query = buildUpsertQueryPostgres(dialect, "{{$schemaTable}}", updateOnConflict, ret, update, conflict, insert, opts...)
115115

116116
cache.valueMapping, err = queries.BindMapping({{$alias.DownSingular}}Type, {{$alias.DownSingular}}Mapping, insert)
117117
if err != nil {

drivers/sqlboiler-psql/driver/override/main/singleton/psql_upsert.go.tpl

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1+
type UpsertOptions struct {
2+
conflictObject string
3+
updateSet string
4+
}
5+
6+
type UpsertOptionFunc func(o *UpsertOptions)
7+
8+
func UpsertConflictObject(conflictObject string) UpsertOptionFunc {
9+
return func(o *UpsertOptions) {
10+
o.conflictObject = conflictObject
11+
}
12+
}
13+
14+
func UpsertUpdateSet(updateSet string) UpsertOptionFunc {
15+
return func(o *UpsertOptions) {
16+
o.updateSet = updateSet
17+
}
18+
}
19+
120
// buildUpsertQueryPostgres builds a SQL statement string using the upsertData provided.
2-
func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnConflict bool, ret, update, conflict, whitelist []string) string {
21+
func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnConflict bool, ret, update, conflict, whitelist []string, opts ...UpsertOptionFunc) string {
322
conflict = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, conflict)
423
whitelist = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, whitelist)
524
ret = strmangle.IdentQuoteSlice(dia.LQ, dia.RQ, ret)
625
26+
upsertOpts := &UpsertOptions{}
27+
for _, o := range opts {
28+
o(upsertOpts)
29+
}
30+
731
buf := strmangle.GetBuffer()
832
defer strmangle.PutBuffer(buf)
933

@@ -21,28 +45,35 @@ func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnCon
2145
columns,
2246
)
2347

24-
if len(conflict) != 0 {
48+
if upsertOpts.conflictObject != "" {
49+
buf.WriteString(upsertOpts.conflictObject)
50+
} else if len(conflict) != 0 {
2551
buf.WriteByte('(')
2652
buf.WriteString(strings.Join(conflict, ", "))
27-
buf.WriteString(") ")
53+
buf.WriteByte(')')
2854
}
55+
buf.WriteByte(' ')
2956

3057
if !updateOnConflict || len(update) == 0 {
3158
buf.WriteString("DO NOTHING")
3259
} else {
3360
buf.WriteString("DO UPDATE SET ")
3461
35-
for i, v := range update {
36-
if len(v) == 0 {
37-
continue
38-
}
39-
if i != 0 {
40-
buf.WriteByte(',')
62+
if upsertOpts.updateSet != "" {
63+
buf.WriteString(upsertOpts.updateSet)
64+
} else {
65+
for i, v := range update {
66+
if len(v) == 0 {
67+
continue
68+
}
69+
if i != 0 {
70+
buf.WriteByte(',')
71+
}
72+
quoted := strmangle.IdentQuote(dia.LQ, dia.RQ, v)
73+
buf.WriteString(quoted)
74+
buf.WriteString(" = EXCLUDED.")
75+
buf.WriteString(quoted)
4176
}
42-
quoted := strmangle.IdentQuote(dia.LQ, dia.RQ, v)
43-
buf.WriteString(quoted)
44-
buf.WriteString(" = EXCLUDED.")
45-
buf.WriteString(quoted)
4677
}
4778
}
4879

0 commit comments

Comments
 (0)