Builder for single query in saving collections
This commit is contained in:
parent
a915af9640
commit
a643fd99f2
|
@ -35,10 +35,26 @@ var _ = strings.Clone
|
|||
{{ enum_macros.enum(u.object) }}
|
||||
{% endfor %}
|
||||
|
||||
type queryDiffBuilder struct {
|
||||
query *strings.Builder
|
||||
values *strings.Builder
|
||||
update *strings.Builder
|
||||
rawValues []any
|
||||
}
|
||||
|
||||
func NewQueryDiffBuilder() queryDiffBuilder {
|
||||
return queryDiffBuilder{
|
||||
query: &strings.Builder{},
|
||||
values: &strings.Builder{},
|
||||
update: &strings.Builder{},
|
||||
}
|
||||
}
|
||||
|
||||
{% for u in structs %}
|
||||
{{ struct_macros.struct(u.object) }}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
func CreateById(classId uint32) (meta.Struct, error) {
|
||||
switch classId {
|
||||
{% for u in structs %}
|
||||
|
|
|
@ -215,11 +215,66 @@ func Save{{ ctx.s.name }}Diff(ctx context.Context, dbe metadb.Execer, rec {{ ctx
|
|||
}
|
||||
|
||||
func Save{{ ctx.s.name }}CollectionDiff(ctx context.Context, dbe metadb.Execer, recs []{{ ctx.s.name }}) error {
|
||||
byFieldsKey := map[string]queryDiffBuilder{}
|
||||
for _, rec := range recs {
|
||||
if err := Save{{ ctx.s.name }}Diff(ctx, dbe, rec); err != nil {
|
||||
return err
|
||||
if rec.changedFields.Empty() {
|
||||
continue
|
||||
}
|
||||
|
||||
key := rec.changedFields.GetFieldsKey()
|
||||
if _, ok := byFieldsKey[key]; !ok {
|
||||
builder := NewQueryDiffBuilder()
|
||||
|
||||
builder.query.WriteString("INSERT INTO `{{ ctx.table_name }}` ({{ ctx.pkey_column_expr }}")
|
||||
builder.update.WriteString(" ON DUPLICATE KEY UPDATE {{ ctx.pkey_update_expr }}")
|
||||
builder.values.WriteString(" VALUES ")
|
||||
|
||||
{% if ctx.raw_nonpk_fields|length > 0 %}
|
||||
{% for f in ctx.raw_nonpk_fields %}
|
||||
if rec.{{ f|fname }}Changed() {
|
||||
builder.query.WriteString(",`{{ f.name }}`")
|
||||
builder.update.WriteString(",`{{ f.name }}`=VALUES(`{{ f.name }}`)")
|
||||
}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
byFieldsKey[key] = builder
|
||||
}
|
||||
|
||||
builder := byFieldsKey[key]
|
||||
builder.values.WriteString("({{ ctx.pkey_values_expr }}")
|
||||
|
||||
{% for f in ctx.pkey %}
|
||||
builder.rawValues = append(builder.rawValues, rec.{{ f|fname }})
|
||||
{% endfor %}
|
||||
|
||||
{% if ctx.raw_nonpk_fields|length > 0 %}
|
||||
{% for f in ctx.raw_nonpk_fields %}
|
||||
if rec.{{ f|fname }}Changed() {
|
||||
builder.values.WriteString(",?")
|
||||
builder.rawValues = append(builder.rawValues, rec.{{ f|fname }})
|
||||
}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
builder.values.WriteRune(')')
|
||||
builder.values.WriteRune(',')
|
||||
}
|
||||
|
||||
for _, builder := range byFieldsKey {
|
||||
var index int = 1
|
||||
if len(builder.rawValues) > 1 {
|
||||
index = 2
|
||||
}
|
||||
queryBuilder := builder.query
|
||||
builder.query.WriteRune(')')
|
||||
queryBuilder.WriteString(builder.values.String()[0 : len(builder.values.String())-index])
|
||||
queryBuilder.WriteString(builder.update.String())
|
||||
|
||||
_, saveErr := dbe.ExecContext(ctx, queryBuilder.String(), builder.rawValues...)
|
||||
return errors.Wrap(saveErr, queryBuilder.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
{% endmacro table_save %}
|
||||
|
|
Loading…
Reference in New Issue