package restful import ( "database/sql" "errors" "fmt" "math" "strconv" "strings" "time" "unsafe" "tmr-watch/conf/setting" _ "github.com/denisenkom/go-mssqldb" _ "github.com/go-sql-driver/mysql" "github.com/patrickmn/go-cache" "github.com/tealeg/xlsx" "github.com/xormplus/xorm" ) var ( Engine *xorm.Engine SqlServerEngine *xorm.Engine Apisql_cache *cache.Cache ) func SQLT() *xorm.Session { tx := Engine.NewSession() return tx } // 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 Engine == nil { var err error if Engine, err = xorm.NewEngine(driverName, dataSourceName); err != nil { return err } if showlog { Engine.ShowSQL(true) } Engine.SetMaxIdleConns(maxIdleConns) Engine.SetMaxOpenConns(maxOpenConns) } if Apisql_cache == nil { Apisql_cache = cache.New(600*time.Second, 10*time.Second) SetCacheSql() } if SqlServerEngine == nil && setting.SQlserverSetting.Host != "" { // setting.SQlserverSetting.Host = "server=192.168.1.152\\MYSQL;user id=sa;password=1;database=SysData;encrypt=disable" sqlserverSourceName := fmt.Sprintf("server=%s;user id=%s;password=%s;database=%s;encrypt=disable", setting.SQlserverSetting.Host, setting.SQlserverSetting.User, setting.SQlserverSetting.Password, setting.SQlserverSetting.Name) var err error fmt.Println(1, sqlserverSourceName) SqlServerEngine, err = xorm.NewEngine("mssql", sqlserverSourceName) if err != nil { fmt.Println(err, 3, sqlserverSourceName) return err } if err = SqlServerEngine.Ping(); err != nil { panic(err) } fmt.Println(2, sqlserverSourceName) if showlog { SqlServerEngine.ShowSQL(true) } SqlServerEngine.SetMaxIdleConns(maxIdleConns) SqlServerEngine.SetMaxOpenConns(maxOpenConns) // count1, err := SqlServerEngine.Table("PFGL").QueryString() // fmt.Println(err, 4, count1) } return nil } func SetCacheSql() { valuesMap, err := Engine.SQL("SELECT sqlname, CONCAT(sqlstr,'|',IFNULL(params,'')) AS sqlstr FROM apisql WHERE ENABLE>0 ").QueryString() 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 *xorm.Session) (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 := tx.SQL("SELECT sqlstr, params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name).QueryString() 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("apisql:" + sqls) fmt.Println("param:" + param) } 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 { valuesMap, err := Engine.SQL("SELECT sqlstr,params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name).QueryString() 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("apisql:" + sqls) fmt.Println("param:" + param) } return sqls, param } func GetSqlByNameDBT(name string, tx *xorm.Session) (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 { valuesMap, err := tx.SQL("SELECT sqlstr,params FROM apisql WHERE sqlname = ? AND ENABLE>0 ", name).QueryString() 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("apisql:" + sqls) fmt.Println("param:" + param) } 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 { tt, err := Engine.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() if err != nil { fmt.Println("s1", err) return nil, err } if tt == nil { recordcount = 0 } else { 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() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List() } //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["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 *xorm.Session) (interface{}, error) { if err := sqlCheckParam(sqlstr); err != nil { return 0, err } recordcount := int64(0) if count > 1 { tt, err := tx.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() if err != nil { fmt.Println("s1", err) return nil, err } if tt == nil { recordcount = 0 } else { switch tt[0]["count"].(type) { case int64: recordcount = tt[0]["count"].(int64) case string: temp, _ := strconv.Atoi(tt[0]["count"].(string)) recordcount = int64(temp) } } } queryData := make([]map[string]interface{}, 1) var err error if count == 0 { queryData, err = tx.SQL(sqlstr, params...).Query().List() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = tx.SQL(sqlstr, params...).Limit(count, offset).Query().List() } //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["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 := Engine.SQL(sqlstr, params...).QueryRows() 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 == "" { 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 := Engine.SQL(sqlstr, params...).QueryRows() 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 //return Engine.SQL(sqlstr, params...).Query().List() } 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 { tt, err := Engine.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() 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() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List() } 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["lists"] = 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 { tt, err := Engine.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() 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() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = Engine.SQL(sqlstr, params...).Limit(count, offset).Query().List() } 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 *xorm.Session) (interface{}, error) { if err := sqlCheckParam(sqlstr); err != nil { return 0, err } if count == 0 { count = 1000 } recordcount := int64(0) if count > 1 { tt, err := tx.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() if err != nil { return nil, err } switch tt[0]["count"].(type) { case int64: recordcount = tt[0]["count"].(int64) case string: temp, _ := strconv.Atoi(tt[0]["count"].(string)) recordcount = int64(temp) } } queryData := make([]map[string]interface{}, 1) var err error if count == 0 { queryData, err = tx.SQL(sqlstr, params...).Query().List() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = tx.SQL(sqlstr, params...).Limit(count, offset).Query().List() } 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["lists"] = 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 QueryByListListT(sqlstr string, offset, count int, params []interface{}, tx *xorm.Session) (interface{}, error) { if err := sqlCheckParam(sqlstr); err != nil { return 0, err } if count == 0 { count = 1000 } recordcount := int64(0) if count > 1 { tt, err := tx.SQL("SELECT COUNT(*) as count FROM ("+sqlstr+") a", params...).Query().List() if err != nil { return nil, err } switch tt[0]["count"].(type) { case int64: recordcount = tt[0]["count"].(int64) case string: temp, _ := strconv.Atoi(tt[0]["count"].(string)) recordcount = int64(temp) } } queryData := make([]map[string]interface{}, 1) var err error if count == 0 { queryData, err = tx.SQL(sqlstr, params...).Query().List() } else { if count > 0 && offset > 0 { offset = offset * count } queryData, err = tx.SQL(sqlstr, params...).Limit(count, offset).Query().List() } 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 := Engine.SQL(sqlstr, params...).Execute() 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 *xorm.Session) (interface{}, error) { if err := sqlCheckParam(sqlstr); err != nil { return 0, err } rows, err := tx.SQL(sqlstr, params...).Execute() if err != nil { fmt.Println("exe", err) return nil, err } LastInsertId, err := 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"] = strconv.Itoa(idd16) data["LastInsertIdStr"] = 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 } func ExecQueryList(sqlstr string, params []interface{}) (interface{}, error) { if err := sqlCheckParam(sqlstr); err != nil { return 0, err } rows, err := Engine.SQL(sqlstr, params...).QueryString() if err != nil { return nil, err } data := make(map[string]interface{}) for _, item := range rows { data["result"] = item } return data, nil }