89 строки
1.5 KiB
Go
89 строки
1.5 KiB
Go
|
package migrate
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
nurl "net/url"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type MultiError struct {
|
||
|
Errs []error
|
||
|
}
|
||
|
|
||
|
func NewMultiError(errs ...error) MultiError {
|
||
|
compactErrs := make([]error, 0)
|
||
|
for _, e := range errs {
|
||
|
if e != nil {
|
||
|
compactErrs = append(compactErrs, e)
|
||
|
}
|
||
|
}
|
||
|
return MultiError{compactErrs}
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
|
||
|
// newSlowReader turns an io.Reader into a slow io.Reader
|
||
|
// use 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()
|
||
|
}
|
||
|
|
||
|
var ErrNoName = fmt.Errorf("no name")
|
||
|
|
||
|
func nameFromUrl(url string) (string, error) {
|
||
|
u, err := nurl.Parse(url)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
if len(u.Scheme) == 0 {
|
||
|
return "", ErrNoName
|
||
|
}
|
||
|
|
||
|
return u.Scheme, nil
|
||
|
}
|