代码拉取完成,页面将自动刷新
package gsql
import (
"bytes"
"database/sql"
"encoding/binary"
"fmt"
"log"
"os"
"reflect"
"strconv"
"time"
)
type FieldType int
const (
ftUnknown FieldType = iota
ftInt
ftUint
ftString
ftFloat
ftBool
ftTime
ftBytes
)
type dbConn interface {
Query(query string, args ...interface{}) (*sql.Rows, error)
QueryRow(query string, args ...interface{}) *sql.Row
Exec(query string, args ...interface{}) (sql.Result, error)
Prepare(query string) (*sql.Stmt, error)
}
type DBx struct {
db *sql.DB
}
var glog *log.Logger
func init() {
glog = log.New(os.Stdout, `gsql>`, log.Lshortfile|log.Ldate|log.Ltime)
}
func New(driverName, dataSourceName string) (dbx *DBx, err error) {
dbx = new(DBx)
dbx.db, err = sql.Open(driverName, dataSourceName)
//glog.Println(err)
return dbx, err
}
func (this *DBx) Close() error {
return this.db.Close()
}
func (this *DBx) NewQuery(args ...interface{}) *Query {
query := new(Query)
query.conn = this.db
query.isPrepare = false
if len(args) > 0 {
if val, ok := args[0].(bool); ok {
query.isPrepare = val
}
}
return query
}
func (this *DBx) NewTrans() (t *Transaction, e error) {
t = new(Transaction)
t.tx, e = this.db.Begin()
return t, e
}
type Transaction struct {
tx *sql.Tx
}
func (this *Transaction) NewQuery(args ...interface{}) *Query {
query := new(Query)
query.conn = this.tx
if len(args) > 0 {
query.isPrepare = true
}
return query
}
func (this *Transaction) Commit() error {
return this.tx.Commit()
}
func (this *Transaction) Rollback() error {
return this.tx.Rollback()
}
type Query struct {
conn dbConn
rows *sql.Rows
fields *Fields
isPrepare bool
stmt *sql.Stmt
sqlStr string
sqlArgs []interface{}
sqlArgs_prepare []interface{}
}
func (this *Query) checkError() {
}
func (this *Query) SetSQL(query string, args ...interface{}) *Query {
this.Close()
this.sqlStr = query
this.sqlArgs = args
return this
}
func (this *Query) GetOne(args ...interface{}) (err error) {
if err = this.Open(args...); err != nil {
return err
}
if !this.Next() {
if err = this.rows.Err(); err != nil {
return err
}
return sql.ErrNoRows
}
return err
}
func (this *Query) Open(args ...interface{}) (err error) {
this.sqlArgs_prepare = args
return this.First()
}
func (this *Query) Exec(args ...interface{}) (ret sql.Result, err error) {
if this.isPrepare {
if this.stmt == nil {
if this.stmt, err = this.conn.Prepare(this.sqlStr); err != nil {
return nil, err
}
}
return this.stmt.Exec(args...)
}
return this.conn.Exec(this.sqlStr, this.sqlArgs...)
}
func (this *Query) Close() error {
if this.rows == nil {
return fmt.Errorf(`no connection`)
}
defer func() {
this.rows = nil
this.stmt = nil
this.fields = nil
}()
if this.stmt != nil {
this.stmt.Close()
}
return this.rows.Close()
}
func (this *Query) First() (err error) {
if this.rows != nil {
this.Close()
}
if this.isPrepare {
if this.stmt == nil {
if this.stmt, err = this.conn.Prepare(this.sqlStr); err != nil {
return err
}
}
this.rows, err = this.stmt.Query(this.sqlArgs_prepare...)
} else {
this.rows, err = this.conn.Query(this.sqlStr, this.sqlArgs...)
}
if err == nil {
this.fields = newFields(this.rows)
}
return err
}
func (this *Query) Next() bool {
this.checkError()
if !this.rows.Next() {
return false
}
this.rows.Scan(this.fields.vals...)
return true
}
func (this *Query) FieldCount() int {
this.checkError()
return this.fields.fieldCount
}
func (this *Query) FieldById(id int) *Field {
this.checkError()
return this.fields.fields[id]
}
func (this *Query) FieldByName(name string) *Field {
this.checkError()
if field, ok := this.fields.list[name]; ok {
return field
}
return nil
}
type Field struct {
fieldName string
fieldValue interface{}
dataType FieldType
refValue reflect.Value
//asInt *int64
//asUint *uint64
//asFloat *float64
//asBool *bool
//asString *string
//asBytes *[]byte
//asTime *time.Time
//
//toInt *int64
//toUint *uint64
//toFloat *float64
//toBool *bool
//toString *string
//toBytes *[]byte
//toTime *time.Time
//asErr error
//toErr error
}
func newField(name string) *Field {
p := new(Field)
p.fieldName = name
return p
}
func (this *Field) getDataType() FieldType {
this.refValue = reflect.ValueOf(this.fieldValue)
if !this.refValue.IsValid() {
return ftUnknown
}
switch this.refValue.Kind() {
case reflect.Int:
fallthrough
case reflect.Int8:
fallthrough
case reflect.Int16:
fallthrough
case reflect.Int32:
fallthrough
case reflect.Int64:
return ftInt
case reflect.Uint:
fallthrough
case reflect.Uint8:
fallthrough
case reflect.Uint16:
fallthrough
case reflect.Uint32:
fallthrough
case reflect.Uint64:
return ftUint
case reflect.Float32:
fallthrough
case reflect.Float64:
return ftFloat
case reflect.String:
return ftString
case reflect.Bool:
return ftBool
case reflect.Slice:
return ftBytes
case reflect.Struct:
switch this.fieldValue.(type) {
case time.Time:
return ftTime
}
}
glog.Println(this.refValue.Kind())
return ftUnknown
}
func (this *Field) IsNull() bool {
return this.getDataType() == ftUnknown
}
func (this *Field) AsInt64() (n int64, e error) {
//if this.asInt != nil {
// return *this.asInt, this.asErr
//}
n = 0
switch this.getDataType() {
case ftInt:
n = this.refValue.Int()
case ftUint:
n = int64(this.ToUint64())
case ftFloat:
n = int64(this.ToFloat64())
case ftBool:
if this.ToBool() {
n = 1
}
case ftString:
n, e = strconv.ParseInt(this.ToString(), 10, 64)
case ftBytes:
e = binary.Read(bytes.NewBuffer(this.ToBytes()), binary.BigEndian, &n)
case ftTime:
n = this.ToTime().UnixNano()
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as int`, this.refValue.Type())
}
//this.asInt = &n
//this.asErr = e
return n, e
}
func (this *Field) ToInt64() (n int64) {
n, _ = this.AsInt64()
return n
}
func (this *Field) AsUint64() (n uint64, e error) {
//if this.asUint != nil {
// return *this.asUint, this.asErr
//}
n = 0
switch this.getDataType() {
case ftUint:
n = this.refValue.Uint()
case ftInt:
n = uint64(this.ToInt64())
case ftFloat:
n = uint64(this.ToFloat64())
case ftBool:
if this.ToBool() {
n = 1
}
case ftString:
n, e = strconv.ParseUint(this.ToString(), 10, 64)
case ftBytes:
e = binary.Read(bytes.NewBuffer(this.ToBytes()), binary.BigEndian, &n)
case ftTime:
n = uint64(this.ToTime().UnixNano())
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as uint`, this.refValue.Type())
}
//this.asUint = &n
//this.asErr = e
return n, e
}
func (this *Field) ToUint64() uint64 {
n, _ := this.AsUint64()
return n
}
func (this *Field) AsFloat32() (f float32, e error) {
f64, e := this.AsFloat64()
return float32(f64), e
}
func (this *Field) ToFloat32() float32 {
f, _ := this.AsFloat32()
return f
}
func (this *Field) AsFloat64() (f float64, e error) {
//if this.asFloat != nil {
// return *this.asFloat, nil
//}
f = 0
switch this.getDataType() {
case ftFloat:
f = this.refValue.Float()
case ftInt:
f = float64(this.ToInt64())
case ftUint:
f = float64(this.ToUint64())
case ftBool:
if this.ToBool() {
f = 1
}
case ftString:
f, e = strconv.ParseFloat(this.ToString(), 64)
case ftBytes:
e = binary.Read(bytes.NewBuffer(this.ToBytes()), binary.BigEndian, &f)
case ftTime:
f = float64(this.ToTime().UnixNano())
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as float`, this.refValue.Type())
}
//this.asFloat = &f
//this.asErr = e
return f, e
}
func (this *Field) ToFloat64() float64 {
f, _ := this.AsFloat64()
return f
}
func (this *Field) AsBytes() (b []byte, e error) {
//if this.asBytes != nil {
// return *this.asBytes, this.asErr
//}
buf := bytes.NewBuffer([]byte{})
switch this.getDataType() {
case ftBytes:
b = this.refValue.Bytes()
buf.Write(b)
case ftInt:
e = binary.Write(buf, binary.BigEndian, this.ToInt64())
case ftUint:
e = binary.Write(buf, binary.BigEndian, this.ToUint64())
case ftFloat:
e = binary.Write(buf, binary.BigEndian, this.ToFloat64())
case ftBool:
e = binary.Write(buf, binary.BigEndian, this.ToBool())
case ftString:
buf.WriteString(this.ToString())
case ftTime:
e = binary.Write(buf, binary.BigEndian, this.ToTime().UnixNano())
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as bytes`, this.refValue.Type())
}
//this.asBytes = &b
//this.asErr = e
return b, e
}
func (this *Field) ToBytes() []byte {
b, _ := this.AsBytes()
return b
}
func (this *Field) AsBool() (b bool, e error) {
//if this.asBool != nil {
// return *this.asBool, this.asErr
//}
b = false
switch this.getDataType() {
case ftBool:
b = this.refValue.Bool()
case ftInt:
b = this.ToInt64() != 0
case ftUint:
b = this.ToUint64() != 0
case ftFloat:
b = this.ToFloat64() != 0
case ftString:
b, e = strconv.ParseBool(this.ToString())
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as bool`, this.refValue.Type())
}
//this.asBool = &b
//this.asErr = e
return b, e
}
func (this *Field) ToBool() bool {
b, _ := this.AsBool()
return b
}
func (this *Field) AsString() (s string, e error) {
//if this.asString != nil {
// return *this.asString, this.asErr
//}
s = ``
switch this.getDataType() {
case ftString:
s = this.refValue.String()
case ftInt:
s = strconv.FormatInt(this.refValue.Int(), 10)
case ftUint:
s = strconv.FormatUint(this.refValue.Uint(), 10)
case ftFloat:
s = strconv.FormatFloat(this.refValue.Float(), 'f', -1, 64)
case ftBool:
s = strconv.FormatBool(this.refValue.Bool())
case ftBytes:
s = string(this.refValue.Bytes())
case ftTime:
s = this.ToTime().String()
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as string`, this.refValue.Type())
}
//this.asString = &s
//this.asErr = e
return s, e
}
func (this *Field) ToString() (s string) {
s, _ = this.AsString()
return s
}
func (this *Field) AsTime() (t time.Time, e error) {
//if this.asTime != nil {
// return *this.asTime, this.asErr
//}
t = time.Unix(0, 0)
switch this.getDataType() {
case ftTime:
t = this.fieldValue.(time.Time)
case ftUnknown:
e = fmt.Errorf(`field is null`)
default:
e = fmt.Errorf(`type [%s] can't as time`, this.refValue.Type())
}
//this.asTime = &t
//this.asErr = e
return t, e
}
func (this *Field) ToTime() (t time.Time) {
//if this.toTime != nil {
// return *this.toTime
//}
t = time.Unix(0, 0)
switch this.getDataType() {
case ftTime:
t = this.fieldValue.(time.Time)
case ftInt:
n := this.ToInt64()
t = time.Unix(n/int64(time.Second), n%int64(time.Second))
case ftUint:
n := int64(this.ToUint64())
t = time.Unix(n/int64(time.Second), n%int64(time.Second))
case ftFloat:
n := int64(this.ToFloat64())
t = time.Unix(n/int64(time.Second), n%int64(time.Second))
}
//this.toTime = &t
return t
}
type Fields struct {
//rows *sql.Rows
fieldCount int
list map[string]*Field
fields []*Field
vals []interface{}
}
func newFields(rows *sql.Rows) *Fields {
p := new(Fields)
p.list = make(map[string]*Field)
//p.rows = rows
names, _ := rows.Columns()
p.fieldCount = len(names)
p.fields = make([]*Field, p.fieldCount)
p.vals = make([]interface{}, p.fieldCount)
for id, name := range names {
field := newField(name)
field.dataType = ftUnknown
p.list[name] = field
p.fields[id] = field
p.vals[id] = &field.fieldValue
}
return p
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。