作者 yangfu

feat: view table by type

... ... @@ -2,20 +2,22 @@ package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"github.com/beego/beego/v2/core/validation"
)
type FieldOptionalValuesCommand struct {
ObjectType string `cname:"对象类型" json:"objectType" valid:"Required"`
ObjectId int `cname:"对象Id标识" json:"objectId" valid:"Required"`
Field domain.Field `cname:"列" json:"field" valid:"Required"`
Match string `cname:"匹配内容" json:"match"`
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
ObjectType string `cname:"对象类型" json:"objectType" valid:"Required"`
ObjectId int `cname:"对象Id标识" json:"objectId" valid:"Required"`
Field domain.Field `cname:"列" json:"field" valid:"Required"`
Match string `cname:"匹配内容" json:"match"`
PageNumber int `json:"pageNumber"`
PageSize int `json:"pageSize"`
Condition *domain.Condition `json:"condition"`
}
func (cmd *FieldOptionalValuesCommand) Valid(validation *validation.Validation) {
... ...
... ... @@ -23,6 +23,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) {
cmd.Where.PageNumber = cmd.PageNumber
cmd.Where.PageSize = cmd.PageSize
}
if err := cmd.Where.ValidSql(); err != nil {
validation.Error(err.Error())
}
}
func (cmd *TablePreviewCommand) ValidateCommand() error {
... ...
... ... @@ -24,6 +24,9 @@ func (cmd *DBTablePreviewCommand) Valid(validation *validation.Validation) {
cmd.Where.PageNumber = cmd.PageNumber
cmd.Where.PageSize = cmd.PageSize
}
if err := cmd.Where.ValidSql(); err != nil {
validation.Error(err.Error())
}
}
func (cmd *DBTablePreviewCommand) ValidateCommand() error {
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
import (
"strings"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
)
type TableDto struct {
// 表Id
... ... @@ -19,3 +23,38 @@ func (d *TableDto) Load(m *domain.Table) {
d.Name = m.Name
d.ParentId = m.ParentId
}
func SuitTableByView(tables []*TableDto, view string, name string) []*TableDto {
var mainTables = make(map[int]*TableDto)
var res = make([]*TableDto, 0)
if view == "main" {
for i := range tables {
t := tables[i]
if t.ParentId == 0 && t.TableType == domain.MainTable.ToString() {
mainTables[t.TableId] = t
res = append(res, t)
}
}
for i := range tables {
t := tables[i]
if t.TableType == domain.SubTable.ToString() {
if _, ok := mainTables[t.ParentId]; ok {
res = append(res, t)
}
}
}
} else {
res = tables
}
var matchName = make([]*TableDto, 0)
if len(name) > 0 {
for i := range res {
t := res[i]
if strings.Contains(t.Name, name) {
matchName = append(matchName, t)
}
}
res = matchName
}
return res
}
... ...
... ... @@ -12,6 +12,7 @@ import (
type SearchTableQuery struct {
// 表名称
Name string `cname:"表名称" json:"name"`
ViewType string `cname:"视图类型 full:完整 main:主表关系" json:"viewType"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"`
// 父级ID
... ...
... ... @@ -2,6 +2,7 @@ package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/command"
... ... @@ -85,6 +86,11 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *
},
},
}
if cmd.Condition != nil {
options.Where = append(options.Where, starrocks.Condition{
Condition: *cmd.Condition,
})
}
options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize)
dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db))
... ...
... ... @@ -241,6 +241,47 @@ func (tableService *TableService) Search(searchQuery *query.SearchTableQuery) (i
}, nil
}
// 表搜索
func (tableService *TableService) RelationGraph(searchQuery *query.SearchTableQuery) (interface{}, error) {
if err := searchQuery.ValidateQuery(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
tableRepository, _, _ := factory.FastPgTable(transactionContext, 0)
name :=searchQuery.Name
searchQuery.Name = ""
_, tables, err := tableRepository.Find(utils.ObjectToMap(searchQuery))
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var result = make([]*dto.TableDto, 0)
for _, table := range tables {
var item = &dto.TableDto{}
item.Load(table)
result = append(result, item)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
result = dto.SuitTableByView(result,searchQuery.ViewType,name)
return map[string]interface{}{
"count": len(result),
"tables":result,
}, nil
}
// 更新表服务
func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) {
if err := updateTableCommand.ValidateCommand(); err != nil {
... ...
... ... @@ -19,6 +19,29 @@ func (w Where) Offset() int {
return (w.PageNumber - 1) * w.PageSize
}
func (w Where) ValidSql() (err error) {
for _, c := range w.Conditions {
if err = SqlDetections(c.Like); err != nil {
return err
}
//if err = SqlDetections(c.In...); err != nil {
// return err
//}
//if err = SqlDetections(c.Ex...); err != nil {
// return err
//}
if err = SqlDetections(c.Order); err != nil {
return err
}
for _, r := range c.Range {
if err = SqlDetections(r.Val); err != nil {
return err
}
}
}
return
}
type Condition struct {
Field *Field `json:"field"`
Like string `json:"like"`
... ...
package domain
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"strings"
)
var sqlKeys = []string{
"'",
"`",
//",",
"--",
"/*",
//";",
"(",
")",
"#",
"*",
"or",
"=",
"having ",
"union",
"sleep",
"as ",
"from",
"where",
"exists",
"and",
"&&",
"or",
"||",
"not",
"in",
"like",
"is",
"between",
"union",
"all",
"having",
"order",
"group",
"by",
"print",
"sleep",
}
var ErrorSqlInject = fmt.Errorf("!!! 请检查输入的内容,存在注入风险")
func SqlDetections(args ...interface{}) error {
for _, item := range args {
if err := sqlDetection(item); err != nil {
return err
}
}
return nil
}
func sqlDetection(val interface{}) error {
sVal := strings.ToLower(utils.AssertString(val))
for _, kw := range sqlKeys {
if strings.Contains(sVal, kw) {
return ErrorSqlInject
}
}
return nil
}
... ...
... ... @@ -24,7 +24,8 @@ func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId i
if err != nil {
return nil, fmt.Errorf("文件未校验")
}
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName})
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableName": tableName,
"tableTypes":[]string{string(domain.MainTable),string(domain.SubTable),string(domain.SideTable)}})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
... ...
... ... @@ -136,6 +136,9 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{})
query.SetWhereByQueryOption(`table_type = ?`, "tableType")
query.SetWhereByQueryOption("name = ?", "tableName")
query.SetWhereByQueryOption("parent_id = ?", "parentId")
if v, ok := queryOptions["tableTypes"]; ok && len(v.([]string)) > 0 {
query.Where(`table_type in (?)`, pg.In(v.([]string)))
}
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, domain.ErrorNotFound
... ...
... ... @@ -111,7 +111,7 @@ func (controller *TableController) RelationGraph() {
Must(controller.Unmarshal(cmd))
cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString()}
cmd.Context = ParseContext(controller.BaseController)
data, err := tableService.Search(cmd)
data, err := tableService.RelationGraph(cmd)
controller.Response(data, err)
}
... ...