migrate/util.go

93 lines
1.7 KiB
Go
Raw Normal View History

package migrate
import (
"bufio"
"fmt"
"io"
nurl "net/url"
"strings"
"time"
)
2017-02-10 00:59:30 +00:00
// MultiError holds multiple errors.
type MultiError struct {
Errs []error
}
2017-02-10 00:59:30 +00:00
// NewMultiError returns an error type holding multiple errors.
func NewMultiError(errs ...error) MultiError {
compactErrs := make([]error, 0)
for _, e := range errs {
if e != nil {
compactErrs = append(compactErrs, e)
}
}
return MultiError{compactErrs}
}
2017-02-10 00:59:30 +00:00
// Error implements error. Mulitple errors are concatenated with 'and's.
func (m MultiError) Error() string {
var strs = make([]string, 0)
for _, e := range m.Errs {
if len(e.Error()) > 0 {
strs = append(strs, e.Error())
}
}
return strings.Join(strs, " and ")
}
// suint safely converts int to uint
// see https://goo.gl/wEcqof
// see https://goo.gl/pai7Dr
func suint(n int) uint {
if n < 0 {
panic(fmt.Sprintf("suint(%v) expects input >= 0", n))
}
return uint(n)
}
2017-02-10 02:19:13 +00:00
// newSlowReader turns an io.ReadCloser into a slow io.ReadCloser.
// Use this to simulate a slow internet connection.
func newSlowReader(r io.ReadCloser) io.ReadCloser {
return &slowReader{
rx: r,
reader: bufio.NewReader(r),
}
}
type slowReader struct {
rx io.ReadCloser
reader *bufio.Reader
}
func (b *slowReader) Read(p []byte) (n int, err error) {
time.Sleep(10 * time.Millisecond)
c, err := b.reader.ReadByte()
if err != nil {
return 0, err
} else {
copy(p, []byte{c})
return 1, nil
}
}
func (b *slowReader) Close() error {
return b.rx.Close()
}
2017-02-10 02:19:13 +00:00
var errNoScheme = fmt.Errorf("no scheme")
2017-02-10 02:19:13 +00:00
// schemeFromUrl returns the scheme from a URL string
func schemeFromUrl(url string) (string, error) {
u, err := nurl.Parse(url)
if err != nil {
return "", err
}
if len(u.Scheme) == 0 {
2017-02-10 02:19:13 +00:00
return "", errNoScheme
}
return u.Scheme, nil
}