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 }