917 lines
26 KiB
Go
917 lines
26 KiB
Go
package dbrest
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
"regexp"
|
||
"strings"
|
||
"time"
|
||
|
||
"be.ems/lib/core/utils/ctx"
|
||
"be.ems/lib/dborm"
|
||
"be.ems/lib/global"
|
||
"be.ems/lib/log"
|
||
"be.ems/lib/services"
|
||
"be.ems/restagent/config"
|
||
|
||
"github.com/gorilla/mux"
|
||
"xorm.io/xorm"
|
||
)
|
||
|
||
type XormResponse struct {
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
type XormInsertResponse struct {
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
var (
|
||
// database management rest pattern, discard
|
||
XormGetDataUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
|
||
XormSelectDataUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/select/{elementTypeValue}/{objectTypeValue}"
|
||
XormInsertDataUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/insert/{elementTypeValue}/{objectTypeValue}"
|
||
XormUpdateDataUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/update/{elementTypeValue}/{objectTypeValue}"
|
||
XormDeleteDataUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/delete/{elementTypeValue}/{objectTypeValue}"
|
||
|
||
CustomXormGetDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
|
||
CustomXormSelectDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/select/{elementTypeValue}/{objectTypeValue}"
|
||
CustomXormInsertDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/insert/{elementTypeValue}/{objectTypeValue}"
|
||
CustomXormUpdateDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/update/{elementTypeValue}/{objectTypeValue}"
|
||
CustomXormDeleteDataUri = config.UriPrefix + "/databaseManagement/{apiVersion}/delete/{elementTypeValue}/{objectTypeValue}"
|
||
|
||
XormCommonUri = config.DefaultUriPrefix + "/databaseManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for internal
|
||
XormDatabaseUri = config.DefaultUriPrefix + "/database/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for crontask
|
||
XormDataRestUri = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/{objectTypeValue}"
|
||
XormExtDataUri = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for external
|
||
XormDataSQLUri = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for external
|
||
|
||
CustomXormCommonUri = config.UriPrefix + "/databaseManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for internal
|
||
CustomXormExtDataUri = config.UriPrefix + "/dataManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for external
|
||
CustomXormDataSQLUri = config.UriPrefix + "/dataManagement/{apiVersion}/{elementTypeValue}/{objectTypeValue}" // for external
|
||
|
||
// 查询数据库连接情况
|
||
UriDbConnection = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/dbConnection"
|
||
CustomUriDbConnection = config.UriPrefix + "/dataManagement/{apiVersion}/dbConnection" // for external
|
||
|
||
// 终结非法的数据库连接
|
||
UriDbStop = config.DefaultUriPrefix + "/dataManagement/{apiVersion}/dbStop"
|
||
CustomUriDbStop = config.UriPrefix + "/dataManagement/{apiVersion}/dbStop" // for external
|
||
|
||
)
|
||
|
||
var XEngine *xorm.Engine
|
||
|
||
type DatabaseClient struct {
|
||
dbType string
|
||
dbUrl string
|
||
dbConnMaxLifetime time.Duration
|
||
dbMaxIdleConns int
|
||
dbMaxOpenConns int
|
||
IsShowSQL bool
|
||
|
||
XEngine *xorm.Engine
|
||
}
|
||
|
||
var DbClient DatabaseClient
|
||
|
||
func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error {
|
||
DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local",
|
||
dbUser, dbPassword, dbHost, dbPort, dbName)
|
||
DbClient.dbType = dbType
|
||
DbClient.dbConnMaxLifetime = 0
|
||
DbClient.dbMaxIdleConns = 0
|
||
DbClient.dbMaxOpenConns = 0
|
||
if log.GetLevel() == log.LOG_TRACE {
|
||
DbClient.IsShowSQL = true
|
||
}
|
||
log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local",
|
||
dbType, dbUser, dbHost, dbPort, dbName)
|
||
|
||
var err error
|
||
DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl)
|
||
if err != nil {
|
||
log.Error("Failed to connet database:", err)
|
||
return err
|
||
}
|
||
DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime)
|
||
DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns)
|
||
DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns)
|
||
if DbClient.IsShowSQL {
|
||
//DbClient.XEngine.SetLogger(&log.Elogger)
|
||
DbClient.XEngine.ShowSQL(true)
|
||
}
|
||
XEngine = DbClient.XEngine
|
||
|
||
return nil
|
||
}
|
||
|
||
func GetUriSQLArray(r *http.Request) []string {
|
||
var sa []string
|
||
vars := r.URL.Query()
|
||
|
||
// 默认SQL
|
||
if s, ok := vars["SQL"]; ok {
|
||
for _, r := range s {
|
||
if r != "" {
|
||
sa = append(sa, r)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 查询总数
|
||
if totalSQL, ok := vars["totalSQL"]; ok {
|
||
if totalSQL[0] != "" {
|
||
sa = append(sa, totalSQL[0])
|
||
}
|
||
}
|
||
// 查询列表
|
||
if rowsSQL, ok := vars["rowsSQL"]; ok {
|
||
if rowsSQL[0] != "" {
|
||
sa = append(sa, rowsSQL[0])
|
||
}
|
||
}
|
||
|
||
if len(sa) == 0 {
|
||
log.Info("SQL is not exist")
|
||
return nil
|
||
}
|
||
|
||
log.Debug("SQL array:", sa)
|
||
return sa
|
||
}
|
||
|
||
// Get table name from SQL
|
||
func GetTableNameFromSQL(s string) string {
|
||
ls := strings.ToLower(s)
|
||
i1 := strings.Index(ls, "from")
|
||
i2 := strings.Index(ls, "where")
|
||
|
||
var ts string
|
||
if i1 > 0 {
|
||
if i2 > 0 && i2 > i1 {
|
||
ts = ls[i1+4 : i2]
|
||
}
|
||
if i2 < 0 {
|
||
ts = ls[i1+4:]
|
||
}
|
||
}
|
||
|
||
tn := strings.Trim(ts, " ")
|
||
log.Debug("i1:", i1, "i2:", i2, "tn:", tn)
|
||
return tn
|
||
}
|
||
|
||
func GetTableName(sql string) string {
|
||
ls := strings.ToLower(sql)
|
||
|
||
re := regexp.MustCompile(`from\s+(\S+)`)
|
||
matches := re.FindStringSubmatch(ls)
|
||
if len(matches) < 2 {
|
||
return ""
|
||
}
|
||
return matches[1]
|
||
}
|
||
|
||
func IsQuerySQL(s string) bool {
|
||
ts := strings.Trim(strings.ToLower(s), " ")
|
||
if strings.Index(ts, "select") != 0 {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
// xorm Get data from database
|
||
func ExtDatabaseExecSQL(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("ExtDatabaseExecSQL processing... ")
|
||
|
||
var sql []string
|
||
var err error
|
||
|
||
_, err = services.CheckExtValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
//vars := mux.Vars(r)
|
||
//tblName := vars["objectTypeValue"]
|
||
sql = GetUriSQLArray(r)
|
||
// select as must, todo ...
|
||
|
||
ls := services.ExtGetUriPageLimitString(r)
|
||
|
||
// data := make([]map[string]interface{}, 0)
|
||
// xormResponse := make([]map[string]interface{}, len(sql))
|
||
var xormResponse XormResponse
|
||
data := make([]map[string]interface{}, 0)
|
||
for i, s := range sql {
|
||
log.Tracef("SQL[%d]: %s", i, sql[i])
|
||
|
||
//rows := make([]map[string]interface{}, 0)
|
||
mapRows := make(map[string]interface{})
|
||
|
||
if s != "" {
|
||
// err = XEngine.SQL(s).Find(&rows)
|
||
// if IsQuerySQL(s) == false {
|
||
// services.ResponseNotAcceptable406QuerySQLError(w)
|
||
// return
|
||
// }
|
||
|
||
querySQL := s
|
||
if i == (len(sql) - 1) {
|
||
querySQL = querySQL + " " + ls
|
||
}
|
||
log.Debug("querySQL:", querySQL)
|
||
rows, err := DbClient.XEngine.Exec(querySQL)
|
||
if err != nil {
|
||
log.Error("SQL failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
tableName := GetTableName(s)
|
||
log.Debugf("s:%s tableName:%s", s, tableName)
|
||
mapRows[tableName] = rows
|
||
data = append(data, mapRows)
|
||
log.Trace("data:", data)
|
||
}
|
||
i++
|
||
}
|
||
xormResponse.Data = data
|
||
|
||
services.ResponseWithJson(w, http.StatusOK, xormResponse)
|
||
}
|
||
|
||
// xorm Get data from database
|
||
func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("ExtDatabaseGetData processing... ")
|
||
|
||
var sql []string
|
||
token, err := services.CheckExtValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
pack := "dbrest"
|
||
vars := mux.Vars(r)
|
||
module := ""
|
||
dbname := vars["elementTypeValue"]
|
||
tbname := vars["objectTypeValue"]
|
||
|
||
log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack)
|
||
|
||
// exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack)
|
||
// if err != nil {
|
||
// log.Error("Failed to get permission:", err)
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
// if !exist {
|
||
// log.Error("Not permission!")
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
|
||
sql = GetUriSQLArray(r)
|
||
// select as must, todo ...
|
||
if sql == nil {
|
||
wc := services.GetUriLocString(r)
|
||
if wc == "" {
|
||
sql = append(sql, fmt.Sprintf("select * from %s", tbname))
|
||
} else {
|
||
sql = append(sql, fmt.Sprintf("select * from %s where %s", tbname, wc))
|
||
}
|
||
}
|
||
|
||
ls := services.ExtGetUriPageLimitString(r)
|
||
|
||
// data := make([]map[string]interface{}, 0)
|
||
// xormResponse := make([]map[string]interface{}, len(sql))
|
||
var xormResponse XormResponse
|
||
data := make([]map[string]interface{}, 0)
|
||
for i, s := range sql {
|
||
log.Tracef("SQL[%d]: %s", i, sql[i])
|
||
|
||
rows := make([]map[string]interface{}, 0)
|
||
mapRows := make(map[string]interface{})
|
||
|
||
if s != "" {
|
||
// err = XEngine.SQL(s).Find(&rows)
|
||
if IsQuerySQL(s) == false {
|
||
services.ResponseNotAcceptable406QuerySQLError(w)
|
||
return
|
||
}
|
||
|
||
querySQL := s
|
||
if i == (len(sql) - 1) {
|
||
querySQL = querySQL + " " + ls
|
||
}
|
||
log.Debug("querySQL:", querySQL)
|
||
rows, err = DbClient.XEngine.QueryInterface(querySQL)
|
||
if err != nil {
|
||
log.Error("SQL failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
tableName := GetTableName(s)
|
||
log.Debugf("s:%s tableName:%s", s, tableName)
|
||
mapRows[tableName] = rows
|
||
data = append(data, mapRows)
|
||
log.Trace("data:", data)
|
||
}
|
||
i++
|
||
}
|
||
xormResponse.Data = data
|
||
|
||
services.ResponseWithJson(w, http.StatusOK, xormResponse)
|
||
}
|
||
|
||
func ExtDatabaseInsertData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("ExtDatabaseInsertData processing... ")
|
||
|
||
token, err := services.CheckExtValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
||
if err != nil {
|
||
log.Error("io.ReadAll failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
module := ""
|
||
dbname := vars["elementTypeValue"]
|
||
tbname := vars["objectTypeValue"]
|
||
pack := "dbrest"
|
||
|
||
log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack)
|
||
|
||
// exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack)
|
||
// if err != nil {
|
||
// log.Error("Failed to get permission:", err)
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
// if !exist {
|
||
// log.Error("permission deny!")
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
|
||
log.Debug("Request body:", string(body), "dataObject:", tbname)
|
||
insertData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &insertData)
|
||
|
||
tn, sql := dborm.ConstructInsertSQL(tbname, insertData)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Insert failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
// affected, err := InsertDataWithJson(insertData)
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
// xormResponse.Data = mapRow
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func ExtDatabaseUpdateData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("ExtDatabaseUpdateData processing... ")
|
||
|
||
token, err := services.CheckExtValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
module := ""
|
||
dbname := vars["elementTypeValue"]
|
||
tbname := vars["objectTypeValue"]
|
||
pack := "dbrest"
|
||
|
||
log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack)
|
||
|
||
// exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack)
|
||
// if err != nil {
|
||
// log.Error("Failed to get permission:", err)
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
// if !exist {
|
||
// log.Error("Not permission!")
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||
if err != nil {
|
||
log.Error("io.ReadAll is failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
wc := services.GetUriLocString(r)
|
||
|
||
log.Debug("Request body:", string(body), "Tablename:", tbname, "wc:", wc)
|
||
updateData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &updateData)
|
||
|
||
tn, sql := dborm.ConstructUpdateSQL(tbname, updateData, wc)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Update failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func ExtDatabaseDeleteData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("ExtDatabaseDeleteData processing... ")
|
||
|
||
token, err := services.CheckExtValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
module := ""
|
||
dbname := vars["elementTypeValue"]
|
||
tbname := vars["objectTypeValue"]
|
||
pack := "dbreset"
|
||
|
||
log.Debugf("token:%s, method:%s, module:%, dbname:%s, tbname:%s pack:%s", token, r.Method, module, dbname, tbname, pack)
|
||
|
||
// exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack)
|
||
// if err != nil {
|
||
// log.Error("Failed to get permission:", err)
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
// if !exist {
|
||
// log.Error("Not permission!")
|
||
// services.ResponseForbidden403NotPermission(w)
|
||
// return
|
||
// }
|
||
|
||
wc := services.GetUriLocString(r)
|
||
|
||
log.Debug("Table name:", tbname, "wc:", wc)
|
||
|
||
sql := dborm.ConstructDeleteSQL(tbname, wc)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
res, err := xSession.Exec(sql)
|
||
if err != nil {
|
||
log.Error("Update failed, err:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
affected, _ := res.RowsAffected()
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow["data"] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
// xorm Get data from database
|
||
func DatabaseGetData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseGetData processing... ")
|
||
|
||
var sql []string
|
||
var err error
|
||
|
||
_, err = services.CheckFrontValidRequest(w, r)
|
||
if err != nil {
|
||
log.Error("Request error:", err)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
sql = GetUriSQLArray(r)
|
||
// select as must, todo ...
|
||
|
||
if sql == nil {
|
||
wc := services.GetUriWhereString(r)
|
||
if wc == "" {
|
||
sql = append(sql, fmt.Sprintf("select * from %s", tblName))
|
||
} else {
|
||
sql = append(sql, fmt.Sprintf("select * from %s where %s", tblName, wc))
|
||
}
|
||
}
|
||
|
||
ls := services.GetUriPageLimitString(r)
|
||
|
||
// data := make([]map[string]interface{}, 0)
|
||
// xormResponse := make([]map[string]interface{}, len(sql))
|
||
var xormResponse XormResponse
|
||
data := make([]map[string]interface{}, 0)
|
||
for i, s := range sql {
|
||
log.Tracef("SQL[%d]: %s", i, sql[i])
|
||
|
||
rows := make([]map[string]interface{}, 0)
|
||
mapRows := make(map[string]interface{})
|
||
|
||
if s != "" {
|
||
// err = XEngine.SQL(s).Find(&rows)
|
||
if IsQuerySQL(s) == false {
|
||
services.ResponseNotAcceptable406QuerySQLError(w)
|
||
return
|
||
}
|
||
|
||
querySQL := s
|
||
if i == (len(sql) - 1) {
|
||
querySQL = querySQL + " " + ls
|
||
}
|
||
log.Debug("querySQL:", querySQL)
|
||
rows, err = DbClient.XEngine.QueryInterface(querySQL)
|
||
if err != nil {
|
||
log.Error("SQL failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
tableName := GetTableName(s)
|
||
log.Debugf("s:%s tableName:%s", s, tableName)
|
||
mapRows[tableName] = rows
|
||
data = append(data, mapRows)
|
||
log.Trace("data:", data)
|
||
}
|
||
i++
|
||
}
|
||
xormResponse.Data = data
|
||
|
||
services.ResponseWithJson(w, http.StatusOK, xormResponse)
|
||
}
|
||
|
||
func DatabaseInsertData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseInsertData processing... ")
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
||
if err != nil {
|
||
log.Error("io.ReadAll failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
tableName := vars["objectTypeValue"]
|
||
log.Debug("Request body:", string(body), "tableName:", tableName)
|
||
insertData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &insertData)
|
||
|
||
// 操作日志的IP
|
||
if tableName == "operation_log" || tableName == "security_log" {
|
||
ipAddr := strings.Split(r.RemoteAddr, ":")[0]
|
||
s := insertData["data"].([]any)
|
||
a := s[0].(map[string]any)
|
||
a["op_ip"] = ipAddr
|
||
} else if tableName == "mml_log" {
|
||
ipAddr := strings.Split(r.RemoteAddr, ":")[0]
|
||
s := insertData["data"].([]any)
|
||
a := s[0].(map[string]any)
|
||
a["ip"] = ipAddr
|
||
}
|
||
|
||
tn, sql := dborm.ConstructInsertSQL(tableName, insertData)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Insert failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
// affected, err := InsertDataWithJson(insertData)
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
// xormResponse.Data = mapRow
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func DatabaseUpdateData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseUpdateData processing... ")
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||
if err != nil {
|
||
log.Error("io.ReadAll is failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
wc := services.GetUriWhereString(r)
|
||
|
||
log.Debug("Request body:", string(body), "Table name:", tblName, "wc:", wc)
|
||
updateData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &updateData)
|
||
|
||
tn, sql := dborm.ConstructUpdateSQL(tblName, updateData, wc)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Update failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func DatabaseDeleteData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseDeleteData processing... ")
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
wc := services.GetUriWhereString(r)
|
||
|
||
log.Debug("Table name:", tblName, "wc:", wc)
|
||
|
||
sql := dborm.ConstructDeleteSQL(tblName, wc)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
res, err := xSession.Exec(sql)
|
||
if err != nil {
|
||
log.Error("Update failed, err:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
affected, _ := res.RowsAffected()
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow["data"] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
// 连接用户实例
|
||
func DbConnection(w http.ResponseWriter, r *http.Request) {
|
||
if dborm.DbClient.XEngine == nil {
|
||
services.ResponseErrorWithJson(w, 400, "无连接")
|
||
}
|
||
// 查询实例
|
||
result, err := dborm.DbClient.XEngine.QueryString("SHOW PROCESSLIST;")
|
||
if err != nil {
|
||
services.ResponseErrorWithJson(w, 500, err.Error())
|
||
}
|
||
filterData := []map[string]string{}
|
||
for _, r := range result {
|
||
if r["User"] != "system user" {
|
||
filterData = append(filterData, r)
|
||
}
|
||
}
|
||
// Sleep:连接处于空闲状态,没有执行任何操作。
|
||
// Query:连接正在执行一个查询语句。
|
||
// Execute:连接正在执行一个准备好的 SQL 语句。
|
||
// Connect:连接正在建立但尚未完成。
|
||
services.ResponseWithJson(w, 200, filterData)
|
||
}
|
||
|
||
// 关闭数据库连接
|
||
func DbStop(w http.ResponseWriter, r *http.Request) {
|
||
if dborm.DbClient.XEngine == nil {
|
||
services.ResponseErrorWithJson(w, 400, "无连接")
|
||
}
|
||
|
||
// json 請求參數獲取
|
||
var bodyArgs struct {
|
||
ID string `json:"ID" validate:"required"`
|
||
}
|
||
err := ctx.ShouldBindJSON(r, &bodyArgs)
|
||
if err != nil {
|
||
log.Error("io.ReadAll is failed:", err)
|
||
services.ResponseErrorWithJson(w, 400, err.Error())
|
||
return
|
||
}
|
||
|
||
// 关闭
|
||
rse, err := dborm.DbClient.XEngine.Exec("KILL ?;", bodyArgs.ID)
|
||
if err != nil {
|
||
services.ResponseErrorWithJson(w, 500, err.Error())
|
||
return
|
||
}
|
||
services.ResponseWithJson(w, 200, rse)
|
||
}
|
||
|
||
// xorm Get data from database
|
||
func TaskDatabaseGetData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseGetData processing... ")
|
||
|
||
var sql []string
|
||
var err error
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
sql = GetUriSQLArray(r)
|
||
// select as must, todo ...
|
||
|
||
if sql == nil {
|
||
wc := services.GetUriWhereString(r)
|
||
if wc == "" {
|
||
sql = append(sql, fmt.Sprintf("select * from %s", tblName))
|
||
} else {
|
||
sql = append(sql, fmt.Sprintf("select * from %s where %s", tblName, wc))
|
||
}
|
||
}
|
||
|
||
ls := services.GetUriPageLimitString(r)
|
||
|
||
// data := make([]map[string]interface{}, 0)
|
||
// xormResponse := make([]map[string]interface{}, len(sql))
|
||
var xormResponse XormResponse
|
||
data := make([]map[string]interface{}, 0)
|
||
for i, s := range sql {
|
||
log.Tracef("SQL[%d]: %s", i, sql[i])
|
||
|
||
rows := make([]map[string]interface{}, 0)
|
||
mapRows := make(map[string]interface{})
|
||
|
||
if s != "" {
|
||
// err = XEngine.SQL(s).Find(&rows)
|
||
if IsQuerySQL(s) == false {
|
||
services.ResponseNotAcceptable406QuerySQLError(w)
|
||
return
|
||
}
|
||
|
||
querySQL := s
|
||
if i == (len(sql) - 1) {
|
||
querySQL = querySQL + " " + ls
|
||
}
|
||
log.Debug("querySQL:", querySQL)
|
||
rows, err = DbClient.XEngine.QueryInterface(querySQL)
|
||
if err != nil {
|
||
log.Error("SQL failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
tableName := GetTableName(s)
|
||
log.Debugf("s:%s tableName:%s", s, tableName)
|
||
mapRows[tableName] = rows
|
||
data = append(data, mapRows)
|
||
log.Trace("data:", data)
|
||
}
|
||
i++
|
||
}
|
||
xormResponse.Data = data
|
||
|
||
services.ResponseWithJson(w, http.StatusOK, xormResponse)
|
||
}
|
||
|
||
func TaskDatabaseInsertData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseInsertData processing... ")
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
||
if err != nil {
|
||
log.Error("io.ReadAll failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
tableName := vars["objectTypeValue"]
|
||
log.Debug("Request body:", string(body), "tableName:", tableName)
|
||
insertData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &insertData)
|
||
|
||
tn, sql := dborm.ConstructInsertSQL(tableName, insertData)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Insert failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
// affected, err := InsertDataWithJson(insertData)
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
// xormResponse.Data = mapRow
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func TaskDatabaseUpdateData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseUpdateData processing... ")
|
||
|
||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||
if err != nil {
|
||
log.Error("io.ReadAll is failed:", err)
|
||
services.ResponseNotFound404UriNotExist(w, r)
|
||
return
|
||
}
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
wc := services.GetUriWhereString(r)
|
||
|
||
log.Debug("Request body:", string(body), "Table name:", tblName, "wc:", wc)
|
||
updateData := make(map[string]interface{})
|
||
_ = json.Unmarshal(body, &updateData)
|
||
|
||
tn, sql := dborm.ConstructUpdateSQL(tblName, updateData, wc)
|
||
log.Tracef("tn: %s sql :%s", tn, sql)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
var affected int64
|
||
for _, s := range sql {
|
||
res, err := xSession.Exec(s)
|
||
if err != nil {
|
||
log.Error("Update failed:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
n, _ := res.RowsAffected()
|
||
affected = affected + n
|
||
}
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow[tn] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|
||
|
||
func TaskDatabaseDeleteData(w http.ResponseWriter, r *http.Request) {
|
||
log.Debug("DatabaseDeleteData processing... ")
|
||
|
||
vars := mux.Vars(r)
|
||
tblName := vars["objectTypeValue"]
|
||
wc := services.GetUriWhereString(r)
|
||
|
||
log.Debug("Table name:", tblName, "wc:", wc)
|
||
|
||
sql := dborm.ConstructDeleteSQL(tblName, wc)
|
||
xSession := DbClient.XEngine.NewSession()
|
||
defer xSession.Close()
|
||
res, err := xSession.Exec(sql)
|
||
if err != nil {
|
||
log.Error("Update failed, err:", err)
|
||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||
return
|
||
}
|
||
affected, _ := res.RowsAffected()
|
||
xSession.Commit()
|
||
mapRow := make(map[string]interface{})
|
||
row := map[string]interface{}{"affectedRows": affected}
|
||
mapRow["data"] = row
|
||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||
}
|