add BeforeSet processor and Dump function
This commit is contained in:
parent
93209fa5b2
commit
9e147d2fde
72
engine.go
72
engine.go
|
@ -6,6 +6,7 @@ import (
|
|||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
@ -265,6 +266,77 @@ func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
|||
return tables, nil
|
||||
}
|
||||
|
||||
func (engine *Engine) DumpAllToFile(fp string) error {
|
||||
f, err := os.Create(fp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
return engine.DumpAll(f)
|
||||
}
|
||||
|
||||
func (engine *Engine) DumpAll(w io.Writer) error {
|
||||
tables, err := engine.DBMetas()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
_, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", "", "")+"\n\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, index := range table.Indexes {
|
||||
_, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+"\n\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := engine.DB().Query("SELECT * FROM " + engine.Quote(table.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cols, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(cols) == 0 {
|
||||
continue
|
||||
}
|
||||
for rows.Next() {
|
||||
dest := make([]interface{}, len(cols))
|
||||
err = rows.ScanSlice(&dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = io.WriteString(w, "INSERT INTO "+engine.Quote(table.Name)+" ("+engine.Quote(strings.Join(cols, engine.Quote(", ")))+") VALUES (")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var temp string
|
||||
for _, d := range dest {
|
||||
if d == nil {
|
||||
temp += ", NULL"
|
||||
} else if reflect.TypeOf(d).Kind() == reflect.String {
|
||||
temp += ", '" + strings.Replace(d.(string), "'", "''", -1) + "'"
|
||||
} else if reflect.TypeOf(d).Kind() == reflect.Slice {
|
||||
temp += fmt.Sprintf(", %s", engine.dialect.FormatBytes(d.([]byte)))
|
||||
} else {
|
||||
temp += fmt.Sprintf(", %v", d)
|
||||
}
|
||||
}
|
||||
_, err = io.WriteString(w, temp[2:]+");\n\n")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// use cascade or not
|
||||
func (engine *Engine) Cascade(trueOrFalse ...bool) *Session {
|
||||
session := engine.NewSession()
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/go-xorm/xorm"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("need db path")
|
||||
return
|
||||
}
|
||||
|
||||
orm, err := xorm.NewEngine("sqlite3", os.Args[1])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
defer orm.Close()
|
||||
orm.ShowSQL = true
|
||||
|
||||
tables, err := orm.DBMetas()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
fmt.Println(table.Name)
|
||||
}
|
||||
}
|
|
@ -15,6 +15,10 @@ type BeforeDeleteProcessor interface {
|
|||
BeforeDelete()
|
||||
}
|
||||
|
||||
type BeforeSetProcessor interface {
|
||||
BeforeSet(string, Cell)
|
||||
}
|
||||
|
||||
// !nashtsai! TODO enable BeforeValidateProcessor when xorm start to support validations
|
||||
//// Executed before an object is validated
|
||||
//type BeforeValidateProcessor interface {
|
||||
|
|
65
session.go
65
session.go
|
@ -883,7 +883,6 @@ func (session *Session) Rows(bean interface{}) (*Rows, error) {
|
|||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||
// map[int64]*Struct
|
||||
func (session *Session) Iterate(bean interface{}, fun IterFunc) error {
|
||||
|
||||
rows, err := session.Rows(bean)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -982,24 +981,6 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
|||
} else {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// resultsSlice, err := session.query(sqlStr, args...)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
// if len(resultsSlice) < 1 {
|
||||
// return false, nil
|
||||
// }
|
||||
|
||||
// err = session.scanMapIntoStruct(bean, resultsSlice[0])
|
||||
// if err != nil {
|
||||
// return true, err
|
||||
// }
|
||||
// if len(resultsSlice) == 1 {
|
||||
// return true, nil
|
||||
// } else {
|
||||
// return true, errors.New("More than one record")
|
||||
// }
|
||||
}
|
||||
|
||||
// Count counts the records. bean's non-empty fields
|
||||
|
@ -1441,6 +1422,8 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c
|
|||
return fieldValue
|
||||
}
|
||||
|
||||
type Cell *interface{}
|
||||
|
||||
func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error {
|
||||
dataStruct := rValue(bean)
|
||||
if dataStruct.Kind() != reflect.Struct {
|
||||
|
@ -1449,18 +1432,24 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
|||
|
||||
table := session.Engine.autoMapType(dataStruct)
|
||||
|
||||
scanResultContainers := make([]interface{}, len(fields))
|
||||
scanResults := make([]interface{}, len(fields))
|
||||
for i := 0; i < len(fields); i++ {
|
||||
var scanResultContainer interface{}
|
||||
scanResultContainers[i] = &scanResultContainer
|
||||
var cell interface{}
|
||||
scanResults[i] = &cell
|
||||
}
|
||||
if err := rows.Scan(scanResultContainers...); err != nil {
|
||||
if err := rows.Scan(scanResults...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, hasBeforeSet := bean.(BeforeSetProcessor)
|
||||
|
||||
for ii, key := range fields {
|
||||
if hasBeforeSet {
|
||||
b.BeforeSet(fields[ii], Cell(scanResults[ii].(*interface{})))
|
||||
}
|
||||
|
||||
if fieldValue := session.getField(&dataStruct, key, table); fieldValue != nil {
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
|
||||
rawValue := reflect.Indirect(reflect.ValueOf(scanResults[ii]))
|
||||
|
||||
//if row is null then ignore
|
||||
if rawValue.Interface() == nil {
|
||||
|
@ -1468,7 +1457,18 @@ func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount i
|
|||
continue
|
||||
}
|
||||
|
||||
if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
|
||||
if fieldValue.CanAddr() {
|
||||
if structConvert, ok := fieldValue.Addr().Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
structConvert.FromDB(data)
|
||||
} else {
|
||||
session.Engine.LogError(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if structConvert, ok := fieldValue.Interface().(core.Conversion); ok {
|
||||
if data, err := value2Bytes(&rawValue); err == nil {
|
||||
structConvert.FromDB(data)
|
||||
} else {
|
||||
|
@ -2451,6 +2451,16 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if fieldConvert, ok := fieldValue.Interface().(core.Conversion); ok {
|
||||
data, err := fieldConvert.ToDB()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else {
|
||||
return string(data), nil
|
||||
}
|
||||
}
|
||||
|
||||
fieldType := fieldValue.Type()
|
||||
k := fieldType.Kind()
|
||||
if k == reflect.Ptr {
|
||||
|
@ -2470,11 +2480,6 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
switch k {
|
||||
case reflect.Bool:
|
||||
return fieldValue.Bool(), nil
|
||||
/*if fieldValue.Bool() {
|
||||
return 1, nil
|
||||
} else {
|
||||
return 0, nil
|
||||
}*/
|
||||
case reflect.String:
|
||||
return fieldValue.String(), nil
|
||||
case reflect.Struct:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package xorm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
|
@ -44,6 +45,10 @@ func (db *sqlite3) SqlType(c *core.Column) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (db *sqlite3) FormatBytes(bs []byte) string {
|
||||
return fmt.Sprintf("X'%x'", bs)
|
||||
}
|
||||
|
||||
func (db *sqlite3) SupportInsertMany() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -451,8 +451,11 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
|
|||
}
|
||||
|
||||
fieldValue := *fieldValuePtr
|
||||
fieldType := reflect.TypeOf(fieldValue.Interface())
|
||||
if fieldValue.Interface() == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldType := reflect.TypeOf(fieldValue.Interface())
|
||||
requiredField := useAllCols
|
||||
if b, ok := mustColumnMap[strings.ToLower(col.Name)]; ok {
|
||||
if b {
|
||||
|
|
Loading…
Reference in New Issue