get rid of goqu builder

This commit is contained in:
Pavel Merzlyakov 2023-06-17 10:56:23 +03:00
parent f8af876761
commit 04c5376009
2 changed files with 100 additions and 92 deletions

View File

@ -11,11 +11,9 @@ import (
"strconv"
"strings"
"git.bit5.ru/backend/meta"
"git.bit5.ru/backend/meta/v2"
"git.bit5.ru/backend/versioning"
"git.bit5.ru/gomodules/metadb"
"github.com/doug-martin/goqu/v9"
"github.com/doug-martin/goqu/v9/exp"
"github.com/go-logr/logr"
"github.com/pkg/errors"
)

View File

@ -36,6 +36,8 @@
{% set select_by = pkey|first %}
{% set delete_by = select_by %}
{% set delete_where_expr = select_where_expr %}
{% set pkey_column_expr = pkey|map(f => "`#{f.name}`")|join(',') %}
{% set pkey_values_expr = arr_fill('?', pkey|length)|join(',') %}
type {{ s.name }} struct {
{%~ for f in pkey %}
@ -77,33 +79,25 @@ type {{ json_fields_type }} struct{
{{ _self.json_set_expr(json_fields_type, json_fields) }}
func Save{{ s.name }}Diff(ctx context.Context, dbe metadb.Execer, rec {{ s.name }}) error {
var b strings.Builder
if err := rec.WriteJsonSetExpr(&b); err != nil {
if rec.changedFields.Empty() {
return nil
}
var builder strings.Builder
builder.Grow({{ 50 + insert_column_expr|length }})
builder.WriteString("INSERT INTO `{{ table_name }}` ({{ insert_column_expr }}) ON DUPLICATE KEY UPDATE `kv`=")
if err := rec.WriteJsonSetExpr(&builder); err != nil {
return err
}
ds := metadb.SqlBuilder().
Insert(goqu.T("{{ table_name }}")).
Cols(
{% for c in insert_columns -%}
goqu.C("{{ c }}"),
{% endfor -%}
).
Vals(goqu.Vals{
{% for f in insert_fields -%}
rec.{{ f }},
{% endfor -%}
}).
OnConflict(goqu.DoUpdate("",
goqu.Record{"kv": goqu.L(b.String())},
))
query, _, err := ds.ToSQL()
if err != nil {
return errors.WithStack(err)
}
_, saveErr := dbe.ExecContext(ctx, query)
_, saveErr := dbe.ExecContext(ctx,
builder.String(),
{% for f in insert_fields -%}
rec.{{ f }},
{% endfor -%}
)
return errors.WithStack(saveErr)
}
@ -127,6 +121,8 @@ func Save{{ s.name }}Diff(ctx context.Context, dbe metadb.Execer, rec {{ s.name
{% set select_by = pkey|first %}
{% set delete_by = select_by %}
{% set delete_where_expr = select_where_expr %}
{% set pkey_column_expr = pkey|map(f => "`#{f.name}`")|join(',') %}
{% set pkey_values_expr = arr_fill('?', pkey|length)|join(',') %}
{{ _self.changed_fields(s.name, nopkey) }}
@ -138,37 +134,52 @@ func Save{{ s.name }}Diff(ctx context.Context, dbe metadb.Execer, rec {{ s.name
{{ _self.table_delete_diff(_context) }}
func Save{{ s.name }}Diff(ctx context.Context, dbe metadb.Execer, rec {{ s.name }}) error {
ds := metadb.SqlBuilder().
Insert(goqu.T("{{ table_name }}")).
Cols(
{% for f in pkey %}
goqu.C("{{ f.name }}"),
{% endfor %}
)
if rec.changedFields.Empty() {
return nil
}
var queryBuilder strings.Builder
queryBuilder.Grow({{ 52 + table_name|length + insert_column_expr|length + insert_values_expr|length + insert_update_expr|length }})
queryBuilder.WriteString("INSERT INTO `{{ table_name }}` ({{ pkey_column_expr }}")
vals := make(goqu.Vals, 0, {{ s.fields|length }})
var valuesBuilder strings.Builder
valuesBuilder.Grow({{ 10 + insert_values_expr|length }})
valuesBuilder.WriteString(" VALUES ({{ pkey_values_expr }}")
var updateBuilder strings.Builder
updateBuilder.Grow({{ 25 + insert_update_expr|length }})
updateBuilder.WriteString(" ON DUPLICATE KEY UPDATE ")
values := make([]any, 0, 10)
{% for f in pkey %}
vals = append(vals, rec.{{ f|fname }})
values = append(values, rec.{{ f|fname }})
{% endfor %}
updateRecord := make(goqu.Record, {{ nopkey|length }})
initUpdateLen := updateBuilder.Len()
{% for f in nopkey %}
if rec.{{ f|fname }}Changed() {
ds = ds.ColsAppend(goqu.C("{{ f.name }}"))
vals = append(vals, rec.{{ f|fname }})
updateRecord["{{ f.name }}"] = goqu.L("VALUES(`{{ f.name }}`)")
queryBuilder.WriteString(",`{{ f.name }}`")
if updateBuilder.Len() > initUpdateLen {
updateBuilder.WriteRune(',')
}
updateBuilder.WriteString("`{{ f.name }}`=VALUES(`{{ f.name }}`)")
valuesBuilder.WriteString(",?")
values = append(values, rec.{{ f|fname }})
}
{% endfor %}
ds = ds.Vals(vals).OnConflict(goqu.DoUpdate("", updateRecord))
valuesBuilder.WriteRune(')')
query, _, err := ds.ToSQL()
if err != nil {
return errors.WithStack(err)
}
queryBuilder.WriteRune(')')
queryBuilder.WriteString(valuesBuilder.String())
queryBuilder.WriteString(updateBuilder.String())
_, saveErr := dbe.ExecContext(ctx, query)
return errors.WithStack(saveErr)
_, saveErr := dbe.ExecContext(ctx, queryBuilder.String(), values...)
return errors.Wrap(saveErr, queryBuilder.String())
}
{{ _self.table_save_coll_diff(s.name) }}
@ -267,35 +278,27 @@ func Save{{ ctx.s.name }}Collection(ctx context.Context, dbe metadb.Execer, recs
return nil
}
ds := metadb.SqlBuilder().
Insert(goqu.T("{{ ctx.table_name }}")).
Cols(
{%~ for c in ctx.insert_columns %}
goqu.C("{{ c }}"),
{%~ endfor %}
).
OnConflict(goqu.DoUpdate("",
goqu.Record{
{%~ for c in ctx.update_columns %}
"{{ c }}": goqu.L("VALUES(`{{ c }}`)"),
{%~ endfor %}
},
))
for _, rec := range recs {
ds = ds.Vals(goqu.Vals{
var builder strings.Builder
builder.Grow({{ 50 + ctx.table_name|length + ctx.insert_column_expr|length + ctx.insert_update_expr|length }}+len(recs)*{{ ctx.insert_values_expr|length + 2 }}-1)
values := make([]any, 0, len(recs)*{{ ctx.insert_fields|length }})
builder.WriteString("INSERT INTO `{{ ctx.table_name }}` ({{ ctx.insert_column_expr }}) VALUES ")
for i, rec := range recs {
if i > 0 {
builder.WriteRune(',')
}
builder.WriteString("({{ ctx.insert_values_expr }})")
values = append(values,
{%~ for f in ctx.insert_fields %}
rec.{{ f }},
{%~ endfor %}
})
)
}
builder.WriteString(" ON DUPLICATE KEY UPDATE {{ ctx.insert_update_expr }}")
query, _, err := ds.ToSQL()
if err != nil {
return errors.WithStack(err)
}
_, saveErr := dbe.ExecContext(ctx, query)
_, saveErr := dbe.ExecContext(ctx, builder.String(), values...)
return errors.WithStack(saveErr)
}
{% endmacro table_save %}
@ -450,7 +453,6 @@ func Delete{{ ctx.s.name }}ById(
return rowsAffected > 0, nil
}
{% set pkey_values_expr = arr_fill('?', ctx.pkey|length)|join(',') %}
func Delete{{ ctx.s.name }}CollectionById(
ctx context.Context,
dbe metadb.Execer,
@ -460,29 +462,27 @@ func Delete{{ ctx.s.name }}CollectionById(
return nil
}
tuples := make([]exp.LiteralExpression, 0, len(ids))
for _, id := range ids {
tuples = append(tuples, goqu.L("({{ pkey_values_expr }})",
var builder strings.Builder
builder.Grow({{ 29 + ctx.table_name|length + ctx.pkey_column_expr|length }}+len(ids)*{{ ctx.pkey_values_expr|length + 2 }}-1)
values := make([]any, 0, len(ids)*{{ ctx.pkey|length }})
builder.WriteString("DELETE FROM `{{ ctx.table_name }}` WHERE ({{ ctx.pkey_column_expr }}) IN (")
for i, id := range ids {
if i > 0 {
builder.WriteRune(',')
}
builder.WriteString("({{ ctx.pkey_values_expr }})")
values = append(values,
{% for f in ctx.pkey %}
id.{{ f|fname }},
{% endfor %}
))
)
}
builder.WriteRune(')')
ds := metadb.SqlBuilder().
Delete(goqu.T("level_state")).
Where(goqu.L("({{ pkey_values_expr }}) IN ?",
{% for f in ctx.pkey %}
goqu.C("{{ f.name }}"),
{% endfor %}
tuples,
))
query, _, err := ds.ToSQL()
if err != nil {
return errors.WithStack(err)
}
_, delErr := dbe.ExecContext(ctx, query)
_, delErr := dbe.ExecContext(ctx, builder.String(), values...)
return errors.WithStack(delErr)
}
{% endmacro table_delete_diff %}
@ -490,9 +490,14 @@ func Delete{{ ctx.s.name }}CollectionById(
{% macro changed_fields(type_name, fields) %}
{% for f in fields %}
func (s {{ type_name }}) {{ f|fname }}Changed() bool {
return s.changedFields.Changed("{{ f|alias }}")
}
func (s *{{ type_name }}) Set{{ f|fname }}Changed() {
s.changedFields.SetChanged("{{ f|alias }}")
}
{% endfor %}
{% endmacro changed_fields %}
@ -576,11 +581,16 @@ func (s *{{ name|default(o.name) }}) Reset() {
{% endfor %}
{% if has_token(o, 'bitfields') ~%}
s.fieldsMask = meta.FieldsMask{}
s.fieldsMask.Reset()
{%- endif ~%}
{% if has_token(o, 'table') %}
s.changedFields.Reset()
if s.changedFields.IsNil() {
s.changedFields = meta.NewChangedFields({{ o.fields|length }})
} else {
s.changedFields.Reset()
}
{% endif %}
}
{% endmacro reset_method %}