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.
starainrt/database.go

474 lines
9.4 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
for _, v := range this.Result {
res = append(res, v.(bool))
}
return res
}
func (this *StarResultCol) MustFloat32() []float32 {
var res []float32
for _, v := range this.Result {
res = append(res, v.(float32))
}
return res
}
func (this *StarResultCol) MustFloat64() []float64 {
var res []float64
for _, v := range this.Result {
res = append(res, v.(float64))
}
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
default:
tmp = v.(string)
}
res = append(res, tmp)
}
return res
}
func (this *StarResultCol) MustInt32() []int32 {
var res []int32
for _, v := range this.Result {
res = append(res, v.(int32))
}
return res
}
func (this *StarResultCol) MustInt64() []int64 {
var res []int64
for _, v := range this.Result {
res = append(res, v.(int64))
}
return res
}
func (this *StarResultCol) MustInt() []int {
var res []int
for _, v := range this.Result {
res = append(res, v.(int))
}
return res
}
func (this *StarResult) MustInt64(name string) int64 {
num, ok := this.columnref[name]
if !ok {
return 0
}
res := this.Result[num].(int64)
return res
}
func (this *StarResult) MustInt32(name string) int32 {
num, ok := this.columnref[name]
if !ok {
return 0
}
res := this.Result[num].(int32)
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
}
return res
}
func (this *StarResult) MustFloat64(name string) float64 {
num, ok := this.columnref[name]
if !ok {
return 0
}
res := this.Result[num].(float64)
return res
}
func (this *StarResult) MustFloat32(name string) float32 {
num, ok := this.columnref[name]
if !ok {
return 0
}
res := this.Result[num].(float32)
return res
}
func (this *StarResult) MustInt(name string) int {
num, ok := this.columnref[name]
if !ok {
return 0
}
res := this.Result[num].(int)
return res
}
func (this *StarResult) MustBool(name string) bool {
num, ok := this.columnref[name]
if !ok {
return false
}
res := this.Result[num].(bool)
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{make(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
}