作者 yangfu

fix:formula create error

... ... @@ -17,9 +17,13 @@ type QuerySetDto struct {
Status int `json:"status"`
// 排序
Sort int `json:"sort"`
// 时间
Time string `json:"time"`
// 绑定的表ID
BindTableId int `json:"tableId"`
}
func (d *QuerySetDto) Load(m *domain.QuerySet) {
func (d *QuerySetDto) Load(m *domain.QuerySet) *QuerySetDto {
d.QuerySetId = m.QuerySetId
d.Type = m.Type
d.Flag = m.Flag
... ... @@ -27,4 +31,17 @@ func (d *QuerySetDto) Load(m *domain.QuerySet) {
d.ParentId = m.ParentId
d.Status = m.Status
d.Sort = m.Sort
d.Time = m.CreatedAt.Local().Format("2006-01-02 15:04:05")
d.BindTableId = m.QuerySetInfo.BindTableId
return d
}
func NewQuerySetDtoList(querySets []*domain.QuerySet) []*QuerySetDto {
var result = make([]*QuerySetDto, 0)
for _, set := range querySets {
var item = &QuerySetDto{}
item.Load(set)
result = append(result, item)
}
return result
}
... ...
... ... @@ -12,6 +12,7 @@ import (
type SearchQuerySetQuery struct {
Type string `cname:"类型" json:"type" valid:"Required"`
Flag string `cname:"标识" json:"flag"`
Status int `cname:"状态 1:启用 2:关闭" json:"status"`
MatchName string `cname:"匹配名称" json:"matchName"`
SortByName string `json:"sortByName"`
SortByTime string `json:"sortByTime"`
... ...
... ... @@ -8,6 +8,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/querySet/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/querySet/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/domainService"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
)
... ... @@ -58,14 +59,16 @@ func (querySetService *QuerySetService) Copy(ctx *domain.Context, copyCommand *c
}()
svr, _ := factory.FastQuerySetServices(transactionContext)
if err := svr.Copy(ctx, copyCommand.QuerySetId, copyCommand.Type, copyCommand.ParentId, copyCommand.Name); err != nil {
querySet, err := svr.Copy(ctx, copyCommand.QuerySetId, copyCommand.Type, copyCommand.ParentId, copyCommand.Name)
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
result := (&dto.QuerySetDto{}).Load(querySet)
return result, nil
}
// 创建查询集合服务
... ... @@ -230,7 +233,21 @@ func (querySetService *QuerySetService) RemoveQuerySet(ctx *domain.Context, remo
transactionContext.RollbackTransaction()
}()
svr, _ := factory.FastQuerySetServices(transactionContext)
if err := svr.Delete(ctx, removeQuerySetCommand.QuerySetId); err != nil {
err = svr.Delete(ctx, removeQuerySetCommand.QuerySetId)
// 依赖错误
if dependencyError, ok := err.(domainService.DependencyError); ok {
bindTables := make([]int, 0)
for _, t := range dependencyError.DependentTables {
bindTables = append(bindTables, t.TableId)
}
querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0)
_, querySets, _ := querySetRepository.Find(map[string]interface{}{"context": ctx, "bindTableIds": bindTables})
return map[string]interface{}{
"internalErr": err.Error(),
"relatedQuerySets": dto.NewQuerySetDtoList(querySets),
}, nil
}
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
... ... @@ -290,12 +307,7 @@ func (querySetService *QuerySetService) SearchQuerySet(ctx *domain.Context, sear
return nil, factory.FastError(err)
}
var result = make([]*dto.QuerySetDto, 0)
for _, set := range querySets {
var item = &dto.QuerySetDto{}
item.Load(set)
result = append(result, item)
}
var result = dto.NewQuerySetDtoList(querySets)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type CheckRowDuplicateCommand struct {
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
}
func (c *CheckRowDuplicateCommand) Valid(validation *validation.Validation) {
}
func (c *CheckRowDuplicateCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(c)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(c).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
} else {
return fmt.Errorf(validErr.Message)
}
}
}
return nil
}
... ...
... ... @@ -19,6 +19,7 @@ type TablePreviewCommand struct {
}
func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) {
if cmd.PageSize > 0 {
cmd.Where.PageNumber = cmd.PageNumber
cmd.Where.PageSize = cmd.PageSize
... ... @@ -30,6 +31,9 @@ func (cmd *TablePreviewCommand) Valid(validation *validation.Validation) {
func (cmd *TablePreviewCommand) ValidateCommand() error {
valid := validation.Validation{}
if cmd.TableId == 0 {
return fmt.Errorf("暂无数据可预览")
}
b, err := valid.Valid(cmd)
if err != nil {
return err
... ...
... ... @@ -42,24 +42,7 @@ func (tableService *TableService) DBTablePreview(ctx *domain.Context, cmd *comma
options.SetCondition(cmd.Where.Conditions)
options.SetOffsetLimit(cmd.Where.PageNumber, cmd.Where.PageSize)
var dataTable *domain.DataTable
switch cmd.ObjectId {
case domain.DBTableTableOperateLog.ToInt():
options.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.CommonLog.ToString()},
}})
case domain.DBTableQuerySetLog.ToInt():
options.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.QuerySetLog.ToString()},
}})
}
options.AdditionOptionsByTable(table)
dataTable, err = starrocks.Query(options, starrocks.WrapQueryFuncWithDB(pg.GormDB))
if err != nil {
... ...
... ... @@ -143,7 +143,28 @@ func exportTableTo(ctx *domain.Context, cmd *command.TablePreviewCommand, table
Limit: blockSize,
Table: table,
}
if table.TableType == domain.ObjectDBTable {
switch table.TableId {
case domain.DBTableTableOperateLog.ToInt():
options.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.CommonLog.ToString()},
}})
case domain.DBTableQuerySetLog.ToInt():
options.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.QuerySetLog.ToString()},
}})
}
}
options.SetCondition(cmd.Where.Conditions).SetDefaultOrder()
source <- Query{
Index: i,
Options: options,
... ...
... ... @@ -73,6 +73,7 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *
}
options := &starrocks.QueryOptions{
Table: table,
TableName: table.SQLName,
Select: []*domain.Field{field},
Where: []starrocks.Condition{
... ... @@ -91,6 +92,7 @@ func (tableService *TableService) FieldOptionalValues(ctx *domain.Context, cmd *
Condition: *cmd.Condition,
})
}
options.AdditionOptionsByTable(table)
options.SetOffsetLimit(cmd.PageNumber, cmd.PageSize)
dataTable, err = starrocks.Query(*options, starrocks.WrapQueryFuncWithDB(db))
... ...
... ... @@ -12,6 +12,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"strconv"
"strings"
)
... ... @@ -431,11 +432,15 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command
for _, f := range cmd.TableFields {
set.AddStr(f.TableSqlName)
}
sql := "select " + cmd.ExprSql + " as expr"
selectValue := cmd.ExprSql
if _, parseErr := strconv.ParseFloat(cmd.ExprSql, 64); parseErr != nil {
selectValue = "'" + selectValue + "'"
}
sql := "select " + selectValue + " as expr"
if len(set.KeysStr()) > 0 {
sql += " from " + strings.Join(set.KeysStr(), ",")
}
sql += " limit 1"
}
tx := starrocks.DB.Exec(sql)
if tx.Error != nil {
return map[string]string{
... ... @@ -445,6 +450,110 @@ func (tableService *TableService) ValidExprSql(ctx *domain.Context, cmd *command
return struct{}{}, nil
}
func (tableService *TableService) CheckRowDuplicate(ctx *domain.Context, cmd *command.CheckRowDuplicateCommand) (interface{}, error) {
var defaultResponse = map[string]interface{}{
"rowDuplicateFlag": false,
}
if cmd.TableId == 0 {
return defaultResponse, nil
}
if err := cmd.ValidateCommand(); 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()
}()
var table *domain.Table
_, table, err = factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, factory.FastError(err)
}
var options = starrocks.QueryOptions{
Table: table,
}
total, duplicateTotal, err := starrocks.WrapQueryHasDuplicateRowWithDB(options, starrocks.DB)()
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"tableName": table.Name,
"rowDuplicateFlag": total != duplicateTotal,
"rowTotal": total,
"rowDuplicateTotal": total - duplicateTotal,
}, nil
}
func (tableService *TableService) CheckRowDuplicateV2(ctx *domain.Context, cmd *command.CheckRowDuplicateCommand) (interface{}, error) {
var defaultResponse = map[string]interface{}{
"rowDuplicateFlag": false,
}
if cmd.TableId == 0 {
return defaultResponse, nil
}
if err := cmd.ValidateCommand(); 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()
}()
var table *domain.Table
_, table, err = factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, factory.FastError(err)
}
querySetRepository, _, _ := factory.FastPgQuerySet(transactionContext, 0)
querySet, err := querySetRepository.FindOne(map[string]interface{}{"BindTableId": table.TableId, "context": ctx})
if err != nil {
return nil, factory.FastError(err)
}
if len(querySet.QueryComponents) == 1 {
return defaultResponse, nil
}
/*
重复判断
select max(id) from Schema_xiao_shou_ming_xi_t266316_c1 GROUP BY id HAVING count(id)>=2 limit 10
SELECT * FROM `Schema_xiao_shou_ming_xi_t266316_c1` where id = '1c04c626-7c96-4c31-9564-744051332b7c'
*/
var options = starrocks.QueryOptions{
Table: table,
}
total, duplicateTotal, err := starrocks.WrapQueryHasDuplicateRowByIDWithDB(options, starrocks.DB)()
if err != nil {
return nil, factory.FastError(err)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"tableName": table.Name,
"rowDuplicateFlag": total != duplicateTotal,
"rowTotal": total,
"rowDuplicateTotal": total - duplicateTotal,
}, nil
}
func NewTableService(options map[string]interface{}) *TableService {
newTableService := &TableService{}
return newTableService
... ...
... ... @@ -43,7 +43,6 @@ func (tableService *TableService) TablePreview(ctx *domain.Context, cmd *command
return nil, factory.FastError(err)
}
response := (&dto.TablePreviewDto{}).Load(table, dataTable, domain.ObjectMetaTable)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
... ...
... ... @@ -237,7 +237,7 @@ var DBTables = map[int]*Table{
},
},
DBTableQuerySetLog.ToInt(): &Table{
TableId: 1,
TableId: 2,
TableType: ObjectDBTable,
Name: "日志信息",
SQLName: "metadata.logs",
... ...
... ... @@ -3,6 +3,7 @@ package domain
import (
"fmt"
"math/rand"
"strings"
"time"
)
... ... @@ -70,7 +71,7 @@ func (table *Table) WithContext(ctx *Context) *Table {
}
func (table *Table) WithPrefix(prefix string) *Table {
table.SQLName = fmt.Sprintf("%v_%v", prefix, table.SQLName)
table.SQLName = fmt.Sprintf("%v_%v", strings.ToLower(prefix), table.SQLName)
return table
}
... ...
... ... @@ -329,7 +329,7 @@ func NewSplitTableRequest(param domain.ReqSplitTable) SplitTableRequest {
return SplitTableRequest{
DatabaseTableName: param.FromTable.SQLName,
SplitTableName: param.ToSubTable.SQLName,
DatabaseTableFieldSchemas: ToFieldSchemas(param.FromTable.DataFields),
DatabaseTableFieldSchemas: ToFieldSchemas(param.ToSubTable.DataFields),
SplitTableFieldSchemas: ToFieldSchemas(param.ToSubTable.Fields(false)),
ManuallyFieldSchemas: ToFieldSchemas(param.ToSubTable.ManualFields),
}
... ...
... ... @@ -14,6 +14,8 @@ var (
ErrQuerySetNameExists = fmt.Errorf("已存在")
ErrQuerySetParentNotExists = fmt.Errorf("父级不存在")
ErrQuerySetInvalidType = fmt.Errorf("查询集合的类型有误")
ErrQuerySetDeleteStatusOn = fmt.Errorf("无法删除已启用的内容")
ErrFieldsNotMatch = func(table string) error { return fmt.Errorf("[%v]字段数量不一致或类型不匹配", table) }
)
type QuerySetService struct {
... ... @@ -99,6 +101,10 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom
return err
}
if err = ptr.validQueryComponents(queryComponents); err != nil {
return err
}
// 调用底层的组装sql
formulasGenerateResponse, err := ByteCore.FormulasGenerate(domain.ReqFormulasGenerate{
QuerySet: qs,
... ... @@ -130,6 +136,24 @@ func (ptr *QuerySetService) Update(ctx *domain.Context, querySetId int, queryCom
return nil
}
func (ptr *QuerySetService) validQueryComponents(queryComponents []*domain.QueryComponent) error {
if len(queryComponents) == 0 {
return nil
}
m := queryComponents[0]
for i := 1; i < len(queryComponents); i++ {
item := queryComponents[i]
if len(item.MasterTable.Name) == 0 {
continue
}
if len(item.MasterTable.Fields) != len(m.MasterTable.Fields) {
return ErrFieldsNotMatch(item.MasterTable.Name)
}
// 类型匹配
}
return nil
}
func (ptr *QuerySetService) UpdateQuerySetLog(ctx *domain.Context, querySet *domain.QuerySet, queryComponents []*domain.QueryComponent) error {
var res = make([]FastSourceLog, 0)
if logs := conditionsEditLog(ctx, querySet, queryComponents); len(logs) > 0 {
... ... @@ -395,6 +419,17 @@ func (ptr *QuerySetService) Rename(ctx *domain.Context, querySetId int, name str
if err != nil {
return err
}
if qs.QuerySetInfo.BindTableId > 0 {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableId": qs.QuerySetInfo.BindTableId})
if err != nil {
return err
}
table.Name = name
if _, err := tableRepository.Save(table); err != nil {
return err
}
}
// 日志
if err = FastLog(ptr.transactionContext, domain.QuerySetLog, qs.QuerySetId, &RenameQuerySetLog{
LogEntry: domain.NewLogEntry(qs.Name, qs.Type, domain.UnKnown, ctx),
... ... @@ -442,17 +477,17 @@ func (ptr *QuerySetService) ChangeStatus(ctx *domain.Context, querySetId int, st
return nil
}
func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, groupId int, name string) error {
func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string, groupId int, name string) (*domain.QuerySet, error) {
querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext)
qs, err := querySetRepository.FindOne(map[string]interface{}{"querySetId": querySetId})
if err != nil {
return err
return nil, err
}
copy := copyQuerySet(qs, t, groupId, name)
copy.Sort, err = dao.QuerySetCurrentSort(ptr.transactionContext, copy.Type, copy.ParentId)
if err != nil {
return err
return nil, err
}
// check duplicate name
options := map[string]interface{}{
... ... @@ -462,45 +497,45 @@ func (ptr *QuerySetService) Copy(ctx *domain.Context, querySetId int, t string,
"parentId": groupId,
}
if found, foundErr := querySetRepository.FindOne(options); foundErr == nil && found != nil && found.Name == name {
return ErrQuerySetNameExists
return nil, ErrQuerySetNameExists
}
if copy.QuerySetInfo.BindTableId != 0 {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": copy.QuerySetInfo.BindTableId})
if err != nil {
return err
return nil, err
}
copyTable := NewTable(domain.TableType(t), name, table.Fields(false), 0).WithContext(ctx).WithPrefix(qs.Type)
copyTable, err = tableRepository.Save(copyTable)
if err != nil {
return err
return nil, err
}
// 调用底层的组装sql
formulasGenerateResponse, err := ByteCore.FormulasGenerate(domain.ReqFormulasGenerate{
QuerySet: qs,
Table: table,
Table: copyTable,
QueryComponents: qs.QueryComponents,
})
if err != nil {
return err
return nil, err
}
if len(formulasGenerateResponse.FormulaName) > 0 && formulasGenerateResponse.FormulaName != table.SQLName {
copyTable.SQLName = formulasGenerateResponse.FormulaName
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
copyTable, err = tableRepository.Save(copyTable)
if err != nil {
return err
return nil, err
}
}
copy.QuerySetInfo.BindTableId = copyTable.TableId
}
_, err = querySetRepository.Save(copy)
copy, err = querySetRepository.Save(copy)
if err != nil {
return err
return nil, err
}
return nil
return copy, nil
}
func copyQuerySet(qs *domain.QuerySet, t string, groupId int, name string) *domain.QuerySet {
... ... @@ -528,10 +563,14 @@ func (ptr *QuerySetService) Delete(ctx *domain.Context, querySetId int) error {
}
querySetRepository, _ := repository.NewQuerySetRepository(ptr.transactionContext)
tableDependencyService, _ := NewTableDependencyService(ptr.transactionContext)
// 1.判断依赖,删除表
for i := range querySets {
if _, err := querySetRepository.Remove(querySets[i]); err != nil {
return err
}
if querySets[i].Flag != domain.FlagGroup && querySets[i].Type == domain.SchemaTable.ToString() && querySets[i].Status == domain.StatusOn {
return ErrQuerySetDeleteStatusOn
}
if querySets[i].QuerySetInfo.BindTableId > 0 {
if err := tableDependencyService.HasDependencyError(ctx, querySets[i].QuerySetInfo.BindTableId); err != nil {
return err
... ... @@ -539,6 +578,11 @@ func (ptr *QuerySetService) Delete(ctx *domain.Context, querySetId int) error {
if err := dao.TableSoftDelete(ptr.transactionContext, querySets[i].QuerySetInfo.BindTableId, domain.TableType(querySets[i].Type)); err != nil {
return err
}
}
}
// 2.底层清理
for i := range querySets {
if querySets[i].QuerySetInfo.BindTableId > 0 {
ByteCore.FormulasClear(domain.ReqFormulasClear{
QuerySetId: querySets[i].QuerySetId,
})
... ... @@ -653,6 +697,14 @@ func (ptr *QuerySetService) DependencyGraph(ctx *domain.Context, querySetId int)
tableDependencyService, _ := NewTableDependencyService(ptr.transactionContext)
dependencies = tableDependencyService.TableDependTree(tables, querySet.QuerySetInfo.BindTableId)
_, querySets, err := querySetRepository.Find(map[string]interface{}{"context": ctx, "bindTableIds": dependencies.TableIds()})
if err != nil {
return nil, err
}
if len(querySets) > 0 {
dependencies.BindQuerySet(querySets)
}
return dependencies, nil
}
... ...
... ... @@ -8,14 +8,19 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"strings"
)
type DependencyError struct {
t *domain.Table
DependentTables []*domain.Table
}
func (d DependencyError) Error() string {
return fmt.Sprintf("已关联%v:%v", domain.EnumsDescription(domain.ObjectTypeMap, d.t.TableType), d.t.Name)
var relations = make([]string, 0)
for _, t := range d.DependentTables {
relations = append(relations, fmt.Sprintf("%v%v", domain.EnumsDescription(domain.ObjectTypeMap, t.TableType), t.Name))
}
return fmt.Sprintf("引用对象:%v", strings.Join(relations, ","))
}
type CircleDependError struct {
... ... @@ -64,11 +69,14 @@ func (ptr *TableDependencyService) CircleTable() *domain.Table {
}
func (ptr *TableDependencyService) HasDependencyError(ctx *domain.Context, dependencyTable int) error {
table, ok := TableHasDependency(ptr.transactionContext, ctx, dependencyTable)
tables, ok := TableHasDependency(ptr.transactionContext, ctx, dependencyTable)
if !ok {
return nil
}
return DependencyError{table}
if len(tables) > 0 {
return DependencyError{tables}
}
return nil
}
func (ptr *TableDependencyService) Detect(ctx *domain.Context, edges [][]int) bool {
... ... @@ -240,16 +248,16 @@ func (ptr *TableDependencyService) makeTrees(childMap map[int][]int, rootNodes [
return set.KeysInt()
}
func TableHasDependency(transactionContext *pgTransaction.TransactionContext, ctx *domain.Context, dependencyTable int) (*domain.Table, bool) {
func TableHasDependency(transactionContext *pgTransaction.TransactionContext, ctx *domain.Context, dependencyTable int) ([]*domain.Table, bool) {
tableRepository, _ := repository.NewTableRepository(transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "dependencyTable": dependencyTable})
_, tables, err := tableRepository.Find(map[string]interface{}{"context": ctx, "dependencyTable": dependencyTable})
if errors.Is(err, domain.ErrorNotFound) {
return nil, false
}
if table == nil && err != nil {
if tables == nil && err != nil {
return nil, false
}
return table, true
return tables, true
}
type TableDependTree struct {
... ... @@ -267,7 +275,31 @@ func (td TableDependTree) EdgesArray() [][]int {
return res
}
func (td TableDependTree) TableIds() []int {
var set = collection.NewSet()
for i := range td.Nodes {
set.Add(td.Nodes[i].TableId)
}
return set.KeysInt()
}
func (td *TableDependTree) BindQuerySet(querySets []*domain.QuerySet) {
for i := range td.Nodes {
for j := range querySets {
if td.Nodes[i].TableId == querySets[j].QuerySetInfo.BindTableId {
td.Nodes[i].QuerySetId = querySets[j].QuerySetId
}
}
}
for j := range querySets {
if td.NodeSelected.TableId == querySets[j].QuerySetInfo.BindTableId {
td.NodeSelected.QuerySetId = querySets[j].QuerySetId
}
}
}
type TableNode struct {
QuerySetId int `json:"querySetId"`
TableId int `json:"tableId"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表
Type string `json:"type"`
... ...
... ... @@ -73,11 +73,10 @@ func (ptr *UpdateTableStructService) UpdateTableStruct(ctx *domain.Context, tabl
}); err != nil {
return nil, err
}
// 通知底层
//if _, err = ByteCore.SplitTable(domain.ReqSplitTable{FromTable: mainTable, ToSubTable: table}); err != nil {
// return nil, err
//}
if _, err = ByteCore.SplitTable(domain.ReqSplitTable{FromTable: mainTable, ToSubTable: table}); err != nil {
return nil, err
}
return struct{}{}, nil
}
... ...
... ... @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"github.com/go-pg/pg/v10"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
... ... @@ -132,6 +133,7 @@ func (repository *QuerySetRepository) FindOne(queryOptions map[string]interface{
query := sqlbuilder.BuildQuery(tx.Model(querySetModel), queryOptions)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption("query_set_id = ?", "querySetId")
query.SetWhereByQueryOption("query_set_info->'BindTableId' = '?'", "BindTableId")
query.SetWhereByQueryOption("type = ?", "type")
query.SetWhereByQueryOption("flag = ?", "flag")
query.SetWhereByQueryOption("parent_id = ?", "parentId")
... ... @@ -157,10 +159,14 @@ func (repository *QuerySetRepository) Find(queryOptions map[string]interface{})
WhereContext(query, queryOptions)
query.SetWhereByQueryOption("type = ?", "type")
query.SetWhereByQueryOption("flag = ?", "flag")
query.SetWhereByQueryOption("status = ?", "status")
query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["matchName"]), "matchName")
if v, ok := queryOptions["inParentIds"]; ok && len(v.([]int)) > 0 {
query.Where("parent_id in (?)", pg.In(v))
}
if v, ok := queryOptions["bindTableIds"]; ok && len(v.([]int)) > 0 {
query.Where("query_set_info->'BindTableId' in (?)", pg.In(utils.ToArrayString(v.([]int))))
}
if v, ok := queryOptions["sortByName"]; ok && len(v.(string)) > 0 {
query.SetOrderDirect("pin_name", v.(string))
} else if v, ok := queryOptions["sortByTime"]; ok && len(v.(string)) > 0 {
... ...
... ... @@ -178,6 +178,9 @@ func (repository *TableRepository) Find(queryOptions map[string]interface{}) (in
if v, ok := queryOptions["module"]; ok && v.(int) > 0 {
query.Where(`(cast(table_info->>'module' as integer) & ?) >0`, v)
}
if v, ok := queryOptions["dependencyTable"]; ok && v.(int) > 0 {
query.Where(`table_info->'dependencyTables' @> '[?]'`, v.(int))
}
//query.SetOffsetAndLimit(20)
query.SetOrderDirect("table_id", "DESC")
... ...
... ... @@ -84,6 +84,31 @@ func (o *QueryOptions) SetDefaultOrder() *QueryOptions {
return o
}
func (o *QueryOptions) AdditionOptionsByTable(table *domain.Table) *QueryOptions {
if table.TableType != domain.ObjectDBTable {
return o
}
switch table.TableId {
case domain.DBTableTableOperateLog.ToInt():
o.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.CommonLog.ToString()},
}})
case domain.DBTableQuerySetLog.ToInt():
o.SetCondition([]domain.Condition{{
Field: &domain.Field{
SQLName: "log_type",
SQLType: domain.String.ToString(),
},
In: []interface{}{domain.QuerySetLog.ToString()},
}})
}
return o
}
type Condition struct {
domain.Condition
Distinct bool
... ... @@ -291,3 +316,54 @@ func ArrayInterfaceToString(args []interface{}) []string {
}
return result
}
// WrapQueryHasDuplicateRowWithDB query table view has duplicate row
// result 1 represent is true other is false
func WrapQueryHasDuplicateRowWithDB(params QueryOptions, db *gorm.DB) func() (int64, int64, error) {
return func() (int64, int64, error) {
var total int64
var duplicateTotal int64
query := db.Table(params.Table.SQLName)
fieldNames := make([]string, 0)
for _, f := range params.Table.DataFields {
fieldNames = append(fieldNames, fmt.Sprintf("ifnull(%s,'')", f.SQLName))
}
query.Select(fmt.Sprintf("count(0) c1,count(distinct %s) c2", strings.Join(fieldNames, ",")))
row := query.Row()
if row.Err() != nil {
return total, duplicateTotal, row.Err()
}
if err := row.Scan(&total, &duplicateTotal); err != nil {
return total, duplicateTotal, err
}
if total == duplicateTotal {
return total, duplicateTotal, nil
}
return total, duplicateTotal, nil
}
}
func WrapQueryHasDuplicateRowByIDWithDB(params QueryOptions, db *gorm.DB) func() (int64, int64, error) {
return func() (int64, int64, error) {
var total int64
var duplicateTotal int64
query := db.Table(params.Table.SQLName)
fieldNames := make([]string, 0)
fieldNames = append(fieldNames, "id")
for _, f := range params.Table.DataFields {
fieldNames = append(fieldNames, fmt.Sprintf("ifnull(%s,'')", f.SQLName))
}
query.Select(fmt.Sprintf("count(0) c1,count(distinct %s) c2", strings.Join(fieldNames, ",")))
row := query.Row()
if row.Err() != nil {
return total, duplicateTotal, row.Err()
}
if err := row.Scan(&total, &duplicateTotal); err != nil {
return total, duplicateTotal, err
}
if total == duplicateTotal {
return total, duplicateTotal, nil
}
return total, duplicateTotal, nil
}
}
... ...
... ... @@ -142,7 +142,7 @@ func (controller *TableController) SearchQuerySetTables() {
if len(cmd.TableTypes) == 0 {
cmd.TableTypes = []string{domain.MainTable.ToString(), domain.SideTable.ToString(), domain.SubTable.ToString(), domain.SubProcessTable.ToString()}
}
cmd.Module = domain.ModuleQuerySetCenter | domain.ModuleCalculateCenter
cmd.Module = domain.ModuleQuerySetCenter
cmd.ReturnDetailStructInfo = true
cmd.Context = ParseContext(controller.BaseController)
data, err := tableService.Search(cmd)
... ... @@ -183,6 +183,22 @@ func (controller *TableController) ValidExprSql() {
controller.Response(data, err)
}
func (controller *TableController) CheckRowDuplicate() {
tableService := service.NewTableService(nil)
cmd := &command.CheckRowDuplicateCommand{}
Must(controller.Unmarshal(cmd))
data, err := tableService.CheckRowDuplicateV2(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) CheckRowValueDuplicate() {
tableService := service.NewTableService(nil)
cmd := &command.CheckRowDuplicateCommand{}
Must(controller.Unmarshal(cmd))
data, err := tableService.CheckRowDuplicate(ParseContext(controller.BaseController), cmd)
controller.Response(data, err)
}
func (controller *TableController) ExportDataTable() {
tableService := service.NewTableService(nil)
cmd := &command.TablePreviewCommand{}
... ...
... ... @@ -16,6 +16,8 @@ func init() {
web.Router("/data/tables/relation-graph", &controllers.TableController{}, "Post:RelationGraph")
web.Router("/data/tables/apply-on", &controllers.TableController{}, "Post:ApplyOn")
web.Router("/data/tables/valid-expr-sql", &controllers.TableController{}, "Post:ValidExprSql")
web.Router("/data/tables/check", &controllers.TableController{}, "Post:CheckRowDuplicate")
web.Router("/data/tables/check-row-value-duplicate", &controllers.TableController{}, "Post:CheckRowValueDuplicate")
web.Router("/data/tables/search-appended-list", &controllers.TableController{}, "Post:SearchAppendedList")
web.Router("/data/tables/search-sub-table-list", &controllers.TableController{}, "Post:SearchSubTableList")
web.Router("/data/tables/search-query-set-tables", &controllers.TableController{}, "Post:SearchQuerySetTables")
... ...