You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
689 lines
14 KiB
Go
689 lines
14 KiB
Go
package starainrt
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
)
|
|
|
|
var DBRes *sql.DB
|
|
var DBRows *sql.Rows
|
|
|
|
type StarDB struct {
|
|
DB *sql.DB
|
|
Rows *sql.Rows
|
|
}
|
|
|
|
type StarRows struct {
|
|
Rows *sql.Rows
|
|
Length int
|
|
StringResult []map[string]string
|
|
Columns []string
|
|
ColumnsType []reflect.Type
|
|
columnref map[string]int
|
|
result [][]interface{}
|
|
}
|
|
|
|
type StarResult struct {
|
|
Result []interface{}
|
|
Columns []string
|
|
columnref map[string]int
|
|
ColumnsType []reflect.Type
|
|
}
|
|
|
|
type StarResultCol struct {
|
|
Result []interface{}
|
|
}
|
|
|
|
func (this *StarResultCol) MustBytes() [][]byte {
|
|
var res [][]byte
|
|
for _, v := range this.Result {
|
|
res = append(res, v.([]byte))
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResultCol) MustBool() []bool {
|
|
var res []bool
|
|
var tmp bool
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = false
|
|
case bool:
|
|
tmp = vtype
|
|
case float64, float32:
|
|
if vtype.(float64) > 0 {
|
|
tmp = true
|
|
} else {
|
|
tmp = false
|
|
}
|
|
case int, int32, int64:
|
|
if vtype.(int) > 0 {
|
|
tmp = true
|
|
} else {
|
|
tmp = false
|
|
}
|
|
case string:
|
|
tmp, _ = strconv.ParseBool(vtype)
|
|
default:
|
|
tmp, _ = strconv.ParseBool(string(vtype.([]byte)))
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResultCol) MustFloat32() []float32 {
|
|
var res []float32
|
|
var tmp float32
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = 0
|
|
case float64, float32:
|
|
tmp = float32(vtype.(float64))
|
|
case string:
|
|
tmps, _ := strconv.ParseFloat(vtype, 32)
|
|
tmp = float32(tmps)
|
|
case int, int32, int64:
|
|
tmp = float32(vtype.(int64))
|
|
default:
|
|
tmp = v.(float32)
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResultCol) MustFloat64() []float64 {
|
|
var res []float64
|
|
var tmp float64
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = 0
|
|
case float64, float32:
|
|
tmp = vtype.(float64)
|
|
case string:
|
|
tmp, _ = strconv.ParseFloat(vtype, 64)
|
|
case int, int32, int64:
|
|
tmp = float64(vtype.(int64))
|
|
default:
|
|
tmp = v.(float64)
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResultCol) MustString() []string {
|
|
var res []string
|
|
var tmp string
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = ""
|
|
case string:
|
|
tmp = vtype
|
|
case int64:
|
|
tmp = strconv.FormatInt(vtype, 10)
|
|
case int32:
|
|
tmp = strconv.Itoa(int(vtype))
|
|
case bool:
|
|
tmp = strconv.FormatBool(vtype)
|
|
case float64:
|
|
tmp = strconv.FormatFloat(vtype, 'f', 10, 64)
|
|
case float32:
|
|
tmp = strconv.FormatFloat(float64(vtype), 'f', 10, 32)
|
|
case int:
|
|
tmp = strconv.Itoa(vtype)
|
|
default:
|
|
tmp = string(vtype.([]byte))
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResultCol) MustInt32() []int32 {
|
|
var res []int32
|
|
var tmp int32
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = 0
|
|
case float64, float32:
|
|
tmp = int32(vtype.(float64))
|
|
case string:
|
|
tmps, _ := strconv.ParseInt(vtype, 10, 32)
|
|
tmp = int32(tmps)
|
|
case int, int32, int64:
|
|
tmp = int32(vtype.(int64))
|
|
default:
|
|
tmp = v.(int32)
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResultCol) MustInt64() []int64 {
|
|
var res []int64
|
|
var tmp int64
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = 0
|
|
case float64, float32:
|
|
tmp = int64(vtype.(float64))
|
|
case string:
|
|
tmp, _ = strconv.ParseInt(vtype, 10, 64)
|
|
case int, int32, int64:
|
|
tmp = (vtype.(int64))
|
|
default:
|
|
tmp = v.(int64)
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResultCol) MustInt() []int {
|
|
var res []int
|
|
var tmp int
|
|
for _, v := range this.Result {
|
|
switch vtype := v.(type) {
|
|
case nil:
|
|
tmp = 0
|
|
case float64, float32:
|
|
tmp = int(vtype.(float64))
|
|
case string:
|
|
tmps, _ := strconv.ParseInt(vtype, 10, 64)
|
|
tmp = int(tmps)
|
|
case int, int32, int64:
|
|
tmp = int(vtype.(int64))
|
|
default:
|
|
tmp = int(v.(int64))
|
|
}
|
|
res = append(res, tmp)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResult) MustInt64(name string) int64 {
|
|
var res int64
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return 0
|
|
}
|
|
tmp := this.Result[num]
|
|
switch vtype := tmp.(type) {
|
|
case nil:
|
|
res = 0
|
|
case float64, float32:
|
|
res = int64(vtype.(float64))
|
|
case string:
|
|
res, _ = strconv.ParseInt(vtype, 10, 64)
|
|
case int, int32, int64:
|
|
res = (vtype.(int64))
|
|
default:
|
|
res, _ = strconv.ParseInt(string(tmp.([]byte)), 10, 64)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResult) MustInt32(name string) int32 {
|
|
var res int32
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return 0
|
|
}
|
|
tmp := this.Result[num]
|
|
switch vtype := tmp.(type) {
|
|
case nil:
|
|
res = 0
|
|
case float64, float32:
|
|
res = int32(vtype.(float64))
|
|
case string:
|
|
ress, _ := strconv.ParseInt(vtype, 10, 32)
|
|
res = int32(ress)
|
|
case int, int32, int64:
|
|
res = int32(vtype.(int64))
|
|
default:
|
|
ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 32)
|
|
res = int32(ress)
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResult) MustString(name string) string {
|
|
var res string
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return ""
|
|
}
|
|
switch vtype := this.Result[num].(type) {
|
|
case nil:
|
|
res = ""
|
|
case string:
|
|
res = vtype
|
|
case int64:
|
|
res = strconv.FormatInt(vtype, 10)
|
|
case int32:
|
|
res = strconv.Itoa(int(vtype))
|
|
case bool:
|
|
res = strconv.FormatBool(vtype)
|
|
case float64:
|
|
res = strconv.FormatFloat(vtype, 'f', 10, 64)
|
|
case float32:
|
|
res = strconv.FormatFloat(float64(vtype), 'f', 10, 32)
|
|
case int:
|
|
res = strconv.Itoa(vtype)
|
|
default:
|
|
res = string(vtype.([]byte))
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResult) MustFloat64(name string) float64 {
|
|
var res float64
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return 0
|
|
}
|
|
switch vtype := this.Result[num].(type) {
|
|
case nil:
|
|
res = 0
|
|
case string:
|
|
res, _ = strconv.ParseFloat(vtype, 64)
|
|
case float64:
|
|
res = vtype
|
|
case int, int64, int32, float32:
|
|
res = vtype.(float64)
|
|
default:
|
|
res, _ = strconv.ParseFloat(string(vtype.([]byte)), 64)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResult) MustFloat32(name string) float32 {
|
|
var res float32
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return 0
|
|
}
|
|
switch vtype := this.Result[num].(type) {
|
|
case nil:
|
|
res = 0
|
|
case string:
|
|
tmp, _ := strconv.ParseFloat(vtype, 32)
|
|
res = float32(tmp)
|
|
case float64:
|
|
res = float32(vtype)
|
|
case float32:
|
|
res = vtype
|
|
case int, int64, int32:
|
|
res = vtype.(float32)
|
|
default:
|
|
tmp, _ := strconv.ParseFloat(string(vtype.([]byte)), 32)
|
|
res = float32(tmp)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResult) MustInt(name string) int {
|
|
var res int
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return 0
|
|
}
|
|
tmp := this.Result[num]
|
|
switch vtype := tmp.(type) {
|
|
case nil:
|
|
res = 0
|
|
case float64, float32:
|
|
res = int(vtype.(float64))
|
|
case string:
|
|
ress, _ := strconv.ParseInt(vtype, 10, 64)
|
|
res = int(ress)
|
|
case int, int32, int64:
|
|
res = int(vtype.(int64))
|
|
default:
|
|
ress, _ := strconv.ParseInt(string(tmp.([]byte)), 10, 64)
|
|
res = int(ress)
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (this *StarResult) MustBool(name string) bool {
|
|
var res bool
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return false
|
|
}
|
|
tmp := this.Result[num]
|
|
switch vtype := tmp.(type) {
|
|
case nil:
|
|
res = false
|
|
case bool:
|
|
res = vtype
|
|
case float64, float32:
|
|
if vtype.(float64) > 0 {
|
|
res = true
|
|
} else {
|
|
res = false
|
|
}
|
|
case int, int32, int64:
|
|
if vtype.(int) > 0 {
|
|
res = true
|
|
} else {
|
|
res = false
|
|
}
|
|
case string:
|
|
res, _ = strconv.ParseBool(vtype)
|
|
default:
|
|
res, _ = strconv.ParseBool(string(vtype.([]byte)))
|
|
}
|
|
return res
|
|
}
|
|
func (this *StarResult) MustBytes(name string) []byte {
|
|
num, ok := this.columnref[name]
|
|
if !ok {
|
|
return []byte{}
|
|
}
|
|
res := this.Result[num].([]byte)
|
|
return res
|
|
}
|
|
|
|
func (this *StarRows) Rescan() {
|
|
this.parserows()
|
|
}
|
|
|
|
func (this *StarRows) Col(name string) *StarResultCol {
|
|
result := new(StarResultCol)
|
|
if _, ok := this.columnref[name]; !ok {
|
|
return result
|
|
}
|
|
var rescol []interface{}
|
|
for _, v := range this.result {
|
|
rescol = append(rescol, v[this.columnref[name]])
|
|
}
|
|
result.Result = rescol
|
|
return result
|
|
}
|
|
|
|
func (this *StarRows) Row(id int) *StarResult {
|
|
result := new(StarResult)
|
|
if id+1 > len(this.result) {
|
|
return result
|
|
}
|
|
result.Result = this.result[id]
|
|
result.Columns = this.Columns
|
|
result.ColumnsType = this.ColumnsType
|
|
result.columnref = this.columnref
|
|
return result
|
|
}
|
|
|
|
func (this *StarRows) Close() error {
|
|
return this.Rows.Close()
|
|
}
|
|
|
|
func (this *StarRows) parserows() {
|
|
this.result = [][]interface{}{}
|
|
this.columnref = make(map[string]int)
|
|
this.StringResult = []map[string]string{}
|
|
this.Columns, _ = this.Rows.Columns()
|
|
types, _ := this.Rows.ColumnTypes()
|
|
for _, v := range types {
|
|
this.ColumnsType = append(this.ColumnsType, v.ScanType())
|
|
}
|
|
scanArgs := make([]interface{}, len(this.Columns))
|
|
values := make([]interface{}, len(this.Columns))
|
|
for i, _ := range values {
|
|
this.columnref[this.Columns[i]] = i
|
|
scanArgs[i] = &values[i]
|
|
}
|
|
for this.Rows.Next() {
|
|
if err := this.Rows.Scan(scanArgs...); err != nil {
|
|
return
|
|
}
|
|
record := make(map[string]string)
|
|
var rescopy []interface{}
|
|
for i, col := range values {
|
|
rescopy = append(rescopy, col)
|
|
switch vtype := col.(type) {
|
|
case float64:
|
|
record[this.Columns[i]] = strconv.FormatFloat(vtype, 'f', -1, 64)
|
|
case int64:
|
|
record[this.Columns[i]] = strconv.FormatInt(vtype, 10)
|
|
case string:
|
|
record[this.Columns[i]] = vtype
|
|
case nil:
|
|
record[this.Columns[i]] = ""
|
|
default:
|
|
record[this.Columns[i]] = string(vtype.([]byte))
|
|
}
|
|
}
|
|
this.result = append(this.result, rescopy)
|
|
this.StringResult = append(this.StringResult, record)
|
|
}
|
|
this.Length = len(this.StringResult)
|
|
}
|
|
|
|
func (this *StarDB) Query(args ...interface{}) (*StarRows, error) {
|
|
var err error
|
|
effect := new(StarRows)
|
|
if err = this.DB.Ping(); err != nil {
|
|
return effect, err
|
|
}
|
|
if len(args) == 0 {
|
|
return effect, errors.New("no args")
|
|
}
|
|
if len(args) == 1 {
|
|
sql := args[0]
|
|
if this.Rows, err = this.DB.Query(sql.(string)); err != nil {
|
|
return effect, err
|
|
}
|
|
effect.Rows = this.Rows
|
|
effect.parserows()
|
|
return effect, nil
|
|
}
|
|
sql := args[0]
|
|
stmt, err := this.DB.Prepare(sql.(string))
|
|
if err != nil {
|
|
return effect, err
|
|
}
|
|
defer stmt.Close()
|
|
var para []interface{}
|
|
for k, v := range args {
|
|
if k != 0 {
|
|
switch vtype := v.(type) {
|
|
default:
|
|
para = append(para, vtype)
|
|
}
|
|
}
|
|
}
|
|
if this.Rows, err = stmt.Query(para...); err != nil {
|
|
return effect, err
|
|
}
|
|
effect.Rows = this.Rows
|
|
effect.parserows()
|
|
return effect, nil
|
|
}
|
|
|
|
func (this *StarDB) Open(Method, ConnStr string) error {
|
|
var err error
|
|
this.DB, err = sql.Open(Method, ConnStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = this.DB.Ping()
|
|
return err
|
|
}
|
|
|
|
func (this *StarDB) Close() error {
|
|
if err := this.DB.Close(); err != nil {
|
|
return err
|
|
}
|
|
return this.DB.Close()
|
|
}
|
|
|
|
func (this *StarDB) Exec(args ...interface{}) (sql.Result, error) {
|
|
var err error
|
|
var effect sql.Result
|
|
if err = this.DB.Ping(); err != nil {
|
|
return effect, err
|
|
}
|
|
if len(args) == 0 {
|
|
return effect, errors.New("no args")
|
|
}
|
|
if len(args) == 1 {
|
|
sql := args[0]
|
|
if _, err = this.DB.Exec(sql.(string)); err != nil {
|
|
return effect, err
|
|
}
|
|
return effect, nil
|
|
}
|
|
sql := args[0]
|
|
stmt, err := this.DB.Prepare(sql.(string))
|
|
defer stmt.Close()
|
|
if err != nil {
|
|
return effect, err
|
|
}
|
|
var para []interface{}
|
|
for k, v := range args {
|
|
if k != 0 {
|
|
switch vtype := v.(type) {
|
|
default:
|
|
para = append(para, vtype)
|
|
}
|
|
}
|
|
}
|
|
if effect, err = stmt.Exec(para...); err != nil {
|
|
return effect, err
|
|
}
|
|
return effect, nil
|
|
}
|
|
|
|
func FetchAll(rows *sql.Rows) (error, map[int]map[string]string) {
|
|
var ii int = 0
|
|
records := make(map[int]map[string]string)
|
|
columns, err := rows.Columns()
|
|
if err != nil {
|
|
return err, records
|
|
}
|
|
scanArgs := make([]interface{}, len(columns))
|
|
values := make([]interface{}, len(columns))
|
|
for i := range values {
|
|
scanArgs[i] = &values[i]
|
|
}
|
|
for rows.Next() {
|
|
if err := rows.Scan(scanArgs...); err != nil {
|
|
return err, records
|
|
}
|
|
record := make(map[string]string)
|
|
for i, col := range values {
|
|
switch vtype := col.(type) {
|
|
case float64:
|
|
record[columns[i]] = strconv.FormatFloat(vtype, 'f', -1, 64)
|
|
case int64:
|
|
record[columns[i]] = strconv.FormatInt(vtype, 10)
|
|
case string:
|
|
record[columns[i]] = vtype
|
|
case nil:
|
|
record[columns[i]] = ""
|
|
default:
|
|
record[columns[i]] = string(vtype.([]byte))
|
|
}
|
|
}
|
|
records[ii] = record
|
|
ii++
|
|
}
|
|
return nil, records
|
|
}
|
|
|
|
func OpenDB(Method, ConnStr string) error {
|
|
var err error
|
|
DBRes, err = sql.Open(Method, ConnStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = DBRes.Ping()
|
|
return err
|
|
}
|
|
func CloseDB() {
|
|
DBRes.Close()
|
|
DBRows.Close()
|
|
}
|
|
|
|
func Query(args ...interface{}) (error, map[int]map[string]string) {
|
|
var err error
|
|
records := make(map[int]map[string]string)
|
|
if err = DBRes.Ping(); err != nil {
|
|
return err, records
|
|
}
|
|
if len(args) == 0 {
|
|
return errors.New("no args"), records
|
|
}
|
|
if len(args) == 1 {
|
|
sql := args[0]
|
|
if DBRows, err = DBRes.Query(sql.(string)); err != nil {
|
|
return err, records
|
|
}
|
|
return FetchAll(DBRows)
|
|
}
|
|
sql := args[0]
|
|
stmt, err := DBRes.Prepare(sql.(string))
|
|
defer stmt.Close()
|
|
if err != nil {
|
|
return err, records
|
|
}
|
|
var para []interface{}
|
|
for k, v := range args {
|
|
if k != 0 {
|
|
switch vtype := v.(type) {
|
|
default:
|
|
para = append(para, vtype)
|
|
}
|
|
}
|
|
}
|
|
if DBRows, err = stmt.Query(para...); err != nil {
|
|
return err, records
|
|
}
|
|
return FetchAll(DBRows)
|
|
|
|
}
|
|
|
|
func DBExec(args ...interface{}) error {
|
|
var err error
|
|
if err = DBRes.Ping(); err != nil {
|
|
return err
|
|
}
|
|
if len(args) == 0 {
|
|
return errors.New("no args")
|
|
}
|
|
if len(args) == 1 {
|
|
sql := args[0]
|
|
if _, err = DBRes.Exec(sql.(string)); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
sql := args[0]
|
|
stmt, err := DBRes.Prepare(sql.(string))
|
|
defer stmt.Close()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var para []interface{}
|
|
for k, v := range args {
|
|
if k != 0 {
|
|
switch vtype := v.(type) {
|
|
default:
|
|
para = append(para, vtype)
|
|
}
|
|
}
|
|
}
|
|
if _, err = stmt.Exec(para...); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
}
|