DB Migrations #67
37
vendor/github.com/go-xorm/builder/.drone.yml
generated
vendored
Normal file
37
vendor/github.com/go-xorm/builder/.drone.yml
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/github.com/go-xorm/builder
|
||||||
|
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: plugins/git:next
|
||||||
|
depth: 50
|
||||||
|
tags: true
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
GO_VERSION:
|
||||||
|
- 1.8
|
||||||
|
- 1.9
|
||||||
|
- 1.10
|
||||||
|
- 1.11
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
test:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go get -u github.com/golang/lint/golint
|
||||||
|
- go get -u github.com/stretchr/testify/assert
|
||||||
|
- go get -u github.com/go-xorm/sqlfiddle
|
||||||
|
- golint ./...
|
||||||
|
- go test -v -race -coverprofile=coverage.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
codecov:
|
||||||
|
image: robertstettner/drone-codecov
|
||||||
|
group: build
|
||||||
|
secrets: [ codecov_token ]
|
||||||
|
files:
|
||||||
|
- coverage.txt
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
100
vendor/github.com/go-xorm/builder/builder_limit.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Builder) limitWriteTo(w Writer) error {
|
||||||
|
if strings.TrimSpace(b.dialect) == "" {
|
||||||
|
return ErrDialectNotSetUp
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.limitation != nil {
|
||||||
|
limit := b.limitation
|
||||||
|
if limit.offset < 0 || limit.limitN <= 0 {
|
||||||
|
return ErrInvalidLimitation
|
||||||
|
}
|
||||||
|
// erase limit condition
|
||||||
|
b.limitation = nil
|
||||||
|
ow := w.(*BytesWriter)
|
||||||
|
|
||||||
|
switch strings.ToLower(strings.TrimSpace(b.dialect)) {
|
||||||
|
case ORACLE:
|
||||||
|
if len(b.selects) == 0 {
|
||||||
|
b.selects = append(b.selects, "*")
|
||||||
|
}
|
||||||
|
|
||||||
|
var final *Builder
|
||||||
|
selects := b.selects
|
||||||
|
b.selects = append(selects, "ROWNUM RN")
|
||||||
|
|
||||||
|
var wb *Builder
|
||||||
|
if b.optype == unionType {
|
||||||
|
wb = Dialect(b.dialect).Select("at.*", "ROWNUM RN").
|
||||||
|
From(b, "at")
|
||||||
|
} else {
|
||||||
|
wb = b
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit.offset == 0 {
|
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at").
|
||||||
|
Where(Lte{"at.RN": limit.limitN})
|
||||||
|
} else {
|
||||||
|
sub := Dialect(b.dialect).Select("*").
|
||||||
|
From(b, "at").Where(Lte{"at.RN": limit.offset + limit.limitN})
|
||||||
|
|
||||||
|
final = Dialect(b.dialect).Select(selects...).From(sub, "att").
|
||||||
|
Where(Gt{"att.RN": limit.offset})
|
||||||
|
}
|
||||||
|
|
||||||
|
return final.WriteTo(ow)
|
||||||
|
case SQLITE, MYSQL, POSTGRES:
|
||||||
|
// if type UNION, we need to write previous content back to current writer
|
||||||
|
if b.optype == unionType {
|
||||||
|
if err := b.WriteTo(ow); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit.offset == 0 {
|
||||||
|
fmt.Fprint(ow, " LIMIT ", limit.limitN)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset)
|
||||||
|
}
|
||||||
|
case MSSQL:
|
||||||
|
if len(b.selects) == 0 {
|
||||||
|
b.selects = append(b.selects, "*")
|
||||||
|
}
|
||||||
|
|
||||||
|
var final *Builder
|
||||||
|
selects := b.selects
|
||||||
|
b.selects = append(append([]string{fmt.Sprintf("TOP %d %v", limit.limitN+limit.offset, b.selects[0])},
|
||||||
|
b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN")
|
||||||
|
|
||||||
|
var wb *Builder
|
||||||
|
if b.optype == unionType {
|
||||||
|
wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN").
|
||||||
|
From(b, "at")
|
||||||
|
} else {
|
||||||
|
wb = b
|
||||||
|
}
|
||||||
|
|
||||||
|
if limit.offset == 0 {
|
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at")
|
||||||
|
} else {
|
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at").Where(Gt{"at.RN": limit.offset})
|
||||||
|
}
|
||||||
|
|
||||||
|
return final.WriteTo(ow)
|
||||||
|
default:
|
||||||
|
return ErrNotSupportType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
47
vendor/github.com/go-xorm/builder/builder_union.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Builder) unionWriteTo(w Writer) error {
|
||||||
|
if b.limitation != nil || b.cond.IsValid() ||
|
||||||
|
b.orderBy != "" || b.having != "" || b.groupBy != "" {
|
||||||
|
return ErrNotUnexpectedUnionConditions
|
||||||
|
}
|
||||||
|
|
||||||
|
for idx, u := range b.unions {
|
||||||
|
current := u.builder
|
||||||
|
if current.optype != selectType {
|
||||||
|
return ErrUnsupportedUnionMembers
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b.unions) == 1 {
|
||||||
|
if err := current.selectWriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if b.dialect != "" && b.dialect != current.dialect {
|
||||||
|
return ErrInconsistentDialect
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx != 0 {
|
||||||
|
fmt.Fprint(w, fmt.Sprintf(" UNION %v ", strings.ToUpper(u.unionType)))
|
||||||
|
}
|
||||||
|
fmt.Fprint(w, "(")
|
||||||
|
|
||||||
|
if err := current.selectWriteTo(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprint(w, ")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
1
vendor/github.com/go-xorm/builder/go.mod
generated
vendored
Normal file
1
vendor/github.com/go-xorm/builder/go.mod
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
module "github.com/go-xorm/builder"
|
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
156
vendor/github.com/go-xorm/builder/sql.go
generated
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder
|
||||||
|
|
||||||
|
import (
|
||||||
|
sql2 "database/sql"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func condToSQL(cond Cond) (string, []interface{}, error) {
|
||||||
|
if cond == nil || !cond.IsValid() {
|
||||||
|
return "", nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
w := NewWriter()
|
||||||
|
if err := cond.WriteTo(w); err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return w.writer.String(), w.args, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func condToBoundSQL(cond Cond) (string, error) {
|
||||||
|
if cond == nil || !cond.IsValid() {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
w := NewWriter()
|
||||||
|
if err := cond.WriteTo(w); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return ConvertToBoundSQL(w.writer.String(), w.args)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSQL convert a builder or conditions to SQL and args
|
||||||
|
func ToSQL(cond interface{}) (string, []interface{}, error) {
|
||||||
|
switch cond.(type) {
|
||||||
|
case Cond:
|
||||||
|
return condToSQL(cond.(Cond))
|
||||||
|
case *Builder:
|
||||||
|
return cond.(*Builder).ToSQL()
|
||||||
|
}
|
||||||
|
return "", nil, ErrNotSupportType
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBoundSQL convert a builder or conditions to parameters bound SQL
|
||||||
|
func ToBoundSQL(cond interface{}) (string, error) {
|
||||||
|
switch cond.(type) {
|
||||||
|
case Cond:
|
||||||
|
return condToBoundSQL(cond.(Cond))
|
||||||
|
case *Builder:
|
||||||
|
return cond.(*Builder).ToBoundSQL()
|
||||||
|
}
|
||||||
|
return "", ErrNotSupportType
|
||||||
|
}
|
||||||
|
|
||||||
|
func noSQLQuoteNeeded(a interface{}) bool {
|
||||||
|
switch a.(type) {
|
||||||
|
case int, int8, int16, int32, int64:
|
||||||
|
return true
|
||||||
|
case uint, uint8, uint16, uint32, uint64:
|
||||||
|
return true
|
||||||
|
case float32, float64:
|
||||||
|
return true
|
||||||
|
case bool:
|
||||||
|
return true
|
||||||
|
case string:
|
||||||
|
return false
|
||||||
|
case time.Time, *time.Time:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
t := reflect.TypeOf(a)
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return true
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return true
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return true
|
||||||
|
case reflect.Bool:
|
||||||
|
return true
|
||||||
|
case reflect.String:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertToBoundSQL will convert SQL and args to a bound SQL
|
||||||
|
func ConvertToBoundSQL(sql string, args []interface{}) (string, error) {
|
||||||
|
buf := StringBuilder{}
|
||||||
|
var i, j, start int
|
||||||
|
for ; i < len(sql); i++ {
|
||||||
|
if sql[i] == '?' {
|
||||||
|
_, err := buf.WriteString(sql[start:i])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
start = i + 1
|
||||||
|
|
||||||
|
if len(args) == j {
|
||||||
|
return "", ErrNeedMoreArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
arg := args[j]
|
||||||
|
if namedArg, ok := arg.(sql2.NamedArg); ok {
|
||||||
|
arg = namedArg.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
if noSQLQuoteNeeded(arg) {
|
||||||
|
_, err = fmt.Fprint(&buf, arg)
|
||||||
|
} else {
|
||||||
|
_, err = fmt.Fprintf(&buf, "'%v'", arg)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
j = j + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := buf.WriteString(sql[start:])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
|
||||||
|
func ConvertPlaceholder(sql, prefix string) (string, error) {
|
||||||
|
buf := StringBuilder{}
|
||||||
|
var i, j, start int
|
||||||
|
for ; i < len(sql); i++ {
|
||||||
|
if sql[i] == '?' {
|
||||||
|
if _, err := buf.WriteString(sql[start:i]); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
start = i + 1
|
||||||
|
j = j + 1
|
||||||
|
|
||||||
|
if _, err := buf.WriteString(fmt.Sprintf("%v%d", prefix, j)); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := buf.WriteString(sql[start:]); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String(), nil
|
||||||
|
}
|
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
119
vendor/github.com/go-xorm/builder/string_builder.go
generated
vendored
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A StringBuilder is used to efficiently build a string using Write methods.
|
||||||
|
// It minimizes memory copying. The zero value is ready to use.
|
||||||
|
// Do not copy a non-zero Builder.
|
||||||
|
type StringBuilder struct {
|
||||||
|
addr *StringBuilder // of receiver, to detect copies by value
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// noescape hides a pointer from escape analysis. noescape is
|
||||||
|
// the identity function but escape analysis doesn't think the
|
||||||
|
// output depends on the input. noescape is inlined and currently
|
||||||
|
// compiles down to zero instructions.
|
||||||
|
// USE CAREFULLY!
|
||||||
|
// This was copied from the runtime; see issues 23382 and 7921.
|
||||||
|
//go:nosplit
|
||||||
|
func noescape(p unsafe.Pointer) unsafe.Pointer {
|
||||||
|
x := uintptr(p)
|
||||||
|
return unsafe.Pointer(x ^ 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *StringBuilder) copyCheck() {
|
||||||
|
if b.addr == nil {
|
||||||
|
// This hack works around a failing of Go's escape analysis
|
||||||
|
// that was causing b to escape and be heap allocated.
|
||||||
|
// See issue 23382.
|
||||||
|
// TODO: once issue 7921 is fixed, this should be reverted to
|
||||||
|
// just "b.addr = b".
|
||||||
|
b.addr = (*StringBuilder)(noescape(unsafe.Pointer(b)))
|
||||||
|
} else if b.addr != b {
|
||||||
|
panic("strings: illegal use of non-zero Builder copied by value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the accumulated string.
|
||||||
|
func (b *StringBuilder) String() string {
|
||||||
|
return *(*string)(unsafe.Pointer(&b.buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
|
||||||
|
func (b *StringBuilder) Len() int { return len(b.buf) }
|
||||||
|
|
||||||
|
// Reset resets the Builder to be empty.
|
||||||
|
func (b *StringBuilder) Reset() {
|
||||||
|
b.addr = nil
|
||||||
|
b.buf = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// grow copies the buffer to a new, larger buffer so that there are at least n
|
||||||
|
// bytes of capacity beyond len(b.buf).
|
||||||
|
func (b *StringBuilder) grow(n int) {
|
||||||
|
buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
|
||||||
|
copy(buf, b.buf)
|
||||||
|
b.buf = buf
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grow grows b's capacity, if necessary, to guarantee space for
|
||||||
|
// another n bytes. After Grow(n), at least n bytes can be written to b
|
||||||
|
// without another allocation. If n is negative, Grow panics.
|
||||||
|
func (b *StringBuilder) Grow(n int) {
|
||||||
|
b.copyCheck()
|
||||||
|
if n < 0 {
|
||||||
|
panic("strings.Builder.Grow: negative count")
|
||||||
|
}
|
||||||
|
if cap(b.buf)-len(b.buf) < n {
|
||||||
|
b.grow(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write appends the contents of p to b's buffer.
|
||||||
|
// Write always returns len(p), nil.
|
||||||
|
func (b *StringBuilder) Write(p []byte) (int, error) {
|
||||||
|
b.copyCheck()
|
||||||
|
b.buf = append(b.buf, p...)
|
||||||
|
return len(p), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteByte appends the byte c to b's buffer.
|
||||||
|
// The returned error is always nil.
|
||||||
|
func (b *StringBuilder) WriteByte(c byte) error {
|
||||||
|
b.copyCheck()
|
||||||
|
b.buf = append(b.buf, c)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
|
||||||
|
// It returns the length of r and a nil error.
|
||||||
|
func (b *StringBuilder) WriteRune(r rune) (int, error) {
|
||||||
|
b.copyCheck()
|
||||||
|
if r < utf8.RuneSelf {
|
||||||
|
b.buf = append(b.buf, byte(r))
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
l := len(b.buf)
|
||||||
|
if cap(b.buf)-l < utf8.UTFMax {
|
||||||
|
b.grow(utf8.UTFMax)
|
||||||
|
}
|
||||||
|
n := utf8.EncodeRune(b.buf[l:l+utf8.UTFMax], r)
|
||||||
|
b.buf = b.buf[:l+n]
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteString appends the contents of s to b's buffer.
|
||||||
|
// It returns the length of s and a nil error.
|
||||||
|
func (b *StringBuilder) WriteString(s string) (int, error) {
|
||||||
|
b.copyCheck()
|
||||||
|
b.buf = append(b.buf, s...)
|
||||||
|
return len(s), nil
|
||||||
|
}
|
125
vendor/github.com/go-xorm/xorm/.drone.yml
generated
vendored
Normal file
125
vendor/github.com/go-xorm/xorm/.drone.yml
generated
vendored
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/github.com/go-xorm/xorm
|
||||||
|
|
||||||
|
clone:
|
||||||
|
git:
|
||||||
|
image: plugins/git:next
|
||||||
|
depth: 50
|
||||||
|
tags: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:5.7
|
||||||
|
environment:
|
||||||
|
- MYSQL_DATABASE=xorm_test
|
||||||
|
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
pgsql:
|
||||||
|
image: postgres:9.5
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=postgres
|
||||||
|
- POSTGRES_DB=xorm_test
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
#mssql:
|
||||||
|
# image: microsoft/mssql-server-linux:2017-CU11
|
||||||
|
# environment:
|
||||||
|
# - ACCEPT_EULA=Y
|
||||||
|
# - SA_PASSWORD=yourStrong(!)Password
|
||||||
|
# - MSSQL_PID=Developer
|
||||||
|
# commands:
|
||||||
|
# - echo 'CREATE DATABASE xorm_test' > create.sql
|
||||||
|
# - /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P yourStrong(!)Password -i "create.sql"
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
GO_VERSION:
|
||||||
|
- 1.8
|
||||||
|
- 1.9
|
||||||
|
- 1.10
|
||||||
|
- 1.11
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
init_postgres:
|
||||||
|
image: postgres:9.5
|
||||||
|
commands:
|
||||||
|
# wait for postgres service to become available
|
||||||
|
- |
|
||||||
|
until psql -U postgres -d xorm_test -h pgsql \
|
||||||
|
-c "SELECT 1;" >/dev/null 2>&1; do sleep 1; done
|
||||||
|
# query the database
|
||||||
|
- |
|
||||||
|
psql -U postgres -d xorm_test -h pgsql \
|
||||||
|
-c "create schema xorm;"
|
||||||
|
|
||||||
|
build:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go get -t -d -v ./...
|
||||||
|
- go get -u github.com/go-xorm/core
|
||||||
|
- go get -u github.com/go-xorm/builder
|
||||||
|
- go build -v
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-sqlite:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go get -u github.com/wadey/gocovmerge
|
||||||
|
- go test -v -race -db="sqlite3" -conn_str="./test.db" -coverprofile=coverage1-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-mysql:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -coverprofile=coverage2-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-mysql-utf8mb4:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -coverprofile=coverage2.1-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@tcp(mysql)/xorm_test?charset=utf8mb4" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-mymysql:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -coverprofile=coverage3-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mymysql" -conn_str="tcp:mysql:3306*xorm_test/root/" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-postgres:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -coverprofile=coverage4-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
test-postgres-schema:
|
||||||
|
image: golang:${GO_VERSION}
|
||||||
|
commands:
|
||||||
|
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="postgres" -conn_str="postgres://postgres:@pgsql/xorm_test?sslmode=disable" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic
|
||||||
|
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage2.1-1.txt coverage2.1-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt coverage5-1.txt coverage5-2.txt > coverage.txt
|
||||||
|
when:
|
||||||
|
event: [ push, pull_request ]
|
||||||
|
|
||||||
|
#coverage:
|
||||||
|
# image: robertstettner/drone-codecov
|
||||||
|
# secrets: [ codecov_token ]
|
||||||
|
# files:
|
||||||
|
# - coverage.txt
|
||||||
|
# when:
|
||||||
|
# event: [ push, pull_request ]
|
||||||
|
# branch: [ master ]
|
26
vendor/github.com/go-xorm/xorm/context.go
generated
vendored
Normal file
26
vendor/github.com/go-xorm/xorm/context.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// PingContext tests if database is alive
|
||||||
|
func (engine *Engine) PingContext(ctx context.Context) error {
|
||||||
|
session := engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
return session.PingContext(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PingContext test if database is ok
|
||||||
|
func (session *Session) PingContext(ctx context.Context) error {
|
||||||
|
if session.isAutoClose {
|
||||||
|
defer session.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName())
|
||||||
|
return session.DB().PingContext(ctx)
|
||||||
|
}
|
30
vendor/github.com/go-xorm/xorm/context_cache.go
generated
vendored
Normal file
30
vendor/github.com/go-xorm/xorm/context_cache.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
// ContextCache is the interface that operates the cache data.
|
||||||
|
type ContextCache interface {
|
||||||
|
// Put puts value into cache with key.
|
||||||
|
Put(key string, val interface{})
|
||||||
|
// Get gets cached value by given key.
|
||||||
|
Get(key string) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type memoryContextCache map[string]interface{}
|
||||||
|
|
||||||
|
// NewMemoryContextCache return memoryContextCache
|
||||||
|
func NewMemoryContextCache() memoryContextCache {
|
||||||
|
return make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put puts value into cache with key.
|
||||||
|
func (m memoryContextCache) Put(key string, val interface{}) {
|
||||||
|
m[key] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get gets cached value by given key.
|
||||||
|
func (m memoryContextCache) Get(key string) interface{} {
|
||||||
|
return m[key]
|
||||||
|
}
|
204
vendor/github.com/go-xorm/xorm/engine_group.go
generated
vendored
Normal file
204
vendor/github.com/go-xorm/xorm/engine_group.go
generated
vendored
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EngineGroup defines an engine group
|
||||||
|
type EngineGroup struct {
|
||||||
|
*Engine
|
||||||
|
slaves []*Engine
|
||||||
|
policy GroupPolicy
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEngineGroup creates a new engine group
|
||||||
|
func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) {
|
||||||
|
var eg EngineGroup
|
||||||
|
if len(policies) > 0 {
|
||||||
|
eg.policy = policies[0]
|
||||||
|
} else {
|
||||||
|
eg.policy = RoundRobinPolicy()
|
||||||
|
}
|
||||||
|
|
||||||
|
driverName, ok1 := args1.(string)
|
||||||
|
conns, ok2 := args2.([]string)
|
||||||
|
if ok1 && ok2 {
|
||||||
|
engines := make([]*Engine, len(conns))
|
||||||
|
for i, conn := range conns {
|
||||||
|
engine, err := NewEngine(driverName, conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
engine.engineGroup = &eg
|
||||||
|
engines[i] = engine
|
||||||
|
}
|
||||||
|
|
||||||
|
eg.Engine = engines[0]
|
||||||
|
eg.slaves = engines[1:]
|
||||||
|
return &eg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
master, ok3 := args1.(*Engine)
|
||||||
|
slaves, ok4 := args2.([]*Engine)
|
||||||
|
if ok3 && ok4 {
|
||||||
|
master.engineGroup = &eg
|
||||||
|
for i := 0; i < len(slaves); i++ {
|
||||||
|
slaves[i].engineGroup = &eg
|
||||||
|
}
|
||||||
|
eg.Engine = master
|
||||||
|
eg.slaves = slaves
|
||||||
|
return &eg, nil
|
||||||
|
}
|
||||||
|
return nil, ErrParamsType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the engine
|
||||||
|
func (eg *EngineGroup) Close() error {
|
||||||
|
err := eg.Engine.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
err := eg.slaves[i].Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Master returns the master engine
|
||||||
|
func (eg *EngineGroup) Master() *Engine {
|
||||||
|
return eg.Engine
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ping tests if database is alive
|
||||||
|
func (eg *EngineGroup) Ping() error {
|
||||||
|
if err := eg.Engine.Ping(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, slave := range eg.slaves {
|
||||||
|
if err := slave.Ping(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetColumnMapper set the column name mapping rule
|
||||||
|
func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) {
|
||||||
|
eg.Engine.ColumnMapper = mapper
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].ColumnMapper = mapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
|
||||||
|
func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) {
|
||||||
|
eg.Engine.SetConnMaxLifetime(d)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].SetConnMaxLifetime(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaultCacher set the default cacher
|
||||||
|
func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) {
|
||||||
|
eg.Engine.SetDefaultCacher(cacher)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].SetDefaultCacher(cacher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogger set the new logger
|
||||||
|
func (eg *EngineGroup) SetLogger(logger core.ILogger) {
|
||||||
|
eg.Engine.SetLogger(logger)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].SetLogger(logger)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLogLevel sets the logger level
|
||||||
|
func (eg *EngineGroup) SetLogLevel(level core.LogLevel) {
|
||||||
|
eg.Engine.SetLogLevel(level)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].SetLogLevel(level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMapper set the name mapping rules
|
||||||
|
func (eg *EngineGroup) SetMapper(mapper core.IMapper) {
|
||||||
|
eg.Engine.SetMapper(mapper)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].SetMapper(mapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMaxIdleConns set the max idle connections on pool, default is 2
|
||||||
|
func (eg *EngineGroup) SetMaxIdleConns(conns int) {
|
||||||
|
eg.Engine.db.SetMaxIdleConns(conns)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].db.SetMaxIdleConns(conns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMaxOpenConns is only available for go 1.2+
|
||||||
|
func (eg *EngineGroup) SetMaxOpenConns(conns int) {
|
||||||
|
eg.Engine.db.SetMaxOpenConns(conns)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].db.SetMaxOpenConns(conns)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPolicy set the group policy
|
||||||
|
func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup {
|
||||||
|
eg.policy = policy
|
||||||
|
return eg
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTableMapper set the table name mapping rule
|
||||||
|
func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) {
|
||||||
|
eg.Engine.TableMapper = mapper
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].TableMapper = mapper
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO
|
||||||
|
func (eg *EngineGroup) ShowExecTime(show ...bool) {
|
||||||
|
eg.Engine.ShowExecTime(show...)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].ShowExecTime(show...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShowSQL show SQL statement or not on logger if log level is great than INFO
|
||||||
|
func (eg *EngineGroup) ShowSQL(show ...bool) {
|
||||||
|
eg.Engine.ShowSQL(show...)
|
||||||
|
for i := 0; i < len(eg.slaves); i++ {
|
||||||
|
eg.slaves[i].ShowSQL(show...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slave returns one of the physical databases which is a slave according the policy
|
||||||
|
func (eg *EngineGroup) Slave() *Engine {
|
||||||
|
switch len(eg.slaves) {
|
||||||
|
case 0:
|
||||||
|
return eg.Engine
|
||||||
|
case 1:
|
||||||
|
return eg.slaves[0]
|
||||||
|
}
|
||||||
|
return eg.policy.Slave(eg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slaves returns all the slaves
|
||||||
|
func (eg *EngineGroup) Slaves() []*Engine {
|
||||||
|
return eg.slaves
|
||||||
|
}
|
116
vendor/github.com/go-xorm/xorm/engine_group_policy.go
generated
vendored
Normal file
116
vendor/github.com/go-xorm/xorm/engine_group_policy.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GroupPolicy is be used by chosing the current slave from slaves
|
||||||
|
type GroupPolicy interface {
|
||||||
|
Slave(*EngineGroup) *Engine
|
||||||
|
}
|
||||||
|
|
||||||
|
// GroupPolicyHandler should be used when a function is a GroupPolicy
|
||||||
|
type GroupPolicyHandler func(*EngineGroup) *Engine
|
||||||
|
|
||||||
|
// Slave implements the chosen of slaves
|
||||||
|
func (h GroupPolicyHandler) Slave(eg *EngineGroup) *Engine {
|
||||||
|
return h(eg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RandomPolicy implmentes randomly chose the slave of slaves
|
||||||
|
func RandomPolicy() GroupPolicyHandler {
|
||||||
|
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
return func(g *EngineGroup) *Engine {
|
||||||
|
return g.Slaves()[r.Intn(len(g.Slaves()))]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WeightRandomPolicy implmentes randomly chose the slave of slaves
|
||||||
|
func WeightRandomPolicy(weights []int) GroupPolicyHandler {
|
||||||
|
var rands = make([]int, 0, len(weights))
|
||||||
|
for i := 0; i < len(weights); i++ {
|
||||||
|
for n := 0; n < weights[i]; n++ {
|
||||||
|
rands = append(rands, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var r = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
|
return func(g *EngineGroup) *Engine {
|
||||||
|
var slaves = g.Slaves()
|
||||||
|
idx := rands[r.Intn(len(rands))]
|
||||||
|
if idx >= len(slaves) {
|
||||||
|
idx = len(slaves) - 1
|
||||||
|
}
|
||||||
|
return slaves[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RoundRobinPolicy() GroupPolicyHandler {
|
||||||
|
var pos = -1
|
||||||
|
var lock sync.Mutex
|
||||||
|
return func(g *EngineGroup) *Engine {
|
||||||
|
var slaves = g.Slaves()
|
||||||
|
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
pos++
|
||||||
|
if pos >= len(slaves) {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return slaves[pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WeightRoundRobinPolicy(weights []int) GroupPolicyHandler {
|
||||||
|
var rands = make([]int, 0, len(weights))
|
||||||
|
for i := 0; i < len(weights); i++ {
|
||||||
|
for n := 0; n < weights[i]; n++ {
|
||||||
|
rands = append(rands, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var pos = -1
|
||||||
|
var lock sync.Mutex
|
||||||
|
|
||||||
|
return func(g *EngineGroup) *Engine {
|
||||||
|
var slaves = g.Slaves()
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
pos++
|
||||||
|
if pos >= len(rands) {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
idx := rands[pos]
|
||||||
|
if idx >= len(slaves) {
|
||||||
|
idx = len(slaves) - 1
|
||||||
|
}
|
||||||
|
return slaves[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeastConnPolicy implements GroupPolicy, every time will get the least connections slave
|
||||||
|
func LeastConnPolicy() GroupPolicyHandler {
|
||||||
|
return func(g *EngineGroup) *Engine {
|
||||||
|
var slaves = g.Slaves()
|
||||||
|
connections := 0
|
||||||
|
idx := 0
|
||||||
|
for i := 0; i < len(slaves); i++ {
|
||||||
|
openConnections := slaves[i].DB().Stats().OpenConnections
|
||||||
|
if i == 0 {
|
||||||
|
connections = openConnections
|
||||||
|
idx = i
|
||||||
|
} else if openConnections <= connections {
|
||||||
|
connections = openConnections
|
||||||
|
idx = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slaves[idx]
|
||||||
|
}
|
||||||
|
}
|
113
vendor/github.com/go-xorm/xorm/engine_table.go
generated
vendored
Normal file
113
vendor/github.com/go-xorm/xorm/engine_table.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TableNameWithSchema will automatically add schema prefix on table name
|
||||||
|
func (engine *Engine) tbNameWithSchema(v string) string {
|
||||||
|
// Add schema name as prefix of table name.
|
||||||
|
// Only for postgres database.
|
||||||
|
if engine.dialect.DBType() == core.POSTGRES &&
|
||||||
|
engine.dialect.URI().Schema != "" &&
|
||||||
|
engine.dialect.URI().Schema != postgresPublicSchema &&
|
||||||
|
strings.Index(v, ".") == -1 {
|
||||||
|
return engine.dialect.URI().Schema + "." + v
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName returns table name with schema prefix if has
|
||||||
|
func (engine *Engine) TableName(bean interface{}, includeSchema ...bool) string {
|
||||||
|
tbName := engine.tbNameNoSchema(bean)
|
||||||
|
if len(includeSchema) > 0 && includeSchema[0] {
|
||||||
|
tbName = engine.tbNameWithSchema(tbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tbName
|
||||||
|
}
|
||||||
|
|
||||||
|
// tbName get some table's table name
|
||||||
|
func (session *Session) tbNameNoSchema(table *core.Table) string {
|
||||||
|
if len(session.statement.AltTableName) > 0 {
|
||||||
|
return session.statement.AltTableName
|
||||||
|
}
|
||||||
|
|
||||||
|
return table.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) tbNameForMap(v reflect.Value) string {
|
||||||
|
if v.Type().Implements(tpTableName) {
|
||||||
|
return v.Interface().(TableName).TableName()
|
||||||
|
}
|
||||||
|
if v.Kind() == reflect.Ptr {
|
||||||
|
v = v.Elem()
|
||||||
|
if v.Type().Implements(tpTableName) {
|
||||||
|
return v.Interface().(TableName).TableName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return engine.TableMapper.Obj2Table(v.Type().Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) tbNameNoSchema(tablename interface{}) string {
|
||||||
|
switch tablename.(type) {
|
||||||
|
case []string:
|
||||||
|
t := tablename.([]string)
|
||||||
|
if len(t) > 1 {
|
||||||
|
return fmt.Sprintf("%v AS %v", engine.Quote(t[0]), engine.Quote(t[1]))
|
||||||
|
} else if len(t) == 1 {
|
||||||
|
return engine.Quote(t[0])
|
||||||
|
}
|
||||||
|
case []interface{}:
|
||||||
|
t := tablename.([]interface{})
|
||||||
|
l := len(t)
|
||||||
|
var table string
|
||||||
|
if l > 0 {
|
||||||
|
f := t[0]
|
||||||
|
switch f.(type) {
|
||||||
|
case string:
|
||||||
|
table = f.(string)
|
||||||
|
case TableName:
|
||||||
|
table = f.(TableName).TableName()
|
||||||
|
default:
|
||||||
|
v := rValue(f)
|
||||||
|
t := v.Type()
|
||||||
|
if t.Kind() == reflect.Struct {
|
||||||
|
table = engine.tbNameForMap(v)
|
||||||
|
} else {
|
||||||
|
table = engine.Quote(fmt.Sprintf("%v", f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if l > 1 {
|
||||||
|
return fmt.Sprintf("%v AS %v", engine.Quote(table),
|
||||||
|
engine.Quote(fmt.Sprintf("%v", t[1])))
|
||||||
|
} else if l == 1 {
|
||||||
|
return engine.Quote(table)
|
||||||
|
}
|
||||||
|
case TableName:
|
||||||
|
return tablename.(TableName).TableName()
|
||||||
|
case string:
|
||||||
|
return tablename.(string)
|
||||||
|
case reflect.Value:
|
||||||
|
v := tablename.(reflect.Value)
|
||||||
|
return engine.tbNameForMap(v)
|
||||||
|
default:
|
||||||
|
v := rValue(tablename)
|
||||||
|
t := v.Type()
|
||||||
|
if t.Kind() == reflect.Struct {
|
||||||
|
return engine.tbNameForMap(v)
|
||||||
|
}
|
||||||
|
return engine.Quote(fmt.Sprintf("%v", tablename))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
24
vendor/github.com/go-xorm/xorm/go.mod
generated
vendored
Normal file
24
vendor/github.com/go-xorm/xorm/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module github.com/go-xorm/xorm
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cockroachdb/apd v1.1.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0
|
||||||
|
github.com/go-xorm/builder v0.3.2
|
||||||
|
github.com/go-xorm/core v0.6.0
|
||||||
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a // indirect
|
||||||
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
||||||
|
github.com/jackc/pgx v3.2.0+incompatible
|
||||||
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
|
github.com/lib/pq v1.0.0
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0
|
||||||
|
github.com/pkg/errors v0.8.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/satori/go.uuid v1.2.0 // indirect
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
|
||||||
|
github.com/stretchr/testify v1.2.2
|
||||||
|
github.com/ziutek/mymysql v1.5.4
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
|
gopkg.in/stretchr/testify.v1 v1.2.2
|
||||||
|
)
|
43
vendor/github.com/go-xorm/xorm/go.sum
generated
vendored
Normal file
43
vendor/github.com/go-xorm/xorm/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f h1:WH0w/R4Yoey+04HhFxqZ6VX6I0d7RMyw5aXQ9UTvQPs=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-xorm/builder v0.3.2 h1:pSsZQRRzJNapKEAEhigw3xLmiLPeAYv5GFlpYZ8+a5I=
|
||||||
|
github.com/go-xorm/builder v0.3.2/go.mod h1:v8mE3MFBgtL+RGFNfUnAMUqqfk/Y4W5KuwCFQIEpQLk=
|
||||||
|
github.com/go-xorm/core v0.6.0 h1:tp6hX+ku4OD9khFZS8VGBDRY3kfVCtelPfmkgCyHxL0=
|
||||||
|
github.com/go-xorm/core v0.6.0/go.mod h1:d8FJ9Br8OGyQl12MCclmYBuBqqxsyeedpXciV5Myih8=
|
||||||
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||||
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||||
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||||
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
|
github.com/jackc/pgx v3.2.0+incompatible h1:0Vihzu20St42/UDsvZGdNE6jak7oi/UOeMzwMPHkgFY=
|
||||||
|
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||||
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
||||||
|
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
|
116
vendor/github.com/go-xorm/xorm/interface.go
generated
vendored
Normal file
116
vendor/github.com/go-xorm/xorm/interface.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Interface defines the interface which Engine, EngineGroup and Session will implementate.
|
||||||
|
type Interface interface {
|
||||||
|
AllCols() *Session
|
||||||
|
Alias(alias string) *Session
|
||||||
|
Asc(colNames ...string) *Session
|
||||||
|
BufferSize(size int) *Session
|
||||||
|
Cols(columns ...string) *Session
|
||||||
|
Count(...interface{}) (int64, error)
|
||||||
|
CreateIndexes(bean interface{}) error
|
||||||
|
CreateUniques(bean interface{}) error
|
||||||
|
Decr(column string, arg ...interface{}) *Session
|
||||||
|
Desc(...string) *Session
|
||||||
|
Delete(interface{}) (int64, error)
|
||||||
|
Distinct(columns ...string) *Session
|
||||||
|
DropIndexes(bean interface{}) error
|
||||||
|
Exec(sqlOrAgrs ...interface{}) (sql.Result, error)
|
||||||
|
Exist(bean ...interface{}) (bool, error)
|
||||||
|
Find(interface{}, ...interface{}) error
|
||||||
|
FindAndCount(interface{}, ...interface{}) (int64, error)
|
||||||
|
Get(interface{}) (bool, error)
|
||||||
|
GroupBy(keys string) *Session
|
||||||
|
ID(interface{}) *Session
|
||||||
|
In(string, ...interface{}) *Session
|
||||||
|
Incr(column string, arg ...interface{}) *Session
|
||||||
|
Insert(...interface{}) (int64, error)
|
||||||
|
InsertOne(interface{}) (int64, error)
|
||||||
|
IsTableEmpty(bean interface{}) (bool, error)
|
||||||
|
IsTableExist(beanOrTableName interface{}) (bool, error)
|
||||||
|
Iterate(interface{}, IterFunc) error
|
||||||
|
Limit(int, ...int) *Session
|
||||||
|
MustCols(columns ...string) *Session
|
||||||
|
NoAutoCondition(...bool) *Session
|
||||||
|
NotIn(string, ...interface{}) *Session
|
||||||
|
Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *Session
|
||||||
|
Omit(columns ...string) *Session
|
||||||
|
OrderBy(order string) *Session
|
||||||
|
Ping() error
|
||||||
|
Query(sqlOrAgrs ...interface{}) (resultsSlice []map[string][]byte, err error)
|
||||||
|
QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error)
|
||||||
|
QueryString(sqlorArgs ...interface{}) ([]map[string]string, error)
|
||||||
|
Rows(bean interface{}) (*Rows, error)
|
||||||
|
SetExpr(string, string) *Session
|
||||||
|
SQL(interface{}, ...interface{}) *Session
|
||||||
|
Sum(bean interface{}, colName string) (float64, error)
|
||||||
|
SumInt(bean interface{}, colName string) (int64, error)
|
||||||
|
Sums(bean interface{}, colNames ...string) ([]float64, error)
|
||||||
|
SumsInt(bean interface{}, colNames ...string) ([]int64, error)
|
||||||
|
Table(tableNameOrBean interface{}) *Session
|
||||||
|
Unscoped() *Session
|
||||||
|
Update(bean interface{}, condiBeans ...interface{}) (int64, error)
|
||||||
|
UseBool(...string) *Session
|
||||||
|
Where(interface{}, ...interface{}) *Session
|
||||||
|
}
|
||||||
|
|
||||||
|
// EngineInterface defines the interface which Engine, EngineGroup will implementate.
|
||||||
|
type EngineInterface interface {
|
||||||
|
Interface
|
||||||
|
|
||||||
|
Before(func(interface{})) *Session
|
||||||
|
Charset(charset string) *Session
|
||||||
|
ClearCache(...interface{}) error
|
||||||
|
CreateTables(...interface{}) error
|
||||||
|
DBMetas() ([]*core.Table, error)
|
||||||
|
Dialect() core.Dialect
|
||||||
|
DropTables(...interface{}) error
|
||||||
|
DumpAllToFile(fp string, tp ...core.DbType) error
|
||||||
|
GetCacher(string) core.Cacher
|
||||||
|
GetColumnMapper() core.IMapper
|
||||||
|
GetDefaultCacher() core.Cacher
|
||||||
|
GetTableMapper() core.IMapper
|
||||||
|
GetTZDatabase() *time.Location
|
||||||
|
GetTZLocation() *time.Location
|
||||||
|
MapCacher(interface{}, core.Cacher) error
|
||||||
|
NewSession() *Session
|
||||||
|
NoAutoTime() *Session
|
||||||
|
Quote(string) string
|
||||||
|
SetCacher(string, core.Cacher)
|
||||||
|
SetConnMaxLifetime(time.Duration)
|
||||||
|
SetDefaultCacher(core.Cacher)
|
||||||
|
SetLogger(logger core.ILogger)
|
||||||
|
SetLogLevel(core.LogLevel)
|
||||||
|
SetMapper(core.IMapper)
|
||||||
|
SetMaxOpenConns(int)
|
||||||
|
SetMaxIdleConns(int)
|
||||||
|
SetSchema(string)
|
||||||
|
SetTZDatabase(tz *time.Location)
|
||||||
|
SetTZLocation(tz *time.Location)
|
||||||
|
ShowExecTime(...bool)
|
||||||
|
ShowSQL(show ...bool)
|
||||||
|
Sync(...interface{}) error
|
||||||
|
Sync2(...interface{}) error
|
||||||
|
StoreEngine(storeEngine string) *Session
|
||||||
|
TableInfo(bean interface{}) *Table
|
||||||
|
TableName(interface{}, ...bool) string
|
||||||
|
UnMapType(reflect.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ Interface = &Session{}
|
||||||
|
_ EngineInterface = &Engine{}
|
||||||
|
_ EngineInterface = &EngineGroup{}
|
||||||
|
)
|
26
vendor/github.com/go-xorm/xorm/transaction.go
generated
vendored
Normal file
26
vendor/github.com/go-xorm/xorm/transaction.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
// Transaction Execute sql wrapped in a transaction(abbr as tx), tx will automatic commit if no errors occurred
|
||||||
|
func (engine *Engine) Transaction(f func(*Session) (interface{}, error)) (interface{}, error) {
|
||||||
|
session := engine.NewSession()
|
||||||
|
defer session.Close()
|
||||||
|
|
||||||
|
if err := session.Begin(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := f(session)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := session.Commit(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
38
vendor/src.techknowlogick.com/xormigrate/.drone.yml
generated
vendored
Normal file
38
vendor/src.techknowlogick.com/xormigrate/.drone.yml
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /go
|
||||||
|
path: src/src.techknowlogick.com/xormigrate
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: fetch-and-test
|
||||||
|
image: golang:1.12
|
||||||
|
environment:
|
||||||
|
GO111MODULE: on
|
||||||
|
commands:
|
||||||
|
- go get ./...
|
||||||
|
- go test -v -tags sqlite
|
||||||
|
- go test -v -tags mysql
|
||||||
|
- go test -v -tags postgresql
|
||||||
|
- go test -v -tags sqlserver
|
||||||
|
|
||||||
|
services:
|
||||||
|
- name: pgsql
|
||||||
|
image: postgres:9.5
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: test
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
|
||||||
|
- name: mysql
|
||||||
|
image: mysql:5.7
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: test
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||||
|
|
||||||
|
- name: mssql
|
||||||
|
image: microsoft/mssql-server-linux:latest
|
||||||
|
environment:
|
||||||
|
ACCEPT_EULA: Y
|
||||||
|
SA_PASSWORD: MwantsaSecurePassword1
|
||||||
|
MSSQL_PID: Standard
|
4
vendor/src.techknowlogick.com/xormigrate/.env
generated
vendored
Normal file
4
vendor/src.techknowlogick.com/xormigrate/.env
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
SQLITE_CONN_STRING=file::memory:?cache=shared
|
||||||
|
PG_CONN_STRING="user=postgres password=postgres host=pgsql dbname=test sslmode=disable"
|
||||||
|
MYSQL_CONN_STRING="root:@(mysql)/test?multiStatements=true"
|
||||||
|
SQLSERVER_CONN_STRING="server=mssql; database=master; user id=sa; password=MwantsaSecurePassword1; encrypt=disable"
|
19
vendor/src.techknowlogick.com/xormigrate/LICENSE
generated
vendored
Normal file
19
vendor/src.techknowlogick.com/xormigrate/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Copyright (c) 2019 Matti Ranta (@techknowlogick)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
162
vendor/src.techknowlogick.com/xormigrate/README.md
generated
vendored
Normal file
162
vendor/src.techknowlogick.com/xormigrate/README.md
generated
vendored
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
# Xormigrate
|
||||||
|
[![Build Status](https://cloud.drone.io/api/badges/techknowlogick/xormigrate/status.svg)](https://cloud.drone.io/techknowlogick/xormigrate)
|
||||||
|
[![Go Report Card](https://goreportcard.com/badge/src.techknowlogick.com/xormigrate)](https://goreportcard.com/report/src.techknowlogick.com/xormigrate)
|
||||||
|
[![GoDoc](https://godoc.org/src.techknowlogick.com/xormigrate?status.svg)](https://godoc.org/src.techknowlogick.com/xormigrate)
|
||||||
|
|
||||||
|
## Supported databases
|
||||||
|
|
||||||
|
It supports any of the databases Xorm supports:
|
||||||
|
|
||||||
|
- PostgreSQL
|
||||||
|
- MySQL
|
||||||
|
- SQLite
|
||||||
|
- Microsoft SQL Server
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get -u src.techknowlogick.com/xormigrate
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"src.techknowlogick.com/xormigrate"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
db, err := xorm.NewEngine("sqlite3", "mydb.sqlite3")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := xormigrate.New(db, []*xormigrate.Migration{
|
||||||
|
// create persons table
|
||||||
|
{
|
||||||
|
ID: "201608301400",
|
||||||
|
// An optional description to print out to the Xormigrate logger
|
||||||
|
Description: "Create the Person table",
|
||||||
|
Migrate: func(tx *xorm.Engine) error {
|
||||||
|
// it's a good pratice to copy the struct inside the function,
|
||||||
|
// so side effects are prevented if the original struct changes during the time
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
return tx.Sync2(&Person{})
|
||||||
|
},
|
||||||
|
Rollback: func(tx *xorm.Engine) error {
|
||||||
|
return tx.DropTables(&Person{})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// add age column to persons
|
||||||
|
{
|
||||||
|
ID: "201608301415",
|
||||||
|
Migrate: func(tx *xorm.Engine) error {
|
||||||
|
// when table already exists, it just adds fields as columns
|
||||||
|
type Person struct {
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
return tx.Sync2(&Person{})
|
||||||
|
},
|
||||||
|
Rollback: func(tx *xorm.Engine) error {
|
||||||
|
// Note: Column dropping in sqlite is not support, and you will need to do this manually
|
||||||
|
_, err = tx.Exec("ALTER TABLE person DROP COLUMN age")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Drop column failed: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// add pets table
|
||||||
|
{
|
||||||
|
ID: "201608301430",
|
||||||
|
Migrate: func(tx *xorm.Engine) error {
|
||||||
|
type Pet struct {
|
||||||
|
Name string
|
||||||
|
PersonID int
|
||||||
|
}
|
||||||
|
return tx.Sync2(&Pet{})
|
||||||
|
},
|
||||||
|
Rollback: func(tx *xorm.Engine) error {
|
||||||
|
return tx.DropTables(&Pet{})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err = m.Migrate(); err != nil {
|
||||||
|
log.Fatalf("Could not migrate: %v", err)
|
||||||
|
}
|
||||||
|
log.Printf("Migration did run successfully")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Having a separated function for initializing the schema
|
||||||
|
|
||||||
|
If you have a lot of migrations, it can be a pain to run all them, as example,
|
||||||
|
when you are deploying a new instance of the app, in a clean database.
|
||||||
|
To prevent this, you can set a function that will run if no migration was run
|
||||||
|
before (in a new clean database). Remember to create everything here, all tables,
|
||||||
|
foreign keys and what more you need in your app.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Person struct {
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pet struct {
|
||||||
|
Name string
|
||||||
|
PersonID int
|
||||||
|
}
|
||||||
|
|
||||||
|
m := xormigrate.New(db, []*xormigrate.Migration{
|
||||||
|
// your migrations here
|
||||||
|
})
|
||||||
|
|
||||||
|
m.InitSchema(func(tx *xorm.Engine) error {
|
||||||
|
err := tx.sync2(
|
||||||
|
&Person{},
|
||||||
|
&Pet{},
|
||||||
|
// all other tables of your app
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding migration descriptions to your logging
|
||||||
|
Xormigrate's logger defaults to stdout, but it can be changed to suit your needs.
|
||||||
|
```go
|
||||||
|
m := xormigrate.New(db, []*xormigrate.Migration{
|
||||||
|
// your migrations here
|
||||||
|
})
|
||||||
|
|
||||||
|
// Don't log anything
|
||||||
|
m.NilLogger()
|
||||||
|
|
||||||
|
// This is the default logger
|
||||||
|
// No need to initialize this unless it was changed
|
||||||
|
// [xormigrate] message
|
||||||
|
m.DefaultLogger()
|
||||||
|
|
||||||
|
// Or, create a logger with any io.Writer you want
|
||||||
|
m.NewLogger(os.Stdout)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* Based on [Gormigrate][gormmigrate]
|
||||||
|
* Uses [Xorm][xorm]
|
||||||
|
|
||||||
|
[xorm]: http://github.com/go-xorm/xorm/
|
||||||
|
[gormmigrate]: https://github.com/go-gormigrate/gormigrate
|
9
vendor/src.techknowlogick.com/xormigrate/go.mod
generated
vendored
Normal file
9
vendor/src.techknowlogick.com/xormigrate/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module src.techknowlogick.com/xormigrate
|
||||||
|
|
||||||
|
go 1.12
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/go-xorm/xorm v0.7.1
|
||||||
|
github.com/joho/godotenv v1.3.0
|
||||||
|
github.com/stretchr/testify v1.3.0
|
||||||
|
)
|
34
vendor/src.techknowlogick.com/xormigrate/go.sum
generated
vendored
Normal file
34
vendor/src.techknowlogick.com/xormigrate/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-xorm/builder v0.3.2 h1:pSsZQRRzJNapKEAEhigw3xLmiLPeAYv5GFlpYZ8+a5I=
|
||||||
|
github.com/go-xorm/builder v0.3.2/go.mod h1:v8mE3MFBgtL+RGFNfUnAMUqqfk/Y4W5KuwCFQIEpQLk=
|
||||||
|
github.com/go-xorm/core v0.6.0 h1:tp6hX+ku4OD9khFZS8VGBDRY3kfVCtelPfmkgCyHxL0=
|
||||||
|
github.com/go-xorm/core v0.6.0/go.mod h1:d8FJ9Br8OGyQl12MCclmYBuBqqxsyeedpXciV5Myih8=
|
||||||
|
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||||
|
github.com/go-xorm/xorm v0.7.1 h1:Kj7mfuqctPdX60zuxP6EoEut0f3E6K66H6hcoxiHUMc=
|
||||||
|
github.com/go-xorm/xorm v0.7.1/go.mod h1:EHS1htMQFptzMaIHKyzqpHGw6C9Rtug75nsq6DA9unI=
|
||||||
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
|
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
|
92
vendor/src.techknowlogick.com/xormigrate/logger.go
generated
vendored
Normal file
92
vendor/src.techknowlogick.com/xormigrate/logger.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package xormigrate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoggerInterface interface {
|
||||||
|
Debug(v ...interface{})
|
||||||
|
Debugf(format string, v ...interface{})
|
||||||
|
Info(v ...interface{})
|
||||||
|
Infof(format string, v ...interface{})
|
||||||
|
Warn(v ...interface{})
|
||||||
|
Warnf(format string, v ...interface{})
|
||||||
|
Error(v ...interface{})
|
||||||
|
Errorf(format string, v ...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
logger LoggerInterface = defaultLogger()
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetLogger sets the Xormigrate logger
|
||||||
|
func (x *Xormigrate) SetLogger(l LoggerInterface) {
|
||||||
|
logger = l
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultLogger() *XormigrateLogger {
|
||||||
|
return &XormigrateLogger{log.New(os.Stdout, "[xormigrate] ", 0)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultLogger sets a Xormigrate logger with default settings
|
||||||
|
// e.g. "[xormigrate] message"
|
||||||
|
func (x *Xormigrate) DefaultLogger() {
|
||||||
|
x.SetLogger(defaultLogger())
|
||||||
|
}
|
||||||
|
|
||||||
|
// NilLogger sets a Xormigrate logger that discards all messages
|
||||||
|
func (x *Xormigrate) NilLogger() {
|
||||||
|
x.SetLogger(&XormigrateLogger{log.New(ioutil.Discard, "", 0)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLogger sets a Xormigrate logger with a specified io.Writer
|
||||||
|
func (x *Xormigrate) NewLogger(writer io.Writer) {
|
||||||
|
x.SetLogger(&XormigrateLogger{log.New(writer, "", 0)})
|
||||||
|
}
|
||||||
|
|
||||||
|
type XormigrateLogger struct {
|
||||||
|
*log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug prints a Debug message
|
||||||
|
func (l *XormigrateLogger) Debug(v ...interface{}) {
|
||||||
|
l.Logger.Print(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugf prints a formatted Debug message
|
||||||
|
func (l *XormigrateLogger) Debugf(format string, v ...interface{}) {
|
||||||
|
l.Logger.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info prints an Info message
|
||||||
|
func (l *XormigrateLogger) Info(v ...interface{}) {
|
||||||
|
l.Logger.Print(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Infof prints a formatted Info message
|
||||||
|
func (l *XormigrateLogger) Infof(format string, v ...interface{}) {
|
||||||
|
l.Logger.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn prints a Warning message
|
||||||
|
func (l *XormigrateLogger) Warn(v ...interface{}) {
|
||||||
|
l.Logger.Print(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warnf prints a formatted Warning message
|
||||||
|
func (l *XormigrateLogger) Warnf(format string, v ...interface{}) {
|
||||||
|
l.Logger.Printf(format, v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error prints an Error message
|
||||||
|
func (l *XormigrateLogger) Error(v ...interface{}) {
|
||||||
|
l.Logger.Print(v...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorf prints a formatted Error message
|
||||||
|
func (l *XormigrateLogger) Errorf(format string, v ...interface{}) {
|
||||||
|
l.Logger.Printf(format, v...)
|
||||||
|
}
|
5
vendor/src.techknowlogick.com/xormigrate/renovate.json
generated
vendored
Normal file
5
vendor/src.techknowlogick.com/xormigrate/renovate.json
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
]
|
||||||
|
}
|
322
vendor/src.techknowlogick.com/xormigrate/xormigrate.go
generated
vendored
Normal file
322
vendor/src.techknowlogick.com/xormigrate/xormigrate.go
generated
vendored
Normal file
|
@ -0,0 +1,322 @@
|
||||||
|
package xormigrate // import "src.techknowlogick.com/xormigrate"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
initSchemaMigrationId = "SCHEMA_INIT"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MigrateFunc is the func signature for migratinx.
|
||||||
|
type MigrateFunc func(*xorm.Engine) error
|
||||||
|
|
||||||
|
// RollbackFunc is the func signature for rollbackinx.
|
||||||
|
type RollbackFunc func(*xorm.Engine) error
|
||||||
|
|
||||||
|
// InitSchemaFunc is the func signature for initializing the schema.
|
||||||
|
type InitSchemaFunc func(*xorm.Engine) error
|
||||||
|
|
||||||
|
// Migration represents a database migration (a modification to be made on the database).
|
||||||
|
type Migration struct {
|
||||||
|
// ID is the migration identifier. Usually a timestamp like "201601021504".
|
||||||
|
ID string `xorm:"id"`
|
||||||
|
// Description is the migration description, which is optionally printed out when the migration is ran.
|
||||||
|
Description string
|
||||||
|
// Migrate is a function that will br executed while running this migration.
|
||||||
|
Migrate MigrateFunc `xorm:"-"`
|
||||||
|
// Rollback will be executed on rollback. Can be nil.
|
||||||
|
Rollback RollbackFunc `xorm:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Xormigrate represents a collection of all migrations of a database schema.
|
||||||
|
type Xormigrate struct {
|
||||||
|
db *xorm.Engine
|
||||||
|
migrations []*Migration
|
||||||
|
initSchema InitSchemaFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReservedIDError is returned when a migration is using a reserved ID
|
||||||
|
type ReservedIDError struct {
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ReservedIDError) Error() string {
|
||||||
|
return fmt.Sprintf(`xormigrate: Reserved migration ID: "%s"`, e.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DuplicatedIDError is returned when more than one migration have the same ID
|
||||||
|
type DuplicatedIDError struct {
|
||||||
|
ID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *DuplicatedIDError) Error() string {
|
||||||
|
return fmt.Sprintf(`xormigrate: Duplicated migration ID: "%s"`, e.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrRollbackImpossible is returned when trying to rollback a migration
|
||||||
|
// that has no rollback function.
|
||||||
|
ErrRollbackImpossible = errors.New("xormigrate: It's impossible to rollback this migration")
|
||||||
|
|
||||||
|
// ErrNoMigrationDefined is returned when no migration is defined.
|
||||||
|
ErrNoMigrationDefined = errors.New("xormigrate: No migration defined")
|
||||||
|
|
||||||
|
// ErrMissingID is returned when the ID od migration is equal to ""
|
||||||
|
ErrMissingID = errors.New("xormigrate: Missing ID in migration")
|
||||||
|
|
||||||
|
// ErrNoRunMigration is returned when any run migration was found while
|
||||||
|
// running RollbackLast
|
||||||
|
ErrNoRunMigration = errors.New("xormigrate: Could not find last run migration")
|
||||||
|
|
||||||
|
// ErrMigrationIDDoesNotExist is returned when migrating or rolling back to a migration ID that
|
||||||
|
// does not exist in the list of migrations
|
||||||
|
ErrMigrationIDDoesNotExist = errors.New("xormigrate: Tried to migrate to an ID that doesn't exist")
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a new Xormigrate.
|
||||||
|
func New(db *xorm.Engine, migrations []*Migration) *Xormigrate {
|
||||||
|
return &Xormigrate{
|
||||||
|
db: db,
|
||||||
|
migrations: migrations,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitSchema sets a function that is run if no migration is found.
|
||||||
|
// The idea is preventing to run all migrations when a new clean database
|
||||||
|
// is being migratinx. In this function you should create all tables and
|
||||||
|
// foreign key necessary to your application.
|
||||||
|
func (x *Xormigrate) InitSchema(initSchema InitSchemaFunc) {
|
||||||
|
x.initSchema = initSchema
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate executes all migrations that did not run yet.
|
||||||
|
func (x *Xormigrate) Migrate() error {
|
||||||
|
return x.migrate("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MigrateTo executes all migrations that did not run yet up to the migration that matches `migrationID`.
|
||||||
|
func (x *Xormigrate) MigrateTo(migrationID string) error {
|
||||||
|
if err := x.checkIDExist(migrationID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return x.migrate(migrationID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) migrate(migrationID string) error {
|
||||||
|
if !x.hasMigrations() {
|
||||||
|
return ErrNoMigrationDefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.checkReservedID(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.checkDuplicatedID(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.createMigrationTableIfNotExists(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if x.initSchema != nil && x.canInitializeSchema() {
|
||||||
|
return x.runInitSchema() // return error or nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, migration := range x.migrations {
|
||||||
|
if err := x.runMigration(migration); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if migrationID != "" && migration.ID == migrationID {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are migrations to apply if either there's a defined
|
||||||
|
// initSchema function or if the list of migrations is not empty.
|
||||||
|
func (x *Xormigrate) hasMigrations() bool {
|
||||||
|
return x.initSchema != nil || len(x.migrations) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether any migration is using a reserved ID.
|
||||||
|
// For now there's only have one reserved ID, but there may be more in the future.
|
||||||
|
func (x *Xormigrate) checkReservedID() error {
|
||||||
|
for _, m := range x.migrations {
|
||||||
|
if m.ID == initSchemaMigrationId {
|
||||||
|
return &ReservedIDError{ID: m.ID}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) checkDuplicatedID() error {
|
||||||
|
lookup := make(map[string]struct{}, len(x.migrations))
|
||||||
|
for _, m := range x.migrations {
|
||||||
|
if _, ok := lookup[m.ID]; ok {
|
||||||
|
return &DuplicatedIDError{ID: m.ID}
|
||||||
|
}
|
||||||
|
lookup[m.ID] = struct{}{}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) checkIDExist(migrationID string) error {
|
||||||
|
for _, migrate := range x.migrations {
|
||||||
|
if migrate.ID == migrationID {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ErrMigrationIDDoesNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// RollbackLast undo the last migration
|
||||||
|
func (x *Xormigrate) RollbackLast() error {
|
||||||
|
if len(x.migrations) == 0 {
|
||||||
|
return ErrNoMigrationDefined
|
||||||
|
}
|
||||||
|
|
||||||
|
lastRunMigration, err := x.getLastRunMigration()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return x.RollbackMigration(lastRunMigration) // return error or nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RollbackTo undoes migrations up to the given migration that matches the `migrationID`.
|
||||||
|
// Migration with the matching `migrationID` is not rolled back.
|
||||||
|
func (x *Xormigrate) RollbackTo(migrationID string) error {
|
||||||
|
if len(x.migrations) == 0 {
|
||||||
|
return ErrNoMigrationDefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.checkIDExist(migrationID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(x.migrations) - 1; i >= 0; i-- {
|
||||||
|
migration := x.migrations[i]
|
||||||
|
if migration.ID == migrationID {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if x.migrationDidRun(migration) {
|
||||||
|
if err := x.rollbackMigration(migration); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) getLastRunMigration() (*Migration, error) {
|
||||||
|
for i := len(x.migrations) - 1; i >= 0; i-- {
|
||||||
|
migration := x.migrations[i]
|
||||||
|
if x.migrationDidRun(migration) {
|
||||||
|
return migration, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, ErrNoRunMigration
|
||||||
|
}
|
||||||
|
|
||||||
|
// RollbackMigration undo a migration.
|
||||||
|
func (x *Xormigrate) RollbackMigration(m *Migration) error {
|
||||||
|
return x.rollbackMigration(m) // return error or nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) rollbackMigration(m *Migration) error {
|
||||||
|
if m.Rollback == nil {
|
||||||
|
return ErrRollbackImpossible
|
||||||
|
}
|
||||||
|
if len(m.Description) > 0 {
|
||||||
|
logger.Errorf("Rolling back migration: %s", m.Description)
|
||||||
|
}
|
||||||
|
if err := m.Rollback(x.db); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := x.db.In("id", m.ID).Delete(&Migration{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) runInitSchema() error {
|
||||||
|
logger.Info("Initializing Schema")
|
||||||
|
if err := x.initSchema(x.db); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := x.insertMigration(initSchemaMigrationId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, migration := range x.migrations {
|
||||||
|
if err := x.insertMigration(migration.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) runMigration(migration *Migration) error {
|
||||||
|
if len(migration.ID) == 0 {
|
||||||
|
return ErrMissingID
|
||||||
|
}
|
||||||
|
|
||||||
|
if !x.migrationDidRun(migration) {
|
||||||
|
if len(migration.Description) > 0 {
|
||||||
|
logger.Info(migration.Description)
|
||||||
|
}
|
||||||
|
if err := migration.Migrate(x.db); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.insertMigration(migration.ID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) createMigrationTableIfNotExists() error {
|
||||||
|
err := x.db.Sync2(new(Migration))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) migrationDidRun(m *Migration) bool {
|
||||||
|
count, err := x.db.
|
||||||
|
In("id", m.ID).
|
||||||
|
Count(&Migration{})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return count > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// The schema can be initialised only if it hasn't been initialised yet
|
||||||
|
// and no other migration has been applied already.
|
||||||
|
func (x *Xormigrate) canInitializeSchema() bool {
|
||||||
|
if x.migrationDidRun(&Migration{ID: initSchemaMigrationId}) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the ID doesn't exist, we also want the list of migrations to be empty
|
||||||
|
count, err := x.db.
|
||||||
|
Count(&Migration{})
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return count == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Xormigrate) insertMigration(id string) error {
|
||||||
|
_, err := x.db.Insert(&Migration{ID: id})
|
||||||
|
return err
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user