mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
dependency(): updated go lib go-xorm
This commit is contained in:
parent
ddbdb54c04
commit
9dac382fbf
9
Godeps/Godeps.json
generated
9
Godeps/Godeps.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"ImportPath": "github.com/grafana/grafana",
|
||||
"GoVersion": "go1.5",
|
||||
"GoVersion": "go1.5.1",
|
||||
"Packages": [
|
||||
"./pkg/..."
|
||||
],
|
||||
@ -106,12 +106,13 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/core",
|
||||
"Rev": "be6e7ac47dc57bd0ada25322fa526944f66ccaa6"
|
||||
"Comment": "v0.4.4-7-g9e608f7",
|
||||
"Rev": "9e608f7330b9d16fe2818cfe731128b3f156cb9a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/xorm",
|
||||
"Comment": "v0.4.2-58-ge2889e5",
|
||||
"Rev": "e2889e5517600b82905f1d2ba8b70deb71823ffe"
|
||||
"Comment": "v0.4.4-44-gf561133",
|
||||
"Rev": "f56113384f2c63dfe4cd8e768e349f1c35122b58"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gosimple/slug",
|
||||
|
27
Godeps/_workspace/src/github.com/go-xorm/core/LICENSE
generated
vendored
Normal file
27
Godeps/_workspace/src/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.
|
19
Godeps/_workspace/src/github.com/go-xorm/core/cache.go
generated
vendored
19
Godeps/_workspace/src/github.com/go-xorm/core/cache.go
generated
vendored
@ -1,10 +1,11 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -47,16 +48,20 @@ type Cacher interface {
|
||||
}
|
||||
|
||||
func encodeIds(ids []PK) (string, error) {
|
||||
b, err := json.Marshal(ids)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
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)
|
||||
err := json.Unmarshal([]byte(s), &pks)
|
||||
|
||||
dec := gob.NewDecoder(bytes.NewBufferString(s))
|
||||
err := dec.Decode(&pks)
|
||||
|
||||
return pks, err
|
||||
}
|
||||
|
||||
|
60
Godeps/_workspace/src/github.com/go-xorm/core/column.go
generated
vendored
60
Godeps/_workspace/src/github.com/go-xorm/core/column.go
generated
vendored
@ -1,10 +1,10 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -35,6 +35,8 @@ type Column struct {
|
||||
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 {
|
||||
@ -122,50 +124,34 @@ func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||
}
|
||||
|
||||
if dataStruct.Type().Kind() == reflect.Map {
|
||||
var keyValue reflect.Value
|
||||
|
||||
if len(col.fieldPath) == 1 {
|
||||
keyValue = reflect.ValueOf(col.FieldName)
|
||||
} else if len(col.fieldPath) == 2 {
|
||||
keyValue = reflect.ValueOf(col.fieldPath[1])
|
||||
} else {
|
||||
return nil, fmt.Errorf("Unsupported mutliderive %v", col.FieldName)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if len(col.fieldPath) == 1 {
|
||||
fieldValue = dataStruct.FieldByName(col.FieldName)
|
||||
} else if len(col.fieldPath) == 2 {
|
||||
parentField := dataStruct.FieldByName(col.fieldPath[0])
|
||||
if parentField.IsValid() {
|
||||
if parentField.Kind() == reflect.Struct {
|
||||
fieldValue = parentField.FieldByName(col.fieldPath[1])
|
||||
} else if parentField.Kind() == reflect.Ptr {
|
||||
if parentField.IsNil() {
|
||||
parentField.Set(reflect.New(parentField.Type().Elem()))
|
||||
fieldValue = parentField.Elem().FieldByName(col.fieldPath[1])
|
||||
} else {
|
||||
parentField = parentField.Elem()
|
||||
if parentField.IsValid() {
|
||||
fieldValue = parentField.FieldByName(col.fieldPath[1])
|
||||
} else {
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// so we can use a different struct as conditions
|
||||
fieldValue = dataStruct.FieldByName(col.fieldPath[1])
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("Unsupported mutliderive %v", col.FieldName)
|
||||
}
|
||||
|
||||
if !fieldValue.IsValid() {
|
||||
return nil, errors.New("no find field matched")
|
||||
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||||
}
|
||||
|
||||
return &fieldValue, nil
|
||||
|
125
Godeps/_workspace/src/github.com/go-xorm/core/db.go
generated
vendored
125
Godeps/_workspace/src/github.com/go-xorm/core/db.go
generated
vendored
@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"reflect"
|
||||
"regexp"
|
||||
@ -29,10 +30,24 @@ func StructToSlice(query string, st interface{}) (string, []interface{}, error)
|
||||
}
|
||||
|
||||
args := make([]interface{}, 0)
|
||||
var err error
|
||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||
args = append(args, vv.Elem().FieldByName(src[1:]).Interface())
|
||||
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
|
||||
}
|
||||
|
||||
@ -43,12 +58,25 @@ type DB struct {
|
||||
|
||||
func Open(driverName, dataSourceName string) (*DB, error) {
|
||||
db, err := sql.Open(driverName, dataSourceName)
|
||||
return &DB{db, NewCacheMapper(&SnakeMapper{})}, err
|
||||
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...)
|
||||
return &Rows{rows, db.Mapper}, err
|
||||
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) {
|
||||
@ -68,28 +96,87 @@ func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
}
|
||||
|
||||
type Row struct {
|
||||
*sql.Row
|
||||
rows *Rows
|
||||
// One of these two will be non-nil:
|
||||
err error // deferred error for easy chaining
|
||||
Mapper IMapper
|
||||
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
|
||||
}
|
||||
return row.Row.Scan(dest...)
|
||||
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.
|
||||
if err := row.rows.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (row *Row) ScanStructByName(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
return row.rows.ScanStructByName(dest)
|
||||
}
|
||||
|
||||
func (row *Row) ScanStructByIndex(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
return row.rows.ScanStructByIndex(dest)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
return row.rows.ScanSlice(dest)
|
||||
}
|
||||
|
||||
// scan data to a map's pointer
|
||||
func (row *Row) ScanMap(dest interface{}) error {
|
||||
if row.err != nil {
|
||||
return row.err
|
||||
}
|
||||
return row.rows.ScanMap(dest)
|
||||
}
|
||||
|
||||
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
||||
row := db.DB.QueryRow(query, args...)
|
||||
return &Row{row, nil, db.Mapper}
|
||||
rows, err := db.Query(query, args...)
|
||||
return &Row{rows, err}
|
||||
}
|
||||
|
||||
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||
query, args, err := MapToSlice(query, mp)
|
||||
if err != nil {
|
||||
return &Row{nil, err, db.Mapper}
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return db.QueryRow(query, args...)
|
||||
}
|
||||
@ -97,7 +184,7 @@ func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return &Row{nil, err, db.Mapper}
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return db.QueryRow(query, args...)
|
||||
}
|
||||
@ -187,14 +274,14 @@ func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
||||
}
|
||||
|
||||
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
||||
row := s.Stmt.QueryRow(args...)
|
||||
return &Row{row, nil, s.Mapper}
|
||||
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"), s.Mapper}
|
||||
return &Row{nil, errors.New("mp should be a map's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
@ -208,7 +295,7 @@ func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
||||
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"), s.Mapper}
|
||||
return &Row{nil, errors.New("st should be a struct's pointer")}
|
||||
}
|
||||
|
||||
args := make([]interface{}, len(s.names))
|
||||
@ -540,14 +627,14 @@ func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||
}
|
||||
|
||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
||||
row := tx.Tx.QueryRow(query, args...)
|
||||
return &Row{row, nil, tx.Mapper}
|
||||
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, tx.Mapper}
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRow(query, args...)
|
||||
}
|
||||
@ -555,7 +642,7 @@ func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
||||
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
||||
query, args, err := StructToSlice(query, st)
|
||||
if err != nil {
|
||||
return &Row{nil, err, tx.Mapper}
|
||||
return &Row{nil, err}
|
||||
}
|
||||
return tx.QueryRow(query, args...)
|
||||
}
|
||||
|
8
Godeps/_workspace/src/github.com/go-xorm/core/db_test.go
generated
vendored
8
Godeps/_workspace/src/github.com/go-xorm/core/db_test.go
generated
vendored
@ -24,7 +24,7 @@ type User struct {
|
||||
Age float32
|
||||
Alias string
|
||||
NickName string
|
||||
Created time.Time
|
||||
Created NullTime
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -85,7 +85,7 @@ func BenchmarkOriQuery(b *testing.B) {
|
||||
var Id int64
|
||||
var Name, Title, Alias, NickName string
|
||||
var Age float32
|
||||
var Created time.Time
|
||||
var Created NullTime
|
||||
err = rows.Scan(&Id, &Name, &Title, &Age, &Alias, &NickName, &Created)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
@ -600,7 +600,7 @@ func TestExecStruct(t *testing.T) {
|
||||
Age: 1.2,
|
||||
Alias: "lunny",
|
||||
NickName: "lunny xiao",
|
||||
Created: time.Now(),
|
||||
Created: NullTime(time.Now()),
|
||||
}
|
||||
|
||||
_, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) "+
|
||||
@ -645,7 +645,7 @@ func BenchmarkExecStruct(b *testing.B) {
|
||||
Age: 1.2,
|
||||
Alias: "lunny",
|
||||
NickName: "lunny xiao",
|
||||
Created: time.Now(),
|
||||
Created: NullTime(time.Now()),
|
||||
}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
63
Godeps/_workspace/src/github.com/go-xorm/core/dialect.go
generated
vendored
63
Godeps/_workspace/src/github.com/go-xorm/core/dialect.go
generated
vendored
@ -54,7 +54,7 @@ type Dialect interface {
|
||||
IndexCheckSql(tableName, idxName string) (string, []interface{})
|
||||
TableCheckSql(tableName string) (string, []interface{})
|
||||
|
||||
IsColumnExist(tableName string, col *Column) (bool, error)
|
||||
IsColumnExist(tableName string, colName string) (bool, error)
|
||||
|
||||
CreateTableSql(table *Table, tableName, storeEngine, charset string) string
|
||||
DropTableSql(tableName string) string
|
||||
@ -63,6 +63,8 @@ type Dialect interface {
|
||||
|
||||
ModifyColumnSql(tableName string, col *Column) string
|
||||
|
||||
ForUpdateSql(query string) string
|
||||
|
||||
//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
||||
//MustDropTable(tableName string) error
|
||||
|
||||
@ -164,10 +166,10 @@ func (db *Base) HasRecords(query string, args ...interface{}) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (db *Base) IsColumnExist(tableName string, col *Column) (bool, error) {
|
||||
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, col.Name)
|
||||
return db.HasRecords(query, db.DbName, tableName, colName)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -229,28 +231,33 @@ func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset stri
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql += b.dialect.Quote(tableName) + " ("
|
||||
sql += b.dialect.Quote(tableName)
|
||||
sql += " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
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)
|
||||
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 += ", "
|
||||
}
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 1 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += b.dialect.Quote(strings.Join(pkList, b.dialect.Quote(",")))
|
||||
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 += ")"
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
if b.dialect.SupportEngine() && storeEngine != "" {
|
||||
sql += " ENGINE=" + storeEngine
|
||||
}
|
||||
@ -262,21 +269,25 @@ func (b *Base) CreateTableSql(table *Table, tableName, storeEngine, charset stri
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
}
|
||||
sql += ";"
|
||||
|
||||
return sql
|
||||
}
|
||||
|
||||
func (b *Base) ForUpdateSql(query string) string {
|
||||
return query + " FOR UPDATE"
|
||||
}
|
||||
|
||||
var (
|
||||
dialects = map[DbType]Dialect{}
|
||||
dialects = map[DbType]func() Dialect{}
|
||||
)
|
||||
|
||||
func RegisterDialect(dbName DbType, dialect Dialect) {
|
||||
if dialect == nil {
|
||||
func RegisterDialect(dbName DbType, dialectFunc func() Dialect) {
|
||||
if dialectFunc == nil {
|
||||
panic("core: Register dialect is nil")
|
||||
}
|
||||
dialects[dbName] = dialect // !nashtsai! allow override dialect
|
||||
dialects[dbName] = dialectFunc // !nashtsai! allow override dialect
|
||||
}
|
||||
|
||||
func QueryDialect(dbName DbType) Dialect {
|
||||
return dialects[dbName]
|
||||
return dialects[dbName]()
|
||||
}
|
||||
|
2
Godeps/_workspace/src/github.com/go-xorm/core/error.go
generated
vendored
2
Godeps/_workspace/src/github.com/go-xorm/core/error.go
generated
vendored
@ -4,7 +4,7 @@ import "errors"
|
||||
|
||||
var (
|
||||
ErrNoMapPointer = errors.New("mp should be a map's pointer")
|
||||
ErrNoStructPointer = errors.New("mp should be a map's pointer")
|
||||
ErrNoStructPointer = errors.New("mp should be a struct's pointer")
|
||||
//ErrNotExist = errors.New("Not exist")
|
||||
//ErrIgnore = errors.New("Ignore")
|
||||
)
|
||||
|
52
Godeps/_workspace/src/github.com/go-xorm/core/scan.go
generated
vendored
Normal file
52
Godeps/_workspace/src/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
|
||||
}
|
10
Godeps/_workspace/src/github.com/go-xorm/core/type.go
generated
vendored
10
Godeps/_workspace/src/github.com/go-xorm/core/type.go
generated
vendored
@ -53,6 +53,10 @@ func (s *SQLType) IsNumeric() bool {
|
||||
return s.IsType(NUMERIC_TYPE)
|
||||
}
|
||||
|
||||
func (s *SQLType) IsJson() bool {
|
||||
return s.Name == Json
|
||||
}
|
||||
|
||||
var (
|
||||
Bit = "BIT"
|
||||
TinyInt = "TINYINT"
|
||||
@ -101,6 +105,8 @@ var (
|
||||
Serial = "SERIAL"
|
||||
BigSerial = "BIGSERIAL"
|
||||
|
||||
Json = "JSON"
|
||||
|
||||
SqlTypes = map[string]int{
|
||||
Bit: NUMERIC_TYPE,
|
||||
TinyInt: NUMERIC_TYPE,
|
||||
@ -112,6 +118,7 @@ var (
|
||||
|
||||
Enum: TEXT_TYPE,
|
||||
Set: TEXT_TYPE,
|
||||
Json: TEXT_TYPE,
|
||||
|
||||
Char: TEXT_TYPE,
|
||||
Varchar: TEXT_TYPE,
|
||||
@ -229,7 +236,6 @@ var (
|
||||
)
|
||||
|
||||
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}
|
||||
@ -252,7 +258,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
||||
case reflect.String:
|
||||
st = SQLType{Varchar, 255, 0}
|
||||
case reflect.Struct:
|
||||
if t.ConvertibleTo(reflect.TypeOf(c_TIME_DEFAULT)) {
|
||||
if t.ConvertibleTo(TimeType) {
|
||||
st = SQLType{DateTime, 0, 0}
|
||||
} else {
|
||||
// TODO need to handle association struct
|
||||
|
2
Godeps/_workspace/src/github.com/go-xorm/xorm/LICENSE
generated
vendored
2
Godeps/_workspace/src/github.com/go-xorm/xorm/LICENSE
generated
vendored
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013 - 2014
|
||||
Copyright (c) 2013 - 2015 The Xorm Authors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
186
Godeps/_workspace/src/github.com/go-xorm/xorm/README.md
generated
vendored
186
Godeps/_workspace/src/github.com/go-xorm/xorm/README.md
generated
vendored
@ -2,6 +2,8 @@
|
||||
|
||||
Xorm is a simple and powerful ORM for Go.
|
||||
|
||||
[](https://gitter.im/go-xorm/xorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
[](https://drone.io/github.com/go-xorm/tests/latest) [](http://gowalker.org/github.com/go-xorm/xorm) [](https://bitdeli.com/free "Bitdeli Badge")
|
||||
|
||||
# Features
|
||||
@ -9,7 +11,7 @@ Xorm is a simple and powerful ORM for Go.
|
||||
* Struct <-> Table Mapping Support
|
||||
|
||||
* Chainable APIs
|
||||
|
||||
|
||||
* Transaction Support
|
||||
|
||||
* Both ORM and raw SQL operation Support
|
||||
@ -33,38 +35,44 @@ Drivers for Go's sql package which currently support database/sql includes:
|
||||
|
||||
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
|
||||
|
||||
* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
|
||||
* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc)
|
||||
|
||||
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment)
|
||||
|
||||
* ql: [github.com/cznic/ql](https://github.com/cznic/ql) (experiment)
|
||||
|
||||
# Changelog
|
||||
|
||||
* **v0.4.1**
|
||||
Features:
|
||||
* Add deleted xorm tag for soft delete and add unscoped
|
||||
* **v0.4.4**
|
||||
* ql database expriment support
|
||||
* tidb database expriment support
|
||||
* sql.NullString and etc. field support
|
||||
* select ForUpdate support
|
||||
* many bugs fixed
|
||||
|
||||
* **v0.4.0 RC1**
|
||||
Changes:
|
||||
* moved xorm cmd to [github.com/go-xorm/cmd](github.com/go-xorm/cmd)
|
||||
* refactored general DB operation a core lib at [github.com/go-xorm/core](https://github.com/go-xorm/core)
|
||||
* moved tests to github.com/go-xorm/tests [github.com/go-xorm/tests](github.com/go-xorm/tests)
|
||||
* **v0.4.3**
|
||||
* Json column type support
|
||||
* oracle expirement support
|
||||
* bug fixed
|
||||
|
||||
Improvements:
|
||||
* Prepared statement cache
|
||||
* Add Incr API
|
||||
* Specify Timezone Location
|
||||
* **v0.4.2**
|
||||
* Transaction will auto rollback if not Rollback or Commit be called.
|
||||
* Gonic Mapper support
|
||||
* bug fixed
|
||||
|
||||
[More changelogs ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-15)
|
||||
[More changelogs ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)
|
||||
|
||||
# Installation
|
||||
|
||||
If you have [gopm](https://github.com/gpmgo/gopm) installed,
|
||||
If you have [gopm](https://github.com/gpmgo/gopm) installed,
|
||||
|
||||
gopm get github.com/go-xorm/xorm
|
||||
|
||||
@ -80,8 +88,152 @@ Or
|
||||
|
||||
* [GoWalker](http://gowalker.org/github.com/go-xorm/xorm)
|
||||
|
||||
# Quick Start
|
||||
|
||||
* Create Engine
|
||||
|
||||
```Go
|
||||
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||
```
|
||||
|
||||
* Define a struct and Sync2 table struct to database
|
||||
|
||||
```Go
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
Salt string
|
||||
Age int
|
||||
Passwd string `xorm:"varchar(200)"`
|
||||
Created time.Time `xorm:"created"`
|
||||
Updated time.Time `xorm:"updated"`
|
||||
}
|
||||
|
||||
err := engine.Sync2(new(User))
|
||||
```
|
||||
|
||||
* Query a SQL string, the returned results is []map[string][]byte
|
||||
|
||||
```Go
|
||||
results, err := engine.Query("select * from user")
|
||||
```
|
||||
|
||||
* Execute a SQL string, the returned results
|
||||
|
||||
```Go
|
||||
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||
```
|
||||
|
||||
* Insert one or multipe records to database
|
||||
|
||||
```Go
|
||||
affected, err := engine.Insert(&user)
|
||||
// INSERT INTO struct () values ()
|
||||
affected, err := engine.Insert(&user1, &user2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values ()
|
||||
affected, err := engine.Insert(&users)
|
||||
// INSERT INTO struct () values (),(),()
|
||||
affected, err := engine.Insert(&user1, &users)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values (),(),()
|
||||
```
|
||||
|
||||
* Query one record from database
|
||||
|
||||
```Go
|
||||
has, err := engine.Get(&user)
|
||||
// SELECT * FROM user LIMIT 1
|
||||
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
```
|
||||
|
||||
* Query multiple records from database, also you can use join and extends
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||
|
||||
type Detail struct {
|
||||
Id int64
|
||||
UserId int64 `xorm:"index"`
|
||||
}
|
||||
|
||||
type UserDetail struct {
|
||||
User `xorm:"extends"`
|
||||
Detail `xorm:"extends"`
|
||||
}
|
||||
|
||||
var users []UserDetail
|
||||
err := engine.Table("user").Select("user.*, detail.*")
|
||||
Join("INNER", "detail", "detail.user_id = user.id").
|
||||
Where("user.name = ?", name).Limit(10, 0).
|
||||
Find(&users)
|
||||
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||
```
|
||||
|
||||
* Query multiple records and record by record handle, there two methods Iterate and Rows
|
||||
|
||||
```Go
|
||||
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||
user := bean.(*User)
|
||||
return nil
|
||||
})
|
||||
// SELECT * FROM user
|
||||
|
||||
rows, err := engine.Rows(&User{Name:name})
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
```
|
||||
|
||||
* Update one or more records, default will update non-empty and non-zero fields except to use Cols, AllCols and etc.
|
||||
|
||||
```Go
|
||||
affected, err := engine.Id(1).Update(&user)
|
||||
// UPDATE user SET ... Where id = ?
|
||||
|
||||
affected, err := engine.Update(&user, &User{Name:name})
|
||||
// UPDATE user SET ... Where name = ?
|
||||
|
||||
var ids = []int64{1, 2, 3}
|
||||
affected, err := engine.In(ids).Update(&user)
|
||||
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||
|
||||
// force update indicated columns by Cols
|
||||
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
// force NOT update indicated columns by Omit
|
||||
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||
```
|
||||
|
||||
* Delete one or more records, Delete MUST has conditon
|
||||
|
||||
```Go
|
||||
affected, err := engine.Where(...).Delete(&user)
|
||||
// DELETE FROM user Where ...
|
||||
```
|
||||
|
||||
* Count records
|
||||
|
||||
```Go
|
||||
counts, err := engine.Count(&user)
|
||||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
# Cases
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
178
Godeps/_workspace/src/github.com/go-xorm/xorm/README_CN.md
generated
vendored
178
Godeps/_workspace/src/github.com/go-xorm/xorm/README_CN.md
generated
vendored
@ -4,6 +4,8 @@
|
||||
|
||||
xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作非常简便。
|
||||
|
||||
[](https://gitter.im/go-xorm/xorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
[](https://drone.io/github.com/go-xorm/tests/latest) [](http://gowalker.org/github.com/go-xorm/xorm)
|
||||
|
||||
## 特性
|
||||
@ -18,7 +20,7 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||
|
||||
* 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函数和结构体等方式作为条件
|
||||
|
||||
* 支持级联加载Struct
|
||||
* 支持级联加载Struct
|
||||
|
||||
* 支持缓存
|
||||
|
||||
@ -34,29 +36,42 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||
|
||||
* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/godrv)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* Postgres: [github.com/lib/pq](https://github.com/lib/pq)
|
||||
|
||||
* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb)
|
||||
|
||||
* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)
|
||||
|
||||
* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)
|
||||
|
||||
* MsSql: [github.com/lunny/godbc](https://github.com/lunny/godbc)
|
||||
|
||||
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持)
|
||||
|
||||
* ql: [github.com/cznic/ql](https://github.com/cznic/ql) (试验性支持)
|
||||
|
||||
## 更新日志
|
||||
|
||||
* **v0.4.2**
|
||||
新特性:
|
||||
* deleted标记
|
||||
* bug fixed
|
||||
* **v0.4.4**
|
||||
* Tidb 数据库支持
|
||||
* QL 试验性支持
|
||||
* sql.NullString支持
|
||||
* ForUpdate 支持
|
||||
* bug修正
|
||||
|
||||
* **v0.4.3**
|
||||
* Json 字段类型支持
|
||||
* oracle实验性支持
|
||||
* bug修正
|
||||
|
||||
[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16)
|
||||
|
||||
## 安装
|
||||
|
||||
推荐使用 [gopm](https://github.com/gpmgo/gopm) 进行安装:
|
||||
推荐使用 [gopm](https://github.com/gpmgo/gopm) 进行安装:
|
||||
|
||||
gopm get github.com/go-xorm/xorm
|
||||
|
||||
|
||||
或者您也可以使用go工具进行安装:
|
||||
|
||||
go get github.com/go-xorm/xorm
|
||||
@ -69,8 +84,151 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||
|
||||
* [Godoc代码文档](http://godoc.org/github.com/go-xorm/xorm)
|
||||
|
||||
# 快速开始
|
||||
|
||||
## 案例
|
||||
* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同
|
||||
|
||||
```Go
|
||||
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||
```
|
||||
|
||||
* 定义一个和表同步的结构体,并且自动同步结构体到数据库
|
||||
|
||||
```Go
|
||||
type User struct {
|
||||
Id int64
|
||||
Name string
|
||||
Salt string
|
||||
Age int
|
||||
Passwd string `xorm:"varchar(200)"`
|
||||
Created time.Time `xorm:"created"`
|
||||
Updated time.Time `xorm:"updated"`
|
||||
}
|
||||
|
||||
err := engine.Sync2(new(User))
|
||||
```
|
||||
|
||||
* 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte
|
||||
|
||||
```Go
|
||||
results, err := engine.Query("select * from user")
|
||||
```
|
||||
|
||||
* 执行一个SQL语句
|
||||
|
||||
```Go
|
||||
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||
```
|
||||
|
||||
* 插入一条或者多条记录
|
||||
|
||||
```Go
|
||||
affected, err := engine.Insert(&user)
|
||||
// INSERT INTO struct () values ()
|
||||
affected, err := engine.Insert(&user1, &user2)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values ()
|
||||
affected, err := engine.Insert(&users)
|
||||
// INSERT INTO struct () values (),(),()
|
||||
affected, err := engine.Insert(&user1, &users)
|
||||
// INSERT INTO struct1 () values ()
|
||||
// INSERT INTO struct2 () values (),(),()
|
||||
```
|
||||
|
||||
* 查询单条记录
|
||||
|
||||
```Go
|
||||
has, err := engine.Get(&user)
|
||||
// SELECT * FROM user LIMIT 1
|
||||
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
```
|
||||
|
||||
* 查询多条记录,当然可以使用Join和extends来组合使用
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||
|
||||
type Detail struct {
|
||||
Id int64
|
||||
UserId int64 `xorm:"index"`
|
||||
}
|
||||
|
||||
type UserDetail struct {
|
||||
User `xorm:"extends"`
|
||||
Detail `xorm:"extends"`
|
||||
}
|
||||
|
||||
var users []UserDetail
|
||||
err := engine.Table("user").Select("user.*, detail.*")
|
||||
Join("INNER", "detail", "detail.user_id = user.id").
|
||||
Where("user.name = ?", name).Limit(10, 0).
|
||||
Find(&users)
|
||||
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||
```
|
||||
|
||||
* 根据条件遍历数据库,可以有两种方式: Iterate and Rows
|
||||
|
||||
```Go
|
||||
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||
user := bean.(*User)
|
||||
return nil
|
||||
})
|
||||
// SELECT * FROM user
|
||||
|
||||
rows, err := engine.Rows(&User{Name:name})
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
```
|
||||
|
||||
* 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段
|
||||
|
||||
```Go
|
||||
affected, err := engine.Id(1).Update(&user)
|
||||
// UPDATE user SET ... Where id = ?
|
||||
|
||||
affected, err := engine.Update(&user, &User{Name:name})
|
||||
// UPDATE user SET ... Where name = ?
|
||||
|
||||
var ids = []int64{1, 2, 3}
|
||||
affected, err := engine.In(ids).Update(&user)
|
||||
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||
|
||||
// force update indicated columns by Cols
|
||||
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
// force NOT update indicated columns by Omit
|
||||
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||
|
||||
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||
```
|
||||
|
||||
* 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable
|
||||
|
||||
```Go
|
||||
affected, err := engine.Where(...).Delete(&user)
|
||||
// DELETE FROM user Where ...
|
||||
```
|
||||
|
||||
* 获取记录条数
|
||||
|
||||
```Go
|
||||
counts, err := engine.Count(&user)
|
||||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
# 案例
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
|
2
Godeps/_workspace/src/github.com/go-xorm/xorm/VERSION
generated
vendored
2
Godeps/_workspace/src/github.com/go-xorm/xorm/VERSION
generated
vendored
@ -1 +1 @@
|
||||
xorm v0.4.2.0225
|
||||
xorm v0.4.5.0204
|
||||
|
2
Godeps/_workspace/src/github.com/go-xorm/xorm/doc.go
generated
vendored
2
Godeps/_workspace/src/github.com/go-xorm/xorm/doc.go
generated
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright 2013 - 2014 The XORM Authors. All rights reserved.
|
||||
// Copyright 2013 - 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
137
Godeps/_workspace/src/github.com/go-xorm/xorm/engine.go
generated
vendored
137
Godeps/_workspace/src/github.com/go-xorm/xorm/engine.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -316,6 +320,12 @@ func (engine *Engine) NoAutoTime() *Session {
|
||||
return session.NoAutoTime()
|
||||
}
|
||||
|
||||
func (engine *Engine) NoAutoCondition(no ...bool) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
return session.NoAutoCondition(no...)
|
||||
}
|
||||
|
||||
// Retrieve all tables, columns, indexes' informations from database.
|
||||
func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
||||
tables, err := engine.dialect.GetTables()
|
||||
@ -373,13 +383,25 @@ func (engine *Engine) DumpAll(w io.Writer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
_, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+"\n\n")
|
||||
_, err = io.WriteString(w, fmt.Sprintf("/*Generated by xorm v%s %s*/\n\n",
|
||||
Version, time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05")))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, table := range tables {
|
||||
if i > 0 {
|
||||
_, err = io.WriteString(w, "\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+";\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, index := range table.Indexes {
|
||||
_, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+"\n\n")
|
||||
_, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+";\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -439,7 +461,7 @@ func (engine *Engine) DumpAll(w io.Writer) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = io.WriteString(w, temp[2:]+");\n\n")
|
||||
_, err = io.WriteString(w, temp[2:]+");\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -506,6 +528,12 @@ func (engine *Engine) Distinct(columns ...string) *Session {
|
||||
return session.Distinct(columns...)
|
||||
}
|
||||
|
||||
func (engine *Engine) Select(str string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
return session.Select(str)
|
||||
}
|
||||
|
||||
// only use the paramters as select or update columns
|
||||
func (engine *Engine) Cols(columns ...string) *Session {
|
||||
session := engine.NewSession()
|
||||
@ -543,6 +571,13 @@ func (engine *Engine) Omit(columns ...string) *Session {
|
||||
return session.Omit(columns...)
|
||||
}
|
||||
|
||||
// Set null when column is zero-value and nullable for update
|
||||
func (engine *Engine) Nullable(columns ...string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
return session.Nullable(columns...)
|
||||
}
|
||||
|
||||
// This method will generate "column IN (?, ?)"
|
||||
func (engine *Engine) In(column string, args ...interface{}) *Session {
|
||||
session := engine.NewSession()
|
||||
@ -642,20 +677,20 @@ func (engine *Engine) Having(conditions string) *Session {
|
||||
|
||||
func (engine *Engine) autoMapType(v reflect.Value) *core.Table {
|
||||
t := v.Type()
|
||||
engine.mutex.RLock()
|
||||
engine.mutex.Lock()
|
||||
table, ok := engine.Tables[t]
|
||||
engine.mutex.RUnlock()
|
||||
if !ok {
|
||||
table = engine.mapType(v)
|
||||
engine.mutex.Lock()
|
||||
engine.Tables[t] = table
|
||||
if v.CanAddr() {
|
||||
engine.GobRegister(v.Addr().Interface())
|
||||
} else {
|
||||
engine.GobRegister(v.Interface())
|
||||
if engine.Cacher != nil {
|
||||
if v.CanAddr() {
|
||||
engine.GobRegister(v.Addr().Interface())
|
||||
} else {
|
||||
engine.GobRegister(v.Interface())
|
||||
}
|
||||
}
|
||||
engine.mutex.Unlock()
|
||||
}
|
||||
engine.mutex.Unlock()
|
||||
return table
|
||||
}
|
||||
|
||||
@ -691,33 +726,24 @@ func (engine *Engine) newTable() *core.Table {
|
||||
return table
|
||||
}
|
||||
|
||||
type TableName interface {
|
||||
TableName() string
|
||||
}
|
||||
|
||||
func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||
t := v.Type()
|
||||
table := engine.newTable()
|
||||
method := v.MethodByName("TableName")
|
||||
if !method.IsValid() {
|
||||
if v.CanAddr() {
|
||||
method = v.Addr().MethodByName("TableName")
|
||||
}
|
||||
}
|
||||
if method.IsValid() {
|
||||
params := []reflect.Value{}
|
||||
results := method.Call(params)
|
||||
if len(results) == 1 {
|
||||
table.Name = results[0].Interface().(string)
|
||||
}
|
||||
}
|
||||
|
||||
if table.Name == "" {
|
||||
if tb, ok := v.Interface().(TableName); ok {
|
||||
table.Name = tb.TableName()
|
||||
} else {
|
||||
table.Name = engine.TableMapper.Obj2Table(t.Name())
|
||||
}
|
||||
|
||||
table.Type = t
|
||||
|
||||
var idFieldColName string
|
||||
var err error
|
||||
|
||||
hasCacheTag := false
|
||||
hasNoCacheTag := false
|
||||
var hasCacheTag, hasNoCacheTag bool
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
tag := t.Field(i).Tag
|
||||
@ -730,7 +756,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||
if ormTagStr != "" {
|
||||
col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
|
||||
IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]bool)}
|
||||
tags := strings.Split(ormTagStr, " ")
|
||||
tags := splitTag(ormTagStr)
|
||||
|
||||
if len(tags) > 0 {
|
||||
if tags[0] == "-" {
|
||||
@ -804,6 +830,16 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||
case k == "VERSION":
|
||||
col.IsVersion = true
|
||||
col.Default = "1"
|
||||
case k == "UTC":
|
||||
col.TimeZone = time.UTC
|
||||
case k == "LOCAL":
|
||||
col.TimeZone = time.Local
|
||||
case strings.HasPrefix(k, "LOCALE(") && strings.HasSuffix(k, ")"):
|
||||
location := k[len("INDEX")+1 : len(k)-1]
|
||||
col.TimeZone, err = time.LoadLocation(location)
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
}
|
||||
case k == "UPDATED":
|
||||
col.IsUpdated = true
|
||||
case k == "DELETED":
|
||||
@ -1112,7 +1148,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
|
||||
session := engine.NewSession()
|
||||
session.Statement.RefTable = table
|
||||
defer session.Close()
|
||||
isExist, err := session.Engine.dialect.IsColumnExist(table.Name, col)
|
||||
isExist, err := session.Engine.dialect.IsColumnExist(table.Name, col.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1387,7 +1423,6 @@ var (
|
||||
)
|
||||
|
||||
func (engine *Engine) TZTime(t time.Time) time.Time {
|
||||
|
||||
if NULL_TIME != t { // if time is not initialized it's not suitable for Time.In()
|
||||
return t.In(engine.TZLocation)
|
||||
}
|
||||
@ -1405,35 +1440,51 @@ func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
|
||||
}
|
||||
|
||||
func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}) {
|
||||
return engine.formatTime(engine.TZLocation, sqlTypeName, t)
|
||||
}
|
||||
|
||||
func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{}) {
|
||||
if col.DisableTimeZone {
|
||||
return engine.formatTime(nil, col.SQLType.Name, t)
|
||||
} else if col.TimeZone != nil {
|
||||
return engine.formatTime(col.TimeZone, col.SQLType.Name, t)
|
||||
}
|
||||
return engine.formatTime(engine.TZLocation, col.SQLType.Name, t)
|
||||
}
|
||||
|
||||
func (engine *Engine) formatTime(tz *time.Location, sqlTypeName string, t time.Time) (v interface{}) {
|
||||
if engine.dialect.DBType() == core.ORACLE {
|
||||
return t
|
||||
}
|
||||
if tz != nil {
|
||||
t = engine.TZTime(t)
|
||||
}
|
||||
switch sqlTypeName {
|
||||
case core.Time:
|
||||
s := engine.TZTime(t).Format("2006-01-02 15:04:05") //time.RFC3339
|
||||
s := t.Format("2006-01-02 15:04:05") //time.RFC3339
|
||||
v = s[11:19]
|
||||
case core.Date:
|
||||
v = engine.TZTime(t).Format("2006-01-02")
|
||||
v = t.Format("2006-01-02")
|
||||
case core.DateTime, core.TimeStamp:
|
||||
if engine.dialect.DBType() == "ql" {
|
||||
v = engine.TZTime(t)
|
||||
v = t
|
||||
} else if engine.dialect.DBType() == "sqlite3" {
|
||||
v = engine.TZTime(t).UTC().Format("2006-01-02 15:04:05")
|
||||
v = t.UTC().Format("2006-01-02 15:04:05")
|
||||
} else {
|
||||
v = engine.TZTime(t).Format("2006-01-02 15:04:05")
|
||||
v = t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
case core.TimeStampz:
|
||||
if engine.dialect.DBType() == core.MSSQL {
|
||||
v = engine.TZTime(t).Format("2006-01-02T15:04:05.9999999Z07:00")
|
||||
v = t.Format("2006-01-02T15:04:05.9999999Z07:00")
|
||||
} else if engine.DriverName() == "mssql" {
|
||||
v = engine.TZTime(t)
|
||||
v = t
|
||||
} else {
|
||||
v = engine.TZTime(t).Format(time.RFC3339Nano)
|
||||
v = t.Format(time.RFC3339Nano)
|
||||
}
|
||||
case core.BigInt, core.Int:
|
||||
v = engine.TZTime(t).Unix()
|
||||
v = t.Unix()
|
||||
default:
|
||||
v = engine.TZTime(t)
|
||||
v = t
|
||||
}
|
||||
return
|
||||
}
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/error.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/error.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
BIN
Godeps/_workspace/src/github.com/go-xorm/xorm/examples/goroutine.db-journal
generated
vendored
BIN
Godeps/_workspace/src/github.com/go-xorm/xorm/examples/goroutine.db-journal
generated
vendored
Binary file not shown.
4
Godeps/_workspace/src/github.com/go-xorm/xorm/examples/goroutine.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/examples/goroutine.go
generated
vendored
@ -33,7 +33,7 @@ func test(engine *xorm.Engine) {
|
||||
return
|
||||
}
|
||||
|
||||
size := 500
|
||||
size := 100
|
||||
queue := make(chan int, size)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
@ -83,7 +83,7 @@ func test(engine *xorm.Engine) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
runtime.GOMAXPROCS(1)
|
||||
runtime.GOMAXPROCS(2)
|
||||
fmt.Println("-----start sqlite go routines-----")
|
||||
engine, err := sqliteEngine()
|
||||
if err != nil {
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/goracle_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/goracle_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
73
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers.go
generated
vendored
73
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -11,6 +15,30 @@ import (
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
func splitTag(tag string) (tags []string) {
|
||||
tag = strings.TrimSpace(tag)
|
||||
var hasQuote = false
|
||||
var lastIdx = 0
|
||||
for i, t := range tag {
|
||||
if t == '\'' {
|
||||
hasQuote = !hasQuote
|
||||
} else if t == ' ' {
|
||||
if lastIdx < i && !hasQuote {
|
||||
tags = append(tags, strings.TrimSpace(tag[lastIdx:i]))
|
||||
lastIdx = i + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
if lastIdx < len(tag) {
|
||||
tags = append(tags, strings.TrimSpace(tag[lastIdx:len(tag)]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type zeroable interface {
|
||||
IsZero() bool
|
||||
}
|
||||
|
||||
func isZero(k interface{}) bool {
|
||||
switch k.(type) {
|
||||
case int:
|
||||
@ -33,12 +61,41 @@ func isZero(k interface{}) bool {
|
||||
return k.(uint32) == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
case float32:
|
||||
return k.(float32) == 0
|
||||
case float64:
|
||||
return k.(float64) == 0
|
||||
case bool:
|
||||
return k.(bool) == false
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
case zeroable:
|
||||
return k.(zeroable).IsZero()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func int64ToInt(id int64, k reflect.Kind) interface{} {
|
||||
var v interface{} = id
|
||||
switch k {
|
||||
case reflect.Int16:
|
||||
v = int16(id)
|
||||
case reflect.Int32:
|
||||
v = int32(id)
|
||||
case reflect.Int:
|
||||
v = int(id)
|
||||
case reflect.Uint16:
|
||||
v = uint16(id)
|
||||
case reflect.Uint32:
|
||||
v = uint32(id)
|
||||
case reflect.Uint64:
|
||||
v = uint64(id)
|
||||
case reflect.Uint:
|
||||
v = uint(id)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func isPKZero(pk core.PK) bool {
|
||||
for _, k := range pk {
|
||||
if isZero(k) {
|
||||
@ -48,6 +105,10 @@ func isPKZero(pk core.PK) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func equalNoCase(s1, s2 string) bool {
|
||||
return strings.ToLower(s1) == strings.ToLower(s2)
|
||||
}
|
||||
|
||||
func indexNoCase(s, sep string) int {
|
||||
return strings.Index(strings.ToLower(s), strings.ToLower(sep))
|
||||
}
|
||||
@ -129,8 +190,8 @@ func reflect2value(rawValue *reflect.Value) (str string, err error) {
|
||||
}
|
||||
//时间类型
|
||||
case reflect.Struct:
|
||||
if aa == core.TimeType {
|
||||
str = rawValue.Interface().(time.Time).Format(time.RFC3339Nano)
|
||||
if aa.ConvertibleTo(core.TimeType) {
|
||||
str = vv.Convert(core.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
|
||||
} else {
|
||||
err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
|
||||
}
|
||||
@ -352,6 +413,14 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool,
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if _, ok := session.Statement.nullableMap[lColName]; ok {
|
||||
if col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.Statement.UseAutoTime {
|
||||
val, t := session.Engine.NowTime2(col.SQLType.Name)
|
||||
args = append(args, val)
|
||||
|
22
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers_test.go
generated
vendored
Normal file
22
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers_test.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
package xorm
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSplitTag(t *testing.T) {
|
||||
var cases = []struct {
|
||||
tag string
|
||||
tags []string
|
||||
}{
|
||||
{"not null default '2000-01-01 00:00:00' TIMESTAMP", []string{"not", "null", "default", "'2000-01-01 00:00:00'", "TIMESTAMP"}},
|
||||
{"TEXT", []string{"TEXT"}},
|
||||
{"default('2000-01-01 00:00:00')", []string{"default('2000-01-01 00:00:00')"}},
|
||||
{"json binary", []string{"json", "binary"}},
|
||||
}
|
||||
|
||||
for _, kase := range cases {
|
||||
tags := splitTag(kase.tag)
|
||||
if !sliceEq(tags, kase.tags) {
|
||||
t.Fatalf("[%d]%v is not equal [%d]%v", len(tags), tags, len(kase.tags), kase.tags)
|
||||
}
|
||||
}
|
||||
}
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/logger.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/logger.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
5
Godeps/_workspace/src/github.com/go-xorm/xorm/lru_cacher.go
generated
vendored
5
Godeps/_workspace/src/github.com/go-xorm/xorm/lru_cacher.go
generated
vendored
@ -1,4 +1,7 @@
|
||||
//LRUCacher implements Cacher according to LRU algorithm
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
@ -1,4 +1,7 @@
|
||||
// MemoryStore implements CacheStore provide local machine
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
19
Godeps/_workspace/src/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
19
Godeps/_workspace/src/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -216,6 +220,11 @@ func (db *mssql) SqlType(c *core.Column) string {
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bool:
|
||||
res = core.TinyInt
|
||||
if c.Default == "true" {
|
||||
c.Default = "1"
|
||||
} else if c.Default == "false" {
|
||||
c.Default = "0"
|
||||
}
|
||||
case core.Serial:
|
||||
c.IsAutoIncrement = true
|
||||
c.IsPrimaryKey = true
|
||||
@ -238,7 +247,7 @@ func (db *mssql) SqlType(c *core.Column) string {
|
||||
c.Length = 7
|
||||
case core.MediumInt:
|
||||
res = core.Int
|
||||
case core.MediumText, core.TinyText, core.LongText:
|
||||
case core.MediumText, core.TinyText, core.LongText, core.Json:
|
||||
res = core.Text
|
||||
case core.Double:
|
||||
res = core.Real
|
||||
@ -311,10 +320,10 @@ func (db *mssql) IndexCheckSql(tableName, idxName string) (string, []interface{}
|
||||
return sql, args
|
||||
}*/
|
||||
|
||||
func (db *mssql) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
||||
func (db *mssql) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
query := `SELECT "COLUMN_NAME" FROM "INFORMATION_SCHEMA"."COLUMNS" WHERE "TABLE_NAME" = ? AND "COLUMN_NAME" = ?`
|
||||
|
||||
return db.HasRecords(query, tableName, col.Name)
|
||||
return db.HasRecords(query, tableName, colName)
|
||||
}
|
||||
|
||||
func (db *mssql) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
@ -500,6 +509,10 @@ func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
||||
return sql
|
||||
}
|
||||
|
||||
func (db *mssql) ForUpdateSql(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
func (db *mssql) Filters() []core.Filter {
|
||||
return []core.Filter{&core.IdFilter{}, &core.QuoteFilter{}}
|
||||
}
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/mymysql_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/mymysql_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
6
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
6
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -221,6 +225,8 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||
case core.Uuid:
|
||||
res = core.Varchar
|
||||
c.Length = 40
|
||||
case core.Json:
|
||||
res = core.Text
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/oci8_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/oci8_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/odbc_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/odbc_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
12
Godeps/_workspace/src/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
12
Godeps/_workspace/src/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -518,7 +522,7 @@ func (db *oracle) SqlType(c *core.Column) string {
|
||||
res = "TIMESTAMP WITH TIME ZONE"
|
||||
case core.Float, core.Double, core.Numeric, core.Decimal:
|
||||
res = "NUMBER"
|
||||
case core.Text, core.MediumText, core.LongText:
|
||||
case core.Text, core.MediumText, core.LongText, core.Json:
|
||||
res = "CLOB"
|
||||
case core.Char, core.Varchar, core.TinyText:
|
||||
res = "VARCHAR2"
|
||||
@ -661,8 +665,8 @@ func (db *oracle) MustDropTable(tableName string) error {
|
||||
" AND column_name = ?", args
|
||||
}*/
|
||||
|
||||
func (db *oracle) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
||||
args := []interface{}{tableName, col.Name}
|
||||
func (db *oracle) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName, colName}
|
||||
query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" +
|
||||
" AND column_name = :2"
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
@ -740,6 +744,8 @@ func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Colum
|
||||
switch dt {
|
||||
case "VARCHAR2":
|
||||
col.SQLType = core.SQLType{core.Varchar, len1, len2}
|
||||
case "NVARCHAR2":
|
||||
col.SQLType = core.SQLType{core.NVarchar, len1, len2}
|
||||
case "TIMESTAMP WITH TIME ZONE":
|
||||
col.SQLType = core.SQLType{core.TimeStampz, 0, 0}
|
||||
case "NUMBER":
|
||||
|
13
Godeps/_workspace/src/github.com/go-xorm/xorm/postgres_dialect.go
generated
vendored
13
Godeps/_workspace/src/github.com/go-xorm/xorm/postgres_dialect.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -892,8 +896,8 @@ func (db *postgres) DropIndexSql(tableName string, index *core.Index) string {
|
||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
||||
}
|
||||
|
||||
func (db *postgres) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
||||
args := []interface{}{tableName, col.Name}
|
||||
func (db *postgres) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName, colName}
|
||||
query := "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = $1" +
|
||||
" AND column_name = $2"
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
@ -909,7 +913,8 @@ func (db *postgres) IsColumnExist(tableName string, col *core.Column) (bool, err
|
||||
}
|
||||
|
||||
func (db *postgres) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{tableName}
|
||||
pgSchema := "public"
|
||||
args := []interface{}{tableName,pgSchema}
|
||||
s := `SELECT column_name, column_default, is_nullable, data_type, character_maximum_length, numeric_precision, numeric_precision_radix ,
|
||||
CASE WHEN p.contype = 'p' THEN true ELSE false END AS primarykey,
|
||||
CASE WHEN p.contype = 'u' THEN true ELSE false END AS uniquekey
|
||||
@ -920,7 +925,7 @@ FROM pg_attribute f
|
||||
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
|
||||
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
|
||||
LEFT JOIN INFORMATION_SCHEMA.COLUMNS s ON s.column_name=f.attname AND c.relname=s.table_name
|
||||
WHERE c.relkind = 'r'::char AND c.relname = $1 AND f.attnum > 0 ORDER BY f.attnum;`
|
||||
WHERE c.relkind = 'r'::char AND c.relname = $1 AND s.table_schema = $2 AND f.attnum > 0 ORDER BY f.attnum;`
|
||||
|
||||
rows, err := db.DB().Query(s, args...)
|
||||
if db.Logger != nil {
|
||||
|
8
Godeps/_workspace/src/github.com/go-xorm/xorm/pq_driver.go
generated
vendored
8
Godeps/_workspace/src/github.com/go-xorm/xorm/pq_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -37,7 +41,7 @@ func parseURL(connstr string) (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if u.Scheme != "postgres" {
|
||||
if u.Scheme != "postgresql" && u.Scheme != "postgres" {
|
||||
return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
|
||||
}
|
||||
|
||||
@ -99,7 +103,7 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.POSTGRES}
|
||||
o := make(values)
|
||||
var err error
|
||||
if strings.HasPrefix(dataSourceName, "postgres://") {
|
||||
if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") {
|
||||
dataSourceName, err = parseURL(dataSourceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
8
Godeps/_workspace/src/github.com/go-xorm/xorm/processors.go
generated
vendored
8
Godeps/_workspace/src/github.com/go-xorm/xorm/processors.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
// Executed before an object is initially persisted to the database
|
||||
@ -19,6 +23,10 @@ type BeforeSetProcessor interface {
|
||||
BeforeSet(string, Cell)
|
||||
}
|
||||
|
||||
type AfterSetProcessor interface {
|
||||
AfterSet(string, Cell)
|
||||
}
|
||||
|
||||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
||||
//// Executed before an object is validated
|
||||
//type BeforeValidateProcessor interface {
|
||||
|
6
Godeps/_workspace/src/github.com/go-xorm/xorm/rows.go
generated
vendored
6
Godeps/_workspace/src/github.com/go-xorm/xorm/rows.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -41,7 +45,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
sqlStr = filter.Do(sqlStr, session.Engine.dialect, rows.session.Statement.RefTable)
|
||||
}
|
||||
|
||||
rows.session.Engine.logSQL(sqlStr, args)
|
||||
rows.session.saveLastSQL(sqlStr, args)
|
||||
var err error
|
||||
rows.stmt, err = rows.session.DB().Prepare(sqlStr)
|
||||
if err != nil {
|
||||
|
955
Godeps/_workspace/src/github.com/go-xorm/xorm/session.go
generated
vendored
955
Godeps/_workspace/src/github.com/go-xorm/xorm/session.go
generated
vendored
File diff suppressed because it is too large
Load Diff
30
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
30
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
@ -1,9 +1,14 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
@ -152,13 +157,21 @@ func (db *sqlite3) Init(d *core.DB, uri *core.Uri, drivername, dataSourceName st
|
||||
|
||||
func (db *sqlite3) SqlType(c *core.Column) string {
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bool:
|
||||
if c.Default == "true" {
|
||||
c.Default = "1"
|
||||
} else if c.Default == "false" {
|
||||
c.Default = "0"
|
||||
}
|
||||
return core.Integer
|
||||
case core.Date, core.DateTime, core.TimeStamp, core.Time:
|
||||
return core.DateTime
|
||||
case core.TimeStampz:
|
||||
return core.Text
|
||||
case core.Char, core.Varchar, core.NVarchar, core.TinyText, core.Text, core.MediumText, core.LongText:
|
||||
case core.Char, core.Varchar, core.NVarchar, core.TinyText,
|
||||
core.Text, core.MediumText, core.LongText, core.Json:
|
||||
return core.Text
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool:
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt:
|
||||
return core.Integer
|
||||
case core.Float, core.Double, core.Real:
|
||||
return core.Real
|
||||
@ -238,15 +251,19 @@ func (db *sqlite3) DropIndexSql(tableName string, index *core.Index) string {
|
||||
return fmt.Sprintf("DROP INDEX %v", quote(idxName))
|
||||
}
|
||||
|
||||
func (db *sqlite3) ForUpdateSql(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
/*func (db *sqlite3) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
args := []interface{}{tableName}
|
||||
sql := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))"
|
||||
return sql, args
|
||||
}*/
|
||||
|
||||
func (db *sqlite3) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
||||
func (db *sqlite3) IsColumnExist(tableName, colName string) (bool, error) {
|
||||
args := []interface{}{tableName}
|
||||
query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + col.Name + "`%') or (sql like '%[" + col.Name + "]%'))"
|
||||
query := "SELECT name FROM sqlite_master WHERE type='table' and name = ? and ((sql like '%`" + colName + "`%') or (sql like '%[" + colName + "]%'))"
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", query, args)
|
||||
@ -290,10 +307,13 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu
|
||||
|
||||
nStart := strings.Index(name, "(")
|
||||
nEnd := strings.LastIndex(name, ")")
|
||||
colCreates := strings.Split(name[nStart+1:nEnd], ",")
|
||||
reg := regexp.MustCompile(`[^\(,\)]*(\([^\(]*\))?`)
|
||||
colCreates := reg.FindAllString(name[nStart+1:nEnd], -1)
|
||||
cols := make(map[string]*core.Column)
|
||||
colSeq := make([]string, 0)
|
||||
for _, colStr := range colCreates {
|
||||
reg = regexp.MustCompile(`,\s`)
|
||||
colStr = reg.ReplaceAllString(colStr, ",")
|
||||
fields := strings.Fields(strings.TrimSpace(colStr))
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]bool)
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_driver.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_driver.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
|
635
Godeps/_workspace/src/github.com/go-xorm/xorm/statement.go
generated
vendored
635
Godeps/_workspace/src/github.com/go-xorm/xorm/statement.go
generated
vendored
@ -1,6 +1,12 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -33,42 +39,46 @@ type exprParam struct {
|
||||
|
||||
// statement save all the sql info for executing SQL
|
||||
type Statement struct {
|
||||
RefTable *core.Table
|
||||
Engine *Engine
|
||||
Start int
|
||||
LimitN int
|
||||
WhereStr string
|
||||
IdParam *core.PK
|
||||
Params []interface{}
|
||||
OrderStr string
|
||||
JoinStr string
|
||||
GroupByStr string
|
||||
HavingStr string
|
||||
ColumnStr string
|
||||
columnMap map[string]bool
|
||||
useAllCols bool
|
||||
OmitStr string
|
||||
ConditionStr string
|
||||
AltTableName string
|
||||
RawSQL string
|
||||
RawParams []interface{}
|
||||
UseCascade bool
|
||||
UseAutoJoin bool
|
||||
StoreEngine string
|
||||
Charset string
|
||||
BeanArgs []interface{}
|
||||
UseCache bool
|
||||
UseAutoTime bool
|
||||
IsDistinct bool
|
||||
TableAlias string
|
||||
allUseBool bool
|
||||
checkVersion bool
|
||||
unscoped bool
|
||||
mustColumnMap map[string]bool
|
||||
inColumns map[string]*inParam
|
||||
incrColumns map[string]incrParam
|
||||
decrColumns map[string]decrParam
|
||||
exprColumns map[string]exprParam
|
||||
RefTable *core.Table
|
||||
Engine *Engine
|
||||
Start int
|
||||
LimitN int
|
||||
WhereStr string
|
||||
IdParam *core.PK
|
||||
Params []interface{}
|
||||
OrderStr string
|
||||
JoinStr string
|
||||
GroupByStr string
|
||||
HavingStr string
|
||||
ColumnStr string
|
||||
selectStr string
|
||||
columnMap map[string]bool
|
||||
useAllCols bool
|
||||
OmitStr string
|
||||
ConditionStr string
|
||||
AltTableName string
|
||||
RawSQL string
|
||||
RawParams []interface{}
|
||||
UseCascade bool
|
||||
UseAutoJoin bool
|
||||
StoreEngine string
|
||||
Charset string
|
||||
BeanArgs []interface{}
|
||||
UseCache bool
|
||||
UseAutoTime bool
|
||||
noAutoCondition bool
|
||||
IsDistinct bool
|
||||
IsForUpdate bool
|
||||
TableAlias string
|
||||
allUseBool bool
|
||||
checkVersion bool
|
||||
unscoped bool
|
||||
mustColumnMap map[string]bool
|
||||
nullableMap map[string]bool
|
||||
inColumns map[string]*inParam
|
||||
incrColumns map[string]incrParam
|
||||
decrColumns map[string]decrParam
|
||||
exprColumns map[string]exprParam
|
||||
}
|
||||
|
||||
// init
|
||||
@ -94,11 +104,15 @@ func (statement *Statement) Init() {
|
||||
statement.BeanArgs = make([]interface{}, 0)
|
||||
statement.UseCache = true
|
||||
statement.UseAutoTime = true
|
||||
statement.noAutoCondition = false
|
||||
statement.IsDistinct = false
|
||||
statement.IsForUpdate = false
|
||||
statement.TableAlias = ""
|
||||
statement.selectStr = ""
|
||||
statement.allUseBool = false
|
||||
statement.useAllCols = false
|
||||
statement.mustColumnMap = make(map[string]bool)
|
||||
statement.nullableMap = make(map[string]bool)
|
||||
statement.checkVersion = true
|
||||
statement.unscoped = false
|
||||
statement.inColumns = make(map[string]*inParam)
|
||||
@ -107,20 +121,29 @@ func (statement *Statement) Init() {
|
||||
statement.exprColumns = make(map[string]exprParam)
|
||||
}
|
||||
|
||||
// add the raw sql statement
|
||||
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function
|
||||
func (statement *Statement) NoAutoCondition(no ...bool) *Statement {
|
||||
statement.noAutoCondition = true
|
||||
if len(no) > 0 {
|
||||
statement.noAutoCondition = no[0]
|
||||
}
|
||||
return statement
|
||||
}
|
||||
|
||||
// Sql add the raw sql statement
|
||||
func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement {
|
||||
statement.RawSQL = querystring
|
||||
statement.RawParams = args
|
||||
return statement
|
||||
}
|
||||
|
||||
// set the table alias
|
||||
// Alias set the table alias
|
||||
func (statement *Statement) Alias(alias string) *Statement {
|
||||
statement.TableAlias = alias
|
||||
return statement
|
||||
}
|
||||
|
||||
// add Where statment
|
||||
// Where add Where statment
|
||||
func (statement *Statement) Where(querystring string, args ...interface{}) *Statement {
|
||||
if !strings.Contains(querystring, statement.Engine.dialect.EqStr()) {
|
||||
querystring = strings.Replace(querystring, "=", statement.Engine.dialect.EqStr(), -1)
|
||||
@ -130,11 +153,13 @@ func (statement *Statement) Where(querystring string, args ...interface{}) *Stat
|
||||
return statement
|
||||
}
|
||||
|
||||
// add Where & and statment
|
||||
// And add Where & and statment
|
||||
func (statement *Statement) And(querystring string, args ...interface{}) *Statement {
|
||||
if statement.WhereStr != "" {
|
||||
statement.WhereStr = fmt.Sprintf("(%v) %s (%v)", statement.WhereStr,
|
||||
if len(statement.WhereStr) > 0 {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr,
|
||||
statement.Engine.dialect.AndStr(), querystring)
|
||||
statement.WhereStr = buf.String()
|
||||
} else {
|
||||
statement.WhereStr = querystring
|
||||
}
|
||||
@ -142,11 +167,13 @@ func (statement *Statement) And(querystring string, args ...interface{}) *Statem
|
||||
return statement
|
||||
}
|
||||
|
||||
// add Where & Or statment
|
||||
// Or add Where & Or statment
|
||||
func (statement *Statement) Or(querystring string, args ...interface{}) *Statement {
|
||||
if statement.WhereStr != "" {
|
||||
statement.WhereStr = fmt.Sprintf("(%v) %s (%v)", statement.WhereStr,
|
||||
if len(statement.WhereStr) > 0 {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr,
|
||||
statement.Engine.dialect.OrStr(), querystring)
|
||||
statement.WhereStr = buf.String()
|
||||
} else {
|
||||
statement.WhereStr = querystring
|
||||
}
|
||||
@ -154,7 +181,7 @@ func (statement *Statement) Or(querystring string, args ...interface{}) *Stateme
|
||||
return statement
|
||||
}
|
||||
|
||||
// tempororily set table name
|
||||
// Table tempororily set table name, the parameter could be a string or a pointer of struct
|
||||
func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
v := rValue(tableNameOrBean)
|
||||
t := v.Type()
|
||||
@ -166,127 +193,12 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
/*func (statement *Statement) genFields(bean interface{}) map[string]interface{} {
|
||||
results := make(map[string]interface{})
|
||||
table := statement.Engine.TableInfo(bean)
|
||||
for _, col := range table.Columns {
|
||||
fieldValue := col.ValueOf(bean)
|
||||
fieldType := reflect.TypeOf(fieldValue.Interface())
|
||||
var val interface{}
|
||||
switch fieldType.Kind() {
|
||||
case reflect.Bool:
|
||||
if allUseBool {
|
||||
val = fieldValue.Interface()
|
||||
} else if _, ok := boolColumnMap[col.Name]; ok {
|
||||
val = fieldValue.Interface()
|
||||
} else {
|
||||
// if a bool in a struct, it will not be as a condition because it default is false,
|
||||
// please use Where() instead
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if fieldValue.String() == "" {
|
||||
continue
|
||||
}
|
||||
// for MyString, should convert to string or panic
|
||||
if fieldType.String() != reflect.String.String() {
|
||||
val = fieldValue.String()
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
}
|
||||
case reflect.Int8, reflect.Int16, reflect.Int, reflect.Int32, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
val = fieldValue.Interface()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if fieldValue.Float() == 0.0 {
|
||||
continue
|
||||
}
|
||||
val = fieldValue.Interface()
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint, reflect.Uint32, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
val = fieldValue.Interface()
|
||||
case reflect.Struct:
|
||||
if fieldType == reflect.TypeOf(time.Now()) {
|
||||
t := fieldValue.Interface().(time.Time)
|
||||
if t.IsZero() || !fieldValue.IsValid() {
|
||||
continue
|
||||
}
|
||||
var str string
|
||||
if col.SQLType.Name == Time {
|
||||
s := t.UTC().Format("2006-01-02 15:04:05")
|
||||
val = s[11:19]
|
||||
} else if col.SQLType.Name == Date {
|
||||
str = t.Format("2006-01-02")
|
||||
val = str
|
||||
} else {
|
||||
val = t
|
||||
}
|
||||
} else {
|
||||
engine.autoMapType(fieldValue.Type())
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumn().FieldName)
|
||||
if pkField.Int() != 0 {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
}
|
||||
}
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
if fieldValue == reflect.Zero(fieldType) {
|
||||
continue
|
||||
}
|
||||
if fieldValue.IsNil() || !fieldValue.IsValid() {
|
||||
continue
|
||||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
continue
|
||||
}
|
||||
val = string(bytes)
|
||||
} else if col.SQLType.IsBlob() {
|
||||
var bytes []byte
|
||||
var err error
|
||||
if (fieldType.Kind() == reflect.Array || fieldType.Kind() == reflect.Slice) &&
|
||||
fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
if fieldValue.Len() > 0 {
|
||||
val = fieldValue.Bytes()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
continue
|
||||
}
|
||||
val = bytes
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
default:
|
||||
val = fieldValue.Interface()
|
||||
}
|
||||
results[col.Name] = val
|
||||
}
|
||||
return results
|
||||
}*/
|
||||
|
||||
// Auto generating conditions according a struct
|
||||
// Auto generating update columnes and values according a struct
|
||||
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
includeVersion bool, includeUpdated bool, includeNil bool,
|
||||
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
||||
mustColumnMap map[string]bool, columnMap map[string]bool, update bool) ([]string, []interface{}) {
|
||||
mustColumnMap map[string]bool, nullableMap map[string]bool,
|
||||
columnMap map[string]bool, update, unscoped bool) ([]string, []interface{}) {
|
||||
|
||||
colNames := make([]string, 0)
|
||||
var args = make([]interface{}, 0)
|
||||
@ -303,17 +215,13 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
if !includeAutoIncr && col.IsAutoIncrement {
|
||||
continue
|
||||
}
|
||||
if col.IsDeleted {
|
||||
if col.IsDeleted && !unscoped {
|
||||
continue
|
||||
}
|
||||
if use, ok := columnMap[col.Name]; ok && !use {
|
||||
continue
|
||||
}
|
||||
|
||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
@ -325,7 +233,9 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
|
||||
requiredField := useAllCols
|
||||
includeNil := useAllCols
|
||||
if b, ok := mustColumnMap[strings.ToLower(col.Name)]; ok {
|
||||
lColName := strings.ToLower(col.Name)
|
||||
|
||||
if b, ok := mustColumnMap[lColName]; ok {
|
||||
if b {
|
||||
requiredField = true
|
||||
} else {
|
||||
@ -333,6 +243,16 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
}
|
||||
}
|
||||
|
||||
// !evalphobia! set fieldValue as nil when column is nullable and zero-value
|
||||
if b, ok := nullableMap[lColName]; ok {
|
||||
if b && col.Nullable && isZero(fieldValue.Interface()) {
|
||||
var nilValue *int
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
fieldType = reflect.TypeOf(fieldValue.Interface())
|
||||
includeNil = true
|
||||
}
|
||||
}
|
||||
|
||||
var val interface{}
|
||||
|
||||
if fieldValue.CanAddr() {
|
||||
@ -410,38 +330,53 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
t := int64(fieldValue.Uint())
|
||||
val = reflect.ValueOf(&t).Interface()
|
||||
case reflect.Struct:
|
||||
if fieldType == reflect.TypeOf(time.Now()) {
|
||||
t := fieldValue.Interface().(time.Time)
|
||||
if fieldType.ConvertibleTo(core.TimeType) {
|
||||
t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
|
||||
if !requiredField && (t.IsZero() || !fieldValue.IsValid()) {
|
||||
continue
|
||||
}
|
||||
val = engine.FormatTime(col.SQLType.Name, t)
|
||||
} else if nulType, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||
val, _ = nulType.Value()
|
||||
} else {
|
||||
engine.autoMapType(fieldValue)
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
//if pkField.Int() != 0 {
|
||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||
val = pkField.Interface()
|
||||
if !col.SQLType.IsJson() {
|
||||
engine.autoMapType(fieldValue)
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
continue
|
||||
//TODO: how to handler?
|
||||
panic("not supported")
|
||||
}
|
||||
} else {
|
||||
//TODO: how to handler?
|
||||
panic("not supported")
|
||||
val = fieldValue.Interface()
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface()))
|
||||
}
|
||||
if col.SQLType.IsText() {
|
||||
val = string(bytes)
|
||||
} else if col.SQLType.IsBlob() {
|
||||
val = bytes
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
if fieldValue == reflect.Zero(fieldType) {
|
||||
continue
|
||||
}
|
||||
if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
|
||||
continue
|
||||
if !requiredField {
|
||||
if fieldValue == reflect.Zero(fieldType) {
|
||||
continue
|
||||
}
|
||||
if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
@ -492,8 +427,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
includeVersion bool, includeUpdated bool, includeNil bool,
|
||||
includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool,
|
||||
mustColumnMap map[string]bool) ([]string, []interface{}) {
|
||||
|
||||
mustColumnMap map[string]bool, tableName, aliasName string, addedTableName bool) ([]string, []interface{}) {
|
||||
colNames := make([]string, 0)
|
||||
var args = make([]interface{}, 0)
|
||||
for _, col := range table.Columns() {
|
||||
@ -510,6 +444,21 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
||||
continue
|
||||
}
|
||||
if col.SQLType.IsJson() {
|
||||
continue
|
||||
}
|
||||
|
||||
var colName string
|
||||
if addedTableName {
|
||||
var nm = tableName
|
||||
if len(aliasName) > 0 {
|
||||
nm = aliasName
|
||||
}
|
||||
colName = engine.Quote(nm) + "." + engine.Quote(col.Name)
|
||||
} else {
|
||||
colName = engine.Quote(col.Name)
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
@ -517,7 +466,8 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
}
|
||||
|
||||
if col.IsDeleted && !unscoped { // tag "deleted" is enabled
|
||||
colNames = append(colNames, fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00')", engine.Quote(col.Name), engine.Quote(col.Name)))
|
||||
colNames = append(colNames, fmt.Sprintf("%v IS NULL or %v = '0001-01-01 00:00:00'",
|
||||
colName, colName))
|
||||
}
|
||||
|
||||
fieldValue := *fieldValuePtr
|
||||
@ -539,7 +489,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
if fieldValue.IsNil() {
|
||||
if includeNil {
|
||||
args = append(args, nil)
|
||||
colNames = append(colNames, fmt.Sprintf("%v %s ?", engine.Quote(col.Name), engine.dialect.EqStr()))
|
||||
colNames = append(colNames, fmt.Sprintf("%v %s ?", colName, engine.dialect.EqStr()))
|
||||
}
|
||||
continue
|
||||
} else if !fieldValue.IsValid() {
|
||||
@ -597,24 +547,49 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
val = engine.FormatTime(col.SQLType.Name, t)
|
||||
} else if _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok {
|
||||
continue
|
||||
} else if valNul, ok := fieldValue.Interface().(driver.Valuer); ok {
|
||||
val, _ = valNul.Value()
|
||||
if val == nil {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
engine.autoMapType(fieldValue)
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
//if pkField.Int() != 0 {
|
||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
if col.SQLType.IsJson() {
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
//TODO: how to handler?
|
||||
panic("not supported")
|
||||
val = string(bytes)
|
||||
} else if col.SQLType.IsBlob() {
|
||||
var bytes []byte
|
||||
var err error
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.LogError(err)
|
||||
continue
|
||||
}
|
||||
val = bytes
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
engine.autoMapType(fieldValue)
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
// fix non-int pk issues
|
||||
//if pkField.Int() != 0 {
|
||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||
val = pkField.Interface()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
//TODO: how to handler?
|
||||
panic(fmt.Sprintln("not supported", fieldValue.Interface(), "as", table.PrimaryKeys))
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
}
|
||||
}
|
||||
}
|
||||
case reflect.Array, reflect.Slice, reflect.Map:
|
||||
@ -662,7 +637,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
||||
if col.IsPrimaryKey && engine.dialect.DBType() == "ql" {
|
||||
condi = "id() == ?"
|
||||
} else {
|
||||
condi = fmt.Sprintf("%v %s ?", engine.Quote(col.Name), engine.dialect.EqStr())
|
||||
condi = fmt.Sprintf("%v %s ?", colName, engine.dialect.EqStr())
|
||||
}
|
||||
colNames = append(colNames, condi)
|
||||
}
|
||||
@ -709,7 +684,7 @@ func (statement *Statement) Id(id interface{}) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Generate "Update ... Set column = column + arg" statment
|
||||
// Incr Generate "Update ... Set column = column + arg" statment
|
||||
func (statement *Statement) Incr(column string, arg ...interface{}) *Statement {
|
||||
k := strings.ToLower(column)
|
||||
if len(arg) > 0 {
|
||||
@ -720,7 +695,7 @@ func (statement *Statement) Incr(column string, arg ...interface{}) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Generate "Update ... Set column = column - arg" statment
|
||||
// Decr Generate "Update ... Set column = column - arg" statment
|
||||
func (statement *Statement) Decr(column string, arg ...interface{}) *Statement {
|
||||
k := strings.ToLower(column)
|
||||
if len(arg) > 0 {
|
||||
@ -731,7 +706,7 @@ func (statement *Statement) Decr(column string, arg ...interface{}) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Generate "Update ... Set column = {expression}" statment
|
||||
// SetExpr Generate "Update ... Set column = {expression}" statment
|
||||
func (statement *Statement) SetExpr(column string, expression string) *Statement {
|
||||
k := strings.ToLower(column)
|
||||
statement.exprColumns[k] = exprParam{column, expression}
|
||||
@ -755,9 +730,14 @@ func (statement *Statement) getExpr() map[string]exprParam {
|
||||
|
||||
// Generate "Where column IN (?) " statment
|
||||
func (statement *Statement) In(column string, args ...interface{}) *Statement {
|
||||
length := len(args)
|
||||
if length == 0 {
|
||||
return statement
|
||||
}
|
||||
|
||||
k := strings.ToLower(column)
|
||||
var newargs []interface{}
|
||||
if len(args) == 1 &&
|
||||
if length == 1 &&
|
||||
reflect.TypeOf(args[0]).Kind() == reflect.Slice {
|
||||
newargs = make([]interface{}, 0)
|
||||
v := reflect.ValueOf(args[0])
|
||||
@ -781,12 +761,17 @@ func (statement *Statement) genInSql() (string, []interface{}) {
|
||||
return "", []interface{}{}
|
||||
}
|
||||
|
||||
inStrs := make([]string, 0, len(statement.inColumns))
|
||||
inStrs := make([]string, len(statement.inColumns), len(statement.inColumns))
|
||||
args := make([]interface{}, 0)
|
||||
var buf bytes.Buffer
|
||||
var i int
|
||||
for _, params := range statement.inColumns {
|
||||
inStrs = append(inStrs, fmt.Sprintf("(%v IN (%v))",
|
||||
buf.Reset()
|
||||
fmt.Fprintf(&buf, "(%v IN (%v))",
|
||||
statement.Engine.autoQuote(params.colName),
|
||||
strings.Join(makeArray("?", len(params.args)), ",")))
|
||||
strings.Join(makeArray("?", len(params.args)), ","))
|
||||
inStrs[i] = buf.String()
|
||||
i++
|
||||
args = append(args, params.args...)
|
||||
}
|
||||
|
||||
@ -799,7 +784,7 @@ func (statement *Statement) genInSql() (string, []interface{}) {
|
||||
func (statement *Statement) attachInSql() {
|
||||
inSql, inArgs := statement.genInSql()
|
||||
if len(inSql) > 0 {
|
||||
if statement.ConditionStr != "" {
|
||||
if len(statement.ConditionStr) > 0 {
|
||||
statement.ConditionStr += " " + statement.Engine.dialect.AndStr() + " "
|
||||
}
|
||||
statement.ConditionStr += inSql
|
||||
@ -858,6 +843,18 @@ func (statement *Statement) Distinct(columns ...string) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Generate "SELECT ... FOR UPDATE" statment
|
||||
func (statement *Statement) ForUpdate() *Statement {
|
||||
statement.IsForUpdate = true
|
||||
return statement
|
||||
}
|
||||
|
||||
// replace select
|
||||
func (s *Statement) Select(str string) *Statement {
|
||||
s.selectStr = str
|
||||
return s
|
||||
}
|
||||
|
||||
// Generate "col1, col2" statement
|
||||
func (statement *Statement) Cols(columns ...string) *Statement {
|
||||
newColumns := col2NewCols(columns...)
|
||||
@ -868,6 +865,7 @@ func (statement *Statement) Cols(columns ...string) *Statement {
|
||||
if strings.Contains(statement.ColumnStr, ".") {
|
||||
statement.ColumnStr = strings.Replace(statement.ColumnStr, ".", statement.Engine.Quote("."), -1)
|
||||
}
|
||||
statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.Quote("*"), "*", -1)
|
||||
return statement
|
||||
}
|
||||
|
||||
@ -886,15 +884,6 @@ func (statement *Statement) MustCols(columns ...string) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// Update use only: not update columns
|
||||
/*func (statement *Statement) NotCols(columns ...string) *Statement {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
statement.mustColumnMap[strings.ToLower(nc)] = false
|
||||
}
|
||||
return statement
|
||||
}*/
|
||||
|
||||
// indicates that use bool fields as update contents and query contiditions
|
||||
func (statement *Statement) UseBool(columns ...string) *Statement {
|
||||
if len(columns) > 0 {
|
||||
@ -914,6 +903,14 @@ func (statement *Statement) Omit(columns ...string) {
|
||||
statement.OmitStr = statement.Engine.Quote(strings.Join(newColumns, statement.Engine.Quote(", ")))
|
||||
}
|
||||
|
||||
// Update use only: update columns to null when value is nullable and zero-value
|
||||
func (statement *Statement) Nullable(columns ...string) {
|
||||
newColumns := col2NewCols(columns...)
|
||||
for _, nc := range newColumns {
|
||||
statement.nullableMap[strings.ToLower(nc)] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Generate LIMIT limit statement
|
||||
func (statement *Statement) Top(limit int) *Statement {
|
||||
statement.Limit(limit)
|
||||
@ -931,7 +928,7 @@ func (statement *Statement) Limit(limit int, start ...int) *Statement {
|
||||
|
||||
// Generate "Order By order" statement
|
||||
func (statement *Statement) OrderBy(order string) *Statement {
|
||||
if statement.OrderStr != "" {
|
||||
if len(statement.OrderStr) > 0 {
|
||||
statement.OrderStr += ", "
|
||||
}
|
||||
statement.OrderStr += order
|
||||
@ -939,44 +936,51 @@ func (statement *Statement) OrderBy(order string) *Statement {
|
||||
}
|
||||
|
||||
func (statement *Statement) Desc(colNames ...string) *Statement {
|
||||
if statement.OrderStr != "" {
|
||||
statement.OrderStr += ", "
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, statement.OrderStr)
|
||||
if len(statement.OrderStr) > 0 {
|
||||
fmt.Fprint(&buf, ", ")
|
||||
}
|
||||
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||
sqlStr := strings.Join(newColNames, " DESC, ")
|
||||
statement.OrderStr += sqlStr + " DESC"
|
||||
fmt.Fprintf(&buf, "%v DESC", strings.Join(newColNames, " DESC, "))
|
||||
statement.OrderStr = buf.String()
|
||||
return statement
|
||||
}
|
||||
|
||||
// Method Asc provide asc order by query condition, the input parameters are columns.
|
||||
func (statement *Statement) Asc(colNames ...string) *Statement {
|
||||
if statement.OrderStr != "" {
|
||||
statement.OrderStr += ", "
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintf(&buf, statement.OrderStr)
|
||||
if len(statement.OrderStr) > 0 {
|
||||
fmt.Fprint(&buf, ", ")
|
||||
}
|
||||
newColNames := statement.col2NewColsWithQuote(colNames...)
|
||||
sqlStr := strings.Join(newColNames, " ASC, ")
|
||||
statement.OrderStr += sqlStr + " ASC"
|
||||
fmt.Fprintf(&buf, "%v ASC", strings.Join(newColNames, " ASC, "))
|
||||
statement.OrderStr = buf.String()
|
||||
return statement
|
||||
}
|
||||
|
||||
//The join_operator should be one of INNER, LEFT OUTER, CROSS etc - this will be prepended to JOIN
|
||||
func (statement *Statement) Join(join_operator string, tablename interface{}, condition string) *Statement {
|
||||
var joinTable string
|
||||
var buf bytes.Buffer
|
||||
if len(statement.JoinStr) > 0 {
|
||||
fmt.Fprintf(&buf, "%v %v JOIN ", statement.JoinStr, join_operator)
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "%v JOIN ", join_operator)
|
||||
}
|
||||
|
||||
switch tablename.(type) {
|
||||
case []string:
|
||||
t := tablename.([]string)
|
||||
l := len(t)
|
||||
if l > 1 {
|
||||
table := t[0]
|
||||
joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1])
|
||||
} else if l == 1 {
|
||||
table := t[0]
|
||||
joinTable = statement.Engine.Quote(table)
|
||||
if len(t) > 1 {
|
||||
fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(t[0]), statement.Engine.Quote(t[1]))
|
||||
} else if len(t) == 1 {
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(t[0]))
|
||||
}
|
||||
case []interface{}:
|
||||
t := tablename.([]interface{})
|
||||
l := len(t)
|
||||
table := ""
|
||||
var table string
|
||||
if l > 0 {
|
||||
f := t[0]
|
||||
v := rValue(f)
|
||||
@ -989,21 +993,17 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
||||
}
|
||||
}
|
||||
if l > 1 {
|
||||
joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(fmt.Sprintf("%v", t[1]))
|
||||
fmt.Fprintf(&buf, "%v AS %v", statement.Engine.Quote(table),
|
||||
statement.Engine.Quote(fmt.Sprintf("%v", t[1])))
|
||||
} else if l == 1 {
|
||||
joinTable = statement.Engine.Quote(table)
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(table))
|
||||
}
|
||||
default:
|
||||
t := fmt.Sprintf("%v", tablename)
|
||||
joinTable = statement.Engine.Quote(t)
|
||||
}
|
||||
if statement.JoinStr != "" {
|
||||
statement.JoinStr = statement.JoinStr + fmt.Sprintf(" %v JOIN %v ON %v", join_operator,
|
||||
joinTable, condition)
|
||||
} else {
|
||||
statement.JoinStr = fmt.Sprintf("%v JOIN %v ON %v", join_operator,
|
||||
joinTable, condition)
|
||||
fmt.Fprintf(&buf, statement.Engine.Quote(fmt.Sprintf("%v", tablename)))
|
||||
}
|
||||
|
||||
fmt.Fprintf(&buf, " ON %v", condition)
|
||||
statement.JoinStr = buf.String()
|
||||
return statement
|
||||
}
|
||||
|
||||
@ -1120,11 +1120,6 @@ func (s *Statement) genDelIndexSQL() []string {
|
||||
return sqls
|
||||
}
|
||||
|
||||
/*
|
||||
func (s *Statement) genDropSQL() string {
|
||||
return s.Engine.dialect.MustDropTa(s.TableName()) + ";"
|
||||
}*/
|
||||
|
||||
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
|
||||
var table *core.Table
|
||||
if statement.RefTable == nil {
|
||||
@ -1134,28 +1129,34 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
|
||||
table = statement.RefTable
|
||||
}
|
||||
|
||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true,
|
||||
false, true, statement.allUseBool, statement.useAllCols,
|
||||
statement.unscoped, statement.mustColumnMap)
|
||||
var addedTableName = (len(statement.JoinStr) > 0)
|
||||
|
||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
||||
statement.BeanArgs = args
|
||||
if !statement.noAutoCondition {
|
||||
colNames, args := statement.buildConditions(table, bean, true, true, false, true, addedTableName)
|
||||
|
||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
||||
statement.BeanArgs = args
|
||||
}
|
||||
|
||||
var columnStr string = statement.ColumnStr
|
||||
if len(statement.JoinStr) == 0 {
|
||||
if len(columnStr) == 0 {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
} else {
|
||||
columnStr = statement.genColumnStr()
|
||||
}
|
||||
}
|
||||
if len(statement.selectStr) > 0 {
|
||||
columnStr = statement.selectStr
|
||||
} else {
|
||||
if len(columnStr) == 0 {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
} else {
|
||||
columnStr = "*"
|
||||
if len(statement.JoinStr) == 0 {
|
||||
if len(columnStr) == 0 {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
} else {
|
||||
columnStr = statement.genColumnStr()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(columnStr) == 0 {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1185,16 +1186,23 @@ func (s *Statement) genAddUniqueStr(uqeName string, cols []string) (string, []in
|
||||
return sql, []interface{}{}
|
||||
}*/
|
||||
|
||||
func (statement *Statement) buildConditions(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) ([]string, []interface{}) {
|
||||
return buildConditions(statement.Engine, table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols,
|
||||
statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
|
||||
}
|
||||
|
||||
func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}) {
|
||||
table := statement.Engine.TableInfo(bean)
|
||||
statement.RefTable = table
|
||||
|
||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,
|
||||
true, statement.allUseBool, statement.useAllCols,
|
||||
statement.unscoped, statement.mustColumnMap)
|
||||
var addedTableName = (len(statement.JoinStr) > 0)
|
||||
|
||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
||||
statement.BeanArgs = args
|
||||
if !statement.noAutoCondition {
|
||||
colNames, args := statement.buildConditions(table, bean, true, true, false, true, addedTableName)
|
||||
|
||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
||||
statement.BeanArgs = args
|
||||
}
|
||||
|
||||
// count(index fieldname) > count(0) > count(*)
|
||||
var id string = "*"
|
||||
@ -1206,47 +1214,46 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
|
||||
}
|
||||
|
||||
func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
/*if statement.GroupByStr != "" {
|
||||
if columnStr == "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
}
|
||||
//statement.GroupByStr = columnStr
|
||||
}*/
|
||||
var distinct string
|
||||
if statement.IsDistinct {
|
||||
distinct = "DISTINCT "
|
||||
}
|
||||
|
||||
var dialect = statement.Engine.Dialect()
|
||||
var quote = statement.Engine.Quote
|
||||
var top string
|
||||
var mssqlCondi string
|
||||
/*var orderBy string
|
||||
if statement.OrderStr != "" {
|
||||
orderBy = fmt.Sprintf(" ORDER BY %v", statement.OrderStr)
|
||||
}*/
|
||||
|
||||
statement.processIdParam()
|
||||
var whereStr string
|
||||
if statement.WhereStr != "" {
|
||||
whereStr = fmt.Sprintf(" WHERE %v", statement.WhereStr)
|
||||
if statement.ConditionStr != "" {
|
||||
whereStr = fmt.Sprintf("%v %s %v", whereStr, statement.Engine.Dialect().AndStr(),
|
||||
statement.ConditionStr)
|
||||
}
|
||||
} else if statement.ConditionStr != "" {
|
||||
whereStr = fmt.Sprintf(" WHERE %v", statement.ConditionStr)
|
||||
}
|
||||
var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName())
|
||||
if statement.TableAlias != "" {
|
||||
if statement.Engine.dialect.DBType() == core.ORACLE {
|
||||
fromStr += " " + statement.Engine.Quote(statement.TableAlias)
|
||||
|
||||
var buf bytes.Buffer
|
||||
if len(statement.WhereStr) > 0 {
|
||||
if len(statement.ConditionStr) > 0 {
|
||||
fmt.Fprintf(&buf, " WHERE (%v)", statement.WhereStr)
|
||||
} else {
|
||||
fromStr += " AS " + statement.Engine.Quote(statement.TableAlias)
|
||||
fmt.Fprintf(&buf, " WHERE %v", statement.WhereStr)
|
||||
}
|
||||
if statement.ConditionStr != "" {
|
||||
fmt.Fprintf(&buf, " %s (%v)", dialect.AndStr(), statement.ConditionStr)
|
||||
}
|
||||
} else if len(statement.ConditionStr) > 0 {
|
||||
fmt.Fprintf(&buf, " WHERE %v", statement.ConditionStr)
|
||||
}
|
||||
var whereStr = buf.String()
|
||||
|
||||
var fromStr string = " FROM " + quote(statement.TableName())
|
||||
if statement.TableAlias != "" {
|
||||
if dialect.DBType() == core.ORACLE {
|
||||
fromStr += " " + quote(statement.TableAlias)
|
||||
} else {
|
||||
fromStr += " AS " + quote(statement.TableAlias)
|
||||
}
|
||||
}
|
||||
if statement.JoinStr != "" {
|
||||
fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
|
||||
}
|
||||
|
||||
if statement.Engine.dialect.DBType() == core.MSSQL {
|
||||
if dialect.DBType() == core.MSSQL {
|
||||
if statement.LimitN > 0 {
|
||||
top = fmt.Sprintf(" TOP %d ", statement.LimitN)
|
||||
}
|
||||
@ -1277,10 +1284,9 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
}
|
||||
|
||||
// !nashtsai! REVIEW Sprintf is considered slowest mean of string concatnation, better to work with builder pattern
|
||||
a = fmt.Sprintf("SELECT %v%v%v%v%v", top, distinct, columnStr,
|
||||
fromStr, whereStr)
|
||||
if mssqlCondi != "" {
|
||||
if whereStr != "" {
|
||||
a = fmt.Sprintf("SELECT %v%v%v%v%v", top, distinct, columnStr, fromStr, whereStr)
|
||||
if len(mssqlCondi) > 0 {
|
||||
if len(whereStr) > 0 {
|
||||
a += " AND " + mssqlCondi
|
||||
} else {
|
||||
a += " WHERE " + mssqlCondi
|
||||
@ -1296,17 +1302,20 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
if statement.OrderStr != "" {
|
||||
a = fmt.Sprintf("%v ORDER BY %v", a, statement.OrderStr)
|
||||
}
|
||||
if statement.Engine.dialect.DBType() != core.MSSQL && statement.Engine.dialect.DBType() != core.ORACLE {
|
||||
if dialect.DBType() != core.MSSQL && dialect.DBType() != core.ORACLE {
|
||||
if statement.Start > 0 {
|
||||
a = fmt.Sprintf("%v LIMIT %v OFFSET %v", a, statement.LimitN, statement.Start)
|
||||
} else if statement.LimitN > 0 {
|
||||
a = fmt.Sprintf("%v LIMIT %v", a, statement.LimitN)
|
||||
}
|
||||
} else if statement.Engine.dialect.DBType() == core.ORACLE {
|
||||
} else if dialect.DBType() == core.ORACLE {
|
||||
if statement.Start != 0 || statement.LimitN != 0 {
|
||||
a = fmt.Sprintf("SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d", columnStr, columnStr, a, statement.Start+statement.LimitN, statement.Start)
|
||||
}
|
||||
}
|
||||
if statement.IsForUpdate {
|
||||
a = dialect.ForUpdateSql(a)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/syslogger.go
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/syslogger.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !windows,!nacl,!plan9
|
||||
|
||||
package xorm
|
||||
|
8
Godeps/_workspace/src/github.com/go-xorm/xorm/xorm.go
generated
vendored
8
Godeps/_workspace/src/github.com/go-xorm/xorm/xorm.go
generated
vendored
@ -1,3 +1,7 @@
|
||||
// Copyright 2015 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
@ -13,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Version string = "0.4.2.0225"
|
||||
Version string = "0.4.5.0204"
|
||||
)
|
||||
|
||||
func regDrvsNDialects() bool {
|
||||
@ -35,7 +39,7 @@ func regDrvsNDialects() bool {
|
||||
for driverName, v := range providedDrvsNDialects {
|
||||
if driver := core.QueryDriver(driverName); driver == nil {
|
||||
core.RegisterDriver(driverName, v.getDriver())
|
||||
core.RegisterDialect(v.dbType, v.getDialect())
|
||||
core.RegisterDialect(v.dbType, v.getDialect)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user