21 Star 41 Fork 9

K. / go-adm

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
result.go 5.77 KB
一键复制 编辑 原始数据 按行查看 历史
package adm
import (
"database/sql"
"git.oschina.net/janpoem/go-agi"
"unsafe"
"time"
"fmt"
"strings"
)
const (
T_STR = iota
T_INT
T_FLOAT
)
type ResultSet struct {
Columns []string
count int
rows []*ResultRow
Error error
}
type ResultRow struct {
rs *ResultSet
values [][]byte
Error error
}
type ExecResult struct {
QueryType QueryType
LastInsertId int64
RowsAffected int64
Error error
}
func NewQueryResult(rawRows *sql.Rows, err error) *ResultSet {
rs := &ResultSet{Error: err }
if err == nil && rawRows != nil {
columns, error := rawRows.Columns()
if error == nil {
rs.Columns = columns
length := len(columns)
rawBytes := make([][]byte, length)
dest := make([]interface{}, length)
for i, _ := range rawBytes {
dest[i] = &rawBytes[i] // Put pointers to each string in the interface slice
}
for rawRows.Next() {
err := rawRows.Scan(dest...)
rs.AddRow(rawBytes, err)
}
rs.count = len(rs.rows)
}
rawRows.Close()
}
return rs
}
func NewExecResult(t QueryType, rs sql.Result, err error) *ExecResult {
result := &ExecResult{QueryType: t, Error: err }
if err == nil {
// 忽略id的错误
id, _ := rs.LastInsertId() // 注意,如果插入行数超过1个,这个id只能代表第一个成功插入的id
rows, err := rs.RowsAffected()
result.Error = err
result.LastInsertId = id
result.RowsAffected = rows
}
return result
}
func (this *ResultSet) AddRow(rawBytes [][]byte, error error) {
newSlice := make([][]byte, len(rawBytes))
copy(newSlice, rawBytes)
this.rows = append(this.rows, &ResultRow{rs: this, values: newSlice, Error: error })
}
func (this *ResultSet) GetErr() error {
return this.Error
}
func (this *ResultSet) HasErr() bool {
return this.Error != nil
}
func (this *ResultSet) Count() int {
return this.count
}
func (this *ResultSet) IsEmpty() bool {
return this.Error != nil || this.count <= 0
}
func (this *ResultSet) Each(fn func(int, *ResultRow)) *ResultSet {
count := this.Count()
if count > 0 {
for i := 0; i < count; i++ {
fn(i, this.rows[i])
}
}
return this
}
func (this *ResultSet) Rows() []*ResultRow {
return this.rows
}
func (this *ResultSet) Row(index int) *ResultRow {
if this.IsEmpty() {
return nil
}
index = agi.OffsetIndex(index, this.count)
return this.rows[index]
}
func (this *ResultSet) ColumnOf(field string) int {
if this.IsEmpty() {
return -1
}
for i, l := 0, len(this.Columns); i < l; i++ {
if field == this.Columns[i] {
return i
}
}
return -1
}
func (this *ResultRow) GetRow() *ResultRow {
return this
}
func (this *ResultRow) IsExists() bool {
if this == nil {
return false
}
if this.Error != nil {
return false
}
if this.rs != nil {
return len(this.values) > 0
}
return false
}
func (this *ResultRow) IsNew() bool {
return !this.IsExists()
}
func (this *ResultRow) getRaw(index int) []byte {
if index > -1 && this.values[index] != nil {
return this.values[index]
}
return []byte{}
}
// 默认返回byte
func (this *ResultRow) Get(f string) []byte {
return this.getRaw(this.rs.ColumnOf(f))
}
func (this *ResultRow) Str(f string) string {
v := this.Get(f)
// @see http://studygolang.com/articles/2909
return *(*string)(unsafe.Pointer(&v))
}
func (this *ResultRow) Int(field string) int {
return agi.StrToFInt(this.Str(field)) // 这里用转成浮点整型,就是最大可能的取到值
}
func (this *ResultRow) Int64(field string) int64 {
return agi.StrToFInt64(this.Str(field)) // 这里用转成浮点整型,就是最大可能的取到值
}
func (this *ResultRow) Float(field string) float64 {
return agi.StrToFloat(this.Str(field))
}
func (this *ResultRow) Round(field string, places int) float64 {
return agi.Round(this.Float(field), places)
}
// 数据库一般都会习惯用0, 1来表达值false or true
// 也有的时候,通过 0 => 强制等价于false
func (this *ResultRow) Bool(field string) bool {
return agi.StrToIntBool(this.Str(field))
}
// 用整型表达的时间值,因为我们已经习惯了用整型值来表达时间
// 不过为了预留配对标准的时间戳、Data、Time,暂时不占用Time的方法名
// 这个方法还是应该只返回一个结果
func (this *ResultRow) IntTime(field string) time.Time {
return agi.IntToTime(this.Int64(field))
}
func (this *ResultRow) Compare(values map[string]interface{}) map[string]interface{} {
diff := make(map[string]interface{})
for key, value := range values {
raw := this.Str(key)
if !strings.EqualFold(fmt.Sprint(value), raw) {
fmt.Println(fmt.Sprint(value), raw)
diff[key] = value
}
}
return diff
}
func (this *ResultRow) Fetch(obj Model) Model {
Bind(this, obj)
return obj
}
func (this *ExecResult) ExecError() error {
if this == nil {
return nil
}
if this.Error == nil {
return nil
}
return this.Error
}
func (this *ExecResult) ExecHasError() bool {
return this.ExecError() != nil
}
func (this *ExecResult) setQueryType(t QueryType) *ExecResult {
this.QueryType = t
return this
}
func (this *ExecResult) IsSuccess() bool {
if this == nil {
return false
}
if this.RowsAffected > 0 {
return true
}
return false
}
func (this *ExecResult) IsDelete() bool {
if this == nil {
return false
}
if this.IsSuccess() && this.QueryType == QUERY_DELETE {
return true
}
return false
}
func (this *ExecResult) IsCreate() bool {
if this == nil {
return false
}
if this.IsSuccess() && this.QueryType == QUERY_INSERT {
return true
}
return false
}
func (this *ExecResult) IsUpdate() bool {
if this == nil {
return false
}
if this.IsSuccess() && this.QueryType == QUERY_UPDATE {
return true
}
return false
}
func (this *ExecResult) IsSave() bool {
if this == nil {
return false
}
if this.IsCreate() || this.IsUpdate() {
return true
}
return false
}
Go
1
https://gitee.com/janpoem/go-adm.git
git@gitee.com:janpoem/go-adm.git
janpoem
go-adm
go-adm
master

搜索帮助