123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359 |
- package restful
- import (
- "database/sql"
- "fmt"
- "log"
- "math"
- "reflect"
- "strconv"
- "strings"
- "time"
- "unsafe"
- "github.com/pkg/errors"
- _ "github.com/go-sql-driver/mysql"
- "github.com/jmoiron/sqlx"
- "github.com/patrickmn/go-cache"
- "github.com/tealeg/xlsx"
- "github.com/xormplus/xorm/schemas"
- "kpt.xdmy/pkg/setting"
- )
- 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(300 * time.Second)
- }
- if Apisql_cache == nil {
- Apisql_cache = cache.New(600*time.Second, 10*time.Second)
- }
- // SetCacheSql()
- return 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, ";") {
- 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 {
- valuesMap, err := MapStr("SELECT sqlstr, params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name)
- if err != nil {
- return err.Error(), "err"
- }
- if len(valuesMap) > 0 {
- sqls = valuesMap["sqlstr"]
- param = valuesMap["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) {
- var sqls, param string
- 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 := 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
- }
- func GetSqlByNameDBT(name string, tx *sqlx.Tx) (string, string) {
- var sqls, param string
- 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 := Dbs.Queryx("SELECT sqlstr,params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name)
- if err != nil {
- log.Default().Printf("GetSqlByNameDBT :%v", err)
- return "", ""
- }
- if rows.Next() {
- rows.Scan(&sqls, ¶m)
- }
- if sqls != "" {
- // 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 {
- sqlstr = fmt.Sprintf("SELECT COUNT(*) as count FROM (%s) a", sqlstr)
- err := BasicList(sqlstr, params, &recordcount)
- if err != nil {
- fmt.Println("s1", err)
- return nil, err
- }
- }
- 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)
- }
- if err != nil {
- return nil, err
- }
- if recordcount == 0 {
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["list"] = 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
- }
- // func QueryByMapT(sqlstr string, offset, count int, params []interface{}, tx *sqlx.Tx) (interface{}, error) {
- func QueryByMapT(sqlstr string, offset, count int, params []interface{}) (interface{}, error) {
- if err := sqlCheckParam(sqlstr); err != nil {
- return 0, err
- }
- recordcount := int64(0)
- if count > 1 {
- sql := "SELECT COUNT(*) as count FROM (" + sqlstr + ") a"
- err := BasicList(sql, params, &recordcount)
- if err != nil {
- fmt.Println("s1", err)
- return nil, err
- }
- }
- queryData := make([]map[string]interface{}, 1)
- // queryData := make([]map[string]string, 1)
- var err error
- if count == 0 {
- // queryData, err = MapStrList(sqlstr, params...)
- queryData, err = MapInterList(sqlstr, params...)
- } else {
- // if count > 0 && offset > 0 {
- // offset = offset * count
- // }
- sqllist := sqlstr + fmt.Sprintf(" limit %d offset %d", count, offset*count)
- // queryData, err = MapStrList(sqllist, params...)
- queryData, err = MapInterList(sqllist, params...)
- }
- if err != nil {
- return nil, err
- }
- if recordcount == 0 {
- recordcount = int64(len(queryData))
- }
- data := make(map[string]interface{})
- data["list"] = 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 {
- 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
- // }
- sqlstr += fmt.Sprintf(" limit %d offset %d", count, offset*count)
- tqueryData, err := Dbs.Queryx(sqlstr, 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["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 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 QueryByListT(sqlstr string, offset, count int, params []interface{}, tx *sqlx.Tx) (interface{}, error) {
- func QueryByListT(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 {
- tt, err := Dbs.Queryx("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...)
- if err != nil {
- return nil, err
- }
- tt.Next()
- tt.Scan(&recordcount)
- }
- var err error
- var sqllist string
- if count > 0 {
- sqllist = sqlstr + fmt.Sprintf(" limit %d offset %d", count, offset*count)
- }
- listdata, err := MapInterList(sqllist, params...)
- if err != nil {
- log.Default().Printf("QueryByListT MapInterList : %v", err)
- }
- data := make(map[string]interface{})
- data["lists"] = listdata
- 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 QueryByListListT(sqlstr string, offset, count int, params []interface{}, tx *sqlx.Tx) (interface{}, error) {
- func QueryByListListT(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 {
- sqlstr = fmt.Sprintf("SELECT COUNT(*) as count FROM (%s) a", sqlstr)
- err := BasicList(sqlstr, params, &recordcount)
- if err != nil {
- return nil, err
- }
- }
- queryData := make([]map[string]string, 1)
- var err error
- if count == 0 {
- queryData, err = MapStrList(sqlstr, params...)
- } else {
- // if count > 0 && offset > 0 {
- // offset = offset * count
- // }
- sqllist := sqlstr + fmt.Sprintf(" limit %d offset %d", count, offset*count)
- queryData, err = MapStrList(sqllist, params...)
- }
- 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 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
- }
- var res sql.Result
- var e error
- res, e = Dbs.Exec(sqlstr, params...)
- if e != nil {
- return nil, e
- }
- fmt.Printf("%#v\n", res)
- 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
- }
- 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 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 MapStrList(sql string, param ...interface{}) ([]map[string]string, error) {
- ress := make([]map[string]string, 0, 0)
- rows, err := Dbs.Queryx(sql, param...)
- if err != nil {
- log.Default().Printf("MapStrList Queryx: %v", err)
- return ress, err
- }
- col, err := rows.Columns()
- if err != nil {
- log.Default().Printf("BigpartUse clolumns: %v", err)
- return ress, err
- }
- for rows.Next() {
- m := make(map[string]string)
- rs, err := rows.SliceScan()
- if err != nil {
- log.Default().Printf("BigpartUse SliceScan: %v", err)
- return ress, err
- }
- for i, r := range rs {
- switch r.(type) {
- case []uint8:
- m[col[i]] = string(r.([]uint8))
- case int64:
- m[col[i]] = strconv.FormatInt(r.(int64), 10)
- }
- }
- ress = append(ress, m)
- }
- defer func() {
- if err := rows.Close(); err != nil {
- log.Default().Printf("sqlx row close:%v", err)
- }
- }()
- return ress, nil
- }
- // func MapInterList(sql string, param ...interface{}) ([]map[string]interface{}, error) {
- // ress := make([]map[string]interface{}, 0, 0)
- // rows, err := Dbs.Queryx(sql, param...)
- // if err != nil {
- // log.Default().Printf("MapInterList Queryx: %v", err)
- // return ress, err
- // }
- // col, err := rows.Columns()
- // if err != nil {
- // log.Default().Printf("BigpartUse clolumns: %v", err)
- // return ress, err
- // }
- // for rows.Next() {
- // m := make(map[string]interface{})
- // rs, err := rows.SliceScan()
- // if err != nil {
- // log.Default().Printf("BigpartUse SliceScan: %v", err)
- // return ress, err
- // }
- // for i, r := range rs {
- // switch r.(type) {
- // case []uint8:
- // m[col[i]] = string(r.([]uint8))
- // case int64:
- // m[col[i]] = r.(int64)
- // }
- // }
- // ress = append(ress, m)
- // }
- // defer func() {
- // if err := rows.Close(); err != nil {
- // log.Default().Printf("sqlx row close:%v", err)
- // }
- // }()
- // return ress, nil
- // }
- func MapInterList(sql string, param ...interface{}) ([]map[string]interface{}, error) {
- ress := make([]map[string]interface{}, 0, 0)
- rows, err := Dbs.Queryx(sql, param...)
- if err != nil {
- log.Default().Printf("MapInterList Queryx: %v", err)
- return ress, err
- }
- col, err := rows.Columns()
- if err != nil {
- log.Default().Printf("BigpartUse clolumns: %v", err)
- return ress, err
- }
- for rows.Next() {
- m := make(map[string]interface{})
- rs, err := rows.SliceScan()
- if err != nil {
- log.Default().Printf("BigpartUse SliceScan: %v", err)
- return ress, err
- }
- for i, r := range rs {
- switch r.(type) {
- case []uint8:
- m[col[i]] = string(r.([]uint8))
- case int64:
- m[col[i]] = r.(int64)
- }
- }
- ress = append(ress, m)
- }
- defer func() {
- if err := rows.Close(); err != nil {
- log.Default().Printf("sqlx row close:%v", err)
- }
- }()
- return ress, nil
- }
- func BasicList(sql string, params []interface{}, res ...interface{}) error {
- // fmt.Printf("%s\n", sql)
- if params == nil {
- params = make([]interface{}, 0)
- }
- // var count int
- tt, err := Dbs.Queryx(sql, params...)
- if err != nil {
- fmt.Println("s1", err)
- return err
- }
- if tt.Next() {
- tt.Scan(res...)
- // tt.Scan(&count)
- }
- defer func() {
- if err := tt.Close(); err != nil {
- log.Default().Printf("sqlx row close:%v", err)
- }
- }()
- return nil
- }
- func MapStr(sql string, param ...interface{}) (map[string]string, error) {
- m := make(map[string]string)
- rows, err := Dbs.Queryx(sql, param...)
- if err != nil {
- log.Default().Printf("MapStr Queryx: %v", err)
- return m, err
- }
- col, err := rows.Columns()
- if err != nil {
- log.Default().Printf("BigpartUse clolumns: %v", err)
- return m, err
- }
- if rows.Next() {
- rs, err := rows.SliceScan()
- if err != nil {
- log.Default().Printf("BigpartUse SliceScan: %v", err)
- return m, err
- }
- for i, r := range rs {
- switch r.(type) {
- case []uint8:
- m[col[i]] = string(r.([]uint8))
- case int64:
- m[col[i]] = strconv.FormatInt(r.(int64), 10)
- }
- }
- }
- defer func() {
- if err := rows.Close(); err != nil {
- log.Default().Printf("sqlx row close:%v", err)
- }
- }()
- return m, nil
- }
- func MapStrListTx(tx *sqlx.Tx, sql string, param ...interface{}) ([]map[string]string, error) {
- ress := make([]map[string]string, 0, 0)
- rows, err := tx.Queryx(sql, param...)
- if err != nil {
- log.Default().Printf("MapStrListTx Queryx: %v", err)
- return ress, err
- }
- col, err := rows.Columns()
- if err != nil {
- log.Default().Printf("BigpartUse clolumns: %v", err)
- return ress, err
- }
- for rows.Next() {
- m := make(map[string]string)
- rs, err := rows.SliceScan()
- if err != nil {
- log.Default().Printf("BigpartUse SliceScan: %v", err)
- return ress, err
- }
- for i, r := range rs {
- switch r.(type) {
- case []uint8:
- m[col[i]] = string(r.([]uint8))
- case int64:
- m[col[i]] = strconv.FormatInt(r.(int64), 10)
- }
- }
- ress = append(ress, m)
- }
- defer func() {
- if err := rows.Close(); err != nil {
- log.Default().Printf("sqlx row close:%v", err)
- }
- }()
- return ress, nil
- }
|