138 lines
4.3 KiB
Go
138 lines
4.3 KiB
Go
package api
|
||
|
||
import (
|
||
"encoding/json"
|
||
"go-desk/internal/service"
|
||
"go-desk/internal/storage/models"
|
||
"go-desk/internal/storage/repository"
|
||
)
|
||
|
||
type SqlAPI struct {
|
||
sqlService *service.SqlExecService
|
||
resultRepo repository.ResultRepository
|
||
}
|
||
|
||
func NewSqlAPI() (*SqlAPI, error) {
|
||
sqlService, err := service.NewSqlExecService()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
resultRepo, err := repository.NewResultRepository()
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return &SqlAPI{sqlService, resultRepo}, nil
|
||
}
|
||
|
||
// ExecuteSQL 执行SQL语句
|
||
// 注意:SQL 语句应该已经包含分页信息(LIMIT 和 OFFSET),由客户端添加
|
||
func (api *SqlAPI) ExecuteSQL(connectionID uint, sqlStr string, database string) (map[string]interface{}, error) {
|
||
result, err := api.sqlService.ExecuteSQL(connectionID, sqlStr, database)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
response := map[string]interface{}{
|
||
"type": result.Type,
|
||
"data": result.Data,
|
||
"rowsAffected": result.RowsAffected,
|
||
"executionTime": result.ExecutionTime,
|
||
}
|
||
// 如果是查询,添加列顺序信息
|
||
if result.Type == "query" && len(result.Columns) > 0 {
|
||
response["columns"] = result.Columns
|
||
}
|
||
|
||
// 自动保存结果到历史记录(异步执行)
|
||
go func() {
|
||
api.resultRepo.Save(connectionID, database, sqlStr, result.Type, result.Data, result.Columns, result.RowsAffected, result.ExecutionTime)
|
||
}()
|
||
|
||
return response, nil
|
||
}
|
||
|
||
func (api *SqlAPI) GetDatabases(connectionID uint) ([]string, error) {
|
||
return api.sqlService.GetDatabases(connectionID)
|
||
}
|
||
|
||
func (api *SqlAPI) GetTables(connectionID uint, database string) ([]string, error) {
|
||
return api.sqlService.GetTables(connectionID, database)
|
||
}
|
||
|
||
func (api *SqlAPI) GetTableStructure(connectionID uint, database, tableName string) (map[string]interface{}, error) {
|
||
return api.sqlService.GetTableStructure(connectionID, database, tableName)
|
||
}
|
||
|
||
func (api *SqlAPI) GetIndexes(connectionID uint, database, tableName string) ([]map[string]interface{}, error) {
|
||
return api.sqlService.GetIndexes(connectionID, database, tableName)
|
||
}
|
||
|
||
func (api *SqlAPI) PreviewTableStructure(connectionID uint, database, tableName string, structure map[string]interface{}) ([]string, error) {
|
||
return api.sqlService.PreviewTableStructure(connectionID, database, tableName, structure)
|
||
}
|
||
|
||
func (api *SqlAPI) UpdateTableStructure(connectionID uint, database, tableName string, structure map[string]interface{}) ([]string, error) {
|
||
return api.sqlService.UpdateTableStructure(connectionID, database, tableName, structure)
|
||
}
|
||
|
||
func (api *SqlAPI) SaveResult(connectionID uint, database, sql string, resultType string, data interface{}, columns []string, rowsAffected int, executionTime int64) (map[string]interface{}, error) {
|
||
history, err := api.resultRepo.Save(connectionID, database, sql, resultType, data, columns, rowsAffected, executionTime)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return historyToMap(history), nil
|
||
}
|
||
|
||
func (api *SqlAPI) GetResultHistory(connectionID *uint, keyword string, limit, offset int) (map[string]interface{}, error) {
|
||
histories, total, err := api.resultRepo.Search(connectionID, keyword, limit, offset)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
items := make([]map[string]interface{}, len(histories))
|
||
for i, h := range histories {
|
||
items[i] = historyToMap(&h)
|
||
}
|
||
|
||
return map[string]interface{}{"items": items, "total": total}, nil
|
||
}
|
||
|
||
func (api *SqlAPI) GetResultHistoryByID(id uint) (map[string]interface{}, error) {
|
||
history, err := api.resultRepo.FindByID(id)
|
||
if err != nil || history == nil {
|
||
return nil, err
|
||
}
|
||
return historyToMap(history), nil
|
||
}
|
||
|
||
func (api *SqlAPI) DeleteResultHistory(id uint) error {
|
||
return api.resultRepo.Delete(id)
|
||
}
|
||
|
||
func historyToMap(history *models.SqlResultHistory) map[string]interface{} {
|
||
result := map[string]interface{}{
|
||
"id": history.ID,
|
||
"connection_id": history.ConnectionID,
|
||
"database": history.Database,
|
||
"sql": history.Sql,
|
||
"type": history.Type,
|
||
"rows_affected": history.RowsAffected,
|
||
"execution_time": history.ExecutionTime,
|
||
"created_at": history.CreatedAt,
|
||
}
|
||
|
||
if history.Data != "" {
|
||
var data interface{}
|
||
json.Unmarshal([]byte(history.Data), &data)
|
||
result["data"] = data
|
||
}
|
||
|
||
if history.Columns != "" {
|
||
var columns []string
|
||
json.Unmarshal([]byte(history.Columns), &columns)
|
||
result["columns"] = columns
|
||
}
|
||
|
||
return result
|
||
}
|