package dao import ( "errors" "reflect" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/globals" "github.com/astaxie/beego/orm" ) const ( useGetRowsWhenGetRow = true ) type DaoDB struct { db orm.Ormer } // func GetRows(db *gorm.DB, inPtr interface{}, sql string, values ...interface{}) (err error) { // if db == nil { // db = gormdb.GetDB() // } // topTypeInfo := reflect.TypeOf(inPtr) // if topTypeInfo.Kind() != reflect.Ptr { // panic("SelectEntities inPtr should be slice ptr (*[]Type)") // } // typeInfo := topTypeInfo.Elem() // if typeInfo.Kind() != reflect.Slice { // panic("SelectEntities inPtr should be slice ptr (*[]Type)") // } // elmType := typeInfo.Elem() // valueInfo := reflect.ValueOf(inPtr) // rows, err := db.Raw(sql, values...).Rows() // if err == nil { // defer rows.Close() // for rows.Next() { // var value reflect.Value // if elmType.Kind() == reflect.Ptr { // value = reflect.New(elmType.Elem()) // } else { // value = reflect.New(elmType) // } // db.ScanRows(rows, value.Interface()) // if elmType.Kind() != reflect.Ptr { // value = value.Elem() // } // valueInfo.Elem().Set(reflect.Append(valueInfo.Elem(), value)) // } // return nil // } // return err // } // beego orm的对于传代表字段的字串,数据库字段名(完全匹配,区分大小写),结构体字段名(不区分大小写)都可以 func GetDB() *DaoDB { return &DaoDB{db: orm.NewOrm()} } func WrapDB(ormDb orm.Ormer) *DaoDB { return &DaoDB{db: ormDb} } func Begin(db *DaoDB) error { return db.db.Begin() } func Commit(db *DaoDB) error { return db.db.Commit() } func Rollback(db *DaoDB) error { return db.db.Rollback() } func GetRow(db *DaoDB, inPtr interface{}, sql string, values ...interface{}) (err error) { if db == nil { db = GetDB() } if !useGetRowsWhenGetRow { // beego QueryRow有bug,嵌入的struct不能正常绑定 err = db.db.Raw(sql, values).QueryRow(inPtr) } else { typeInfo := reflect.TypeOf(inPtr) if typeInfo.Kind() != reflect.Ptr { return errors.New("inPtr must be ptr") } slice := reflect.New(reflect.SliceOf(typeInfo.Elem())) if err = GetRows(db, slice.Interface(), sql, values...); err == nil { slice = slice.Elem() if slice.Len() > 0 { reflect.ValueOf(inPtr).Elem().Set(slice.Index(0)) } else { return orm.ErrNoRows } } } return err } func GetRows(db *DaoDB, inPtr interface{}, sql string, values ...interface{}) (err error) { if db == nil { db = GetDB() } _, err = db.db.Raw(sql, values).QueryRows(inPtr) return err } func GetEntity(db *DaoDB, item interface{}, cols ...string) (err error) { if db == nil { db = GetDB() } err = utils.CallFuncLogErrorIgnore(func() error { return db.db.Read(item, cols...) }, reflect.TypeOf(item).Name(), orm.ErrNoRows) return err } func UpdateEntity(db *DaoDB, item interface{}, cols ...string) (num int64, err error) { if db == nil { db = GetDB() } num, err = db.db.Update(item, cols...) if err != nil && !IsDuplicateError(err) { globals.SugarLogger.Errorf("UpdateEntity %s failed with error:%v", reflect.TypeOf(item).Name(), err) } return num, err } func CreateEntity(db *DaoDB, item interface{}) (err error) { if db == nil { db = GetDB() } if _, err = db.db.Insert(item); err != nil && !IsDuplicateError(err) { globals.SugarLogger.Errorf("CreateEntity %s failed with error:%v", reflect.TypeOf(item).Name(), err) } return err } func CreateOrUpdate(db *DaoDB, item interface{}, colConflitAndArgs ...string) (err error) { if db == nil { db = GetDB() } _, err = db.db.InsertOrUpdate(item, colConflitAndArgs...) return err } func DeleteEntity(db *DaoDB, item interface{}, cols ...string) (num int64, err error) { if db == nil { db = GetDB() } err = utils.CallFuncLogError(func() error { num, err = db.db.Delete(item, cols...) return err }, reflect.TypeOf(item).Name()) return num, err } func ExecuteSQL(db *DaoDB, sql string, params ...interface{}) (num int64, err error) { if db == nil { db = GetDB() } err = utils.CallFuncLogError(func() error { result, err2 := db.db.Raw(sql, params...).Exec() if err2 == nil { num, _ = result.RowsAffected() } return err2 }, sql) return num, err }