Added all required dependencies

This commit is contained in:
Thomas Boerger 2016-11-03 23:16:01 +01:00
parent 78f86abba4
commit 1ebb35b988
No known key found for this signature in database
GPG key ID: 5A388F55283960B6
660 changed files with 502447 additions and 0 deletions

27
vendor/github.com/go-xorm/core/LICENSE generated vendored Normal file
View file

@ -0,0 +1,27 @@
Copyright (c) 2013 - 2015 Lunny Xiao <xiaolunwen@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the {organization} nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

114
vendor/github.com/go-xorm/core/README.md generated vendored Normal file
View file

@ -0,0 +1,114 @@
Core is a lightweight wrapper of sql.DB.
# Open
```Go
db, _ := core.Open(db, connstr)
```
# SetMapper
```Go
db.SetMapper(SameMapper())
```
## Scan usage
### Scan
```Go
rows, _ := db.Query()
for rows.Next() {
rows.Scan()
}
```
### ScanMap
```Go
rows, _ := db.Query()
for rows.Next() {
rows.ScanMap()
```
### ScanSlice
You can use `[]string`, `[][]byte`, `[]interface{}`, `[]*string`, `[]sql.NullString` to ScanSclice. Notice, slice's length should be equal or less than select columns.
```Go
rows, _ := db.Query()
cols, _ := rows.Columns()
for rows.Next() {
var s = make([]string, len(cols))
rows.ScanSlice(&s)
}
```
```Go
rows, _ := db.Query()
cols, _ := rows.Columns()
for rows.Next() {
var s = make([]*string, len(cols))
rows.ScanSlice(&s)
}
```
### ScanStruct
```Go
rows, _ := db.Query()
for rows.Next() {
rows.ScanStructByName()
rows.ScanStructByIndex()
}
```
## Query usage
```Go
rows, err := db.Query("select * from table where name = ?", name)
user = User{
Name:"lunny",
}
rows, err := db.QueryStruct("select * from table where name = ?Name",
&user)
var user = map[string]interface{}{
"name": "lunny",
}
rows, err = db.QueryMap("select * from table where name = ?name",
&user)
```
## QueryRow usage
```Go
row := db.QueryRow("select * from table where name = ?", name)
user = User{
Name:"lunny",
}
row := db.QueryRowStruct("select * from table where name = ?Name",
&user)
var user = map[string]interface{}{
"name": "lunny",
}
row = db.QueryRowMap("select * from table where name = ?name",
&user)
```
## Exec usage
```Go
db.Exec("insert into user (`name`, title, age, alias, nick_name,created) values (?,?,?,?,?,?)", name, title, age, alias...)
user = User{
Name:"lunny",
Title:"test",
Age: 18,
}
result, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
&user)
var user = map[string]interface{}{
"Name": "lunny",
"Title": "test",
"Age": 18,
}
result, err = db.ExecMap("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
&user)
```

1
vendor/github.com/go-xorm/core/benchmark.sh generated vendored Executable file
View file

@ -0,0 +1 @@
go test -v -bench=. -run=XXX

87
vendor/github.com/go-xorm/core/cache.go generated vendored Normal file
View file

@ -0,0 +1,87 @@
package core
import (
"errors"
"fmt"
"time"
"bytes"
"encoding/gob"
)
const (
// default cache expired time
CacheExpired = 60 * time.Minute
// not use now
CacheMaxMemory = 256
// evey ten minutes to clear all expired nodes
CacheGcInterval = 10 * time.Minute
// each time when gc to removed max nodes
CacheGcMaxRemoved = 20
)
var (
ErrCacheMiss = errors.New("xorm/cache: key not found.")
ErrNotStored = errors.New("xorm/cache: not stored.")
)
// CacheStore is a interface to store cache
type CacheStore interface {
// key is primary key or composite primary key
// value is struct's pointer
// key format : <tablename>-p-<pk1>-<pk2>...
Put(key string, value interface{}) error
Get(key string) (interface{}, error)
Del(key string) error
}
// Cacher is an interface to provide cache
// id format : u-<pk1>-<pk2>...
type Cacher interface {
GetIds(tableName, sql string) interface{}
GetBean(tableName string, id string) interface{}
PutIds(tableName, sql string, ids interface{})
PutBean(tableName string, id string, obj interface{})
DelIds(tableName, sql string)
DelBean(tableName string, id string)
ClearIds(tableName string)
ClearBeans(tableName string)
}
func encodeIds(ids []PK) (string, error) {
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
err := enc.Encode(ids)
return buf.String(), err
}
func decodeIds(s string) ([]PK, error) {
pks := make([]PK, 0)
dec := gob.NewDecoder(bytes.NewBufferString(s))
err := dec.Decode(&pks)
return pks, err
}
func GetCacheSql(m Cacher, tableName, sql string, args interface{}) ([]PK, error) {
bytes := m.GetIds(tableName, GenSqlKey(sql, args))
if bytes == nil {
return nil, errors.New("Not Exist")
}
return decodeIds(bytes.(string))
}
func PutCacheSql(m Cacher, ids []PK, tableName, sql string, args interface{}) error {
bytes, err := encodeIds(ids)
if err != nil {
return err
}
m.PutIds(tableName, GenSqlKey(sql, args), bytes)
return nil
}
func GenSqlKey(sql string, args interface{}) string {
return fmt.Sprintf("%v-%v", sql, args)
}

160
vendor/github.com/go-xorm/core/column.go generated vendored Normal file
View file

@ -0,0 +1,160 @@
package core
import (
"fmt"
"reflect"
"strings"
"time"
)
const (
TWOSIDES = iota + 1
ONLYTODB
ONLYFROMDB
)
// database column
type Column struct {
Name string
TableName string
FieldName string
SQLType SQLType
Length int
Length2 int
Nullable bool
Default string
Indexes map[string]int
IsPrimaryKey bool
IsAutoIncrement bool
MapType int
IsCreated bool
IsUpdated bool
IsDeleted bool
IsCascade bool
IsVersion bool
fieldPath []string
DefaultIsEmpty bool
EnumOptions map[string]int
SetOptions map[string]int
DisableTimeZone bool
TimeZone *time.Location // column specified time zone
}
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
return &Column{
Name: name,
TableName: "",
FieldName: fieldName,
SQLType: sqlType,
Length: len1,
Length2: len2,
Nullable: nullable,
Default: "",
Indexes: make(map[string]int),
IsPrimaryKey: false,
IsAutoIncrement: false,
MapType: TWOSIDES,
IsCreated: false,
IsUpdated: false,
IsDeleted: false,
IsCascade: false,
IsVersion: false,
fieldPath: nil,
DefaultIsEmpty: false,
EnumOptions: make(map[string]int),
}
}
// generate column description string according dialect
func (col *Column) String(d Dialect) string {
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
sql += d.SqlType(col) + " "
if col.IsPrimaryKey {
sql += "PRIMARY KEY "
if col.IsAutoIncrement {
sql += d.AutoIncrStr() + " "
}
}
if d.ShowCreateNull() {
if col.Nullable {
sql += "NULL "
} else {
sql += "NOT NULL "
}
}
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
return sql
}
func (col *Column) StringNoPk(d Dialect) string {
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
sql += d.SqlType(col) + " "
if d.ShowCreateNull() {
if col.Nullable {
sql += "NULL "
} else {
sql += "NOT NULL "
}
}
if col.Default != "" {
sql += "DEFAULT " + col.Default + " "
}
return sql
}
// return col's filed of struct's value
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
return col.ValueOfV(&dataStruct)
}
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
var fieldValue reflect.Value
if col.fieldPath == nil {
col.fieldPath = strings.Split(col.FieldName, ".")
}
if dataStruct.Type().Kind() == reflect.Map {
keyValue := reflect.ValueOf(col.fieldPath[len(col.fieldPath)-1])
fieldValue = dataStruct.MapIndex(keyValue)
return &fieldValue, nil
} else if dataStruct.Type().Kind() == reflect.Interface {
structValue := reflect.ValueOf(dataStruct.Interface())
dataStruct = &structValue
}
level := len(col.fieldPath)
fieldValue = dataStruct.FieldByName(col.fieldPath[0])
for i := 0; i < level-1; i++ {
if !fieldValue.IsValid() {
break
}
if fieldValue.Kind() == reflect.Struct {
fieldValue = fieldValue.FieldByName(col.fieldPath[i+1])
} else if fieldValue.Kind() == reflect.Ptr {
if fieldValue.IsNil() {
fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
}
fieldValue = fieldValue.Elem().FieldByName(col.fieldPath[i+1])
} else {
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
}
}
if !fieldValue.IsValid() {
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
}
return &fieldValue, nil
}

8
vendor/github.com/go-xorm/core/converstion.go generated vendored Normal file
View file

@ -0,0 +1,8 @@
package core
// Conversion is an interface. A type implements Conversion will according
// the custom method to fill into database and retrieve from database.
type Conversion interface {
FromDB([]byte) error
ToDB() ([]byte, error)
}

368
vendor/github.com/go-xorm/core/db.go generated vendored Normal file
View file

@ -0,0 +1,368 @@
package core
import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"reflect"
"regexp"
)
func MapToSlice(query string, mp interface{}) (string, []interface{}, error) {
vv := reflect.ValueOf(mp)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return "", []interface{}{}, ErrNoMapPointer
}
args := make([]interface{}, 0, len(vv.Elem().MapKeys()))
var err error
query = re.ReplaceAllStringFunc(query, func(src string) string {
v := vv.Elem().MapIndex(reflect.ValueOf(src[1:]))
if !v.IsValid() {
err = fmt.Errorf("map key %s is missing", src[1:])
} else {
args = append(args, v.Interface())
}
return "?"
})
return query, args, err
}
func StructToSlice(query string, st interface{}) (string, []interface{}, error) {
vv := reflect.ValueOf(st)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return "", []interface{}{}, ErrNoStructPointer
}
args := make([]interface{}, 0)
var err error
query = re.ReplaceAllStringFunc(query, func(src string) string {
fv := vv.Elem().FieldByName(src[1:]).Interface()
if v, ok := fv.(driver.Valuer); ok {
var value driver.Value
value, err = v.Value()
if err != nil {
return "?"
}
args = append(args, value)
} else {
args = append(args, fv)
}
return "?"
})
if err != nil {
return "", []interface{}{}, err
}
return query, args, nil
}
type DB struct {
*sql.DB
Mapper IMapper
}
func Open(driverName, dataSourceName string) (*DB, error) {
db, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
return &DB{db, NewCacheMapper(&SnakeMapper{})}, nil
}
func FromDB(db *sql.DB) *DB {
return &DB{db, NewCacheMapper(&SnakeMapper{})}
}
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
rows, err := db.DB.Query(query, args...)
if err != nil {
if rows != nil {
rows.Close()
}
return nil, err
}
return &Rows{rows, db.Mapper}, nil
}
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
query, args, err := MapToSlice(query, mp)
if err != nil {
return nil, err
}
return db.Query(query, args...)
}
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
query, args, err := StructToSlice(query, st)
if err != nil {
return nil, err
}
return db.Query(query, args...)
}
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
rows, err := db.Query(query, args...)
if err != nil {
return &Row{nil, err}
}
return &Row{rows, nil}
}
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
query, args, err := MapToSlice(query, mp)
if err != nil {
return &Row{nil, err}
}
return db.QueryRow(query, args...)
}
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
query, args, err := StructToSlice(query, st)
if err != nil {
return &Row{nil, err}
}
return db.QueryRow(query, args...)
}
type Stmt struct {
*sql.Stmt
Mapper IMapper
names map[string]int
}
func (db *DB) Prepare(query string) (*Stmt, error) {
names := make(map[string]int)
var i int
query = re.ReplaceAllStringFunc(query, func(src string) string {
names[src[1:]] = i
i += 1
return "?"
})
stmt, err := db.DB.Prepare(query)
if err != nil {
return nil, err
}
return &Stmt{stmt, db.Mapper, names}, nil
}
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
vv := reflect.ValueOf(mp)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return nil, errors.New("mp should be a map's pointer")
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
}
return s.Stmt.Exec(args...)
}
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
vv := reflect.ValueOf(st)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return nil, errors.New("mp should be a map's pointer")
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().FieldByName(k).Interface()
}
return s.Stmt.Exec(args...)
}
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
rows, err := s.Stmt.Query(args...)
if err != nil {
return nil, err
}
return &Rows{rows, s.Mapper}, nil
}
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
vv := reflect.ValueOf(mp)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return nil, errors.New("mp should be a map's pointer")
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
}
return s.Query(args...)
}
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
vv := reflect.ValueOf(st)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return nil, errors.New("mp should be a map's pointer")
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().FieldByName(k).Interface()
}
return s.Query(args...)
}
func (s *Stmt) QueryRow(args ...interface{}) *Row {
rows, err := s.Query(args...)
return &Row{rows, err}
}
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
vv := reflect.ValueOf(mp)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return &Row{nil, errors.New("mp should be a map's pointer")}
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
}
return s.QueryRow(args...)
}
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
vv := reflect.ValueOf(st)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return &Row{nil, errors.New("st should be a struct's pointer")}
}
args := make([]interface{}, len(s.names))
for k, i := range s.names {
args[i] = vv.Elem().FieldByName(k).Interface()
}
return s.QueryRow(args...)
}
var (
re = regexp.MustCompile(`[?](\w+)`)
)
// insert into (name) values (?)
// insert into (name) values (?name)
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
query, args, err := MapToSlice(query, mp)
if err != nil {
return nil, err
}
return db.DB.Exec(query, args...)
}
func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
query, args, err := StructToSlice(query, st)
if err != nil {
return nil, err
}
return db.DB.Exec(query, args...)
}
type EmptyScanner struct {
}
func (EmptyScanner) Scan(src interface{}) error {
return nil
}
type Tx struct {
*sql.Tx
Mapper IMapper
}
func (db *DB) Begin() (*Tx, error) {
tx, err := db.DB.Begin()
if err != nil {
return nil, err
}
return &Tx{tx, db.Mapper}, nil
}
func (tx *Tx) Prepare(query string) (*Stmt, error) {
names := make(map[string]int)
var i int
query = re.ReplaceAllStringFunc(query, func(src string) string {
names[src[1:]] = i
i += 1
return "?"
})
stmt, err := tx.Tx.Prepare(query)
if err != nil {
return nil, err
}
return &Stmt{stmt, tx.Mapper, names}, nil
}
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
// TODO:
return stmt
}
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
query, args, err := MapToSlice(query, mp)
if err != nil {
return nil, err
}
return tx.Tx.Exec(query, args...)
}
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
query, args, err := StructToSlice(query, st)
if err != nil {
return nil, err
}
return tx.Tx.Exec(query, args...)
}
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
rows, err := tx.Tx.Query(query, args...)
if err != nil {
return nil, err
}
return &Rows{rows, tx.Mapper}, nil
}
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
query, args, err := MapToSlice(query, mp)
if err != nil {
return nil, err
}
return tx.Query(query, args...)
}
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
query, args, err := StructToSlice(query, st)
if err != nil {
return nil, err
}
return tx.Query(query, args...)
}
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
rows, err := tx.Query(query, args...)
return &Row{rows, err}
}
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
query, args, err := MapToSlice(query, mp)
if err != nil {
return &Row{nil, err}
}
return tx.QueryRow(query, args...)
}
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
query, args, err := StructToSlice(query, st)
if err != nil {
return &Row{nil, err}
}
return tx.QueryRow(query, args...)
}

302
vendor/github.com/go-xorm/core/dialect.go generated vendored Normal file
View file

@ -0,0 +1,302 @@
package core
import (
"fmt"
"strings"
"time"
)
type DbType string
type Uri struct {
DbType DbType
Proto string
Host string
Port string
DbName string
User string
Passwd string
Charset string
Laddr string
Raddr string
Timeout time.Duration
Schema string
}
// a dialect is a driver's wrapper
type Dialect interface {
SetLogger(logger ILogger)
Init(*DB, *Uri, string, string) error
URI() *Uri
DB() *DB
DBType() DbType
SqlType(*Column) string
FormatBytes(b []byte) string
DriverName() string
DataSourceName() string
QuoteStr() string
IsReserved(string) bool
Quote(string) string
AndStr() string
OrStr() string
EqStr() string
RollBackStr() string
AutoIncrStr() string
SupportInsertMany() bool
SupportEngine() bool
SupportCharset() bool
SupportDropIfExists() bool
IndexOnTable() bool
ShowCreateNull() bool
IndexCheckSql(tableName, idxName string) (string, []interface{})
TableCheckSql(tableName string) (string, []interface{})
IsColumnExist(tableName string, colName string) (bool, error)
CreateTableSql(table *Table, tableName, storeEngine, charset string) string
DropTableSql(tableName string) string
CreateIndexSql(tableName string, index *Index) string
DropIndexSql(tableName string, index *Index) string
ModifyColumnSql(tableName string, col *Column) string
ForUpdateSql(query string) string
//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
//MustDropTable(tableName string) error
GetColumns(tableName string) ([]string, map[string]*Column, error)
GetTables() ([]*Table, error)
GetIndexes(tableName string) (map[string]*Index, error)
Filters() []Filter
}
func OpenDialect(dialect Dialect) (*DB, error) {
return Open(dialect.DriverName(), dialect.DataSourceName())
}
type Base struct {
db *DB
dialect Dialect
driverName string
dataSourceName string
logger ILogger
*Uri
}
func (b *Base) DB() *DB {
return b.db
}
func (b *Base) SetLogger(logger ILogger) {
b.logger = logger
}
func (b *Base) Init(db *DB, dialect Dialect, uri *Uri, drivername, dataSourceName string) error {
b.db, b.dialect, b.Uri = db, dialect, uri
b.driverName, b.dataSourceName = drivername, dataSourceName
return nil
}
func (b *Base) URI() *Uri {
return b.Uri
}
func (b *Base) DBType() DbType {
return b.Uri.DbType
}
func (b *Base) FormatBytes(bs []byte) string {
return fmt.Sprintf("0x%x", bs)
}
func (b *Base) DriverName() string {
return b.driverName
}
func (b *Base) ShowCreateNull() bool {
return true
}
func (b *Base) DataSourceName() string {
return b.dataSourceName
}
func (b *Base) AndStr() string {
return "AND"
}
func (b *Base) OrStr() string {
return "OR"
}
func (b *Base) EqStr() string {
return "="
}
func (db *Base) RollBackStr() string {
return "ROLL BACK"
}
func (db *Base) SupportDropIfExists() bool {
return true
}
func (db *Base) DropTableSql(tableName string) string {
return fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
}
func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
db.LogSQL(query, args)
rows, err := db.DB().Query(query, args...)
if err != nil {
return false, err
}
defer rows.Close()
if rows.Next() {
return true, nil
}
return false, nil
}
func (db *Base) IsColumnExist(tableName, colName string) (bool, error) {
query := "SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = ? AND `TABLE_NAME` = ? AND `COLUMN_NAME` = ?"
query = strings.Replace(query, "`", db.dialect.QuoteStr(), -1)
return db.HasRecords(query, db.DbName, tableName, colName)
}
/*
func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
sql, args := db.dialect.TableCheckSql(tableName)
rows, err := db.DB().Query(sql, args...)
if db.Logger != nil {
db.Logger.Info("[sql]", sql, args)
}
if err != nil {
return err
}
defer rows.Close()
if rows.Next() {
return nil
}
sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
_, err = db.DB().Exec(sql)
if db.Logger != nil {
db.Logger.Info("[sql]", sql)
}
return err
}*/
func (db *Base) CreateIndexSql(tableName string, index *Index) string {
quote := db.dialect.Quote
var unique string
var idxName string
if index.Type == UniqueType {
unique = " UNIQUE"
}
idxName = index.XName(tableName)
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
quote(idxName), quote(tableName),
quote(strings.Join(index.Cols, quote(","))))
}
func (db *Base) DropIndexSql(tableName string, index *Index) string {
quote := db.dialect.Quote
var name string
if index.IsRegular {
name = index.XName(tableName)
} else {
name = index.Name
}
return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
}
func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
return fmt.Sprintf("alter table %s MODIFY COLUMN %s", tableName, col.StringNoPk(db.dialect))
}
func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset string) string {
var sql string
sql = "CREATE TABLE IF NOT EXISTS "
if tableName == "" {
tableName = table.Name
}
sql += b.dialect.Quote(tableName)
sql += " ("
if len(table.ColumnsSeq()) > 0 {
pkList := table.PrimaryKeys
for _, colName := range table.ColumnsSeq() {
col := table.GetColumn(colName)
if col.IsPrimaryKey && len(pkList) == 1 {
sql += col.String(b.dialect)
} else {
sql += col.StringNoPk(b.dialect)
}
sql = strings.TrimSpace(sql)
sql += ", "
}
if len(pkList) > 1 {
sql += "PRIMARY KEY ( "
sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
sql += " ), "
}
sql = sql[:len(sql)-2]
}
sql += ")"
if b.dialect.SupportEngine() && storeEngine != "" {
sql += " ENGINE=" + storeEngine
}
if b.dialect.SupportCharset() {
if len(charset) == 0 {
charset = b.dialect.URI().Charset
}
if len(charset) > 0 {
sql += " DEFAULT CHARSET " + charset
}
}
return sql
}
func (b *Base) ForUpdateSql(query string) string {
return query + " FOR UPDATE"
}
func (b *Base) LogSQL(sql string, args []interface{}) {
if b.logger != nil && b.logger.IsShowSQL() {
if len(args) > 0 {
b.logger.Info("[sql]", sql, args)
} else {
b.logger.Info("[sql]", sql)
}
}
}
var (
dialects = map[DbType]func() Dialect{}
)
func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
if dialectFunc == nil {
panic("core: Register dialect is nil")
}
dialects[dbName] = dialectFunc // !nashtsai! allow override dialect
}
func QueryDialect(dbName DbType) Dialect {
return dialects[dbName]()
}

27
vendor/github.com/go-xorm/core/driver.go generated vendored Normal file
View file

@ -0,0 +1,27 @@
package core
type Driver interface {
Parse(string, string) (*Uri, error)
}
var (
drivers = map[string]Driver{}
)
func RegisterDriver(driverName string, driver Driver) {
if driver == nil {
panic("core: Register driver is nil")
}
if _, dup := drivers[driverName]; dup {
panic("core: Register called twice for driver " + driverName)
}
drivers[driverName] = driver
}
func QueryDriver(driverName string) Driver {
return drivers[driverName]
}
func RegisteredDriverSize() int {
return len(drivers)
}

8
vendor/github.com/go-xorm/core/error.go generated vendored Normal file
View file

@ -0,0 +1,8 @@
package core
import "errors"
var (
ErrNoMapPointer = errors.New("mp should be a map's pointer")
ErrNoStructPointer = errors.New("mp should be a struct's pointer")
)

64
vendor/github.com/go-xorm/core/filter.go generated vendored Normal file
View file

@ -0,0 +1,64 @@
package core
import (
"fmt"
"strings"
)
// Filter is an interface to filter SQL
type Filter interface {
Do(sql string, dialect Dialect, table *Table) string
}
// QuoteFilter filter SQL replace ` to database's own quote character
type QuoteFilter struct {
}
func (s *QuoteFilter) Do(sql string, dialect Dialect, table *Table) string {
return strings.Replace(sql, "`", dialect.QuoteStr(), -1)
}
// IdFilter filter SQL replace (id) to primary key column name
type IdFilter struct {
}
type Quoter struct {
dialect Dialect
}
func NewQuoter(dialect Dialect) *Quoter {
return &Quoter{dialect}
}
func (q *Quoter) Quote(content string) string {
return q.dialect.QuoteStr() + content + q.dialect.QuoteStr()
}
func (i *IdFilter) Do(sql string, dialect Dialect, table *Table) string {
quoter := NewQuoter(dialect)
if table != nil && len(table.PrimaryKeys) == 1 {
sql = strings.Replace(sql, "`(id)`", quoter.Quote(table.PrimaryKeys[0]), -1)
sql = strings.Replace(sql, quoter.Quote("(id)"), quoter.Quote(table.PrimaryKeys[0]), -1)
return strings.Replace(sql, "(id)", quoter.Quote(table.PrimaryKeys[0]), -1)
}
return sql
}
// SeqFilter filter SQL replace ?, ? ... to $1, $2 ...
type SeqFilter struct {
Prefix string
Start int
}
func (s *SeqFilter) Do(sql string, dialect Dialect, table *Table) string {
segs := strings.Split(sql, "?")
size := len(segs)
res := ""
for i, c := range segs {
if i < size-1 {
res += c + fmt.Sprintf("%s%v", s.Prefix, i+s.Start)
}
}
res += segs[size-1]
return res
}

31
vendor/github.com/go-xorm/core/ilogger.go generated vendored Normal file
View file

@ -0,0 +1,31 @@
package core
type LogLevel int
const (
// !nashtsai! following level also match syslog.Priority value
LOG_DEBUG LogLevel = iota
LOG_INFO
LOG_WARNING
LOG_ERR
LOG_OFF
LOG_UNKNOWN
)
// logger interface
type ILogger interface {
Debug(v ...interface{})
Debugf(format string, v ...interface{})
Error(v ...interface{})
Errorf(format string, v ...interface{})
Info(v ...interface{})
Infof(format string, v ...interface{})
Warn(v ...interface{})
Warnf(format string, v ...interface{})
Level() LogLevel
SetLevel(l LogLevel)
ShowSQL(show ...bool)
IsShowSQL() bool
}

61
vendor/github.com/go-xorm/core/index.go generated vendored Normal file
View file

@ -0,0 +1,61 @@
package core
import (
"fmt"
"sort"
"strings"
)
const (
IndexType = iota + 1
UniqueType
)
// database index
type Index struct {
IsRegular bool
Name string
Type int
Cols []string
}
func (index *Index) XName(tableName string) string {
if !strings.HasPrefix(index.Name, "UQE_") &&
!strings.HasPrefix(index.Name, "IDX_") {
if index.Type == UniqueType {
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
}
return fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
}
return index.Name
}
// add columns which will be composite index
func (index *Index) AddColumn(cols ...string) {
for _, col := range cols {
index.Cols = append(index.Cols, col)
}
}
func (index *Index) Equal(dst *Index) bool {
if index.Type != dst.Type {
return false
}
if len(index.Cols) != len(dst.Cols) {
return false
}
sort.StringSlice(index.Cols).Sort()
sort.StringSlice(dst.Cols).Sort()
for i := 0; i < len(index.Cols); i++ {
if index.Cols[i] != dst.Cols[i] {
return false
}
}
return true
}
// new an index
func NewIndex(name string, indexType int) *Index {
return &Index{true, name, indexType, make([]string, 0)}
}

254
vendor/github.com/go-xorm/core/mapper.go generated vendored Normal file
View file

@ -0,0 +1,254 @@
package core
import (
"strings"
"sync"
)
// name translation between struct, fields names and table, column names
type IMapper interface {
Obj2Table(string) string
Table2Obj(string) string
}
type CacheMapper struct {
oriMapper IMapper
obj2tableCache map[string]string
obj2tableMutex sync.RWMutex
table2objCache map[string]string
table2objMutex sync.RWMutex
}
func NewCacheMapper(mapper IMapper) *CacheMapper {
return &CacheMapper{oriMapper: mapper, obj2tableCache: make(map[string]string),
table2objCache: make(map[string]string),
}
}
func (m *CacheMapper) Obj2Table(o string) string {
m.obj2tableMutex.RLock()
t, ok := m.obj2tableCache[o]
m.obj2tableMutex.RUnlock()
if ok {
return t
}
t = m.oriMapper.Obj2Table(o)
m.obj2tableMutex.Lock()
m.obj2tableCache[o] = t
m.obj2tableMutex.Unlock()
return t
}
func (m *CacheMapper) Table2Obj(t string) string {
m.table2objMutex.RLock()
o, ok := m.table2objCache[t]
m.table2objMutex.RUnlock()
if ok {
return o
}
o = m.oriMapper.Table2Obj(t)
m.table2objMutex.Lock()
m.table2objCache[t] = o
m.table2objMutex.Unlock()
return o
}
// SameMapper implements IMapper and provides same name between struct and
// database table
type SameMapper struct {
}
func (m SameMapper) Obj2Table(o string) string {
return o
}
func (m SameMapper) Table2Obj(t string) string {
return t
}
// SnakeMapper implements IMapper and provides name transaltion between
// struct and database table
type SnakeMapper struct {
}
func snakeCasedName(name string) string {
newstr := make([]rune, 0)
for idx, chr := range name {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
if idx > 0 {
newstr = append(newstr, '_')
}
chr -= ('A' - 'a')
}
newstr = append(newstr, chr)
}
return string(newstr)
}
func (mapper SnakeMapper) Obj2Table(name string) string {
return snakeCasedName(name)
}
func titleCasedName(name string) string {
newstr := make([]rune, 0)
upNextChar := true
name = strings.ToLower(name)
for _, chr := range name {
switch {
case upNextChar:
upNextChar = false
if 'a' <= chr && chr <= 'z' {
chr -= ('a' - 'A')
}
case chr == '_':
upNextChar = true
continue
}
newstr = append(newstr, chr)
}
return string(newstr)
}
func (mapper SnakeMapper) Table2Obj(name string) string {
return titleCasedName(name)
}
// GonicMapper implements IMapper. It will consider initialisms when mapping names.
// E.g. id -> ID, user -> User and to table names: UserID -> user_id, MyUID -> my_uid
type GonicMapper map[string]bool
func isASCIIUpper(r rune) bool {
return 'A' <= r && r <= 'Z'
}
func toASCIIUpper(r rune) rune {
if 'a' <= r && r <= 'z' {
r -= ('a' - 'A')
}
return r
}
func gonicCasedName(name string) string {
newstr := make([]rune, 0, len(name)+3)
for idx, chr := range name {
if isASCIIUpper(chr) && idx > 0 {
if !isASCIIUpper(newstr[len(newstr)-1]) {
newstr = append(newstr, '_')
}
}
if !isASCIIUpper(chr) && idx > 1 {
l := len(newstr)
if isASCIIUpper(newstr[l-1]) && isASCIIUpper(newstr[l-2]) {
newstr = append(newstr, newstr[l-1])
newstr[l-1] = '_'
}
}
newstr = append(newstr, chr)
}
return strings.ToLower(string(newstr))
}
func (mapper GonicMapper) Obj2Table(name string) string {
return gonicCasedName(name)
}
func (mapper GonicMapper) Table2Obj(name string) string {
newstr := make([]rune, 0)
name = strings.ToLower(name)
parts := strings.Split(name, "_")
for _, p := range parts {
_, isInitialism := mapper[strings.ToUpper(p)]
for i, r := range p {
if i == 0 || isInitialism {
r = toASCIIUpper(r)
}
newstr = append(newstr, r)
}
}
return string(newstr)
}
// A GonicMapper that contains a list of common initialisms taken from golang/lint
var LintGonicMapper = GonicMapper{
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SSH": true,
"TLS": true,
"TTL": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XSRF": true,
"XSS": true,
}
// provide prefix table name support
type PrefixMapper struct {
Mapper IMapper
Prefix string
}
func (mapper PrefixMapper) Obj2Table(name string) string {
return mapper.Prefix + mapper.Mapper.Obj2Table(name)
}
func (mapper PrefixMapper) Table2Obj(name string) string {
return mapper.Mapper.Table2Obj(name[len(mapper.Prefix):])
}
func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
return PrefixMapper{mapper, prefix}
}
// provide suffix table name support
type SuffixMapper struct {
Mapper IMapper
Suffix string
}
func (mapper SuffixMapper) Obj2Table(name string) string {
return mapper.Mapper.Obj2Table(name) + mapper.Suffix
}
func (mapper SuffixMapper) Table2Obj(name string) string {
return mapper.Mapper.Table2Obj(name[:len(name)-len(mapper.Suffix)])
}
func NewSuffixMapper(mapper IMapper, suffix string) SuffixMapper {
return SuffixMapper{mapper, suffix}
}

26
vendor/github.com/go-xorm/core/pk.go generated vendored Normal file
View file

@ -0,0 +1,26 @@
package core
import (
"bytes"
"encoding/gob"
)
type PK []interface{}
func NewPK(pks ...interface{}) *PK {
p := PK(pks)
return &p
}
func (p *PK) ToString() (string, error) {
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
err := enc.Encode(*p)
return buf.String(), err
}
func (p *PK) FromString(content string) error {
dec := gob.NewDecoder(bytes.NewBufferString(content))
err := dec.Decode(p)
return err
}

380
vendor/github.com/go-xorm/core/rows.go generated vendored Normal file
View file

@ -0,0 +1,380 @@
package core
import (
"database/sql"
"errors"
"reflect"
"sync"
)
type Rows struct {
*sql.Rows
Mapper IMapper
}
func (rs *Rows) ToMapString() ([]map[string]string, error) {
cols, err := rs.Columns()
if err != nil {
return nil, err
}
var results = make([]map[string]string, 0, 10)
for rs.Next() {
var record = make(map[string]string, len(cols))
err = rs.ScanMap(&record)
if err != nil {
return nil, err
}
results = append(results, record)
}
return results, nil
}
// scan data to a struct's pointer according field index
func (rs *Rows) ScanStructByIndex(dest ...interface{}) error {
if len(dest) == 0 {
return errors.New("at least one struct")
}
vvvs := make([]reflect.Value, len(dest))
for i, s := range dest {
vv := reflect.ValueOf(s)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return errors.New("dest should be a struct's pointer")
}
vvvs[i] = vv.Elem()
}
cols, err := rs.Columns()
if err != nil {
return err
}
newDest := make([]interface{}, len(cols))
var i = 0
for _, vvv := range vvvs {
for j := 0; j < vvv.NumField(); j++ {
newDest[i] = vvv.Field(j).Addr().Interface()
i = i + 1
}
}
return rs.Rows.Scan(newDest...)
}
var (
fieldCache = make(map[reflect.Type]map[string]int)
fieldCacheMutex sync.RWMutex
)
func fieldByName(v reflect.Value, name string) reflect.Value {
t := v.Type()
fieldCacheMutex.RLock()
cache, ok := fieldCache[t]
fieldCacheMutex.RUnlock()
if !ok {
cache = make(map[string]int)
for i := 0; i < v.NumField(); i++ {
cache[t.Field(i).Name] = i
}
fieldCacheMutex.Lock()
fieldCache[t] = cache
fieldCacheMutex.Unlock()
}
if i, ok := cache[name]; ok {
return v.Field(i)
}
return reflect.Zero(t)
}
// scan data to a struct's pointer according field name
func (rs *Rows) ScanStructByName(dest interface{}) error {
vv := reflect.ValueOf(dest)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
return errors.New("dest should be a struct's pointer")
}
cols, err := rs.Columns()
if err != nil {
return err
}
newDest := make([]interface{}, len(cols))
var v EmptyScanner
for j, name := range cols {
f := fieldByName(vv.Elem(), rs.Mapper.Table2Obj(name))
if f.IsValid() {
newDest[j] = f.Addr().Interface()
} else {
newDest[j] = &v
}
}
return rs.Rows.Scan(newDest...)
}
type cacheStruct struct {
value reflect.Value
idx int
}
var (
reflectCache = make(map[reflect.Type]*cacheStruct)
reflectCacheMutex sync.RWMutex
)
func ReflectNew(typ reflect.Type) reflect.Value {
reflectCacheMutex.RLock()
cs, ok := reflectCache[typ]
reflectCacheMutex.RUnlock()
const newSize = 200
if !ok || cs.idx+1 > newSize-1 {
cs = &cacheStruct{reflect.MakeSlice(reflect.SliceOf(typ), newSize, newSize), 0}
reflectCacheMutex.Lock()
reflectCache[typ] = cs
reflectCacheMutex.Unlock()
} else {
reflectCacheMutex.Lock()
cs.idx = cs.idx + 1
reflectCacheMutex.Unlock()
}
return cs.value.Index(cs.idx).Addr()
}
// scan data to a slice's pointer, slice's length should equal to columns' number
func (rs *Rows) ScanSlice(dest interface{}) error {
vv := reflect.ValueOf(dest)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Slice {
return errors.New("dest should be a slice's pointer")
}
vvv := vv.Elem()
cols, err := rs.Columns()
if err != nil {
return err
}
newDest := make([]interface{}, len(cols))
for j := 0; j < len(cols); j++ {
if j >= vvv.Len() {
newDest[j] = reflect.New(vvv.Type().Elem()).Interface()
} else {
newDest[j] = vvv.Index(j).Addr().Interface()
}
}
err = rs.Rows.Scan(newDest...)
if err != nil {
return err
}
srcLen := vvv.Len()
for i := srcLen; i < len(cols); i++ {
vvv = reflect.Append(vvv, reflect.ValueOf(newDest[i]).Elem())
}
return nil
}
// scan data to a map's pointer
func (rs *Rows) ScanMap(dest interface{}) error {
vv := reflect.ValueOf(dest)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return errors.New("dest should be a map's pointer")
}
cols, err := rs.Columns()
if err != nil {
return err
}
newDest := make([]interface{}, len(cols))
vvv := vv.Elem()
for i, _ := range cols {
newDest[i] = ReflectNew(vvv.Type().Elem()).Interface()
//v := reflect.New(vvv.Type().Elem())
//newDest[i] = v.Interface()
}
err = rs.Rows.Scan(newDest...)
if err != nil {
return err
}
for i, name := range cols {
vname := reflect.ValueOf(name)
vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
}
return nil
}
/*func (rs *Rows) ScanMap(dest interface{}) error {
vv := reflect.ValueOf(dest)
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
return errors.New("dest should be a map's pointer")
}
cols, err := rs.Columns()
if err != nil {
return err
}
newDest := make([]interface{}, len(cols))
err = rs.ScanSlice(newDest)
if err != nil {
return err
}
vvv := vv.Elem()
for i, name := range cols {
vname := reflect.ValueOf(name)
vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
}
return nil
}*/
type Row struct {
rows *Rows
// One of these two will be non-nil:
err error // deferred error for easy chaining
}
func (row *Row) Columns() ([]string, error) {
if row.err != nil {
return nil, row.err
}
return row.rows.Columns()
}
func (row *Row) Scan(dest ...interface{}) error {
if row.err != nil {
return row.err
}
defer row.rows.Close()
for _, dp := range dest {
if _, ok := dp.(*sql.RawBytes); ok {
return errors.New("sql: RawBytes isn't allowed on Row.Scan")
}
}
if !row.rows.Next() {
if err := row.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
err := row.rows.Scan(dest...)
if err != nil {
return err
}
// Make sure the query can be processed to completion with no errors.
return row.rows.Close()
}
func (row *Row) ScanStructByName(dest interface{}) error {
if row.err != nil {
return row.err
}
defer row.rows.Close()
if !row.rows.Next() {
if err := row.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
err := row.rows.ScanStructByName(dest)
if err != nil {
return err
}
// Make sure the query can be processed to completion with no errors.
return row.rows.Close()
}
func (row *Row) ScanStructByIndex(dest interface{}) error {
if row.err != nil {
return row.err
}
defer row.rows.Close()
if !row.rows.Next() {
if err := row.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
err := row.rows.ScanStructByIndex(dest)
if err != nil {
return err
}
// Make sure the query can be processed to completion with no errors.
return row.rows.Close()
}
// scan data to a slice's pointer, slice's length should equal to columns' number
func (row *Row) ScanSlice(dest interface{}) error {
if row.err != nil {
return row.err
}
defer row.rows.Close()
if !row.rows.Next() {
if err := row.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
err := row.rows.ScanSlice(dest)
if err != nil {
return err
}
// Make sure the query can be processed to completion with no errors.
return row.rows.Close()
}
// scan data to a map's pointer
func (row *Row) ScanMap(dest interface{}) error {
if row.err != nil {
return row.err
}
defer row.rows.Close()
if !row.rows.Next() {
if err := row.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
err := row.rows.ScanMap(dest)
if err != nil {
return err
}
// Make sure the query can be processed to completion with no errors.
return row.rows.Close()
}
func (row *Row) ToMapString() (map[string]string, error) {
cols, err := row.Columns()
if err != nil {
return nil, err
}
var record = make(map[string]string, len(cols))
err = row.ScanMap(&record)
if err != nil {
return nil, err
}
return record, nil
}

52
vendor/github.com/go-xorm/core/scan.go generated vendored Normal file
View file

@ -0,0 +1,52 @@
package core
import (
"database/sql/driver"
"fmt"
"time"
)
type NullTime time.Time
var (
_ driver.Valuer = NullTime{}
)
func (ns *NullTime) Scan(value interface{}) error {
if value == nil {
return nil
}
return convertTime(ns, value)
}
// Value implements the driver Valuer interface.
func (ns NullTime) Value() (driver.Value, error) {
if (time.Time)(ns).IsZero() {
return nil, nil
}
return (time.Time)(ns).Format("2006-01-02 15:04:05"), nil
}
func convertTime(dest *NullTime, src interface{}) error {
// Common cases, without reflect.
switch s := src.(type) {
case string:
t, err := time.Parse("2006-01-02 15:04:05", s)
if err != nil {
return err
}
*dest = NullTime(t)
return nil
case []uint8:
t, err := time.Parse("2006-01-02 15:04:05", string(s))
if err != nil {
return err
}
*dest = NullTime(t)
return nil
case nil:
default:
return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
}
return nil
}

151
vendor/github.com/go-xorm/core/table.go generated vendored Normal file
View file

@ -0,0 +1,151 @@
package core
import (
"reflect"
"strings"
)
// database table
type Table struct {
Name string
Type reflect.Type
columnsSeq []string
columnsMap map[string][]*Column
columns []*Column
Indexes map[string]*Index
PrimaryKeys []string
AutoIncrement string
Created map[string]bool
Updated string
Deleted string
Version string
Cacher Cacher
StoreEngine string
Charset string
}
func (table *Table) Columns() []*Column {
return table.columns
}
func (table *Table) ColumnsSeq() []string {
return table.columnsSeq
}
func NewEmptyTable() *Table {
return NewTable("", nil)
}
func NewTable(name string, t reflect.Type) *Table {
return &Table{Name: name, Type: t,
columnsSeq: make([]string, 0),
columns: make([]*Column, 0),
columnsMap: make(map[string][]*Column),
Indexes: make(map[string]*Index),
Created: make(map[string]bool),
PrimaryKeys: make([]string, 0),
}
}
func (table *Table) columnsByName(name string) []*Column {
n := len(name)
for k := range table.columnsMap {
if len(k) != n {
continue
}
if strings.EqualFold(k, name) {
return table.columnsMap[k]
}
}
return nil
}
func (table *Table) GetColumn(name string) *Column {
cols := table.columnsByName(name)
if cols != nil {
return cols[0]
}
return nil
}
func (table *Table) GetColumnIdx(name string, idx int) *Column {
cols := table.columnsByName(name)
if cols != nil && idx < len(cols) {
return cols[idx]
}
return nil
}
// if has primary key, return column
func (table *Table) PKColumns() []*Column {
columns := make([]*Column, len(table.PrimaryKeys))
for i, name := range table.PrimaryKeys {
columns[i] = table.GetColumn(name)
}
return columns
}
func (table *Table) ColumnType(name string) reflect.Type {
t, _ := table.Type.FieldByName(name)
return t.Type
}
func (table *Table) AutoIncrColumn() *Column {
return table.GetColumn(table.AutoIncrement)
}
func (table *Table) VersionColumn() *Column {
return table.GetColumn(table.Version)
}
func (table *Table) UpdatedColumn() *Column {
return table.GetColumn(table.Updated)
}
func (table *Table) DeletedColumn() *Column {
return table.GetColumn(table.Deleted)
}
// add a column to table
func (table *Table) AddColumn(col *Column) {
table.columnsSeq = append(table.columnsSeq, col.Name)
table.columns = append(table.columns, col)
colName := strings.ToLower(col.Name)
if c, ok := table.columnsMap[colName]; ok {
table.columnsMap[colName] = append(c, col)
} else {
table.columnsMap[colName] = []*Column{col}
}
if col.IsPrimaryKey {
table.PrimaryKeys = append(table.PrimaryKeys, col.Name)
}
if col.IsAutoIncrement {
table.AutoIncrement = col.Name
}
if col.IsCreated {
table.Created[col.Name] = true
}
if col.IsUpdated {
table.Updated = col.Name
}
if col.IsDeleted {
table.Deleted = col.Name
}
if col.IsVersion {
table.Version = col.Name
}
}
// add an index or an unique to table
func (table *Table) AddIndex(index *Index) {
table.Indexes[index.Name] = index
}

304
vendor/github.com/go-xorm/core/type.go generated vendored Normal file
View file

@ -0,0 +1,304 @@
package core
import (
"reflect"
"sort"
"strings"
"time"
)
const (
POSTGRES = "postgres"
SQLITE = "sqlite3"
MYSQL = "mysql"
MSSQL = "mssql"
ORACLE = "oracle"
)
// xorm SQL types
type SQLType struct {
Name string
DefaultLength int
DefaultLength2 int
}
const (
UNKNOW_TYPE = iota
TEXT_TYPE
BLOB_TYPE
TIME_TYPE
NUMERIC_TYPE
)
func (s *SQLType) IsType(st int) bool {
if t, ok := SqlTypes[s.Name]; ok && t == st {
return true
}
return false
}
func (s *SQLType) IsText() bool {
return s.IsType(TEXT_TYPE)
}
func (s *SQLType) IsBlob() bool {
return s.IsType(BLOB_TYPE)
}
func (s *SQLType) IsTime() bool {
return s.IsType(TIME_TYPE)
}
func (s *SQLType) IsNumeric() bool {
return s.IsType(NUMERIC_TYPE)
}
func (s *SQLType) IsJson() bool {
return s.Name == Json
}
var (
Bit = "BIT"
TinyInt = "TINYINT"
SmallInt = "SMALLINT"
MediumInt = "MEDIUMINT"
Int = "INT"
Integer = "INTEGER"
BigInt = "BIGINT"
Enum = "ENUM"
Set = "SET"
Char = "CHAR"
Varchar = "VARCHAR"
NVarchar = "NVARCHAR"
TinyText = "TINYTEXT"
Text = "TEXT"
Clob = "CLOB"
MediumText = "MEDIUMTEXT"
LongText = "LONGTEXT"
Uuid = "UUID"
Date = "DATE"
DateTime = "DATETIME"
Time = "TIME"
TimeStamp = "TIMESTAMP"
TimeStampz = "TIMESTAMPZ"
Decimal = "DECIMAL"
Numeric = "NUMERIC"
Real = "REAL"
Float = "FLOAT"
Double = "DOUBLE"
Binary = "BINARY"
VarBinary = "VARBINARY"
TinyBlob = "TINYBLOB"
Blob = "BLOB"
MediumBlob = "MEDIUMBLOB"
LongBlob = "LONGBLOB"
Bytea = "BYTEA"
Bool = "BOOL"
Serial = "SERIAL"
BigSerial = "BIGSERIAL"
Json = "JSON"
Jsonb = "JSONB"
SqlTypes = map[string]int{
Bit: NUMERIC_TYPE,
TinyInt: NUMERIC_TYPE,
SmallInt: NUMERIC_TYPE,
MediumInt: NUMERIC_TYPE,
Int: NUMERIC_TYPE,
Integer: NUMERIC_TYPE,
BigInt: NUMERIC_TYPE,
Enum: TEXT_TYPE,
Set: TEXT_TYPE,
Json: TEXT_TYPE,
Jsonb: TEXT_TYPE,
Char: TEXT_TYPE,
Varchar: TEXT_TYPE,
NVarchar: TEXT_TYPE,
TinyText: TEXT_TYPE,
Text: TEXT_TYPE,
MediumText: TEXT_TYPE,
LongText: TEXT_TYPE,
Uuid: TEXT_TYPE,
Clob: TEXT_TYPE,
Date: TIME_TYPE,
DateTime: TIME_TYPE,
Time: TIME_TYPE,
TimeStamp: TIME_TYPE,
TimeStampz: TIME_TYPE,
Decimal: NUMERIC_TYPE,
Numeric: NUMERIC_TYPE,
Real: NUMERIC_TYPE,
Float: NUMERIC_TYPE,
Double: NUMERIC_TYPE,
Binary: BLOB_TYPE,
VarBinary: BLOB_TYPE,
TinyBlob: BLOB_TYPE,
Blob: BLOB_TYPE,
MediumBlob: BLOB_TYPE,
LongBlob: BLOB_TYPE,
Bytea: BLOB_TYPE,
Bool: NUMERIC_TYPE,
Serial: NUMERIC_TYPE,
BigSerial: NUMERIC_TYPE,
}
intTypes = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
)
// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparision
var (
c_EMPTY_STRING string
c_BOOL_DEFAULT bool
c_BYTE_DEFAULT byte
c_COMPLEX64_DEFAULT complex64
c_COMPLEX128_DEFAULT complex128
c_FLOAT32_DEFAULT float32
c_FLOAT64_DEFAULT float64
c_INT64_DEFAULT int64
c_UINT64_DEFAULT uint64
c_INT32_DEFAULT int32
c_UINT32_DEFAULT uint32
c_INT16_DEFAULT int16
c_UINT16_DEFAULT uint16
c_INT8_DEFAULT int8
c_UINT8_DEFAULT uint8
c_INT_DEFAULT int
c_UINT_DEFAULT uint
c_TIME_DEFAULT time.Time
)
var (
IntType = reflect.TypeOf(c_INT_DEFAULT)
Int8Type = reflect.TypeOf(c_INT8_DEFAULT)
Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
Int64Type = reflect.TypeOf(c_INT64_DEFAULT)
UintType = reflect.TypeOf(c_UINT_DEFAULT)
Uint8Type = reflect.TypeOf(c_UINT8_DEFAULT)
Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)
Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)
Complex64Type = reflect.TypeOf(c_COMPLEX64_DEFAULT)
Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)
StringType = reflect.TypeOf(c_EMPTY_STRING)
BoolType = reflect.TypeOf(c_BOOL_DEFAULT)
ByteType = reflect.TypeOf(c_BYTE_DEFAULT)
BytesType = reflect.SliceOf(ByteType)
TimeType = reflect.TypeOf(c_TIME_DEFAULT)
)
var (
PtrIntType = reflect.PtrTo(IntType)
PtrInt8Type = reflect.PtrTo(Int8Type)
PtrInt16Type = reflect.PtrTo(Int16Type)
PtrInt32Type = reflect.PtrTo(Int32Type)
PtrInt64Type = reflect.PtrTo(Int64Type)
PtrUintType = reflect.PtrTo(UintType)
PtrUint8Type = reflect.PtrTo(Uint8Type)
PtrUint16Type = reflect.PtrTo(Uint16Type)
PtrUint32Type = reflect.PtrTo(Uint32Type)
PtrUint64Type = reflect.PtrTo(Uint64Type)
PtrFloat32Type = reflect.PtrTo(Float32Type)
PtrFloat64Type = reflect.PtrTo(Float64Type)
PtrComplex64Type = reflect.PtrTo(Complex64Type)
PtrComplex128Type = reflect.PtrTo(Complex128Type)
PtrStringType = reflect.PtrTo(StringType)
PtrBoolType = reflect.PtrTo(BoolType)
PtrByteType = reflect.PtrTo(ByteType)
PtrTimeType = reflect.PtrTo(TimeType)
)
// Type2SQLType generate SQLType acorrding Go's type
func Type2SQLType(t reflect.Type) (st SQLType) {
switch k := t.Kind(); k {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
st = SQLType{Int, 0, 0}
case reflect.Int64, reflect.Uint64:
st = SQLType{BigInt, 0, 0}
case reflect.Float32:
st = SQLType{Float, 0, 0}
case reflect.Float64:
st = SQLType{Double, 0, 0}
case reflect.Complex64, reflect.Complex128:
st = SQLType{Varchar, 64, 0}
case reflect.Array, reflect.Slice, reflect.Map:
if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
st = SQLType{Blob, 0, 0}
} else {
st = SQLType{Text, 0, 0}
}
case reflect.Bool:
st = SQLType{Bool, 0, 0}
case reflect.String:
st = SQLType{Varchar, 255, 0}
case reflect.Struct:
if t.ConvertibleTo(TimeType) {
st = SQLType{DateTime, 0, 0}
} else {
// TODO need to handle association struct
st = SQLType{Text, 0, 0}
}
case reflect.Ptr:
st = Type2SQLType(t.Elem())
default:
st = SQLType{Text, 0, 0}
}
return
}
// default sql type change to go types
func SQLType2Type(st SQLType) reflect.Type {
name := strings.ToUpper(st.Name)
switch name {
case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
return reflect.TypeOf(1)
case BigInt, BigSerial:
return reflect.TypeOf(int64(1))
case Float, Real:
return reflect.TypeOf(float32(1))
case Double:
return reflect.TypeOf(float64(1))
case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid, Clob:
return reflect.TypeOf("")
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary:
return reflect.TypeOf([]byte{})
case Bool:
return reflect.TypeOf(true)
case DateTime, Date, Time, TimeStamp, TimeStampz:
return reflect.TypeOf(c_TIME_DEFAULT)
case Decimal, Numeric:
return reflect.TypeOf("")
default:
return reflect.TypeOf("")
}
}