mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
updated xorm, go-sqlite3 dependencies
This commit is contained in:
parent
71aa2ef2c2
commit
fcac4c057c
8
Godeps/Godeps.json
generated
8
Godeps/Godeps.json
generated
@ -25,12 +25,12 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/core",
|
||||
"Rev": "a949e067ced1cb6e6ef5c38b6f28b074fa718f1e"
|
||||
"Rev": "be6e7ac47dc57bd0ada25322fa526944f66ccaa6"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-xorm/xorm",
|
||||
"Comment": "v0.4.1-19-g5c23849",
|
||||
"Rev": "5c23849a66f4593e68909bb6c1fa30651b5b0541"
|
||||
"Comment": "v0.4.2-58-ge2889e5",
|
||||
"Rev": "e2889e5517600b82905f1d2ba8b70deb71823ffe"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jtolds/gls",
|
||||
@ -51,7 +51,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-sqlite3",
|
||||
"Rev": "d10e2c8f62100097910367dee90a9bd89d426a44"
|
||||
"Rev": "e28cd440fabdd39b9520344bc26829f61db40ece"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey",
|
||||
|
114
Godeps/_workspace/src/github.com/go-xorm/core/README.md
generated
vendored
Normal file
114
Godeps/_workspace/src/github.com/go-xorm/core/README.md
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
Core is a lightweight wrapper of sql.DB.
|
||||
|
||||
# Open
|
||||
```Go
|
||||
db, _ := core.Open(db, connstr)
|
||||
```
|
||||
|
||||
# SetMapper
|
||||
```Go
|
||||
db.SetMapper(SameMapper())
|
||||
```
|
||||
|
||||
## Scan usage
|
||||
|
||||
### Scan
|
||||
```Go
|
||||
rows, _ := db.Query()
|
||||
for rows.Next() {
|
||||
rows.Scan()
|
||||
}
|
||||
```
|
||||
|
||||
### ScanMap
|
||||
```Go
|
||||
rows, _ := db.Query()
|
||||
for rows.Next() {
|
||||
rows.ScanMap()
|
||||
```
|
||||
|
||||
### ScanSlice
|
||||
|
||||
You can use `[]string`, `[][]byte`, `[]interface{}`, `[]*string`, `[]sql.NullString` to ScanSclice. Notice, slice's length should be equal or less than select columns.
|
||||
|
||||
```Go
|
||||
rows, _ := db.Query()
|
||||
cols, _ := rows.Columns()
|
||||
for rows.Next() {
|
||||
var s = make([]string, len(cols))
|
||||
rows.ScanSlice(&s)
|
||||
}
|
||||
```
|
||||
|
||||
```Go
|
||||
rows, _ := db.Query()
|
||||
cols, _ := rows.Columns()
|
||||
for rows.Next() {
|
||||
var s = make([]*string, len(cols))
|
||||
rows.ScanSlice(&s)
|
||||
}
|
||||
```
|
||||
|
||||
### ScanStruct
|
||||
```Go
|
||||
rows, _ := db.Query()
|
||||
for rows.Next() {
|
||||
rows.ScanStructByName()
|
||||
rows.ScanStructByIndex()
|
||||
}
|
||||
```
|
||||
|
||||
## Query usage
|
||||
```Go
|
||||
rows, err := db.Query("select * from table where name = ?", name)
|
||||
|
||||
user = User{
|
||||
Name:"lunny",
|
||||
}
|
||||
rows, err := db.QueryStruct("select * from table where name = ?Name",
|
||||
&user)
|
||||
|
||||
var user = map[string]interface{}{
|
||||
"name": "lunny",
|
||||
}
|
||||
rows, err = db.QueryMap("select * from table where name = ?name",
|
||||
&user)
|
||||
```
|
||||
|
||||
## QueryRow usage
|
||||
```Go
|
||||
row := db.QueryRow("select * from table where name = ?", name)
|
||||
|
||||
user = User{
|
||||
Name:"lunny",
|
||||
}
|
||||
row := db.QueryRowStruct("select * from table where name = ?Name",
|
||||
&user)
|
||||
|
||||
var user = map[string]interface{}{
|
||||
"name": "lunny",
|
||||
}
|
||||
row = db.QueryRowMap("select * from table where name = ?name",
|
||||
&user)
|
||||
```
|
||||
|
||||
## Exec usage
|
||||
```Go
|
||||
db.Exec("insert into user (`name`, title, age, alias, nick_name,created) values (?,?,?,?,?,?)", name, title, age, alias...)
|
||||
|
||||
user = User{
|
||||
Name:"lunny",
|
||||
Title:"test",
|
||||
Age: 18,
|
||||
}
|
||||
result, err = db.ExecStruct("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
|
||||
&user)
|
||||
|
||||
var user = map[string]interface{}{
|
||||
"Name": "lunny",
|
||||
"Title": "test",
|
||||
"Age": 18,
|
||||
}
|
||||
result, err = db.ExecMap("insert into user (`name`, title, age, alias, nick_name,created) values (?Name,?Title,?Age,?Alias,?NickName,?Created)",
|
||||
&user)
|
||||
```
|
15
Godeps/_workspace/src/github.com/go-xorm/core/column.go
generated
vendored
15
Godeps/_workspace/src/github.com/go-xorm/core/column.go
generated
vendored
@ -121,6 +121,21 @@ func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||
col.fieldPath = strings.Split(col.FieldName, ".")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fieldValue = dataStruct.MapIndex(keyValue)
|
||||
return &fieldValue, nil
|
||||
}
|
||||
|
||||
if len(col.fieldPath) == 1 {
|
||||
fieldValue = dataStruct.FieldByName(col.FieldName)
|
||||
} else if len(col.fieldPath) == 2 {
|
||||
|
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
@ -47,15 +47,13 @@ type Dialect interface {
|
||||
SupportInsertMany() bool
|
||||
SupportEngine() bool
|
||||
SupportCharset() bool
|
||||
SupportDropIfExists() bool
|
||||
IndexOnTable() bool
|
||||
ShowCreateNull() bool
|
||||
|
||||
IndexCheckSql(tableName, idxName string) (string, []interface{})
|
||||
TableCheckSql(tableName string) (string, []interface{})
|
||||
//ColumnCheckSql(tableName, colName string) (string, []interface{})
|
||||
|
||||
//IsTableExist(tableName string) (bool, error)
|
||||
//IsIndexExist(tableName string, idx *Index) (bool, error)
|
||||
IsColumnExist(tableName string, col *Column) (bool, error)
|
||||
|
||||
CreateTableSql(table *Table, tableName, storeEngine, charset string) string
|
||||
@ -65,15 +63,13 @@ type Dialect interface {
|
||||
|
||||
ModifyColumnSql(tableName string, col *Column) string
|
||||
|
||||
//CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error
|
||||
//MustDropTable(tableName string) error
|
||||
|
||||
GetColumns(tableName string) ([]string, map[string]*Column, error)
|
||||
GetTables() ([]*Table, error)
|
||||
GetIndexes(tableName string) (map[string]*Index, error)
|
||||
|
||||
// Get data from db cell to a struct's field
|
||||
//GetData(col *Column, fieldValue *reflect.Value, cellData interface{}) error
|
||||
// Set field data to db
|
||||
//SetData(col *Column, fieldValue *refelct.Value) (interface{}, error)
|
||||
|
||||
Filters() []Filter
|
||||
}
|
||||
|
||||
@ -144,6 +140,10 @@ func (db *Base) RollBackStr() string {
|
||||
return "ROLL BACK"
|
||||
}
|
||||
|
||||
func (db *Base) SupportDropIfExists() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (db *Base) DropTableSql(tableName string) string {
|
||||
return fmt.Sprintf("DROP TABLE IF EXISTS `%s`", tableName)
|
||||
}
|
||||
@ -170,35 +170,52 @@ func (db *Base) IsColumnExist(tableName string, col *Column) (bool, error) {
|
||||
return db.HasRecords(query, db.DbName, tableName, col.Name)
|
||||
}
|
||||
|
||||
/*
|
||||
func (db *Base) CreateTableIfNotExists(table *Table, tableName, storeEngine, charset string) error {
|
||||
sql, args := db.dialect.TableCheckSql(tableName)
|
||||
rows, err := db.DB().Query(sql, args...)
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", sql, args)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
return nil
|
||||
}
|
||||
|
||||
sql = db.dialect.CreateTableSql(table, tableName, storeEngine, charset)
|
||||
_, err = db.DB().Exec(sql)
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", sql)
|
||||
}
|
||||
return err
|
||||
}*/
|
||||
|
||||
func (db *Base) CreateIndexSql(tableName string, index *Index) string {
|
||||
quote := db.dialect.Quote
|
||||
var unique string
|
||||
var idxName string
|
||||
if index.Type == UniqueType {
|
||||
unique = " UNIQUE"
|
||||
idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
} else {
|
||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v);", unique,
|
||||
idxName = index.XName(tableName)
|
||||
return fmt.Sprintf("CREATE%s INDEX %v ON %v (%v)", unique,
|
||||
quote(idxName), quote(tableName),
|
||||
quote(strings.Join(index.Cols, quote(","))))
|
||||
}
|
||||
|
||||
func (db *Base) DropIndexSql(tableName string, index *Index) string {
|
||||
quote := db.dialect.Quote
|
||||
//var unique string
|
||||
var idxName string = index.Name
|
||||
if !strings.HasPrefix(idxName, "UQE_") &&
|
||||
!strings.HasPrefix(idxName, "IDX_") {
|
||||
if index.Type == UniqueType {
|
||||
idxName = fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
} else {
|
||||
idxName = fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
var name string
|
||||
if index.IsRegular {
|
||||
name = index.XName(tableName)
|
||||
} else {
|
||||
name = index.Name
|
||||
}
|
||||
return fmt.Sprintf("DROP INDEX %v ON %s",
|
||||
quote(idxName), quote(tableName))
|
||||
return fmt.Sprintf("DROP INDEX %v ON %s", quote(name), quote(tableName))
|
||||
}
|
||||
|
||||
func (db *Base) ModifyColumnSql(tableName string, col *Column) string {
|
||||
|
25
Godeps/_workspace/src/github.com/go-xorm/core/index.go
generated
vendored
25
Godeps/_workspace/src/github.com/go-xorm/core/index.go
generated
vendored
@ -1,7 +1,9 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -11,9 +13,21 @@ const (
|
||||
|
||||
// database index
|
||||
type Index struct {
|
||||
Name string
|
||||
Type int
|
||||
Cols []string
|
||||
IsRegular bool
|
||||
Name string
|
||||
Type int
|
||||
Cols []string
|
||||
}
|
||||
|
||||
func (index *Index) XName(tableName string) string {
|
||||
if !strings.HasPrefix(index.Name, "UQE_") &&
|
||||
!strings.HasPrefix(index.Name, "IDX_") {
|
||||
if index.Type == UniqueType {
|
||||
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||
}
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, index.Name)
|
||||
}
|
||||
return index.Name
|
||||
}
|
||||
|
||||
// add columns which will be composite index
|
||||
@ -24,6 +38,9 @@ func (index *Index) AddColumn(cols ...string) {
|
||||
}
|
||||
|
||||
func (index *Index) Equal(dst *Index) bool {
|
||||
if index.Type != dst.Type {
|
||||
return false
|
||||
}
|
||||
if len(index.Cols) != len(dst.Cols) {
|
||||
return false
|
||||
}
|
||||
@ -40,5 +57,5 @@ func (index *Index) Equal(dst *Index) bool {
|
||||
|
||||
// new an index
|
||||
func NewIndex(name string, indexType int) *Index {
|
||||
return &Index{name, indexType, make([]string, 0)}
|
||||
return &Index{true, name, indexType, make([]string, 0)}
|
||||
}
|
||||
|
134
Godeps/_workspace/src/github.com/go-xorm/core/mapper.go
generated
vendored
134
Godeps/_workspace/src/github.com/go-xorm/core/mapper.go
generated
vendored
@ -9,7 +9,6 @@ import (
|
||||
type IMapper interface {
|
||||
Obj2Table(string) string
|
||||
Table2Obj(string) string
|
||||
TableName(string) string
|
||||
}
|
||||
|
||||
type CacheMapper struct {
|
||||
@ -56,10 +55,6 @@ func (m *CacheMapper) Table2Obj(t string) string {
|
||||
return o
|
||||
}
|
||||
|
||||
func (m *CacheMapper) TableName(t string) string {
|
||||
return t
|
||||
}
|
||||
|
||||
// SameMapper implements IMapper and provides same name between struct and
|
||||
// database table
|
||||
type SameMapper struct {
|
||||
@ -73,10 +68,6 @@ func (m SameMapper) Table2Obj(t string) string {
|
||||
return t
|
||||
}
|
||||
|
||||
func (m SameMapper) TableName(t string) string {
|
||||
return t
|
||||
}
|
||||
|
||||
// SnakeMapper implements IMapper and provides name transaltion between
|
||||
// struct and database table
|
||||
type SnakeMapper struct {
|
||||
@ -97,25 +88,6 @@ func snakeCasedName(name string) string {
|
||||
return string(newstr)
|
||||
}
|
||||
|
||||
/*func pascal2Sql(s string) (d string) {
|
||||
d = ""
|
||||
lastIdx := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= 'A' && s[i] <= 'Z' {
|
||||
if lastIdx < i {
|
||||
d += s[lastIdx+1 : i]
|
||||
}
|
||||
if i != 0 {
|
||||
d += "_"
|
||||
}
|
||||
d += string(s[i] + 32)
|
||||
lastIdx = i
|
||||
}
|
||||
}
|
||||
d += s[lastIdx+1:]
|
||||
return
|
||||
}*/
|
||||
|
||||
func (mapper SnakeMapper) Obj2Table(name string) string {
|
||||
return snakeCasedName(name)
|
||||
}
|
||||
@ -148,9 +120,103 @@ func (mapper SnakeMapper) Table2Obj(name string) string {
|
||||
return titleCasedName(name)
|
||||
}
|
||||
|
||||
func (mapper SnakeMapper) TableName(t string) string {
|
||||
return t
|
||||
// GonicMapper implements IMapper. It will consider initialisms when mapping names.
|
||||
// E.g. id -> ID, user -> User and to table names: UserID -> user_id, MyUID -> my_uid
|
||||
type GonicMapper map[string]bool
|
||||
|
||||
func isASCIIUpper(r rune) bool {
|
||||
return 'A' <= r && r <= 'Z'
|
||||
}
|
||||
|
||||
func toASCIIUpper(r rune) rune {
|
||||
if 'a' <= r && r <= 'z' {
|
||||
r -= ('a' - 'A')
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func gonicCasedName(name string) string {
|
||||
newstr := make([]rune, 0, len(name)+3)
|
||||
for idx, chr := range name {
|
||||
if isASCIIUpper(chr) && idx > 0 {
|
||||
if !isASCIIUpper(newstr[len(newstr)-1]) {
|
||||
newstr = append(newstr, '_')
|
||||
}
|
||||
}
|
||||
|
||||
if !isASCIIUpper(chr) && idx > 1 {
|
||||
l := len(newstr)
|
||||
if isASCIIUpper(newstr[l-1]) && isASCIIUpper(newstr[l-2]) {
|
||||
newstr = append(newstr, newstr[l-1])
|
||||
newstr[l-1] = '_'
|
||||
}
|
||||
}
|
||||
|
||||
newstr = append(newstr, chr)
|
||||
}
|
||||
return strings.ToLower(string(newstr))
|
||||
}
|
||||
|
||||
func (mapper GonicMapper) Obj2Table(name string) string {
|
||||
return gonicCasedName(name)
|
||||
}
|
||||
|
||||
func (mapper GonicMapper) Table2Obj(name string) string {
|
||||
newstr := make([]rune, 0)
|
||||
|
||||
name = strings.ToLower(name)
|
||||
parts := strings.Split(name, "_")
|
||||
|
||||
for _, p := range parts {
|
||||
_, isInitialism := mapper[strings.ToUpper(p)]
|
||||
for i, r := range p {
|
||||
if i == 0 || isInitialism {
|
||||
r = toASCIIUpper(r)
|
||||
}
|
||||
newstr = append(newstr, r)
|
||||
}
|
||||
}
|
||||
|
||||
return string(newstr)
|
||||
}
|
||||
|
||||
// A GonicMapper that contains a list of common initialisms taken from golang/lint
|
||||
var LintGonicMapper = GonicMapper{
|
||||
"API": true,
|
||||
"ASCII": true,
|
||||
"CPU": true,
|
||||
"CSS": true,
|
||||
"DNS": true,
|
||||
"EOF": true,
|
||||
"GUID": true,
|
||||
"HTML": true,
|
||||
"HTTP": true,
|
||||
"HTTPS": true,
|
||||
"ID": true,
|
||||
"IP": true,
|
||||
"JSON": true,
|
||||
"LHS": true,
|
||||
"QPS": true,
|
||||
"RAM": true,
|
||||
"RHS": true,
|
||||
"RPC": true,
|
||||
"SLA": true,
|
||||
"SMTP": true,
|
||||
"SSH": true,
|
||||
"TLS": true,
|
||||
"TTL": true,
|
||||
"UI": true,
|
||||
"UID": true,
|
||||
"UUID": true,
|
||||
"URI": true,
|
||||
"URL": true,
|
||||
"UTF8": true,
|
||||
"VM": true,
|
||||
"XML": true,
|
||||
"XSRF": true,
|
||||
"XSS": true,
|
||||
}
|
||||
|
||||
// provide prefix table name support
|
||||
type PrefixMapper struct {
|
||||
Mapper IMapper
|
||||
@ -165,10 +231,6 @@ func (mapper PrefixMapper) Table2Obj(name string) string {
|
||||
return mapper.Mapper.Table2Obj(name[len(mapper.Prefix):])
|
||||
}
|
||||
|
||||
func (mapper PrefixMapper) TableName(name string) string {
|
||||
return mapper.Prefix + name
|
||||
}
|
||||
|
||||
func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
|
||||
return PrefixMapper{mapper, prefix}
|
||||
}
|
||||
@ -187,10 +249,6 @@ func (mapper SuffixMapper) Table2Obj(name string) string {
|
||||
return mapper.Mapper.Table2Obj(name[:len(name)-len(mapper.Suffix)])
|
||||
}
|
||||
|
||||
func (mapper SuffixMapper) TableName(name string) string {
|
||||
return name + mapper.Suffix
|
||||
}
|
||||
|
||||
func NewSuffixMapper(mapper IMapper, suffix string) SuffixMapper {
|
||||
return SuffixMapper{mapper, suffix}
|
||||
}
|
||||
|
45
Godeps/_workspace/src/github.com/go-xorm/core/mapper_test.go
generated
vendored
Normal file
45
Godeps/_workspace/src/github.com/go-xorm/core/mapper_test.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGonicMapperFromObj(t *testing.T) {
|
||||
testCases := map[string]string{
|
||||
"HTTPLib": "http_lib",
|
||||
"id": "id",
|
||||
"ID": "id",
|
||||
"IDa": "i_da",
|
||||
"iDa": "i_da",
|
||||
"IDAa": "id_aa",
|
||||
"aID": "a_id",
|
||||
"aaID": "aa_id",
|
||||
"aaaID": "aaa_id",
|
||||
"MyREalFunkYLONgNAME": "my_r_eal_funk_ylo_ng_name",
|
||||
}
|
||||
|
||||
for in, expected := range testCases {
|
||||
out := gonicCasedName(in)
|
||||
if out != expected {
|
||||
t.Errorf("Given %s, expected %s but got %s", in, expected, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGonicMapperToObj(t *testing.T) {
|
||||
testCases := map[string]string{
|
||||
"http_lib": "HTTPLib",
|
||||
"id": "ID",
|
||||
"ida": "Ida",
|
||||
"id_aa": "IDAa",
|
||||
"aa_id": "AaID",
|
||||
"my_r_eal_funk_ylo_ng_name": "MyREalFunkYloNgName",
|
||||
}
|
||||
|
||||
for in, expected := range testCases {
|
||||
out := LintGonicMapper.Table2Obj(in)
|
||||
if out != expected {
|
||||
t.Errorf("Given %s, expected %s but got %s", in, expected, out)
|
||||
}
|
||||
}
|
||||
}
|
17
Godeps/_workspace/src/github.com/go-xorm/core/pk.go
generated
vendored
17
Godeps/_workspace/src/github.com/go-xorm/core/pk.go
generated
vendored
@ -1,7 +1,8 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
type PK []interface{}
|
||||
@ -12,14 +13,14 @@ func NewPK(pks ...interface{}) *PK {
|
||||
}
|
||||
|
||||
func (p *PK) ToString() (string, error) {
|
||||
bs, err := json.Marshal(*p)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return string(bs), nil
|
||||
buf := new(bytes.Buffer)
|
||||
enc := gob.NewEncoder(buf)
|
||||
err := enc.Encode(*p)
|
||||
return buf.String(), err
|
||||
}
|
||||
|
||||
func (p *PK) FromString(content string) error {
|
||||
return json.Unmarshal([]byte(content), p)
|
||||
dec := gob.NewDecoder(bytes.NewBufferString(content))
|
||||
err := dec.Decode(p)
|
||||
return err
|
||||
}
|
||||
|
11
Godeps/_workspace/src/github.com/go-xorm/core/pk_test.go
generated
vendored
11
Godeps/_workspace/src/github.com/go-xorm/core/pk_test.go
generated
vendored
@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@ -19,4 +20,14 @@ func TestPK(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
fmt.Println(s)
|
||||
|
||||
if len(*p) != len(*s) {
|
||||
t.Fatal("p", *p, "should be equal", *s)
|
||||
}
|
||||
|
||||
for i, ori := range *p {
|
||||
if ori != (*s)[i] {
|
||||
t.Fatal("ori", ori, reflect.ValueOf(ori), "should be equal", (*s)[i], reflect.ValueOf((*s)[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
Godeps/_workspace/src/github.com/go-xorm/core/table.go
generated
vendored
11
Godeps/_workspace/src/github.com/go-xorm/core/table.go
generated
vendored
@ -65,13 +65,18 @@ func (table *Table) GetColumnIdx(name string, idx int) *Column {
|
||||
|
||||
// if has primary key, return column
|
||||
func (table *Table) PKColumns() []*Column {
|
||||
columns := make([]*Column, 0)
|
||||
for _, name := range table.PrimaryKeys {
|
||||
columns = append(columns, table.GetColumn(name))
|
||||
columns := make([]*Column, len(table.PrimaryKeys))
|
||||
for i, name := range table.PrimaryKeys {
|
||||
columns[i] = table.GetColumn(name)
|
||||
}
|
||||
return columns
|
||||
}
|
||||
|
||||
func (table *Table) ColumnType(name string) reflect.Type {
|
||||
t, _ := table.Type.FieldByName(name)
|
||||
return t.Type
|
||||
}
|
||||
|
||||
func (table *Table) AutoIncrColumn() *Column {
|
||||
return table.GetColumn(table.AutoIncrement)
|
||||
}
|
||||
|
6
Godeps/_workspace/src/github.com/go-xorm/core/type.go
generated
vendored
6
Godeps/_workspace/src/github.com/go-xorm/core/type.go
generated
vendored
@ -70,6 +70,7 @@ var (
|
||||
NVarchar = "NVARCHAR"
|
||||
TinyText = "TINYTEXT"
|
||||
Text = "TEXT"
|
||||
Clob = "CLOB"
|
||||
MediumText = "MEDIUMTEXT"
|
||||
LongText = "LONGTEXT"
|
||||
Uuid = "UUID"
|
||||
@ -120,6 +121,7 @@ var (
|
||||
MediumText: TEXT_TYPE,
|
||||
LongText: TEXT_TYPE,
|
||||
Uuid: TEXT_TYPE,
|
||||
Clob: TEXT_TYPE,
|
||||
|
||||
Date: TIME_TYPE,
|
||||
DateTime: TIME_TYPE,
|
||||
@ -250,7 +252,7 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
||||
case reflect.String:
|
||||
st = SQLType{Varchar, 255, 0}
|
||||
case reflect.Struct:
|
||||
if t == reflect.TypeOf(c_TIME_DEFAULT) {
|
||||
if t.ConvertibleTo(reflect.TypeOf(c_TIME_DEFAULT)) {
|
||||
st = SQLType{DateTime, 0, 0}
|
||||
} else {
|
||||
// TODO need to handle association struct
|
||||
@ -303,7 +305,7 @@ func SQLType2Type(st SQLType) reflect.Type {
|
||||
return reflect.TypeOf(float32(1))
|
||||
case Double:
|
||||
return reflect.TypeOf(float64(1))
|
||||
case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid:
|
||||
case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid, Clob:
|
||||
return reflect.TypeOf("")
|
||||
case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary:
|
||||
return reflect.TypeOf([]byte{})
|
||||
|
4
Godeps/_workspace/src/github.com/go-xorm/xorm/README.md
generated
vendored
4
Godeps/_workspace/src/github.com/go-xorm/xorm/README.md
generated
vendored
@ -82,11 +82,13 @@ Or
|
||||
|
||||
# Cases
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
|
||||
* [Gorevel](http://http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)
|
||||
* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)
|
||||
|
||||
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
||||
|
||||
|
16
Godeps/_workspace/src/github.com/go-xorm/xorm/README_CN.md
generated
vendored
16
Godeps/_workspace/src/github.com/go-xorm/xorm/README_CN.md
generated
vendored
@ -44,16 +44,10 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||
|
||||
## 更新日志
|
||||
|
||||
* **v0.4.0 RC1**
|
||||
新特性:
|
||||
* 移动xorm cmd [github.com/go-xorm/cmd](github.com/go-xorm/cmd)
|
||||
* 在重构一般DB操作核心库 [github.com/go-xorm/core](https://github.com/go-xorm/core)
|
||||
* 移动测试github.com/复XORM/测试 [github.com/go-xorm/tests](github.com/go-xorm/tests)
|
||||
|
||||
改进:
|
||||
* Prepared statement 缓存
|
||||
* 添加 Incr API
|
||||
* 指定时区位置
|
||||
* **v0.4.2**
|
||||
新特性:
|
||||
* deleted标记
|
||||
* bug fixed
|
||||
|
||||
[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16)
|
||||
|
||||
@ -78,6 +72,8 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||
|
||||
## 案例
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
|
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.1
|
||||
xorm v0.4.2.0225
|
||||
|
13
Godeps/_workspace/src/github.com/go-xorm/xorm/doc.go
generated
vendored
13
Godeps/_workspace/src/github.com/go-xorm/xorm/doc.go
generated
vendored
@ -63,21 +63,22 @@ There are 7 major ORM methods and many helpful methods to use to operate databas
|
||||
// SELECT * FROM user
|
||||
|
||||
4. Query multiple records and record by record handle, there two methods, one is Iterate,
|
||||
another is Raws
|
||||
another is Rows
|
||||
|
||||
err := engine.Iterate(...)
|
||||
// SELECT * FROM user
|
||||
|
||||
raws, err := engine.Raws(...)
|
||||
rows, err := engine.Rows(...)
|
||||
// SELECT * FROM user
|
||||
defer rows.Close()
|
||||
bean := new(Struct)
|
||||
for raws.Next() {
|
||||
err = raws.Scan(bean)
|
||||
for rows.Next() {
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
|
||||
5. Update one or more records
|
||||
|
||||
affected, err := engine.Update(&user)
|
||||
affected, err := engine.Id(...).Update(&user)
|
||||
// UPDATE user SET ...
|
||||
|
||||
6. Delete one or more records, Delete MUST has conditon
|
||||
@ -150,6 +151,6 @@ Attention: the above 7 methods should be the last chainable method.
|
||||
engine.Join("LEFT", "userdetail", "user.id=userdetail.id").Find()
|
||||
//SELECT * FROM user LEFT JOIN userdetail ON user.id=userdetail.id
|
||||
|
||||
More usage, please visit https://github.com/go-xorm/xorm/blob/master/docs/QuickStartEn.md
|
||||
More usage, please visit http://xorm.io/docs
|
||||
*/
|
||||
package xorm
|
||||
|
90
Godeps/_workspace/src/github.com/go-xorm/xorm/engine.go
generated
vendored
90
Godeps/_workspace/src/github.com/go-xorm/xorm/engine.go
generated
vendored
@ -344,7 +344,7 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
||||
if col := table.GetColumn(name); col != nil {
|
||||
col.Indexes[index.Name] = true
|
||||
} else {
|
||||
return nil, fmt.Errorf("Unknown col "+name+" in indexes %v", index)
|
||||
return nil, fmt.Errorf("Unknown col "+name+" in indexes %v of table", index, table.ColumnsSeq())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,6 +352,9 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
/*
|
||||
dump database all table structs and data to a file
|
||||
*/
|
||||
func (engine *Engine) DumpAllToFile(fp string) error {
|
||||
f, err := os.Create(fp)
|
||||
if err != nil {
|
||||
@ -361,6 +364,9 @@ func (engine *Engine) DumpAllToFile(fp string) error {
|
||||
return engine.DumpAll(f)
|
||||
}
|
||||
|
||||
/*
|
||||
dump database all table structs and data to w
|
||||
*/
|
||||
func (engine *Engine) DumpAll(w io.Writer) error {
|
||||
tables, err := engine.DBMetas()
|
||||
if err != nil {
|
||||
@ -558,6 +564,13 @@ func (engine *Engine) Decr(column string, arg ...interface{}) *Session {
|
||||
return session.Decr(column, arg...)
|
||||
}
|
||||
|
||||
// Method SetExpr provides a update string like "column = {expression}"
|
||||
func (engine *Engine) SetExpr(column string, expression string) *Session {
|
||||
session := engine.NewSession()
|
||||
session.IsAutoClose = true
|
||||
return session.SetExpr(column, expression)
|
||||
}
|
||||
|
||||
// Temporarily change the Get, Find, Update's table
|
||||
func (engine *Engine) Table(tableNameOrBean interface{}) *Session {
|
||||
session := engine.NewSession()
|
||||
@ -766,7 +779,12 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||
col.IsPrimaryKey = true
|
||||
col.Nullable = false
|
||||
case k == "NULL":
|
||||
col.Nullable = (strings.ToUpper(tags[j-1]) != "NOT")
|
||||
if j == 0 {
|
||||
col.Nullable = true
|
||||
} else {
|
||||
col.Nullable = (strings.ToUpper(tags[j-1]) != "NOT")
|
||||
}
|
||||
// TODO: for postgres how add autoincr?
|
||||
/*case strings.HasPrefix(k, "AUTOINCR(") && strings.HasSuffix(k, ")"):
|
||||
col.IsAutoIncrement = true
|
||||
|
||||
@ -915,7 +933,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||
|
||||
table.AddColumn(col)
|
||||
|
||||
if fieldType.Kind() == reflect.Int64 && (col.FieldName == "Id" || strings.HasSuffix(col.FieldName, ".Id")) {
|
||||
if fieldType.Kind() == reflect.Int64 && (strings.ToUpper(col.FieldName) == "ID" || strings.HasSuffix(strings.ToUpper(col.FieldName), ".ID")) {
|
||||
idFieldColName = col.Name
|
||||
}
|
||||
} // end for
|
||||
@ -959,40 +977,25 @@ func (engine *Engine) mapping(beans ...interface{}) (e error) {
|
||||
|
||||
// If a table has any reocrd
|
||||
func (engine *Engine) IsTableEmpty(bean interface{}) (bool, error) {
|
||||
v := rValue(bean)
|
||||
t := v.Type()
|
||||
if t.Kind() != reflect.Struct {
|
||||
return false, errors.New("bean should be a struct or struct's point")
|
||||
}
|
||||
engine.autoMapType(v)
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
rows, err := session.Count(bean)
|
||||
return rows == 0, err
|
||||
return session.IsTableEmpty(bean)
|
||||
}
|
||||
|
||||
// If a table is exist
|
||||
func (engine *Engine) IsTableExist(bean interface{}) (bool, error) {
|
||||
v := rValue(bean)
|
||||
var tableName string
|
||||
if v.Type().Kind() == reflect.String {
|
||||
tableName = bean.(string)
|
||||
} else if v.Type().Kind() == reflect.Struct {
|
||||
table := engine.autoMapType(v)
|
||||
tableName = table.Name
|
||||
} else {
|
||||
return false, errors.New("bean should be a struct or struct's point")
|
||||
}
|
||||
|
||||
func (engine *Engine) IsTableExist(beanOrTableName interface{}) (bool, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
has, err := session.isTableExist(tableName)
|
||||
return has, err
|
||||
return session.IsTableExist(beanOrTableName)
|
||||
}
|
||||
|
||||
func (engine *Engine) IdOf(bean interface{}) core.PK {
|
||||
table := engine.TableInfo(bean)
|
||||
v := reflect.Indirect(reflect.ValueOf(bean))
|
||||
return engine.IdOfV(reflect.ValueOf(bean))
|
||||
}
|
||||
|
||||
func (engine *Engine) IdOfV(rv reflect.Value) core.PK {
|
||||
v := reflect.Indirect(rv)
|
||||
table := engine.autoMapType(v)
|
||||
pk := make([]interface{}, len(table.PrimaryKeys))
|
||||
for i, col := range table.PKColumns() {
|
||||
pkField := v.FieldByName(col.FieldName)
|
||||
@ -1109,7 +1112,7 @@ func (engine *Engine) Sync(beans ...interface{}) error {
|
||||
session := engine.NewSession()
|
||||
session.Statement.RefTable = table
|
||||
defer session.Close()
|
||||
isExist, err := session.isColumnExist(table.Name, col)
|
||||
isExist, err := session.Engine.dialect.IsColumnExist(table.Name, col)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1222,8 +1225,9 @@ func (engine *Engine) CreateTables(beans ...interface{}) error {
|
||||
|
||||
func (engine *Engine) DropTables(beans ...interface{}) error {
|
||||
session := engine.NewSession()
|
||||
err := session.Begin()
|
||||
defer session.Close()
|
||||
|
||||
err := session.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1258,13 +1262,6 @@ func (engine *Engine) Query(sql string, paramStr ...interface{}) (resultsSlice [
|
||||
return session.Query(sql, paramStr...)
|
||||
}
|
||||
|
||||
// Exec a raw sql and return records as []map[string]string
|
||||
func (engine *Engine) Q(sql string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Q(sql, paramStr...)
|
||||
}
|
||||
|
||||
// Insert one or more records
|
||||
func (engine *Engine) Insert(beans ...interface{}) (int64, error) {
|
||||
session := engine.NewSession()
|
||||
@ -1371,18 +1368,11 @@ func (engine *Engine) Import(r io.Reader) ([]sql.Result, error) {
|
||||
|
||||
scanner.Split(semiColSpliter)
|
||||
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
err := session.newDb()
|
||||
if err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
for scanner.Scan() {
|
||||
query := scanner.Text()
|
||||
query = strings.Trim(query, " \t")
|
||||
if len(query) > 0 {
|
||||
result, err := session.Db.Exec(query)
|
||||
result, err := engine.DB().Exec(query)
|
||||
results = append(results, result)
|
||||
if err != nil {
|
||||
lastError = err
|
||||
@ -1409,7 +1399,15 @@ func (engine *Engine) NowTime(sqlTypeName string) interface{} {
|
||||
return engine.FormatTime(sqlTypeName, t)
|
||||
}
|
||||
|
||||
func (engine *Engine) NowTime2(sqlTypeName string) (interface{}, time.Time) {
|
||||
t := time.Now()
|
||||
return engine.FormatTime(sqlTypeName, t), t
|
||||
}
|
||||
|
||||
func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}) {
|
||||
if engine.dialect.DBType() == core.ORACLE {
|
||||
return t
|
||||
}
|
||||
switch sqlTypeName {
|
||||
case core.Time:
|
||||
s := engine.TZTime(t).Format("2006-01-02 15:04:05") //time.RFC3339
|
||||
@ -1419,6 +1417,8 @@ func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}
|
||||
case core.DateTime, core.TimeStamp:
|
||||
if engine.dialect.DBType() == "ql" {
|
||||
v = engine.TZTime(t)
|
||||
} else if engine.dialect.DBType() == "sqlite3" {
|
||||
v = engine.TZTime(t).UTC().Format("2006-01-02 15:04:05")
|
||||
} else {
|
||||
v = engine.TZTime(t).Format("2006-01-02 15:04:05")
|
||||
}
|
||||
@ -1430,6 +1430,8 @@ func (engine *Engine) FormatTime(sqlTypeName string, t time.Time) (v interface{}
|
||||
} else {
|
||||
v = engine.TZTime(t).Format(time.RFC3339Nano)
|
||||
}
|
||||
case core.BigInt, core.Int:
|
||||
v = engine.TZTime(t).Unix()
|
||||
default:
|
||||
v = engine.TZTime(t)
|
||||
}
|
||||
|
216
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers.go
generated
vendored
216
Godeps/_workspace/src/github.com/go-xorm/xorm/helpers.go
generated
vendored
@ -11,6 +11,43 @@ import (
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
func isZero(k interface{}) bool {
|
||||
switch k.(type) {
|
||||
case int:
|
||||
return k.(int) == 0
|
||||
case int8:
|
||||
return k.(int8) == 0
|
||||
case int16:
|
||||
return k.(int16) == 0
|
||||
case int32:
|
||||
return k.(int32) == 0
|
||||
case int64:
|
||||
return k.(int64) == 0
|
||||
case uint:
|
||||
return k.(uint) == 0
|
||||
case uint8:
|
||||
return k.(uint8) == 0
|
||||
case uint16:
|
||||
return k.(uint16) == 0
|
||||
case uint32:
|
||||
return k.(uint32) == 0
|
||||
case uint64:
|
||||
return k.(uint64) == 0
|
||||
case string:
|
||||
return k.(string) == ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isPKZero(pk core.PK) bool {
|
||||
for _, k := range pk {
|
||||
if isZero(k) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func indexNoCase(s, sep string) int {
|
||||
return strings.Index(strings.ToLower(s), strings.ToLower(sep))
|
||||
}
|
||||
@ -163,3 +200,182 @@ func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) {
|
||||
|
||||
return resultsSlice, nil
|
||||
}
|
||||
|
||||
func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) {
|
||||
result := make(map[string][]byte)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func row2mapStr(rows *core.Rows, fields []string) (resultsMap map[string]string, err error) {
|
||||
result := make(map[string]string)
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for ii, key := range fields {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
//fmt.Println("ignore ...", key, rawValue)
|
||||
continue
|
||||
}
|
||||
|
||||
if data, err := value2String(&rawValue); err == nil {
|
||||
result[key] = data
|
||||
} else {
|
||||
return nil, err // !nashtsai! REVIEW, should return err or just error log?
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
||||
rows, err := tx.Query(sqlStr, params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func query2(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
||||
s, err := db.Prepare(sqlStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.Close()
|
||||
rows, err := s.Query(params...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return rows2Strings(rows)
|
||||
}
|
||||
|
||||
func setColumnTime(bean interface{}, col *core.Column, t time.Time) {
|
||||
v, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if v.CanSet() {
|
||||
switch v.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
v.Set(reflect.ValueOf(t).Convert(v.Type()))
|
||||
case reflect.Int, reflect.Int64, reflect.Int32:
|
||||
v.SetInt(t.Unix())
|
||||
case reflect.Uint, reflect.Uint64, reflect.Uint32:
|
||||
v.SetUint(uint64(t.Unix()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, includeQuote bool) ([]string, []interface{}, error) {
|
||||
colNames := make([]string, 0)
|
||||
args := make([]interface{}, 0)
|
||||
|
||||
for _, col := range table.Columns() {
|
||||
lColName := strings.ToLower(col.Name)
|
||||
if useCol && !col.IsVersion && !col.IsCreated && !col.IsUpdated {
|
||||
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if col.MapType == core.ONLYFROMDB {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldValuePtr, err := col.ValueOf(bean)
|
||||
if err != nil {
|
||||
session.Engine.LogError(err)
|
||||
continue
|
||||
}
|
||||
fieldValue := *fieldValuePtr
|
||||
|
||||
if col.IsAutoIncrement {
|
||||
switch fieldValue.Type().Kind() {
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int, reflect.Int64:
|
||||
if fieldValue.Int() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint, reflect.Uint64:
|
||||
if fieldValue.Uint() == 0 {
|
||||
continue
|
||||
}
|
||||
case reflect.String:
|
||||
if len(fieldValue.String()) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
|
||||
if session.Statement.ColumnStr != "" {
|
||||
if _, ok := session.Statement.columnMap[lColName]; !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if session.Statement.OmitStr != "" {
|
||||
if _, ok := session.Statement.columnMap[lColName]; ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.Statement.UseAutoTime {
|
||||
val, t := session.Engine.NowTime2(col.SQLType.Name)
|
||||
args = append(args, val)
|
||||
|
||||
var colName = col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.Statement.checkVersion {
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
arg, err := session.value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
}
|
||||
args = append(args, arg)
|
||||
}
|
||||
|
||||
if includeQuote {
|
||||
colNames = append(colNames, session.Engine.Quote(col.Name)+" = ?")
|
||||
} else {
|
||||
colNames = append(colNames, col.Name)
|
||||
}
|
||||
}
|
||||
return colNames, args, nil
|
||||
}
|
||||
|
2
Godeps/_workspace/src/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
2
Godeps/_workspace/src/github.com/go-xorm/xorm/mssql_dialect.go
generated
vendored
@ -270,7 +270,7 @@ func (db *mssql) IsReserved(name string) bool {
|
||||
}
|
||||
|
||||
func (db *mssql) Quote(name string) string {
|
||||
return "[" + name + "]"
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *mssql) QuoteStr() string {
|
||||
|
8
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
8
Godeps/_workspace/src/github.com/go-xorm/xorm/mysql_dialect.go
generated
vendored
@ -218,6 +218,9 @@ func (db *mysql) SqlType(c *core.Column) string {
|
||||
res += ")"
|
||||
case core.NVarchar:
|
||||
res = core.Varchar
|
||||
case core.Uuid:
|
||||
res = core.Varchar
|
||||
c.Length = 40
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
@ -317,7 +320,6 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
//fmt.Println(columnName, isNullable, colType, colKey, extra, colDefault)
|
||||
col.Name = strings.Trim(columnName, "` ")
|
||||
if "YES" == isNullable {
|
||||
col.Nullable = true
|
||||
@ -467,15 +469,17 @@ func (db *mysql) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
}
|
||||
|
||||
colName = strings.Trim(colName, "` ")
|
||||
|
||||
var isRegular bool
|
||||
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
||||
indexName = indexName[5+len(tableName) : len(indexName)]
|
||||
isRegular = true
|
||||
}
|
||||
|
||||
var index *core.Index
|
||||
var ok bool
|
||||
if index, ok = indexes[indexName]; !ok {
|
||||
index = new(core.Index)
|
||||
index.IsRegular = isRegular
|
||||
index.Type = indexType
|
||||
index.Name = indexName
|
||||
indexes[indexName] = index
|
||||
|
159
Godeps/_workspace/src/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
159
Godeps/_workspace/src/github.com/go-xorm/xorm/oracle_dialect.go
generated
vendored
@ -509,7 +509,7 @@ func (db *oracle) SqlType(c *core.Column) string {
|
||||
var res string
|
||||
switch t := c.SQLType.Name; t {
|
||||
case core.Bit, core.TinyInt, core.SmallInt, core.MediumInt, core.Int, core.Integer, core.BigInt, core.Bool, core.Serial, core.BigSerial:
|
||||
return "NUMBER"
|
||||
res = "NUMBER"
|
||||
case core.Binary, core.VarBinary, core.Blob, core.TinyBlob, core.MediumBlob, core.LongBlob, core.Bytea:
|
||||
return core.Blob
|
||||
case core.Time, core.DateTime, core.TimeStamp:
|
||||
@ -521,7 +521,7 @@ func (db *oracle) SqlType(c *core.Column) string {
|
||||
case core.Text, core.MediumText, core.LongText:
|
||||
res = "CLOB"
|
||||
case core.Char, core.Varchar, core.TinyText:
|
||||
return "VARCHAR2"
|
||||
res = "VARCHAR2"
|
||||
default:
|
||||
res = t
|
||||
}
|
||||
@ -536,6 +536,10 @@ func (db *oracle) SqlType(c *core.Column) string {
|
||||
return res
|
||||
}
|
||||
|
||||
func (db *oracle) AutoIncrStr() string {
|
||||
return "AUTO_INCREMENT"
|
||||
}
|
||||
|
||||
func (db *oracle) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
@ -553,10 +557,6 @@ func (db *oracle) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *oracle) AutoIncrStr() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (db *oracle) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
@ -565,19 +565,94 @@ func (db *oracle) SupportCharset() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) SupportDropIfExists() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) IndexOnTable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (db *oracle) DropTableSql(tableName string) string {
|
||||
return fmt.Sprintf("DROP TABLE `%s`", tableName)
|
||||
}
|
||||
|
||||
func (b *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, charset string) string {
|
||||
var sql string
|
||||
sql = "CREATE TABLE "
|
||||
if tableName == "" {
|
||||
tableName = table.Name
|
||||
}
|
||||
|
||||
sql += b.Quote(tableName) + " ("
|
||||
|
||||
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)
|
||||
//}
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
||||
if len(pkList) > 0 {
|
||||
sql += "PRIMARY KEY ( "
|
||||
sql += b.Quote(strings.Join(pkList, b.Quote(",")))
|
||||
sql += " ), "
|
||||
}
|
||||
|
||||
sql = sql[:len(sql)-2] + ")"
|
||||
if b.SupportEngine() && storeEngine != "" {
|
||||
sql += " ENGINE=" + storeEngine
|
||||
}
|
||||
if b.SupportCharset() {
|
||||
if len(charset) == 0 {
|
||||
charset = b.URI().Charset
|
||||
}
|
||||
if len(charset) > 0 {
|
||||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
}
|
||||
return sql
|
||||
}
|
||||
|
||||
func (db *oracle) IndexCheckSql(tableName, idxName string) (string, []interface{}) {
|
||||
args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(idxName)}
|
||||
args := []interface{}{tableName, idxName}
|
||||
return `SELECT INDEX_NAME FROM USER_INDEXES ` +
|
||||
`WHERE TABLE_NAME = ? AND INDEX_NAME = ?`, args
|
||||
`WHERE TABLE_NAME = :1 AND INDEX_NAME = :2`, args
|
||||
}
|
||||
|
||||
func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
args := []interface{}{strings.ToUpper(tableName)}
|
||||
return `SELECT table_name FROM user_tables WHERE table_name = ?`, args
|
||||
args := []interface{}{tableName}
|
||||
return `SELECT table_name FROM user_tables WHERE table_name = :1`, args
|
||||
}
|
||||
|
||||
func (db *oracle) MustDropTable(tableName string) error {
|
||||
sql, args := db.TableCheckSql(tableName)
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", sql, args)
|
||||
}
|
||||
|
||||
rows, err := db.DB().Query(sql, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
if !rows.Next() {
|
||||
return nil
|
||||
}
|
||||
|
||||
sql = "Drop Table \"" + tableName + "\""
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", sql)
|
||||
}
|
||||
_, err = db.DB().Exec(sql)
|
||||
return err
|
||||
}
|
||||
|
||||
/*func (db *oracle) ColumnCheckSql(tableName, colName string) (string, []interface{}) {
|
||||
@ -587,9 +662,9 @@ func (db *oracle) TableCheckSql(tableName string) (string, []interface{}) {
|
||||
}*/
|
||||
|
||||
func (db *oracle) IsColumnExist(tableName string, col *core.Column) (bool, error) {
|
||||
args := []interface{}{strings.ToUpper(tableName), strings.ToUpper(col.Name)}
|
||||
query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = ?" +
|
||||
" AND column_name = ?"
|
||||
args := []interface{}{tableName, col.Name}
|
||||
query := "SELECT column_name FROM USER_TAB_COLUMNS WHERE table_name = :1" +
|
||||
" AND column_name = :2"
|
||||
rows, err := db.DB().Query(query, args...)
|
||||
if db.Logger != nil {
|
||||
db.Logger.Info("[sql]", query, args)
|
||||
@ -606,7 +681,7 @@ func (db *oracle) IsColumnExist(tableName string, col *core.Column) (bool, error
|
||||
}
|
||||
|
||||
func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Column, error) {
|
||||
args := []interface{}{strings.ToUpper(tableName)}
|
||||
args := []interface{}{tableName}
|
||||
s := "SELECT column_name,data_default,data_type,data_length,data_precision,data_scale," +
|
||||
"nullable FROM USER_TAB_COLUMNS WHERE table_name = :1"
|
||||
|
||||
@ -625,7 +700,7 @@ func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Colum
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]bool)
|
||||
|
||||
var colName, colDefault, nullable, dataType, dataPrecision, dataScale string
|
||||
var colName, colDefault, nullable, dataType, dataPrecision, dataScale *string
|
||||
var dataLen int
|
||||
|
||||
err = rows.Scan(&colName, &colDefault, &dataType, &dataLen, &dataPrecision,
|
||||
@ -634,36 +709,66 @@ func (db *oracle) GetColumns(tableName string) ([]string, map[string]*core.Colum
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
col.Name = strings.Trim(colName, `" `)
|
||||
col.Default = colDefault
|
||||
col.Name = strings.Trim(*colName, `" `)
|
||||
if colDefault != nil {
|
||||
col.Default = *colDefault
|
||||
col.DefaultIsEmpty = false
|
||||
}
|
||||
|
||||
if nullable == "Y" {
|
||||
if *nullable == "Y" {
|
||||
col.Nullable = true
|
||||
} else {
|
||||
col.Nullable = false
|
||||
}
|
||||
|
||||
switch dataType {
|
||||
var ignore bool
|
||||
|
||||
var dt string
|
||||
var len1, len2 int
|
||||
dts := strings.Split(*dataType, "(")
|
||||
dt = dts[0]
|
||||
if len(dts) > 1 {
|
||||
lens := strings.Split(dts[1][:len(dts[1])-1], ",")
|
||||
if len(lens) > 1 {
|
||||
len1, _ = strconv.Atoi(lens[0])
|
||||
len2, _ = strconv.Atoi(lens[1])
|
||||
} else {
|
||||
len1, _ = strconv.Atoi(lens[0])
|
||||
}
|
||||
}
|
||||
|
||||
switch dt {
|
||||
case "VARCHAR2":
|
||||
col.SQLType = core.SQLType{core.Varchar, 0, 0}
|
||||
col.SQLType = core.SQLType{core.Varchar, len1, len2}
|
||||
case "TIMESTAMP WITH TIME ZONE":
|
||||
col.SQLType = core.SQLType{core.TimeStampz, 0, 0}
|
||||
case "NUMBER":
|
||||
col.SQLType = core.SQLType{core.Double, len1, len2}
|
||||
case "LONG", "LONG RAW":
|
||||
col.SQLType = core.SQLType{core.Text, 0, 0}
|
||||
case "RAW":
|
||||
col.SQLType = core.SQLType{core.Binary, 0, 0}
|
||||
case "ROWID":
|
||||
col.SQLType = core.SQLType{core.Varchar, 18, 0}
|
||||
case "AQ$_SUBSCRIBERS":
|
||||
ignore = true
|
||||
default:
|
||||
col.SQLType = core.SQLType{strings.ToUpper(dataType), 0, 0}
|
||||
col.SQLType = core.SQLType{strings.ToUpper(dt), len1, len2}
|
||||
}
|
||||
|
||||
if ignore {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := core.SqlTypes[col.SQLType.Name]; !ok {
|
||||
return nil, nil, errors.New(fmt.Sprintf("unkonw colType %v", dataType))
|
||||
return nil, nil, errors.New(fmt.Sprintf("unkonw colType %v %v", *dataType, col.SQLType))
|
||||
}
|
||||
|
||||
col.Length = dataLen
|
||||
|
||||
if col.SQLType.IsText() || col.SQLType.IsTime() {
|
||||
if col.Default != "" {
|
||||
if !col.DefaultIsEmpty {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
} else {
|
||||
if col.DefaultIsEmpty {
|
||||
col.Default = "''"
|
||||
}
|
||||
}
|
||||
}
|
||||
cols[col.Name] = col
|
||||
|
9
Godeps/_workspace/src/github.com/go-xorm/xorm/rows.go
generated
vendored
9
Godeps/_workspace/src/github.com/go-xorm/xorm/rows.go
generated
vendored
@ -25,11 +25,6 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
rows.session = session
|
||||
rows.beanType = reflect.Indirect(reflect.ValueOf(bean)).Type()
|
||||
|
||||
err := rows.session.newDb()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.session.Statement.Init()
|
||||
|
||||
var sqlStr string
|
||||
@ -47,8 +42,8 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
|
||||
}
|
||||
|
||||
rows.session.Engine.logSQL(sqlStr, args)
|
||||
|
||||
rows.stmt, err = rows.session.Db.Prepare(sqlStr)
|
||||
var err error
|
||||
rows.stmt, err = rows.session.DB().Prepare(sqlStr)
|
||||
if err != nil {
|
||||
rows.lastError = err
|
||||
defer rows.Close()
|
||||
|
946
Godeps/_workspace/src/github.com/go-xorm/xorm/session.go
generated
vendored
946
Godeps/_workspace/src/github.com/go-xorm/xorm/session.go
generated
vendored
File diff suppressed because it is too large
Load Diff
18
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
18
Godeps/_workspace/src/github.com/go-xorm/xorm/sqlite3_dialect.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@ -152,7 +153,7 @@ 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.Date, core.DateTime, core.TimeStamp, core.Time:
|
||||
return core.Numeric
|
||||
return core.DateTime
|
||||
case core.TimeStampz:
|
||||
return core.Text
|
||||
case core.Char, core.Varchar, core.NVarchar, core.TinyText, core.Text, core.MediumText, core.LongText:
|
||||
@ -297,6 +298,7 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu
|
||||
col := new(core.Column)
|
||||
col.Indexes = make(map[string]bool)
|
||||
col.Nullable = true
|
||||
col.DefaultIsEmpty = true
|
||||
for idx, field := range fields {
|
||||
if idx == 0 {
|
||||
col.Name = strings.Trim(field, "`[] ")
|
||||
@ -315,8 +317,14 @@ func (db *sqlite3) GetColumns(tableName string) ([]string, map[string]*core.Colu
|
||||
} else {
|
||||
col.Nullable = true
|
||||
}
|
||||
case "DEFAULT":
|
||||
col.Default = fields[idx+1]
|
||||
col.DefaultIsEmpty = false
|
||||
}
|
||||
}
|
||||
if !col.SQLType.IsNumeric() && !col.DefaultIsEmpty {
|
||||
col.Default = "'" + col.Default + "'"
|
||||
}
|
||||
cols[col.Name] = col
|
||||
colSeq = append(colSeq, col.Name)
|
||||
}
|
||||
@ -366,15 +374,16 @@ func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error)
|
||||
|
||||
indexes := make(map[string]*core.Index, 0)
|
||||
for rows.Next() {
|
||||
var sql string
|
||||
err = rows.Scan(&sql)
|
||||
var tmpSql sql.NullString
|
||||
err = rows.Scan(&tmpSql)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if sql == "" {
|
||||
if !tmpSql.Valid {
|
||||
continue
|
||||
}
|
||||
sql := tmpSql.String
|
||||
|
||||
index := new(core.Index)
|
||||
nNStart := strings.Index(sql, "INDEX")
|
||||
@ -384,7 +393,6 @@ func (db *sqlite3) GetIndexes(tableName string) (map[string]*core.Index, error)
|
||||
}
|
||||
|
||||
indexName := strings.Trim(sql[nNStart+6:nNEnd], "` []")
|
||||
//fmt.Println(indexName)
|
||||
if strings.HasPrefix(indexName, "IDX_"+tableName) || strings.HasPrefix(indexName, "UQE_"+tableName) {
|
||||
index.Name = indexName[5+len(tableName) : len(indexName)]
|
||||
} else {
|
||||
|
114
Godeps/_workspace/src/github.com/go-xorm/xorm/statement.go
generated
vendored
114
Godeps/_workspace/src/github.com/go-xorm/xorm/statement.go
generated
vendored
@ -26,6 +26,11 @@ type decrParam struct {
|
||||
arg interface{}
|
||||
}
|
||||
|
||||
type exprParam struct {
|
||||
colName string
|
||||
expr string
|
||||
}
|
||||
|
||||
// statement save all the sql info for executing SQL
|
||||
type Statement struct {
|
||||
RefTable *core.Table
|
||||
@ -63,6 +68,7 @@ type Statement struct {
|
||||
inColumns map[string]*inParam
|
||||
incrColumns map[string]incrParam
|
||||
decrColumns map[string]decrParam
|
||||
exprColumns map[string]exprParam
|
||||
}
|
||||
|
||||
// init
|
||||
@ -98,6 +104,7 @@ func (statement *Statement) Init() {
|
||||
statement.inColumns = make(map[string]*inParam)
|
||||
statement.incrColumns = make(map[string]incrParam)
|
||||
statement.decrColumns = make(map[string]decrParam)
|
||||
statement.exprColumns = make(map[string]exprParam)
|
||||
}
|
||||
|
||||
// add the raw sql statement
|
||||
@ -153,9 +160,6 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.String {
|
||||
statement.AltTableName = tableNameOrBean.(string)
|
||||
if statement.AltTableName[0] == '~' {
|
||||
statement.AltTableName = statement.Engine.TableMapper.TableName(statement.AltTableName[1:])
|
||||
}
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
statement.RefTable = statement.Engine.autoMapType(v)
|
||||
}
|
||||
@ -282,7 +286,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||
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, update bool) ([]string, []interface{}) {
|
||||
mustColumnMap map[string]bool, columnMap map[string]bool, update bool) ([]string, []interface{}) {
|
||||
|
||||
colNames := make([]string, 0)
|
||||
var args = make([]interface{}, 0)
|
||||
@ -302,6 +306,9 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
if col.IsDeleted {
|
||||
continue
|
||||
}
|
||||
if use, ok := columnMap[col.Name]; ok && !use {
|
||||
continue
|
||||
}
|
||||
|
||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
||||
continue
|
||||
@ -414,13 +421,16 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||
if table, ok := engine.Tables[fieldValue.Type()]; ok {
|
||||
if len(table.PrimaryKeys) == 1 {
|
||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||
if pkField.Int() != 0 {
|
||||
// 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("not supported")
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
@ -579,24 +589,29 @@ func buildConditions(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 _, ok := reflect.New(fieldType).Interface().(core.Conversion); ok {
|
||||
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)
|
||||
if pkField.Int() != 0 {
|
||||
// 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("not supported")
|
||||
}
|
||||
} else {
|
||||
val = fieldValue.Interface()
|
||||
@ -716,6 +731,13 @@ func (statement *Statement) Decr(column string, arg ...interface{}) *Statement {
|
||||
return statement
|
||||
}
|
||||
|
||||
// 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}
|
||||
return statement
|
||||
}
|
||||
|
||||
// Generate "Update ... Set column = column + arg" statment
|
||||
func (statement *Statement) getInc() map[string]incrParam {
|
||||
return statement.incrColumns
|
||||
@ -726,6 +748,11 @@ func (statement *Statement) getDec() map[string]decrParam {
|
||||
return statement.decrColumns
|
||||
}
|
||||
|
||||
// Generate "Update ... Set column = {expression}" statment
|
||||
func (statement *Statement) getExpr() map[string]exprParam {
|
||||
return statement.exprColumns
|
||||
}
|
||||
|
||||
// Generate "Where column IN (?) " statment
|
||||
func (statement *Statement) In(column string, args ...interface{}) *Statement {
|
||||
k := strings.ToLower(column)
|
||||
@ -941,15 +968,9 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
||||
l := len(t)
|
||||
if l > 1 {
|
||||
table := t[0]
|
||||
if table[0] == '~' {
|
||||
table = statement.Engine.TableMapper.TableName(table[1:])
|
||||
}
|
||||
joinTable = statement.Engine.Quote(table) + " AS " + statement.Engine.Quote(t[1])
|
||||
} else if l == 1 {
|
||||
table := t[0]
|
||||
if table[0] == '~' {
|
||||
table = statement.Engine.TableMapper.TableName(table[1:])
|
||||
}
|
||||
joinTable = statement.Engine.Quote(table)
|
||||
}
|
||||
case []interface{}:
|
||||
@ -962,9 +983,6 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
||||
t := v.Type()
|
||||
if t.Kind() == reflect.String {
|
||||
table = f.(string)
|
||||
if table[0] == '~' {
|
||||
table = statement.Engine.TableMapper.TableName(table[1:])
|
||||
}
|
||||
} else if t.Kind() == reflect.Struct {
|
||||
r := statement.Engine.autoMapType(v)
|
||||
table = r.Name
|
||||
@ -977,9 +995,6 @@ func (statement *Statement) Join(join_operator string, tablename interface{}, co
|
||||
}
|
||||
default:
|
||||
t := fmt.Sprintf("%v", tablename)
|
||||
if t[0] == '~' {
|
||||
t = statement.Engine.TableMapper.TableName(t[1:])
|
||||
}
|
||||
joinTable = statement.Engine.Quote(t)
|
||||
}
|
||||
if statement.JoinStr != "" {
|
||||
@ -1105,9 +1120,10 @@ func (s *Statement) genDelIndexSQL() []string {
|
||||
return sqls
|
||||
}
|
||||
|
||||
/*
|
||||
func (s *Statement) genDropSQL() string {
|
||||
return s.Engine.dialect.DropTableSql(s.TableName()) + ";"
|
||||
}
|
||||
return s.Engine.dialect.MustDropTa(s.TableName()) + ";"
|
||||
}*/
|
||||
|
||||
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) {
|
||||
var table *core.Table
|
||||
@ -1126,13 +1142,21 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
|
||||
statement.BeanArgs = args
|
||||
|
||||
var columnStr string = statement.ColumnStr
|
||||
if statement.JoinStr == "" {
|
||||
if columnStr == "" {
|
||||
columnStr = statement.genColumnStr()
|
||||
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 columnStr == "" {
|
||||
columnStr = "*"
|
||||
if len(columnStr) == 0 {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
} else {
|
||||
columnStr = "*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1178,14 +1202,16 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
|
||||
id = ""
|
||||
}
|
||||
statement.attachInSql()
|
||||
return statement.genSelectSql(fmt.Sprintf("count(%v) AS %v", id, statement.Engine.Quote("total"))), append(statement.Params, statement.BeanArgs...)
|
||||
return statement.genSelectSql(fmt.Sprintf("count(%v)", id)), append(statement.Params, statement.BeanArgs...)
|
||||
}
|
||||
|
||||
func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
if statement.GroupByStr != "" {
|
||||
columnStr = statement.Engine.Quote(strings.Replace(statement.GroupByStr, ",", statement.Engine.Quote(","), -1))
|
||||
statement.GroupByStr = columnStr
|
||||
}
|
||||
/*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 "
|
||||
@ -1210,7 +1236,11 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
}
|
||||
var fromStr string = " FROM " + statement.Engine.Quote(statement.TableName())
|
||||
if statement.TableAlias != "" {
|
||||
fromStr += " AS " + statement.Engine.Quote(statement.TableAlias)
|
||||
if statement.Engine.dialect.DBType() == core.ORACLE {
|
||||
fromStr += " " + statement.Engine.Quote(statement.TableAlias)
|
||||
} else {
|
||||
fromStr += " AS " + statement.Engine.Quote(statement.TableAlias)
|
||||
}
|
||||
}
|
||||
if statement.JoinStr != "" {
|
||||
fromStr = fmt.Sprintf("%v %v", fromStr, statement.JoinStr)
|
||||
@ -1233,8 +1263,16 @@ func (statement *Statement) genSelectSql(columnStr string) (a string) {
|
||||
column = statement.RefTable.ColumnsSeq()[0]
|
||||
}
|
||||
}
|
||||
mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s))",
|
||||
column, statement.Start, column, fromStr, whereStr)
|
||||
var orderStr string
|
||||
if len(statement.OrderStr) > 0 {
|
||||
orderStr = " ORDER BY " + statement.OrderStr
|
||||
}
|
||||
var groupStr string
|
||||
if len(statement.GroupByStr) > 0 {
|
||||
groupStr = " GROUP BY " + statement.GroupByStr
|
||||
}
|
||||
mssqlCondi = fmt.Sprintf("(%s NOT IN (SELECT TOP %d %s%s%s%s%s))",
|
||||
column, statement.Start, column, fromStr, whereStr, orderStr, groupStr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1258,12 +1296,16 @@ 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 {
|
||||
if statement.Engine.dialect.DBType() != core.MSSQL && statement.Engine.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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
|
13
Godeps/_workspace/src/github.com/go-xorm/xorm/xorm.go
generated
vendored
13
Godeps/_workspace/src/github.com/go-xorm/xorm/xorm.go
generated
vendored
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
Version string = "0.4.1"
|
||||
Version string = "0.4.2.0225"
|
||||
)
|
||||
|
||||
func regDrvsNDialects() bool {
|
||||
@ -84,17 +84,16 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) {
|
||||
TZLocation: time.Local,
|
||||
}
|
||||
|
||||
engine.dialect.SetLogger(engine.Logger)
|
||||
|
||||
engine.SetMapper(core.NewCacheMapper(new(core.SnakeMapper)))
|
||||
|
||||
//engine.Filters = dialect.Filters()
|
||||
//engine.Cacher = NewLRUCacher()
|
||||
//err = engine.SetPool(NewSysConnectPool())
|
||||
|
||||
runtime.SetFinalizer(engine, close)
|
||||
return engine, err
|
||||
|
||||
return engine, nil
|
||||
}
|
||||
|
||||
// clone an engine
|
||||
func (engine *Engine) Clone() (*Engine, error) {
|
||||
return NewEngine(engine.dialect.DriverName(), engine.dialect.DataSourceName())
|
||||
return NewEngine(engine.DriverName(), engine.DataSourceName())
|
||||
}
|
||||
|
8
Godeps/_workspace/src/github.com/mattn/go-sqlite3/README.md
generated
vendored
8
Godeps/_workspace/src/github.com/mattn/go-sqlite3/README.md
generated
vendored
@ -41,12 +41,18 @@ FAQ
|
||||
> See: https://github.com/mattn/go-sqlite3/issues/106
|
||||
> See also: http://www.limitlessfx.com/cross-compile-golang-app-for-windows-from-linux.html
|
||||
|
||||
* Want to get time.Time with current locale
|
||||
|
||||
Use `loc=auto` in SQLite3 filename schema like `file:foo.db?loc=auto`.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT: http://mattn.mit-license.org/2012
|
||||
|
||||
sqlite.c, sqlite3.h, sqlite3ext.h
|
||||
sqlite3-binding.c, sqlite3-binding.h, sqlite3ext.h
|
||||
|
||||
The -binding suffix was added to avoid build failures under gccgo.
|
||||
|
||||
In this repository, those files are amalgamation code that copied from SQLite3. The license of those codes are depend on the license of SQLite3.
|
||||
|
||||
|
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/backup.go
generated
vendored
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/backup.go
generated
vendored
@ -6,7 +6,7 @@
|
||||
package sqlite3
|
||||
|
||||
/*
|
||||
#include <sqlite3.h>
|
||||
#include <sqlite3-binding.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
|
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/error_test.go
generated
vendored
6
Godeps/_workspace/src/github.com/mattn/go-sqlite3/error_test.go
generated
vendored
@ -231,6 +231,12 @@ func TestExtendedErrorCodes_Unique(t *testing.T) {
|
||||
t.Errorf("Wrong extended error code: %d != %d",
|
||||
sqliteErr.ExtendedCode, ErrConstraintUnique)
|
||||
}
|
||||
extended := sqliteErr.Code.Extend(3).Error()
|
||||
expected := "constraint failed"
|
||||
if extended != expected {
|
||||
t.Errorf("Wrong basic error code: %q != %q",
|
||||
extended, expected)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
188
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
188
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
@ -6,7 +6,10 @@
|
||||
package sqlite3
|
||||
|
||||
/*
|
||||
#include <sqlite3.h>
|
||||
#cgo CFLAGS: -std=gnu99
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS
|
||||
#include <sqlite3-binding.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -44,14 +47,23 @@ _sqlite3_bind_blob(sqlite3_stmt *stmt, int n, void *p, int np) {
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static long
|
||||
_sqlite3_last_insert_rowid(sqlite3* db) {
|
||||
return (long) sqlite3_last_insert_rowid(db);
|
||||
static int
|
||||
_sqlite3_exec(sqlite3* db, const char* pcmd, long* rowid, long* changes)
|
||||
{
|
||||
int rv = sqlite3_exec(db, pcmd, 0, 0, 0);
|
||||
*rowid = (long) sqlite3_last_insert_rowid(db);
|
||||
*changes = (long) sqlite3_changes(db);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static long
|
||||
_sqlite3_changes(sqlite3* db) {
|
||||
return (long) sqlite3_changes(db);
|
||||
static int
|
||||
_sqlite3_step(sqlite3_stmt* stmt, long* rowid, long* changes)
|
||||
{
|
||||
int rv = sqlite3_step(stmt);
|
||||
sqlite3* db = sqlite3_db_handle(stmt);
|
||||
*rowid = (long) sqlite3_last_insert_rowid(db);
|
||||
*changes = (long) sqlite3_changes(db);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*/
|
||||
@ -60,8 +72,11 @@ import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
@ -102,7 +117,8 @@ type SQLiteDriver struct {
|
||||
|
||||
// Conn struct.
|
||||
type SQLiteConn struct {
|
||||
db *C.sqlite3
|
||||
db *C.sqlite3
|
||||
loc *time.Location
|
||||
}
|
||||
|
||||
// Tx struct.
|
||||
@ -114,6 +130,8 @@ type SQLiteTx struct {
|
||||
type SQLiteStmt struct {
|
||||
c *SQLiteConn
|
||||
s *C.sqlite3_stmt
|
||||
nv int
|
||||
nn []string
|
||||
t string
|
||||
closed bool
|
||||
cls bool
|
||||
@ -174,7 +192,7 @@ func (c *SQLiteConn) Exec(query string, args []driver.Value) (driver.Result, err
|
||||
if s.(*SQLiteStmt).s != nil {
|
||||
na := s.NumInput()
|
||||
if len(args) < na {
|
||||
return nil, errors.New("args is not enough to execute query")
|
||||
return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args))
|
||||
}
|
||||
res, err = s.Exec(args[:na])
|
||||
if err != nil && err != driver.ErrSkip {
|
||||
@ -201,6 +219,9 @@ func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
||||
}
|
||||
s.(*SQLiteStmt).cls = true
|
||||
na := s.NumInput()
|
||||
if len(args) < na {
|
||||
return nil, fmt.Errorf("Not enough args to execute query. Expected %d, got %d.", na, len(args))
|
||||
}
|
||||
rows, err := s.Query(args[:na])
|
||||
if err != nil && err != driver.ErrSkip {
|
||||
s.Close()
|
||||
@ -220,14 +241,13 @@ func (c *SQLiteConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
||||
func (c *SQLiteConn) exec(cmd string) (driver.Result, error) {
|
||||
pcmd := C.CString(cmd)
|
||||
defer C.free(unsafe.Pointer(pcmd))
|
||||
rv := C.sqlite3_exec(c.db, pcmd, nil, nil, nil)
|
||||
|
||||
var rowid, changes C.long
|
||||
rv := C._sqlite3_exec(c.db, pcmd, &rowid, &changes)
|
||||
if rv != C.SQLITE_OK {
|
||||
return nil, c.lastError()
|
||||
}
|
||||
return &SQLiteResult{
|
||||
int64(C._sqlite3_last_insert_rowid(c.db)),
|
||||
int64(C._sqlite3_changes(c.db)),
|
||||
}, nil
|
||||
return &SQLiteResult{int64(rowid), int64(changes)}, nil
|
||||
}
|
||||
|
||||
// Begin transaction.
|
||||
@ -248,11 +268,51 @@ func errorString(err Error) string {
|
||||
// file:test.db?cache=shared&mode=memory
|
||||
// :memory:
|
||||
// file::memory:
|
||||
// go-sqlite handle especially query parameters.
|
||||
// _loc=XXX
|
||||
// Specify location of time format. It's possible to specify "auto".
|
||||
// _busy_timeout=XXX
|
||||
// Specify value for sqlite3_busy_timeout.
|
||||
func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
if C.sqlite3_threadsafe() == 0 {
|
||||
return nil, errors.New("sqlite library was not compiled for thread-safe operation")
|
||||
}
|
||||
|
||||
var loc *time.Location
|
||||
busy_timeout := 5000
|
||||
pos := strings.IndexRune(dsn, '?')
|
||||
if pos >= 1 {
|
||||
params, err := url.ParseQuery(dsn[pos+1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// _loc
|
||||
if val := params.Get("_loc"); val != "" {
|
||||
if val == "auto" {
|
||||
loc = time.Local
|
||||
} else {
|
||||
loc, err = time.LoadLocation(val)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Invalid _loc: %v: %v", val, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _busy_timeout
|
||||
if val := params.Get("_busy_timeout"); val != "" {
|
||||
iv, err := strconv.ParseInt(val, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err)
|
||||
}
|
||||
busy_timeout = int(iv)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(dsn, "file:") {
|
||||
dsn = dsn[:pos]
|
||||
}
|
||||
}
|
||||
|
||||
var db *C.sqlite3
|
||||
name := C.CString(dsn)
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
@ -268,12 +328,12 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
return nil, errors.New("sqlite succeeded without returning a database")
|
||||
}
|
||||
|
||||
rv = C.sqlite3_busy_timeout(db, 5000)
|
||||
rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout))
|
||||
if rv != C.SQLITE_OK {
|
||||
return nil, Error{Code: ErrNo(rv)}
|
||||
}
|
||||
|
||||
conn := &SQLiteConn{db}
|
||||
conn := &SQLiteConn{db: db, loc: loc}
|
||||
|
||||
if len(d.Extensions) > 0 {
|
||||
rv = C.sqlite3_enable_load_extension(db, 1)
|
||||
@ -281,21 +341,15 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||
return nil, errors.New(C.GoString(C.sqlite3_errmsg(db)))
|
||||
}
|
||||
|
||||
stmt, err := conn.Prepare("SELECT load_extension(?);")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, extension := range d.Extensions {
|
||||
if _, err = stmt.Exec([]driver.Value{extension}); err != nil {
|
||||
return nil, err
|
||||
cext := C.CString(extension)
|
||||
defer C.free(unsafe.Pointer(cext))
|
||||
rv = C.sqlite3_load_extension(db, cext, nil, nil)
|
||||
if rv != C.SQLITE_OK {
|
||||
return nil, errors.New(C.GoString(C.sqlite3_errmsg(db)))
|
||||
}
|
||||
}
|
||||
|
||||
if err = stmt.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rv = C.sqlite3_enable_load_extension(db, 0)
|
||||
if rv != C.SQLITE_OK {
|
||||
return nil, errors.New(C.GoString(C.sqlite3_errmsg(db)))
|
||||
@ -333,10 +387,18 @@ func (c *SQLiteConn) Prepare(query string) (driver.Stmt, error) {
|
||||
return nil, c.lastError()
|
||||
}
|
||||
var t string
|
||||
if tail != nil && C.strlen(tail) > 0 {
|
||||
if tail != nil && *tail != '\000' {
|
||||
t = strings.TrimSpace(C.GoString(tail))
|
||||
}
|
||||
ss := &SQLiteStmt{c: c, s: s, t: t}
|
||||
nv := int(C.sqlite3_bind_parameter_count(s))
|
||||
var nn []string
|
||||
for i := 0; i < nv; i++ {
|
||||
pn := C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1)))
|
||||
if len(pn) > 1 && pn[0] == '$' && 48 <= pn[1] && pn[1] <= 57 {
|
||||
nn = append(nn, C.GoString(C.sqlite3_bind_parameter_name(s, C.int(i+1))))
|
||||
}
|
||||
}
|
||||
ss := &SQLiteStmt{c: c, s: s, nv: nv, nn: nn, t: t}
|
||||
runtime.SetFinalizer(ss, (*SQLiteStmt).Close)
|
||||
return ss, nil
|
||||
}
|
||||
@ -360,7 +422,12 @@ func (s *SQLiteStmt) Close() error {
|
||||
|
||||
// Return a number of parameters.
|
||||
func (s *SQLiteStmt) NumInput() int {
|
||||
return int(C.sqlite3_bind_parameter_count(s.s))
|
||||
return s.nv
|
||||
}
|
||||
|
||||
type bindArg struct {
|
||||
n int
|
||||
v driver.Value
|
||||
}
|
||||
|
||||
func (s *SQLiteStmt) bind(args []driver.Value) error {
|
||||
@ -369,8 +436,24 @@ func (s *SQLiteStmt) bind(args []driver.Value) error {
|
||||
return s.c.lastError()
|
||||
}
|
||||
|
||||
for i, v := range args {
|
||||
n := C.int(i + 1)
|
||||
var vargs []bindArg
|
||||
narg := len(args)
|
||||
vargs = make([]bindArg, narg)
|
||||
if len(s.nn) > 0 {
|
||||
for i, v := range s.nn {
|
||||
if pi, err := strconv.Atoi(v[1:]); err == nil {
|
||||
vargs[i] = bindArg{pi, args[i]}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i, v := range args {
|
||||
vargs[i] = bindArg{i + 1, v}
|
||||
}
|
||||
}
|
||||
|
||||
for _, varg := range vargs {
|
||||
n := C.int(varg.n)
|
||||
v := varg.v
|
||||
switch v := v.(type) {
|
||||
case nil:
|
||||
rv = C.sqlite3_bind_null(s.s, n)
|
||||
@ -431,19 +514,18 @@ func (r *SQLiteResult) RowsAffected() (int64, error) {
|
||||
func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
if err := s.bind(args); err != nil {
|
||||
C.sqlite3_reset(s.s)
|
||||
C.sqlite3_clear_bindings(s.s)
|
||||
return nil, err
|
||||
}
|
||||
rv := C.sqlite3_step(s.s)
|
||||
var rowid, changes C.long
|
||||
rv := C._sqlite3_step(s.s, &rowid, &changes)
|
||||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
||||
err := s.c.lastError()
|
||||
C.sqlite3_reset(s.s)
|
||||
return nil, s.c.lastError()
|
||||
C.sqlite3_clear_bindings(s.s)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &SQLiteResult{
|
||||
int64(C._sqlite3_last_insert_rowid(s.c.db)),
|
||||
int64(C._sqlite3_changes(s.c.db)),
|
||||
}
|
||||
return res, nil
|
||||
return &SQLiteResult{int64(rowid), int64(changes)}, nil
|
||||
}
|
||||
|
||||
// Close the rows.
|
||||
@ -499,7 +581,22 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||
val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i)))
|
||||
switch rc.decltype[i] {
|
||||
case "timestamp", "datetime", "date":
|
||||
dest[i] = time.Unix(val, 0).Local()
|
||||
unixTimestamp := strconv.FormatInt(val, 10)
|
||||
var t time.Time
|
||||
if len(unixTimestamp) == 13 {
|
||||
duration, err := time.ParseDuration(unixTimestamp + "ms")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing %s value %d, %s", rc.decltype[i], val, err)
|
||||
}
|
||||
epoch := time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
t = epoch.Add(duration)
|
||||
} else {
|
||||
t = time.Unix(val, 0)
|
||||
}
|
||||
if rc.s.c.loc != nil {
|
||||
t = t.In(rc.s.c.loc)
|
||||
}
|
||||
dest[i] = t
|
||||
case "boolean":
|
||||
dest[i] = val > 0
|
||||
default:
|
||||
@ -531,16 +628,21 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||
|
||||
switch rc.decltype[i] {
|
||||
case "timestamp", "datetime", "date":
|
||||
var t time.Time
|
||||
for _, format := range SQLiteTimestampFormats {
|
||||
if timeVal, err = time.ParseInLocation(format, s, time.UTC); err == nil {
|
||||
dest[i] = timeVal.Local()
|
||||
t = timeVal
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
// The column is a time value, so return the zero time on parse failure.
|
||||
dest[i] = time.Time{}
|
||||
t = time.Time{}
|
||||
}
|
||||
if rc.s.c.loc != nil {
|
||||
t = t.In(rc.s.c.loc)
|
||||
}
|
||||
dest[i] = t
|
||||
default:
|
||||
dest[i] = []byte(s)
|
||||
}
|
||||
|
83
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_fts3_test.go
generated
vendored
Normal file
83
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_fts3_test.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright (C) 2015 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||
//
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package sqlite3
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFTS3(t *testing.T) {
|
||||
tempFilename := TempFilename()
|
||||
db, err := sql.Open("sqlite3", tempFilename)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer os.Remove(tempFilename)
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("DROP TABLE foo")
|
||||
_, err = db.Exec("CREATE VIRTUAL TABLE foo USING fts3(id INTEGER PRIMARY KEY, value TEXT)")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create table:", err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("INSERT INTO foo(id, value) VALUES(?, ?)", 1, `今日の 晩御飯は 天麩羅よ`)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert value:", err)
|
||||
}
|
||||
|
||||
_, err = db.Exec("INSERT INTO foo(id, value) VALUES(?, ?)", 2, `今日は いい 天気だ`)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert value:", err)
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT id, value FROM foo WHERE value MATCH '今日* 天*'")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to query foo table:", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var value string
|
||||
|
||||
if err := rows.Scan(&id, &value); err != nil {
|
||||
t.Error("Unable to scan results:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if id == 1 && value != `今日の 晩御飯は 天麩羅よ` {
|
||||
t.Error("Value for id 1 should be `今日の 晩御飯は 天麩羅よ`, but:", value)
|
||||
} else if id == 2 && value != `今日は いい 天気だ` {
|
||||
t.Error("Value for id 2 should be `今日は いい 天気だ`, but:", value)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err = db.Query("SELECT value FROM foo WHERE value MATCH '今日* 天麩羅*'")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to query foo table:", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var value string
|
||||
if !rows.Next() {
|
||||
t.Fatal("Result should be only one")
|
||||
}
|
||||
|
||||
if err := rows.Scan(&value); err != nil {
|
||||
t.Fatal("Unable to scan results:", err)
|
||||
}
|
||||
|
||||
if value != `今日の 晩御飯は 天麩羅よ` {
|
||||
t.Fatal("Value should be `今日の 晩御飯は 天麩羅よ`, but:", value)
|
||||
}
|
||||
|
||||
if rows.Next() {
|
||||
t.Fatal("Result should be only one")
|
||||
}
|
||||
}
|
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
@ -9,6 +9,6 @@ package sqlite3
|
||||
/*
|
||||
#cgo CFLAGS: -I.
|
||||
#cgo linux LDFLAGS: -ldl
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE
|
||||
#cgo LDFLAGS: -lpthread
|
||||
*/
|
||||
import "C"
|
||||
|
203
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test.go
generated
vendored
203
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_test.go
generated
vendored
@ -9,8 +9,10 @@ import (
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -309,6 +311,7 @@ func TestTimestamp(t *testing.T) {
|
||||
{"0000-00-00 00:00:00", time.Time{}},
|
||||
{timestamp1, timestamp1},
|
||||
{timestamp1.Unix(), timestamp1},
|
||||
{timestamp1.UnixNano() / int64(time.Millisecond), timestamp1},
|
||||
{timestamp1.In(time.FixedZone("TEST", -7*3600)), timestamp1},
|
||||
{timestamp1.Format("2006-01-02 15:04:05.000"), timestamp1},
|
||||
{timestamp1.Format("2006-01-02T15:04:05.000"), timestamp1},
|
||||
@ -633,6 +636,102 @@ func TestWAL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimezoneConversion(t *testing.T) {
|
||||
zones := []string{"UTC", "US/Central", "US/Pacific", "Local"}
|
||||
for _, tz := range zones {
|
||||
tempFilename := TempFilename()
|
||||
db, err := sql.Open("sqlite3", tempFilename+"?_loc="+url.QueryEscape(tz))
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer os.Remove(tempFilename)
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec("DROP TABLE foo")
|
||||
_, err = db.Exec("CREATE TABLE foo(id INTEGER, ts TIMESTAMP, dt DATETIME)")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to create table:", err)
|
||||
}
|
||||
|
||||
loc, err := time.LoadLocation(tz)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to load location:", err)
|
||||
}
|
||||
|
||||
timestamp1 := time.Date(2012, time.April, 6, 22, 50, 0, 0, time.UTC)
|
||||
timestamp2 := time.Date(2006, time.January, 2, 15, 4, 5, 123456789, time.UTC)
|
||||
timestamp3 := time.Date(2012, time.November, 4, 0, 0, 0, 0, time.UTC)
|
||||
tests := []struct {
|
||||
value interface{}
|
||||
expected time.Time
|
||||
}{
|
||||
{"nonsense", time.Time{}.In(loc)},
|
||||
{"0000-00-00 00:00:00", time.Time{}.In(loc)},
|
||||
{timestamp1, timestamp1.In(loc)},
|
||||
{timestamp1.Unix(), timestamp1.In(loc)},
|
||||
{timestamp1.In(time.FixedZone("TEST", -7*3600)), timestamp1.In(loc)},
|
||||
{timestamp1.Format("2006-01-02 15:04:05.000"), timestamp1.In(loc)},
|
||||
{timestamp1.Format("2006-01-02T15:04:05.000"), timestamp1.In(loc)},
|
||||
{timestamp1.Format("2006-01-02 15:04:05"), timestamp1.In(loc)},
|
||||
{timestamp1.Format("2006-01-02T15:04:05"), timestamp1.In(loc)},
|
||||
{timestamp2, timestamp2.In(loc)},
|
||||
{"2006-01-02 15:04:05.123456789", timestamp2.In(loc)},
|
||||
{"2006-01-02T15:04:05.123456789", timestamp2.In(loc)},
|
||||
{"2012-11-04", timestamp3.In(loc)},
|
||||
{"2012-11-04 00:00", timestamp3.In(loc)},
|
||||
{"2012-11-04 00:00:00", timestamp3.In(loc)},
|
||||
{"2012-11-04 00:00:00.000", timestamp3.In(loc)},
|
||||
{"2012-11-04T00:00", timestamp3.In(loc)},
|
||||
{"2012-11-04T00:00:00", timestamp3.In(loc)},
|
||||
{"2012-11-04T00:00:00.000", timestamp3.In(loc)},
|
||||
}
|
||||
for i := range tests {
|
||||
_, err = db.Exec("INSERT INTO foo(id, ts, dt) VALUES(?, ?, ?)", i, tests[i].value, tests[i].value)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to insert timestamp:", err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := db.Query("SELECT id, ts, dt FROM foo ORDER BY id ASC")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to query foo table:", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
seen := 0
|
||||
for rows.Next() {
|
||||
var id int
|
||||
var ts, dt time.Time
|
||||
|
||||
if err := rows.Scan(&id, &ts, &dt); err != nil {
|
||||
t.Error("Unable to scan results:", err)
|
||||
continue
|
||||
}
|
||||
if id < 0 || id >= len(tests) {
|
||||
t.Error("Bad row id: ", id)
|
||||
continue
|
||||
}
|
||||
seen++
|
||||
if !tests[id].expected.Equal(ts) {
|
||||
t.Errorf("Timestamp value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, ts)
|
||||
}
|
||||
if !tests[id].expected.Equal(dt) {
|
||||
t.Errorf("Datetime value for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected, dt)
|
||||
}
|
||||
if tests[id].expected.Location().String() != ts.Location().String() {
|
||||
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), ts.Location().String())
|
||||
}
|
||||
if tests[id].expected.Location().String() != dt.Location().String() {
|
||||
t.Errorf("Location for id %v (%v) should be %v, not %v", id, tests[id].value, tests[id].expected.Location().String(), dt.Location().String())
|
||||
}
|
||||
}
|
||||
|
||||
if seen != len(tests) {
|
||||
t.Errorf("Expected to see %d rows", len(tests))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSuite(t *testing.T) {
|
||||
db, err := sql.Open("sqlite3", ":memory:")
|
||||
if err != nil {
|
||||
@ -742,3 +841,107 @@ func TestStress(t *testing.T) {
|
||||
db.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateTimeLocal(t *testing.T) {
|
||||
zone := "Asia/Tokyo"
|
||||
tempFilename := TempFilename()
|
||||
db, err := sql.Open("sqlite3", tempFilename+"?_loc="+zone)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
db.Exec("CREATE TABLE foo (dt datetime);")
|
||||
db.Exec("INSERT INTO foo VALUES('2015-03-05 15:16:17');")
|
||||
|
||||
row := db.QueryRow("select * from foo")
|
||||
var d time.Time
|
||||
err = row.Scan(&d)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to scan datetime:", err)
|
||||
}
|
||||
if d.Hour() == 15 || !strings.Contains(d.String(), "JST") {
|
||||
t.Fatal("Result should have timezone", d)
|
||||
}
|
||||
db.Close()
|
||||
|
||||
db, err = sql.Open("sqlite3", tempFilename)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
|
||||
row = db.QueryRow("select * from foo")
|
||||
err = row.Scan(&d)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to scan datetime:", err)
|
||||
}
|
||||
if d.UTC().Hour() != 15 || !strings.Contains(d.String(), "UTC") {
|
||||
t.Fatalf("Result should not have timezone %v %v", zone, d.String())
|
||||
}
|
||||
|
||||
_, err = db.Exec("DELETE FROM foo")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to delete table:", err)
|
||||
}
|
||||
dt, err := time.Parse("2006/1/2 15/4/5 -0700 MST", "2015/3/5 15/16/17 +0900 JST")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to parse datetime:", err)
|
||||
}
|
||||
db.Exec("INSERT INTO foo VALUES(?);", dt)
|
||||
|
||||
db.Close()
|
||||
db, err = sql.Open("sqlite3", tempFilename+"?_loc="+zone)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
|
||||
row = db.QueryRow("select * from foo")
|
||||
err = row.Scan(&d)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to scan datetime:", err)
|
||||
}
|
||||
if d.Hour() != 15 || !strings.Contains(d.String(), "JST") {
|
||||
t.Fatalf("Result should have timezone %v %v", zone, d.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersion(t *testing.T) {
|
||||
s, n, id := Version()
|
||||
if s == "" || n == 0 || id == "" {
|
||||
t.Errorf("Version failed %q, %d, %q\n", s, n, id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNumberNamedParams(t *testing.T) {
|
||||
tempFilename := TempFilename()
|
||||
db, err := sql.Open("sqlite3", tempFilename)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer os.Remove(tempFilename)
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec(`
|
||||
create table foo (id integer, name text, extra text);
|
||||
`)
|
||||
if err != nil {
|
||||
t.Error("Failed to call db.Query:", err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(`insert into foo(id, name, extra) values($1, $2, $2)`, 1, "foo")
|
||||
if err != nil {
|
||||
t.Error("Failed to call db.Exec:", err)
|
||||
}
|
||||
|
||||
row := db.QueryRow(`select id, extra from foo where id = $1 and extra = $2`, 1, "foo")
|
||||
if row == nil {
|
||||
t.Error("Failed to call db.QueryRow")
|
||||
}
|
||||
var id int
|
||||
var extra string
|
||||
err = row.Scan(&id, &extra)
|
||||
if err != nil {
|
||||
t.Error("Failed to db.Scan:", err)
|
||||
}
|
||||
if id != 1 || extra != "foo" {
|
||||
t.Error("Failed to db.QueryRow: not matched results")
|
||||
}
|
||||
}
|
||||
|
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_windows.go
generated
vendored
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3_windows.go
generated
vendored
@ -2,6 +2,7 @@
|
||||
//
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
// +build windows
|
||||
|
||||
package sqlite3
|
||||
|
||||
@ -9,6 +10,5 @@ package sqlite3
|
||||
#cgo CFLAGS: -I. -fno-stack-check -fno-stack-protector -mno-stack-arg-probe
|
||||
#cgo windows,386 CFLAGS: -D_localtime32=localtime
|
||||
#cgo LDFLAGS: -lmingwex -lmingw32
|
||||
#cgo CFLAGS: -DSQLITE_ENABLE_RTREE -DSQLITE_THREADSAFE
|
||||
*/
|
||||
import "C"
|
||||
|
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
2
Godeps/_workspace/src/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
@ -17,7 +17,7 @@
|
||||
*/
|
||||
#ifndef _SQLITE3EXT_H_
|
||||
#define _SQLITE3EXT_H_
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite3-binding.h"
|
||||
|
||||
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user