123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257 |
- package restful
- import (
- "database/sql"
- "errors"
- "fmt"
- _ "github.com/go-sql-driver/mysql"
- "github.com/jmoiron/sqlx"
- "github.com/kptyun/KPTCOMM/pkg/setting"
- "github.com/patrickmn/go-cache"
- "github.com/tealeg/xlsx"
- "github.com/xormplus/xorm/schemas"
- "math"
- "reflect"
- "strconv"
- "strings"
- "time"
- "unsafe"
- )
- var (
- Dbs *sqlx.DB
- Apisql_cache *cache.Cache
- )
- // SQLInit 初始化数据库操作句柄,这里要提供:
- // driverName string: 数据库类型,例如mysql、sqlite等,参考github.com/go-sql-driver/mysql官方介绍
- // dataSourceName string: 数据库地址,参考github.com/go-sql-driver/mysql官方介绍
- // MaxOpenConns int: 最大缓存连接数,这个数值包含了MaxIdleConns
- // MaxIdleConns int:预备的最大空闲连接数
- func SQLInit(driverName, dataSourceName string, maxOpenConns, maxIdleConns int, showlog bool) error {
- if Dbs == nil {
- var err error
- if Dbs, err = sqlx.Open(driverName, dataSourceName); err != nil {
- return err
- }
- Dbs.SetMaxOpenConns(maxOpenConns)
- Dbs.SetMaxIdleConns(maxIdleConns)
- Dbs.SetConnMaxLifetime(5 * time.Second)
- }
- if Apisql_cache == nil {
- Apisql_cache = cache.New(600*time.Second, 10*time.Second)
- SetCacheSql()
- }
- return nil
- }
- func value2String(rawValue *reflect.Value) (str string, err error) {
- aa := reflect.TypeOf((*rawValue).Interface())
- vv := reflect.ValueOf((*rawValue).Interface())
- switch aa.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- str = strconv.FormatInt(vv.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- str = strconv.FormatUint(vv.Uint(), 10)
- case reflect.Float32, reflect.Float64:
- str = strconv.FormatFloat(vv.Float(), 'f', -1, 64)
- case reflect.String:
- str = vv.String()
- case reflect.Array, reflect.Slice:
- switch aa.Elem().Kind() {
- case reflect.Uint8:
- data := rawValue.Interface().([]byte)
- str = string(data)
- if str == "\x00" {
- str = "0"
- }
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- // time type
- case reflect.Struct:
- if aa.ConvertibleTo(schemas.TimeType) {
- str = vv.Convert(schemas.TimeType).Interface().(time.Time).Format(time.RFC3339Nano)
- } else {
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- case reflect.Bool:
- str = strconv.FormatBool(vv.Bool())
- case reflect.Complex128, reflect.Complex64:
- str = fmt.Sprintf("%v", vv.Complex())
- /* TODO: unsupported types below
- case reflect.Map:
- case reflect.Ptr:
- case reflect.Uintptr:
- case reflect.UnsafePointer:
- case reflect.Chan, reflect.Func, reflect.Interface:
- */
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- return
- }
- func reflect2object(rawValue *reflect.Value) (value interface{}, err error) {
- aa := reflect.TypeOf((*rawValue).Interface())
- vv := reflect.ValueOf((*rawValue).Interface())
- switch aa.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- value = vv.Int()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- value = vv.Uint()
- case reflect.Float32, reflect.Float64:
- value = vv.Float()
- case reflect.String:
- value = vv.String()
- case reflect.Array, reflect.Slice:
- switch aa.Elem().Kind() {
- case reflect.Uint8:
- data := rawValue.Interface().([]byte)
- value = string(data)
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- // time type
- case reflect.Struct:
- if aa.ConvertibleTo(schemas.TimeType) {
- value = vv.Convert(schemas.TimeType).Interface().(time.Time)
- } else {
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- case reflect.Bool:
- value = vv.Bool()
- case reflect.Complex128, reflect.Complex64:
- value = vv.Complex()
- /* TODO: unsupported types below
- case reflect.Map:
- case reflect.Ptr:
- case reflect.Uintptr:
- case reflect.UnsafePointer:
- case reflect.Chan, reflect.Func, reflect.Interface:
- */
- default:
- err = fmt.Errorf("Unsupported struct type %v", vv.Type().Name())
- }
- return
- }
- func value2Object(rawValue *reflect.Value) (data interface{}, err error) {
- data, err = reflect2object(rawValue)
- if err != nil {
- return
- }
- return
- }
- func rows2mapObjects(rows *sqlx.Rows) (resultsSlice []map[string]interface{}, err error) {
- fields, err := rows.Columns()
- if err != nil {
- return nil, err
- }
- for rows.Next() {
- result, err := rows2mapObject(rows, fields)
- if err != nil {
- return nil, err
- }
- resultsSlice = append(resultsSlice, result)
- }
- return resultsSlice, nil
- }
- func rows2mapObject(rows *sqlx.Rows, fields []string) (resultsMap map[string]interface{}, err error) {
- result := make(map[string]interface{})
- scanResultContainers := make([]interface{}, len(fields))
- for i := 0; i < len(fields); i++ {
- var scanResultContainer interface{}
- scanResultContainers[i] = &scanResultContainer
- }
- if err := rows.Scan(scanResultContainers...); err != nil {
- return nil, err
- }
- for ii, key := range fields {
- rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
- //if row is null then ignore
- if rawValue.Interface() == nil {
- continue
- }
- if data, err := value2Object(&rawValue); err == nil {
- result[key] = data
- } else {
- return nil, err // !nashtsai! REVIEW, should return err or just error log?
- }
- }
- return result, nil
- }
- func row2mapStr(rows *sqlx.Rows, fields []string) (resultsMap map[string]string, err error) {
- result := make(map[string]string)
- scanResultContainers := make([]interface{}, len(fields))
- for i := 0; i < len(fields); i++ {
- var scanResultContainer interface{}
- scanResultContainers[i] = &scanResultContainer
- }
- if err := rows.Scan(scanResultContainers...); err != nil {
- return nil, err
- }
- for ii, key := range fields {
- rawValue := reflect.Indirect(reflect.ValueOf(scanResultContainers[ii]))
- // if row is null then as empty string
- if rawValue.Interface() == nil {
- result[key] = ""
- continue
- }
- if data, err := value2String(&rawValue); err == nil {
- result[key] = data
- } else {
- return nil, err
- }
- }
- return result, nil
- }
- func rows2Strings(rows *sqlx.Rows) (resultsSlice []map[string]string, err error) {
- fields, err := rows.Columns()
- if err != nil {
- return nil, err
- }
- for rows.Next() {
- result, err := row2mapStr(rows, fields)
- if err != nil {
- return nil, err
- }
- resultsSlice = append(resultsSlice, result)
- }
- return resultsSlice, nil
- }
- func SetCacheSql() {
- rows, err := Dbs.Queryx("SELECT sqlname, CONCAT(sqlstr,'|',IFNULL(params,'')) AS sqlstr FROM apisql WHERE ENABLE>0 ")
- if err != nil {
- return
- }
- valuesMap, err := rows2Strings(rows)
- if err == nil && len(valuesMap) > 0 {
- for _, v := range valuesMap {
- Apisql_cache.Set(v["sqlname"], v["sqlstr"], cache.DefaultExpiration)
- }
- }
- }
- func sqlCheckParam(param string) error {
- /*if strings.Contains(param, "where") {
- return errors.New("can not have where")
- }
- if strings.Contains(param, "and") {
- return errors.New("can not have and")
- }
- if strings.Contains(param, "or") {
- return errors.New("can not have or")
- }
- if strings.Contains(param, "=") {
- return errors.New("can not have =")
- }*/
- if strings.Contains(param, ";") {
- return errors.New("can not have ;")
- }
- return nil
- }
- func GetSqlByName(name string, tx *sqlx.Tx) (string, string) {
- sqls := ""
- param := ""
- if sql, ok := Apisql_cache.Get(name); ok {
- tempstrb := strings.IndexAny(sql.(string), "|")
- sqls = sql.(string)[0:tempstrb]
- param = sql.(string)[tempstrb+1:]
- } else {
- rows, err := tx.Queryx("SELECT sqlstr, params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name)
- if err != nil {
- return err.Error(), "err"
- }
- valuesMap, err := rows2Strings(rows)
- if err == nil && len(valuesMap) > 0 {
- sqls = valuesMap[0]["sqlstr"]
- param = valuesMap[0]["params"]
- Apisql_cache.Set(name, (sqls + "|" + param), cache.DefaultExpiration)
- }
- }
- if setting.DatabaseSetting.ShowGetSqllog {
- fmt.Println("==============")
- fmt.Println("apisql:" + sqls)
- fmt.Println("--------------")
- fmt.Println("param:" + param)
- fmt.Println("==============")
- }
- return sqls, param
- }
- func GetSqlByNameDB(name string) (string, string) {
- sqls := ""
- param := ""
- if sql, ok := Apisql_cache.Get(name); ok && setting.DatabaseSetting.CacheApiSql {
- tempstrb := strings.IndexAny(sql.(string), "|")
- sqls = sql.(string)[0:tempstrb]
- param = sql.(string)[tempstrb+1:]
- } else {
- rows, err := Dbs.Queryx("SELECT sqlstr,params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name)
- if err != nil {
- return err.Error(), "err"
- }
- valuesMap, err := rows2Strings(rows)
- if err == nil && len(valuesMap) > 0 {
- sqls = valuesMap[0]["sqlstr"]
- param = valuesMap[0]["params"]
- Apisql_cache.Set(name, (sqls + "|" + param), cache.DefaultExpiration)
- }
- }
- if setting.DatabaseSetting.ShowGetSqllog {
- fmt.Println("==============")
- fmt.Println("apisql:" + sqls)
- fmt.Println("--------------")
- fmt.Println("param:" + param)
- fmt.Println("==============")
- }
- return sqls, param
- }
- // sqlGetValues 根据结构体中指向实际数据的指针获取出数据,并存储到另一张表中返回
- func sqlGetValues(pvs []interface{}, columnsType []*sql.ColumnType, columnsLen int) map[string]interface{} {
- result := make(map[string]interface{}, columnsLen)
- for a := 0; a < columnsLen; a++ {
- switch s := pvs[a].(type) {
- case *int8:
- result[columnsType[a].Name()] = *s
- case *int16:
- result[columnsType[a].Name()] = *s
- case *int32:
- result[columnsType[a].Name()] = *s
- case *int64:
- result[columnsType[a].Name()] = *s
- case *float32:
- result[columnsType[a].Name()] = *s
- case *float64:
- result[columnsType[a].Name()] = *s
- case *string:
- result[columnsType[a].Name()] = *s
- case *sql.NullInt64:
- result[columnsType[a].Name()] = *s
- case *sql.NullString:
- result[columnsType[a].Name()] = *s
- }
- }
- return result
- }
- // 这里返回的是原始数组的基础上加上了字段名标识
- func sqlQuery(columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) ([]map[string]interface{}, error) {
- jsondata := make([]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- jsondata[k1] = sqlGetValues(v1, columnsType, columnsLen)
- }
- return jsondata, nil
- }
- func sqlQueryByTinyIntMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[int8]map[string]interface{}, error) {
- jsondata := make(map[int8]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*int8); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryBySmallIntMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[int16]map[string]interface{}, error) {
- jsondata := make(map[int16]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*int16); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryByIntMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[int32]map[string]interface{}, error) {
- jsondata := make(map[int32]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*int32); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryByBigIntMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[int64]map[string]interface{}, error) {
- jsondata := make(map[int64]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*int64); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryByFloatIntMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[float32]map[string]interface{}, error) {
- jsondata := make(map[float32]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*float32); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryByDoubleMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[float64]map[string]interface{}, error) {
- jsondata := make(map[float64]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*float64); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlQueryByStringMap(columnName string, columnsType []*sql.ColumnType, columnsLen int, queryData [][]interface{}, queryCount int) (map[string]map[string]interface{}, error) {
- jsondata := make(map[string]map[string]interface{}, queryCount)
- for k1, v1 := range queryData {
- if k1 >= queryCount {
- break
- }
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == columnName {
- if value, ok := v1[a].(*string); ok {
- jsondata[*value] = sqlGetValues(v1, columnsType, columnsLen)
- }
- break
- }
- }
- }
- return jsondata, nil
- }
- func sqlGetColumnType(columnsType []*sql.ColumnType, columnsLen int, valueName string) string {
- for a := 0; a < columnsLen; a++ {
- if columnsType[a].Name() == valueName {
- return columnsType[a].DatabaseTypeName()
- }
- }
- return ""
- }
- func round(num float64) int {
- return int(num + math.Copysign(0.5, num))
- }
- func toFixed(num float64, precision int) float64 {
- output := math.Pow(10, float64(precision))
- return float64(round(num*output)) / output
- }
- // QueryByMap 将查询到的数据,按照指定字段的值做为索引构建map并返回
- // columnName string: 作为索引的字段名称
- // sql string: 查询需要获取哪些字段的值,就是select后面跟着的部分,一般用"*"
- // where string: 过滤条件,就是where后面跟着的部分
- // order string: 排序条件,就是order by后面跟着的部分。默认是ASC排序,除非"-"开头则DESC排序
- // offset string: limit后面逗号相隔的两个数值,前者就是offset,后者就是count
- // count string: limit后面逗号相隔的两个数值,前者就是offset,后者就是count
- func QueryByMap(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- recordcount := int64(0)
- if count > 1 {
- row := Dbs.QueryRow("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...)
- var rowcount int64
- err := row.Scan(&rowcount)
- //tt, err := Engine.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List()
- if err != nil {
- fmt.Println("s1", err)
- return nil, err
- }
- recordcount = rowcount
- /* if tt == nil {
- recordcount = 0
- } else {
- recordcount = tt[0]["count"].(int64)
- }*/
- }
- queryData := make([]map[string]interface{}, 1)
- var err error
- if count == 0 {
- rows, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return err.Error(), err
- }
- queryData, err = rows2mapObjects(rows)
- } else {
- if count > 0 && offset > 0 {
- offset = offset * count
- }
- rows, err := Dbs.Queryx(fmt.Sprintf(sqlstr+" limit %d , %d", offset, count), params...)
- if err != nil {
- return err.Error(), err
- }
- queryData, err = rows2mapObjects(rows)
- }
- //fmt.Println("count, offset==================",count, offset)
- if err != nil {
- return nil, err
- }
- if recordcount == 0 {
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["rows"] = queryData
- data["total"] = recordcount
- data["code"] = 0
- data["message"] = "ok"
- if count > 0 {
- data["pages"] = math.Ceil(float64(recordcount) / float64(count))
- data["pageNum"] = math.Ceil(float64(offset+1) / float64(count))
- }
- data["pageSize"] = count
- return data, nil
- }
- // QueryByXlsx 将查询到的数据,按照指定字段的值做为索引构建map并返回
- // sql string: 查询需要获取哪些字段的值,就是select后面跟着的部分,一般用"*"
- // params string: 过滤条件,就是where后面跟着的部分
- func QueryByXlsx(sqlstr string, params []interface{}) (*xlsx.File, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return nil, err
- }
- rows, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- columnsType, _ := rows.ColumnTypes()
- columnsLen := len(columnsType)
- columns, _ := rows.Columns()
- values := make([]interface{}, columnsLen)
- valuePtrs := make([]interface{}, columnsLen)
- var sheet *xlsx.Sheet
- var row *xlsx.Row
- var cell *xlsx.Cell
- file := xlsx.NewFile()
- sheet, err = file.AddSheet("Sheet1")
- if err != nil {
- fmt.Printf(err.Error())
- }
- row = sheet.AddRow()
- for _, columnname := range columns {
- cell = row.AddCell()
- cell.Value = columnname
- }
- for rows.Next() {
- for a := 0; a < columnsLen; a++ {
- valuePtrs[a] = &values[a]
- }
- rows.Scan(valuePtrs...)
- row = sheet.AddRow()
- for i, _ := range columns {
- var v interface{}
- val := values[i]
- b, ok := val.([]byte)
- cell = row.AddCell()
- if ok {
- v1 := string(b)
- switch columnsType[i].DatabaseTypeName() {
- case "TINYINT", "SMALLINT", "MEDIUMINT", "INT", "INTEGER", "BIGINT":
- {
- v, _ = strconv.ParseInt(v1, 10, 32)
- cell.Value = fmt.Sprintf("%v", v)
- }
- case "FLOAT", "DOUBLE", "DECIMAL":
- {
- cindex := len(val.([]byte)) - strings.Index(v1, ".") - 1
- v2, _ := strconv.ParseFloat(v1, 32)
- v = toFixed(v2, cindex)
- cell.Value = fmt.Sprintf("%v", v)
- }
- case "BOOL":
- {
- v, _ = strconv.ParseBool(v1)
- cell.Value = fmt.Sprintf("%v", v)
- }
- default:
- {
- v = v1
- cell.Value = fmt.Sprintf("%v", v)
- }
- }
- } else {
- v = val
- cell.Value = fmt.Sprintf("%v", v)
- }
- if cell.Value == "<nil>" {
- cell.Value = ""
- }
- }
- }
- return file, nil
- }
- // QueryByMap 将查询到的数据,按照指定字段的值做为索引构建map并返回
- // columnName string: 作为索引的字段名称
- // sql string: 查询需要获取哪些字段的值,就是select后面跟着的部分,一般用"*"
- // where string: 过滤条件,就是where后面跟着的部分
- // order string: 排序条件,就是order by后面跟着的部分。默认是ASC排序,除非"-"开头则DESC排序
- // offset string: limit后面逗号相隔的两个数值,前者就是offset,后者就是count
- // count string: limit后面逗号相隔的两个数值,前者就是offset,后者就是count
- func QueryByMapMenu(sqlstr string, offset, count int, params []interface{}) ([]map[string]interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return nil, err
- }
- if offset < 0 {
- offset = 0
- }
- if count <= 0 {
- count = 0
- }
- if count > 0 {
- sqlstr += " limit " + strconv.Itoa(offset) + "," + strconv.Itoa(count)
- }
- rows, err := Dbs.Query(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- columnsType, _ := rows.ColumnTypes()
- columnsLen := len(columnsType)
- columns, _ := rows.Columns()
- queryData := make([]map[string]interface{}, 0)
- values := make([]interface{}, columnsLen)
- valuePtrs := make([]interface{}, columnsLen)
- for rows.Next() {
- for a := 0; a < columnsLen; a++ {
- valuePtrs[a] = &values[a]
- }
- rows.Scan(valuePtrs...)
- entry := make(map[string]interface{})
- for i, col := range columns {
- entry[col] = getValue(values[i], columnsType[i].DatabaseTypeName())
- }
- queryData = append(queryData, entry)
- }
- data := queryData
- return data, nil
- }
- func QueryByList(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- if count == 0 {
- count = 1000
- }
- recordcount := int64(0)
- if count > 1 {
- trow, err := Dbs.Queryx("SELECT COUNT(1) as count FROM ("+sqlstr+") a", params...)
- if err != nil {
- return nil, err
- }
- tt, err := rows2mapObjects(trow)
- if err != nil {
- return nil, err
- }
- recordcount = tt[0]["count"].(int64)
- }
- queryData := make([]map[string]interface{}, 1)
- var err error
- if count == 0 {
- // queryData, err = Engine.SQL(sqlstr, params...).Query().List()
- tqueryData, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- } else {
- if count > 0 && offset > 0 {
- offset = offset * count
- }
- //queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List()
- tqueryData, err := Dbs.Queryx(fmt.Sprintf(sqlstr+" limit %d , %d", offset, count), params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- }
- if err != nil {
- return nil, err
- }
- columnsname := make([]string, 0)
- listdata := make(map[string][]interface{})
- if len(queryData) > 0 {
- for i, _ := range queryData {
- if i == 0 {
- for i, _ := range queryData[0] {
- columnsname = append(columnsname, i)
- }
- }
- for _, v := range columnsname {
- listdata[v] = append(listdata[v], queryData[i][v])
- }
- }
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["rows"] = listdata
- //data["columnsname"] = columnsname
- data["total"] = recordcount
- data["code"] = 0
- data["message"] = "ok"
- if count > 0 {
- data["pages"] = math.Ceil(float64(recordcount) / float64(count))
- data["pageNum"] = math.Ceil(float64(offset+1) / float64(count))
- }
- data["pageSize"] = count
- return data, nil
- }
- func QueryByOption(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- if count == 0 {
- count = 1000
- }
- recordcount := int64(0)
- if count > 1 {
- trow, err := Dbs.Queryx("SELECT COUNT(1) as count FROM ("+sqlstr+") a", params...)
- if err != nil {
- return nil, err
- }
- tt, err := rows2mapObjects(trow)
- if err != nil {
- return nil, err
- }
- recordcount = tt[0]["count"].(int64)
- }
- queryData := make([]map[string]interface{}, 1)
- var err error
- if count == 0 {
- // queryData, err = Engine.SQL(sqlstr, params...).Query().List()
- tqueryData, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- } else {
- if count > 0 && offset > 0 {
- offset = offset * count
- }
- //queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List()
- tqueryData, err := Dbs.Queryx(fmt.Sprintf(sqlstr+" limit %d , %d", offset, count), params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- }
- if err != nil {
- return nil, err
- }
- columnsname := make([]string, 0)
- listdata := make(map[string][]interface{})
- if len(queryData) > 0 {
- for i, _ := range queryData {
- if i == 0 {
- for i, _ := range queryData[0] {
- columnsname = append(columnsname, i)
- }
- }
- for _, v := range columnsname {
- listdata[v] = append(listdata[v], queryData[i][v])
- }
- }
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["options"] = listdata
- //data["columnsname"] = columnsname
- data["total"] = recordcount
- data["code"] = 0
- data["message"] = "ok"
- if count > 0 {
- data["pages"] = math.Ceil(float64(recordcount) / float64(count))
- data["pageNum"] = math.Ceil(float64(offset+1) / float64(count))
- }
- data["pageSize"] = count
- return data, nil
- }
- func QueryByListSqlx(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- if count == 0 {
- count = 1000
- }
- recordcount := int64(0)
- if count > 1 {
- trow, err := Dbs.Queryx("SELECT COUNT(1) as count FROM ("+sqlstr+") a", params...)
- if err != nil {
- return nil, err
- }
- tt, err := rows2mapObjects(trow)
- if err != nil {
- return nil, err
- }
- recordcount = tt[0]["count"].(int64)
- }
- queryData := make([]map[string]interface{}, 1)
- var err error
- if count == 0 {
- // queryData, err = Engine.SQL(sqlstr, params...).Query().List()
- tqueryData, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- } else {
- if count > 0 && offset > 0 {
- offset = offset * count
- }
- //queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List()
- tqueryData, err := Dbs.Queryx(fmt.Sprintf(sqlstr+" limit %d , %d", offset, count), params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- }
- if err != nil {
- return nil, err
- }
- columnsname := make([]string, 0)
- listdata := make(map[string][]interface{})
- if len(queryData) > 0 {
- for i, _ := range queryData {
- if i == 0 {
- for i, _ := range queryData[0] {
- columnsname = append(columnsname, i)
- }
- }
- for _, v := range columnsname {
- listdata[v] = append(listdata[v], queryData[i][v])
- }
- }
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["rows"] = listdata
- //data["columnsname"] = columnsname
- data["total"] = recordcount
- data["code"] = 0
- data["message"] = "ok"
- if count > 0 {
- data["pages"] = math.Ceil(float64(recordcount) / float64(count))
- data["pageNum"] = math.Ceil(float64(offset+1) / float64(count))
- }
- data["pageSize"] = count
- return data, nil
- }
- func QueryByListv2Sqlx(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- //s := time.Now()
- queryData := make([]map[string]interface{}, 1)
- var err error
- tx, err := Dbs.Beginx()
- if err != nil {
- fmt.Println("GetT error:", err)
- }
- defer func() {
- switch {
- case err != nil:
- fmt.Println("__error:", err)
- if tx != nil {
- tx.Rollback()
- }
- default:
- if tx != nil {
- err = tx.Commit()
- }
- }
- }()
- //var resultstr string
- tqueryData, err := tx.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- //rows,_ := Dbs.Query(sqlstr,params...)
- //for rows.Next(){
- // rows.Scan(&resultstr)
- //}
- //println("QueryByListv2Sqlx=================",time.Now().Sub(s).Milliseconds())
- //fmt.Println(params)
- if err != nil {
- return nil, err
- }
- data := make(map[string]interface{})
- data["rows"] = queryData
- return data, nil
- }
- func QueryByListv2(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- queryData := make([]map[string]interface{}, 1)
- var err error
- tx, err := Dbs.Beginx()
- if err != nil {
- fmt.Println("GetT error:", err)
- }
- defer func() {
- switch {
- case err != nil:
- fmt.Println("__error:", err)
- if tx != nil {
- tx.Rollback()
- }
- default:
- if tx != nil {
- err = tx.Commit()
- }
- }
- }()
- tqueryData, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- if err != nil {
- return nil, err
- }
- data := make(map[string]interface{})
- data["rows"] = queryData
- return data, nil
- }
- func QueryByListList(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- if count == 0 {
- count = 1000
- }
- recordcount := int64(0)
- if count > 1 {
- trow, err := Dbs.Queryx("SELECT COUNT(1) as count FROM ("+sqlstr+") a", params...)
- if err != nil {
- return nil, err
- }
- tt, err := rows2mapObjects(trow)
- if err != nil {
- return nil, err
- }
- recordcount = tt[0]["count"].(int64)
- }
- queryData := make([]map[string]interface{}, 1)
- var err error
- if count == 0 {
- tqueryData, err := Dbs.Queryx(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- } else {
- if count > 0 && offset > 0 {
- offset = offset * count
- }
- tqueryData, err := Dbs.Queryx(fmt.Sprintf(sqlstr+" limit %d , %d", offset, count), params...)
- if err != nil {
- return nil, err
- }
- queryData, err = rows2mapObjects(tqueryData)
- }
- if err != nil {
- return nil, err
- }
- columnsname := make([]string, 0)
- listdata := make([]interface{}, 0)
- if len(queryData) > 0 {
- for i, _ := range queryData {
- if i == 0 {
- for i, _ := range queryData[0] {
- columnsname = append(columnsname, i)
- }
- }
- listdatarow := make([]interface{}, 0)
- for _, v := range columnsname {
- listdatarow = append(listdatarow, queryData[i][v])
- }
- listdata = append(listdata, listdatarow)
- }
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["list"] = listdata
- data["columnsname"] = columnsname
- data["total"] = recordcount
- data["code"] = 0
- data["message"] = "ok"
- if count > 0 {
- data["pages"] = math.Ceil(float64(recordcount) / float64(count))
- data["pageNum"] = math.Ceil(float64(offset+1) / float64(count))
- }
- data["pageSize"] = count
- return data, nil
- }
- func ExecQuery(sqlstr string, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- rows, err := Dbs.Exec(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- data := make(map[string]interface{})
- LastInsertId, _ := rows.LastInsertId()
- idPointer := (*int)(unsafe.Pointer(&LastInsertId))
- idd16 := *idPointer
- RowsAffected, _ := rows.RowsAffected()
- _idPointer := (*int)(unsafe.Pointer(&RowsAffected))
- _idd16 := *_idPointer
- data["result"] = rows
- data["LastInsertId"] = idd16
- data["RowsAffected"] = _idd16
- return data, nil
- }
- func ExecQuerySqlx(sqlstr string, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- rows, err := Dbs.Exec(sqlstr, params...)
- if err != nil {
- return nil, err
- }
- data := make(map[string]interface{})
- LastInsertId, _ := rows.LastInsertId()
- idPointer := (*int)(unsafe.Pointer(&LastInsertId))
- idd16 := *idPointer
- RowsAffected, _ := rows.RowsAffected()
- _idPointer := (*int)(unsafe.Pointer(&RowsAffected))
- _idd16 := *_idPointer
- data["result"] = rows
- data["LastInsertId"] = idd16
- data["RowsAffected"] = _idd16
- return data, nil
- }
- func ExecQueryT(sqlstr string, params []interface{}, tx *sqlx.Tx) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- rows, err := tx.Exec(sqlstr, params...)
- if err != nil {
- fmt.Println("exe", err)
- return nil, err
- }
- LastInsertId, _ := rows.LastInsertId()
- idPointer := (*int)(unsafe.Pointer(&LastInsertId))
- idd16 := *idPointer
- data := make(map[string]interface{})
- RowsAffected, _ := rows.RowsAffected()
- _idPointer := (*int)(unsafe.Pointer(&RowsAffected))
- _idd16 := *_idPointer
- data["LastInsertId"] = idd16
- data["RowsAffected"] = _idd16
- data["result"] = rows
- return data, nil
- }
- func ExecQuerys(sqlstr string, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- /*for i, v := range params{
- _, err := Dbs.Exec(sqlstr, v[i]...)
- if err != nil {
- return nil, err
- }
- }
- */
- data := make(map[string]interface{})
- data["result"] = nil
- return data, nil
- }
- func getValue(value interface{}, CT string) interface{} {
- var v interface{}
- val := value
- b, ok := val.([]byte)
- if ok {
- v1 := string(b)
- switch CT {
- case "TINYINT", "SMALLINT", "MEDIUMINT", "INT", "INTEGER", "BIGINT":
- {
- v, _ = strconv.ParseInt(v1, 10, 32)
- }
- case "FLOAT", "DOUBLE", "DECIMAL":
- {
- cindex := len(val.([]byte)) - strings.Index(v1, ".") - 1
- v2, _ := strconv.ParseFloat(v1, 32)
- v = toFixed(v2, cindex)
- }
- case "BOOL":
- {
- v, _ = strconv.ParseBool(v1)
- }
- default:
- {
- v = v1
- }
- }
- } else {
- v = val
- }
- return v
- }
|