migrate-template/template.go

92 lines
1.6 KiB
Go

package template
import (
"bytes"
"io"
"io/ioutil"
"text/template"
"github.com/golang-migrate/migrate/v4/source"
)
type driver struct {
source.Driver
funcs template.FuncMap
vars M
}
func (d *driver) parse(r io.ReadCloser) (io.ReadCloser, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
tpl, err := template.New("").Funcs(d.funcs).Parse(string(data))
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
if err = tpl.Execute(buf, d.vars); err != nil {
return nil, err
}
return ioutil.NopCloser(buf), nil
}
func (d *driver) Open(url string) (source.Driver, error) {
inner, err := d.Driver.Open(url)
if err != nil {
return nil, err
}
return &driver{Driver: inner}, nil
}
func (d *driver) ReadUp(version uint) (r io.ReadCloser, identifier string, err error) {
r, identifier, err = d.Driver.ReadUp(version)
if err == nil {
r, err = d.parse(r)
}
return
}
func (d *driver) ReadDown(version uint) (r io.ReadCloser, identifier string, err error) {
r, identifier, err = d.Driver.ReadDown(version)
if err == nil {
r, err = d.parse(r)
}
return
}
type Option func(d *driver)
type M map[string]interface{}
func WithVars(vars M) Option {
return func(d *driver) {
for k := range vars {
d.vars[k] = vars[k]
}
}
}
func WithFuncs(funcs template.FuncMap) Option {
return func(d *driver) {
for k := range funcs {
d.funcs[k] = funcs[k]
}
}
}
func Wrap(inner source.Driver, opts ...Option) source.Driver {
d := &driver{
Driver: inner,
funcs: make(template.FuncMap),
vars: make(M),
}
for _, opt := range opts {
opt(d)
}
return d
}