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 for _, v := range this.Result { res = append(res, v.(string)) } 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 { num, ok := this.columnref[name] if !ok { return "" } res := this.Result[num].(string) 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)) 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 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.Rows.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 }