Skip to content

Instantly share code, notes, and snippets.

@uzimith
Created April 27, 2020 07:03
Show Gist options
  • Save uzimith/930fe30c75290f8e86b433e993abd7bf to your computer and use it in GitHub Desktop.
Save uzimith/930fe30c75290f8e86b433e993abd7bf to your computer and use it in GitHub Desktop.
SQLboiler bulk update
{{- $alias := .Aliases.Table .Table.Name -}}
{{- $schemaTable := .Table.Name | .SchemaTable}}
// UpsertAll upserts all rows with the specified column values, using an executor.
func (o {{$alias.UpSingular}}Slice) UpsertAll({{if .NoContext}}exec boil.Executor{{else}}ctx context.Context, exec boil.ContextExecutor{{end}}, columns boil.Columns) error {
ln := int64(len(o))
if ln == 0 {
return nil
}
var sql string
vals := []interface{}{}
for i, row := range o {
{{- template "timestamp_bulk_upsert_helper" . }}
nzDefaults := queries.NonZeroDefaultSet({{$alias.DownSingular}}ColumnsWithDefault, row)
wl, _ := columns.InsertColumnSet(
{{$alias.DownSingular}}AllColumns,
{{$alias.DownSingular}}ColumnsWithDefault,
{{$alias.DownSingular}}ColumnsWithoutDefault,
nzDefaults,
)
if i == 0 {
sql = "INSERT INTO {{$schemaTable}} " + "({{.LQ}}" + strings.Join(wl, "{{.RQ}},{{.LQ}}") + "{{.RQ}})" + " VALUES "
}
sql += strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), len(vals)+1, len(wl))
if i != len(o)-1 {
sql += ","
}
valMapping, err := queries.BindMapping({{$alias.DownSingular}}Type, {{$alias.DownSingular}}Mapping, wl)
if err != nil {
return err
}
value := reflect.Indirect(reflect.ValueOf(row))
vals = append(vals, queries.ValuesFromMapping(value, valMapping)...)
if i == len(o)-1 {
keyValues := make([]string, 0, len(wl))
for _, col := range wl {
keyValues = append(keyValues, col+"=VALUES("+col+")")
}
sql += " ON DUPLICATE KEY UPDATE " + strings.Join(keyValues, ", ")
}
}
if boil.DebugMode {
fmt.Fprintln(boil.DebugWriter, sql)
fmt.Fprintln(boil.DebugWriter, vals...)
}
{{if .NoContext -}}
_, err := exec.Exec(ctx, sql, vals...)
{{else -}}
_, err := exec.ExecContext(ctx, sql, vals...)
{{end -}}
if err != nil {
return errors.Wrap(err, "{{.PkgName}}: unable to upsert into {{.Table.Name}}")
}
return nil
}
{{- define "timestamp_bulk_upsert_helper" -}}
{{- if not .NoAutoTimestamps -}}
{{- $colNames := .Table.Columns | columnNames -}}
{{if containsAny $colNames "created_at" "updated_at"}}
{{if not .NoContext -}}
if !boil.TimestampsAreSkipped(ctx) {
{{end -}}
currTime := time.Now().In(boil.GetLocation())
{{range $ind, $col := .Table.Columns}}
{{- if eq $col.Name "created_at" -}}
{{- if eq $col.Type "time.Time" }}
if row.CreatedAt.IsZero() {
row.CreatedAt = currTime
}
{{- else}}
if queries.MustTime(row.CreatedAt).IsZero() {
queries.SetScanner(&row.CreatedAt, currTime)
}
{{- end -}}
{{- end -}}
{{- if eq $col.Name "updated_at" -}}
{{- if eq $col.Type "time.Time"}}
if row.UpdatedAt.IsZero() {
row.UpdatedAt = currTime
}
{{- else}}
if queries.MustTime(row.UpdatedAt).IsZero() {
queries.SetScanner(&row.UpdatedAt, currTime)
}
{{- end -}}
{{- end -}}
{{end}}
{{if not .NoContext -}}
}
{{end -}}
{{end}}
{{- end}}
{{- end -}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment