mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Added all required dependencies
This commit is contained in:
		
							
								
								
									
										27
									
								
								vendor/github.com/go-xorm/core/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/go-xorm/core/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										114
									
								
								vendor/github.com/go-xorm/core/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/go-xorm/core/benchmark.sh
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1 @@ | ||||
| go test -v -bench=. -run=XXX | ||||
							
								
								
									
										87
									
								
								vendor/github.com/go-xorm/core/cache.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								vendor/github.com/go-xorm/core/cache.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										160
									
								
								vendor/github.com/go-xorm/core/column.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/go-xorm/core/converstion.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										368
									
								
								vendor/github.com/go-xorm/core/db.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										302
									
								
								vendor/github.com/go-xorm/core/dialect.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/go-xorm/core/driver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/go-xorm/core/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/go-xorm/core/filter.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										31
									
								
								vendor/github.com/go-xorm/core/ilogger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										61
									
								
								vendor/github.com/go-xorm/core/index.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										254
									
								
								vendor/github.com/go-xorm/core/mapper.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/go-xorm/core/pk.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										380
									
								
								vendor/github.com/go-xorm/core/rows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/go-xorm/core/scan.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										151
									
								
								vendor/github.com/go-xorm/core/table.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										304
									
								
								vendor/github.com/go-xorm/core/type.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal 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("") | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user