github.com/postmates/migrate@v3.0.2-0.20200730201548-1a6ead3e680d+incompatible/util.go (about)

     1  package migrate
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"io"
     7  	nurl "net/url"
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  // MultiError holds multiple errors.
    13  type MultiError struct {
    14  	Errs []error
    15  }
    16  
    17  // NewMultiError returns an error type holding multiple errors.
    18  func NewMultiError(errs ...error) MultiError {
    19  	compactErrs := make([]error, 0)
    20  	for _, e := range errs {
    21  		if e != nil {
    22  			compactErrs = append(compactErrs, e)
    23  		}
    24  	}
    25  	return MultiError{compactErrs}
    26  }
    27  
    28  // Error implements error. Mulitple errors are concatenated with 'and's.
    29  func (m MultiError) Error() string {
    30  	var strs = make([]string, 0)
    31  	for _, e := range m.Errs {
    32  		if len(e.Error()) > 0 {
    33  			strs = append(strs, e.Error())
    34  		}
    35  	}
    36  	return strings.Join(strs, " and ")
    37  }
    38  
    39  // suint safely converts int to uint
    40  // see https://goo.gl/wEcqof
    41  // see https://goo.gl/pai7Dr
    42  func suint(n int) uint {
    43  	if n < 0 {
    44  		panic(fmt.Sprintf("suint(%v) expects input >= 0", n))
    45  	}
    46  	return uint(n)
    47  }
    48  
    49  // newSlowReader turns an io.ReadCloser into a slow io.ReadCloser.
    50  // Use this to simulate a slow internet connection.
    51  func newSlowReader(r io.ReadCloser) io.ReadCloser {
    52  	return &slowReader{
    53  		rx:     r,
    54  		reader: bufio.NewReader(r),
    55  	}
    56  }
    57  
    58  type slowReader struct {
    59  	rx     io.ReadCloser
    60  	reader *bufio.Reader
    61  }
    62  
    63  func (b *slowReader) Read(p []byte) (n int, err error) {
    64  	time.Sleep(10 * time.Millisecond)
    65  	c, err := b.reader.ReadByte()
    66  	if err != nil {
    67  		return 0, err
    68  	} else {
    69  		copy(p, []byte{c})
    70  		return 1, nil
    71  	}
    72  }
    73  
    74  func (b *slowReader) Close() error {
    75  	return b.rx.Close()
    76  }
    77  
    78  var errNoScheme = fmt.Errorf("no scheme")
    79  
    80  // schemeFromUrl returns the scheme from a URL string
    81  func schemeFromUrl(url string) (string, error) {
    82  	u, err := nurl.Parse(url)
    83  	if err != nil {
    84  		return "", err
    85  	}
    86  
    87  	if len(u.Scheme) == 0 {
    88  		return "", errNoScheme
    89  	}
    90  
    91  	return u.Scheme, nil
    92  }
    93  
    94  // FilterCustomQuery filters all query values starting with `x-`
    95  func FilterCustomQuery(u *nurl.URL) *nurl.URL {
    96  	ux := *u
    97  	vx := make(nurl.Values)
    98  	for k, v := range ux.Query() {
    99  		if len(k) <= 1 || (len(k) > 1 && k[0:2] != "x-") {
   100  			vx[k] = v
   101  		}
   102  	}
   103  	ux.RawQuery = vx.Encode()
   104  	return &ux
   105  }