Fit caching in to insert.
This commit is contained in:
parent
e1bfd9d0da
commit
793306d749
3 changed files with 75 additions and 20 deletions
|
@ -18,5 +18,28 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
// Cache for insert and update
|
||||
var (
|
||||
{{$varNameSingular}}Mapping = boil.MakeStructMapping(&{{$tableNameSingular}}{})
|
||||
{{$varNameSingular}}InsertCacheMut sync.RMutex
|
||||
{{$varNameSingular}}InsertCache = make(map[string]insertCache)
|
||||
{{$varNameSingular}}UpdateCacheMut sync.RMutex
|
||||
{{$varNameSingular}}UpdateCache = make(map[string]updateCache)
|
||||
)
|
||||
|
||||
func makeCacheKey(wl, nzDefaults []string) string {
|
||||
buf := strmangle.GetBuffer()
|
||||
|
||||
for _, w := range wl {
|
||||
buf.WriteString(w)
|
||||
}
|
||||
for _, nz := range nzDefaults {
|
||||
buf.WriteString(nz)
|
||||
}
|
||||
|
||||
str := buf.String()
|
||||
strmangle.PutBuffer(buf)
|
||||
}
|
||||
|
||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||
var _ = time.Second
|
||||
|
|
|
@ -40,15 +40,35 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
}
|
||||
{{- end}}
|
||||
|
||||
wl, returnColumns := strmangle.InsertColumnSet(
|
||||
{{$varNameSingular}}Columns,
|
||||
{{$varNameSingular}}ColumnsWithDefault,
|
||||
{{$varNameSingular}}ColumnsWithoutDefault,
|
||||
boil.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, {{$varNameSingular}}TitleCases, o),
|
||||
whitelist,
|
||||
)
|
||||
nzDefaults := boil.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, o)
|
||||
|
||||
ins := fmt.Sprintf(`INSERT INTO {{.Table.Name}} ("%s") VALUES (%s)`, strings.Join(wl, `","`), strmangle.Placeholders(len(wl), 1, 1))
|
||||
key := makeCacheKey(whitelist, nzDefaults)
|
||||
{{$varNameSingular}}InsertCacheMut.RLock()
|
||||
cache, cached := {{$varNameSingular}}InsertCache[key]
|
||||
{{$varNameSingular}}InsertCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl, returnColumns := strmangle.InsertColumnSet(
|
||||
{{$varNameSingular}}Columns,
|
||||
{{$varNameSingular}}ColumnsWithDefault,
|
||||
{{$varNameSingular}}ColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
whitelist,
|
||||
)
|
||||
|
||||
typ := reflect.TypeOf(o)
|
||||
cache.valueMapping = boil.BindMapping(typ, {{$varNameSingular}}Mapping, wl)
|
||||
cache.retMapping = boil.BindMapping(typ, {{$varNameSingular}}Mapping, returnColumns)
|
||||
cache.query = fmt.Sprintf(`INSERT INTO {{.Table.Name}} ("%s") VALUES (%s)`, strings.Join(wl, `","`), strmangle.Placeholders(len(wl), 1, 1))
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
{{if .UseLastInsertID -}}
|
||||
cache.query += fmt.Sprintf(` RETURNING %s`, strings.Join(returnColumns, ","))
|
||||
{{else -}}
|
||||
cache.retQuery = fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, {{$varNameSingular}}AutoIncPrimaryKeys))
|
||||
{{end -}}
|
||||
}
|
||||
}
|
||||
|
||||
{{if .UseLastInsertID}}
|
||||
if boil.DebugMode {
|
||||
|
@ -61,32 +81,28 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
return errors.Wrap(err, "{{.PkgName}}: unable to insert into {{.Table.Name}}")
|
||||
}
|
||||
|
||||
if len(cache.retMapping) == 0 {
|
||||
{{if not .NoHooks -}}
|
||||
if len(returnColumns) == 0 {
|
||||
return o.doAfterInsertHooks(exec)
|
||||
}
|
||||
{{- else -}}
|
||||
if len(returnColumns) == 0 {
|
||||
return o.doAfterInsertHooks(exec)
|
||||
{{else -}}
|
||||
return nil
|
||||
{{end -}}
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
lastID, err := result.LastInsertId()
|
||||
if err != nil || lastID == 0 || len({{$varNameSingular}}AutoIncPrimaryKeys) != 1 {
|
||||
return ErrSyncFail
|
||||
}
|
||||
|
||||
sel := fmt.Sprintf(`SELECT %s FROM {{.Table.Name}} WHERE %s`, strings.Join(returnColumns, `","`), strmangle.WhereClause(1, {{$varNameSingular}}AutoIncPrimaryKeys))
|
||||
err = exec.QueryRow(sel, lastID).Scan(boil.GetStructPointers(o, returnColumns...))
|
||||
err = exec.QueryRow(cache.retQuery, lastID).Scan(boil.GetStructPointers(o, returnColumns...))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "{{.PkgName}}: unable to populate default values for {{.Table.Name}}")
|
||||
}
|
||||
{{else}}
|
||||
if len(returnColumns) != 0 {
|
||||
ins = ins + fmt.Sprintf(` RETURNING %s`, strings.Join(returnColumns, ","))
|
||||
err = exec.QueryRow(ins, boil.GetStructValues(o, wl...)...).Scan(boil.GetStructPointers(o, returnColumns...)...)
|
||||
if len(cache.retMapping) != 0 {
|
||||
err = exec.QueryRow(cache.query, boil.GetStructValues(o, wl...)...).Scan(boil.GetStructPointers(o, returnColumns...)...)
|
||||
} else {
|
||||
_, err = exec.Exec(ins, boil.GetStructValues(o, wl...)...)
|
||||
_, err = exec.Exec(cache.query, boil.GetStructValues(o, wl...)...)
|
||||
}
|
||||
|
||||
if boil.DebugMode {
|
||||
|
@ -99,6 +115,10 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
|||
}
|
||||
{{end}}
|
||||
|
||||
{{$varNameSingular}}InsertCacheMut.Lock()
|
||||
{{$varNameSingular}}InsertCache[key] = cache
|
||||
{{$varNameSingular}}InsertCacheMut.Unlock()
|
||||
|
||||
{{if not .NoHooks -}}
|
||||
return o.doAfterInsertHooks(exec)
|
||||
{{- else -}}
|
||||
|
|
|
@ -5,3 +5,15 @@ type M map[string]interface{}
|
|||
// order to populate default value information. This usually happens when LastInsertId
|
||||
// fails or there was a primary key configuration that was not resolvable.
|
||||
var ErrSyncFail = errors.New("{{.PkgName}}: failed to synchronize data after insert")
|
||||
|
||||
type insertCache struct{
|
||||
query string
|
||||
retQuery string
|
||||
valueMapping []uint64
|
||||
retMapping []uint64
|
||||
}
|
||||
|
||||
type updateCache struct{
|
||||
query string
|
||||
valueMapping []uint64
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue