作者 yangfu

feat: table operate

正在显示 100 个修改的文件 包含 3365 行增加74 行删除

要显示太多修改。

为保证性能只显示 100 of 100+ 个文件。

... ... @@ -107,4 +107,37 @@
},
"msg": "ok"
}
```
\ No newline at end of file
```
## 表关联关系
- [x] 可追加数据的表列表 /tables/search-appended-list
- [x] 校验文件列表 /files/search-verified-file
- [x] 匹配方案列表 /mapping-rule-config/search
- [x] 匹配方案主表 /mapping-rule-config/prepare //主表 校验表 主表字段 校验文件表字段
- [x] 匹配方案添加 /mapping-rule-config/
- [x] 匹配方案删除 /mapping-rule-config/:id
- [ ] 追加数据到表格 /append-data-to-table // 验证是否追加过
- [x] 表结构更新 /tables/update-table-struct
- [x] 表结构添加 /tables/add-table-struct
- [x] 分表列表 /tables/search
- [x] 表复制 /tables/copy-data-table
- [x] 表删除 /tables/:id // 若是删除主表,需级联删除关联的分表,删除内容包括表数据及表结构;? 分表的副表是否要删除
- [x] 表详情 /tables/:id // 表结构
- [x] 表更新 /tables/:id // 表结构、分表才可以编辑
- [x] 日志搜索 /log/search
- [x] 校验步骤日志 /log/verified-step-Log
## 数据预览
- [ ] 表数据预览(格式) /table/preview
- [ ] 表数据自定义查询 /table/preview where conditions 升序、降序 包含、不包含
- [ ] 表数据字段可选值搜索 /table/field-optional 文本匹配
- [ ] 表数据更新、添加、删除 /table/row-data-mutation
- [ ] 表数据导出
## 数据验证
- [ ] 文件验证 /data/edit-data-table
\ No newline at end of file
... ...
version: v1
kind: HttpApi
metadata:
service: mappingRule
path: /mapping-rules
endpoints:
- method: createMappingRule
route:
post: /
- method: updateMappingRule
route:
put: /{mappingRuleId}
- method: getMappingRule
route:
get: /{mappingRuleId}
- method: removeMappingRule
route:
delete: /{mappingRuleId}
- method: listMappingRule
route:
get: /
params:
- name: offset
- name: limit
- method: search
route:
post: /search
- method: prepare
route:
post: /prepare
\ No newline at end of file
... ...
version: v1
kind: HttpApi
metadata:
service: table
path: /tables
endpoints:
- method: createTable
route:
post: /
- method: updateTable
route:
put: /{tableId}
- method: getTable
route:
get: /{tableId}
- method: removeTable
route:
delete: /{tableId}
- method: listTable
route:
get: /
params:
- name: offset
- name: limit
- method: splitDataTable
route:
post: /split-data-table
- method: batchEditSubTable
route:
post: /batch-edit-sub-table
- method: copyDataTable
route:
post: /copy-data-table
- method: search
route:
post: /search
\ No newline at end of file
... ...
version: v1
kind: Attribute
metadata:
name: mainTableFields
description: 主表列
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: mappingFields
description: 校验文件列
type:
primitive: string
... ...
version: v1
kind: Attribute
metadata:
name: mappingRuleId
description: 匹配规则ID
type:
primitive: int
... ...
version: v1
kind: Attribute
metadata:
name: verifiedFileFields
description: 校验文件列
type:
primitive: string
... ...
version: v1
kind: Schema
metadata:
name: mappingRule
description: 匹配规则配置
attributes:
- ref: mappingRuleId
required: true
- ref: name
required: true
- ref: tableId
required: true
- ref: fileId
required: true
- ref: mainTableFields
required: true
- ref: verifiedFileFields
required: true
- ref: mappingFields
required: true
- ref: createdAt
required: true
- ref: updatedAt
required: true
- ref: deletedAt
required: true
... ...
version: v1
kind: Method
metadata:
name: createMappingRule
type: command
description: 创建匹配规则服务
payload:
- ref: name
required: true
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: getMappingRule
type: query
description: 返回匹配规则服务
payload:
- ref: mappingRuleId
required: true
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: listMappingRule
type: query
description: 返回匹配规则服务列表
payload:
- ref: offset
required: true
- ref: limit
required: true
result:
- ref: count
required: true
- name: mappingRules
type:
array: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: prepare
type: command
description: 匹配规则预准备(新建规则)
payload:
- ref: tableId
required: true
- ref: fileId
required: true
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: removeMappingRule
type: command
description: 移除匹配规则服务
payload:
- ref: mappingRuleId
required: true
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: search
type: command
description: 搜索规则
payload:
- ref: name
required: false
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Method
metadata:
name: updateMappingRule
type: command
description: 更新匹配规则服务
payload:
- ref: mappingRuleId
required: true
result:
- name: mappingRule
type:
schema: mappingRule
required: true
... ...
version: v1
kind: Service
metadata:
name: mappingRule
description: 匹配规则服务
... ...
version: v1
kind: Method
metadata:
name: batchEditSubTable
type: command
description: 批量编辑分表
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: copyDataTable
type: command
description: 表复制
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: createTable
type: command
description: 创建表服务
payload:
- ref: name
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: getTable
type: query
description: 返回表服务
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: listTable
type: query
description: 返回表服务列表
payload:
- ref: offset
required: true
- ref: limit
required: true
result:
- ref: count
required: true
- name: tables
type:
array: table
required: true
... ...
version: v1
kind: Method
metadata:
name: removeTable
type: command
description: 移除表服务
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: search
type: query
description: 表搜索
payload:
- ref: tableType
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: splitDataTable
type: command
description: 表拆分
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Method
metadata:
name: updateTable
type: command
description: 更新表服务
payload:
- ref: tableId
required: true
result:
- name: table
type:
schema: table
required: true
... ...
version: v1
kind: Service
metadata:
name: table
description: 表服务
... ...
... ... @@ -14,7 +14,7 @@ require (
github.com/golang/snappy v0.0.3 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.3.0
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7
github.com/moul/http2curl v1.0.0 // indirect
... ... @@ -31,6 +31,8 @@ require (
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
golang.org/x/text v0.3.7
gorm.io/driver/mysql v1.3.6
gorm.io/gorm v1.23.8
)
replace github.com/linmadan/egglib-go v0.0.0-20210313060205-8b5e456b11f7 => github.com/tiptok/egglib-go v0.0.0-20220421085958-9682d0ac42c1
... ...
... ... @@ -6,6 +6,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/redis"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/starrocks"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
"time"
... ... @@ -25,6 +26,9 @@ func main() {
log.InitLogHook(constant.ENABLE_KAFKA_LOG, true)
redis.InitRedis()
pg.Init()
if err := starrocks.Init(); err != nil {
log.Logger.Error(err.Error())
}
time.Sleep(time.Second)
log.Logger.Info("server start!")
... ...
... ... @@ -27,3 +27,19 @@ func CreateDeleteFileService(transactionContext application.TransactionContext)
func CreateGenerateMainTableService(transactionContext application.TransactionContext) (domain.GenerateMainTableService, error) {
return domainService.NewGenerateMainTableService(transactionContext.(*pg.TransactionContext))
}
func CreateCopyDataTableService(transactionContext application.TransactionContext) (domain.CopyDataTableService, error) {
return domainService.NewCopyDataTableService(transactionContext.(*pg.TransactionContext))
}
func CreateDeleteDataTableService(transactionContext application.TransactionContext) (domain.DeleteDataTableService, error) {
return domainService.NewDeleteDataTableService(transactionContext.(*pg.TransactionContext))
}
func CreateUpdateTableStructService(transactionContext application.TransactionContext) (domain.UpdateTableStructService, error) {
return domainService.NewUpdateTableStructService(transactionContext.(*pg.TransactionContext))
}
func CreateAddTableStructService(transactionContext application.TransactionContext) (domain.AddTableStructService, error) {
return domainService.NewAddTableStructService(transactionContext.(*pg.TransactionContext))
}
... ...
... ... @@ -59,3 +59,55 @@ func FastPgTable(transactionContext application.TransactionContext, id int) (dom
}
return rep, mod, err
}
// FastPgLog 快速返回日志对象
//
// transactionContext 事务
// id 对象唯一标识
func FastPgLog(transactionContext application.TransactionContext, id int) (domain.LogRepository, *domain.Log, error) {
var rep domain.LogRepository
var mod *domain.Log
var err error
if value, err := CreateLogRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
rep = value
}
if id > 0 {
if mod, err = rep.FindOne(map[string]interface{}{"logId": id}); err != nil {
if err == domain.ErrorNotFound {
return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该日志不存在")
}
return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
}
return rep, mod, err
}
// FastPgMappingRule 快速返回匹配规则对象
//
// transactionContext 事务
// id 对象唯一标识
func FastPgMappingRule(transactionContext application.TransactionContext, id int) (domain.MappingRuleRepository, *domain.MappingRule, error) {
var rep domain.MappingRuleRepository
var mod *domain.MappingRule
var err error
if value, err := CreateMappingRuleRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
rep = value
}
if id > 0 {
if mod, err = rep.FindOne(map[string]interface{}{"mappingRuleId": id}); err != nil {
if err == domain.ErrorNotFound {
return nil, nil, application.ThrowError(application.RES_NO_FIND_ERROR, "该匹配规则不存在")
}
return nil, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
}
return rep, mod, err
}
... ...
... ... @@ -29,3 +29,11 @@ func CreateFileRepository(options map[string]interface{}) (domain.FileRepository
}
return repository.NewFileRepository(transactionContext)
}
func CreateMappingRuleRepository(options map[string]interface{}) (domain.MappingRuleRepository, error) {
var transactionContext *pg.TransactionContext
if value, ok := options["transactionContext"]; ok {
transactionContext = value.(*pg.TransactionContext)
}
return repository.NewMappingRuleRepository(transactionContext)
}
... ...
... ... @@ -21,6 +21,7 @@ type SearchFileQuery struct {
PageSize int `cname:"页数" json:"pageSize,omitempty"`
LastId int `cname:"最后一条记录ID" json:"lastId"`
FileType domain.FileType `cname:"文件类型" json:"fileType" valid:"Required"`
Context *domain.Context
}
func (cmd *SearchFileQuery) Valid(validation *validation.Validation) {
... ...
... ... @@ -9,7 +9,7 @@ import (
)
// 加载表格数据
func (fileService *FileService) LoadDataTable(loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {
func (fileService *FileService) LoadDataTable(ctx *domain.Context, loadDataTableCommand *command.LoadDataTableCommand) (interface{}, error) {
if err := loadDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -25,7 +25,7 @@ func (fileService *FileService) LoadDataTable(loadDataTableCommand *command.Load
}()
loadDataTableService, _ := factory.CreateLoadDataTableService(transactionContext)
if _, err := loadDataTableService.Load(loadDataTableCommand.FileId); err != nil {
if _, err := loadDataTableService.Load(ctx, loadDataTableCommand.FileId); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ... @@ -37,7 +37,7 @@ func (fileService *FileService) LoadDataTable(loadDataTableCommand *command.Load
}
// 编辑表格数据
func (fileService *FileService) EditDataTable(editDataTableCommand *command.EditDataTableCommand) (interface{}, error) {
func (fileService *FileService) EditDataTable(ctx *domain.Context, editDataTableCommand *command.EditDataTableCommand) (interface{}, error) {
if err := editDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -58,7 +58,7 @@ func (fileService *FileService) EditDataTable(editDataTableCommand *command.Edit
}
// 持久化表格数据
func (fileService *FileService) FlushDataTable(flushDataTableCommand *command.FlushDataTableCommand) (interface{}, error) {
func (fileService *FileService) FlushDataTable(ctx *domain.Context, flushDataTableCommand *command.FlushDataTableCommand) (interface{}, error) {
if err := flushDataTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -80,7 +80,7 @@ func (fileService *FileService) FlushDataTable(flushDataTableCommand *command.Fl
SQLType: f.Type,
})
}
if _, err := flushDataTableService.Flush(flushDataTableCommand.FileId, &domain.Table{
if _, err := flushDataTableService.Flush(ctx, flushDataTableCommand.FileId, &domain.Table{
DataFields: fields,
RowCount: flushDataTableCommand.RowCount,
}); err != nil {
... ... @@ -93,7 +93,7 @@ func (fileService *FileService) FlushDataTable(flushDataTableCommand *command.Fl
}
// 生成主表
func (fileService *FileService) GenerateMainTable(generateMainTableCommand *command.GenerateMainTableCommand) (interface{}, error) {
func (fileService *FileService) GenerateMainTable(ctx *domain.Context, generateMainTableCommand *command.GenerateMainTableCommand) (interface{}, error) {
if err := generateMainTableCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -109,7 +109,7 @@ func (fileService *FileService) GenerateMainTable(generateMainTableCommand *comm
}()
generateMainTableService, _ := factory.CreateGenerateMainTableService(transactionContext)
_, err = generateMainTableService.GenerateTable(generateMainTableCommand.FileId, generateMainTableCommand.TableName)
_, err = generateMainTableService.GenerateTable(ctx, generateMainTableCommand.FileId, generateMainTableCommand.TableName)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ...
... ... @@ -20,7 +20,7 @@ type FileService struct {
}
// 创建文件服务
func (fileService *FileService) CreateFile(createFileCommand *command.CreateFileCommand) (interface{}, error) {
func (fileService *FileService) CreateFile(ctx *domain.Context, createFileCommand *command.CreateFileCommand) (interface{}, error) {
if err := createFileCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
... ... @@ -43,9 +43,10 @@ func (fileService *FileService) CreateFile(createFileCommand *command.CreateFile
Ext: filepath.Ext(createFileCommand.Name),
},
SourceFileId: 0,
Operator: "",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
//Operator: "",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Context: ctx,
}
fileRepository, _, _ := factory.FastPgFile(transactionContext, 0)
file, err := fileRepository.Save(newFile)
... ... @@ -53,7 +54,7 @@ func (fileService *FileService) CreateFile(createFileCommand *command.CreateFile
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err = factory.FastLog(transactionContext, domain.CommonLog, file.FileId, &domainService.FileUploadSuccessLog{
LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ""),
LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.SourceFile.ToString(), domain.FileUpload, ctx),
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ... @@ -209,7 +210,7 @@ func (fileService *FileService) RemoveFile(removeFileCommand *command.RemoveFile
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeFileCommand.FileId)))
}
deleteFileService, _ := factory.CreateDeleteFileService(transactionContext)
err = deleteFileService.Delete(file)
err = deleteFileService.Delete(nil, file)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
... ...
... ... @@ -2,29 +2,62 @@ package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"time"
"github.com/beego/beego/v2/core/validation"
)
type SearchLogCommand struct {
// 日志类型 VerifiedStepLog:校验步骤 CommonLog:常规日志
LogType string `json:"logType"`
// 日志内容
Content string `cname:"日志内容" json:"content,omitempty"`
MatchContent string `cname:"匹配日志内容" json:"matchContent,omitempty"`
// 源数据ID
SourceId int `cname:"源数据ID" json:"sourceId"`
// 多个源数据ID
InSourceId []int `cname:"多个源数据ID" json:"inSourceId"`
// 页码
PageNumber int `cname:"页码" json:"pageNumber,omitempty"`
// 页数
PageSize int `cname:"页数" json:"pageSize,omitempty"`
Year int `cname:"年" json:"year,omitempty"`
Month int `cname:"月" json:"month,omitempty"`
Day int `cname:"日" json:"day,omitempty"`
// 开始时间
BeginTime time.Time `cname:"开始时间" json:"beginTime"`
// 结束时间
EndTime time.Time `cname:"结束时间" json:"endTime"`
Context *domain.Context
}
func (searchLogCommand *SearchLogCommand) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
func (cmd *SearchLogCommand) Valid(validation *validation.Validation) {
if cmd.Year > 0 && cmd.Month == 0 && cmd.Day == 0 {
cmd.BeginTime = time.Date(cmd.Year, 1, 1, 0, 0, 0, 0, time.Local)
cmd.EndTime = cmd.BeginTime.AddDate(1, 0, 0)
}
if cmd.Year > 0 && cmd.Month > 0 && cmd.Day == 0 {
cmd.BeginTime = time.Date(cmd.Year, time.Month(cmd.Month), 1, 0, 0, 0, 0, time.Local)
cmd.EndTime = cmd.BeginTime.AddDate(0, 1, 0)
}
if cmd.Year > 0 && cmd.Month > 0 && cmd.Day > 0 {
cmd.BeginTime = time.Date(cmd.Year, time.Month(cmd.Month), cmd.Day, 0, 0, 0, 0, time.Local)
cmd.EndTime = cmd.BeginTime.AddDate(0, 0, cmd.Day)
}
}
func (searchLogCommand *SearchLogCommand) ValidateCommand() error {
func (cmd *SearchLogCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(searchLogCommand)
b, err := valid.Valid(cmd)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(searchLogCommand).Elem()
elem := reflect.TypeOf(cmd).Elem()
for _, validErr := range valid.Errors {
field, isExist := elem.FieldByName(validErr.Field)
if isExist {
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type LogDto struct {
// 日志ID
LogId int `json:"logId"`
// 日志类型 1.校验步骤 2.常规日志
//LogType string `json:"logType"`
// 源数据ID
SourceId int `json:"sourceId"`
// 对象名称 数据表名 / 文件名
ObjectName string `json:"objectName"`
// 对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件
ObjectType string `json:"objectType"`
// 操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验
OperationType string `json:"operationType"`
// 日志内容
Content string `json:"content"`
// 操作人名称
OperatorName string `json:"operatorName"`
// 创建时间
CreatedAt string `json:"createdAt"`
}
func (d *LogDto) Load(m *domain.Log) {
d.LogId = m.LogId
d.SourceId = m.SourceId
d.ObjectName = m.ObjectName
d.ObjectType = m.ObjectType
d.OperationType = m.OperationType
d.Content = m.Content
d.OperatorName = m.OperatorName
d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05")
}
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type VerifiedStepLogDto struct {
// 日志ID
LogId int `json:"logId"`
// 日志类型 1.校验步骤 2.常规日志
//LogType string `json:"logType"`
// 源数据ID
//SourceId int `json:"sourceId"`
// 对象名称 数据表名 / 文件名
//ObjectName string `json:"objectName"`
// 对象类型 1.主表 2.分表 3.副表 4.源文件 5.校验文件
//ObjectType string `json:"objectType"`
// 操作类型 1.主表生成 2.主表拆分 3.数据导入 4.分表生成 5.表复制 6.编辑记录 7.文件上传 8.文件校验
//OperationType string `json:"operationType"`
// 日志内容
Content string `json:"content"`
// 操作人名称
//OperatorName string `json:"operatorName"`
// 创建时间
CreatedAt string `json:"createdAt"`
}
func (d *VerifiedStepLogDto) Load(m *domain.Log) {
d.LogId = m.LogId
//d.SourceId = m.SourceId
//d.ObjectName = m.ObjectName
//d.ObjectType = m.ObjectType
//d.OperationType = m.OperationType
d.Content = m.Content
//d.OperatorName = m.OperatorName
d.CreatedAt = m.CreatedAt.Local().Format("2006-01-02 15:04:05")
}
... ...
... ... @@ -6,8 +6,10 @@ import (
"github.com/linmadan/egglib-go/utils/tool_funs"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/log/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
)
// 日志服务
... ... @@ -168,24 +170,86 @@ func (logService *LogService) RemoveLog(removeLogCommand *command.RemoveLogComma
}
// 搜索日志
func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogCommand) (interface{}, error) {
func (logService *LogService) SearchLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) {
if err := searchLogCommand.ValidateCommand(); err != nil {
return nil, application.ThrowError(application.ARG_ERROR, err.Error())
return 0, 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())
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
logRepository, _, _ := factory.FastPgLog(transactionContext, 0)
count, logs, err := logRepository.Find(utils.ObjectToMap(searchLogCommand))
if err != nil {
return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var result = make([]*dto.LogDto, 0)
for _, m := range logs {
var item = &dto.LogDto{}
item.Load(m)
result = append(result, item)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return count, result, nil
}
// 搜索日志
func (logService *LogService) VerifiedStepLog(searchLogCommand *command.SearchLogCommand) (int64, interface{}, error) {
if err := searchLogCommand.ValidateCommand(); err != nil {
return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error())
}
transactionContext, err := factory.CreateTransactionContext(nil)
if err != nil {
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
if err := transactionContext.StartTransaction(); err != nil {
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
defer func() {
transactionContext.RollbackTransaction()
}()
_, sourceFile, err := factory.FastPgFile(transactionContext, searchLogCommand.SourceId)
if err != nil {
return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
searchLogCommand.LogType = domain.VerifiedStepLog.ToString()
searchLogCommand.SourceId = 0
searchLogCommand.InSourceId = []int{sourceFile.FileId, sourceFile.SourceFileId}
searchLogCommand.PageNumber = 1
searchLogCommand.PageSize = 1000
logRepository, _, _ := factory.FastPgLog(transactionContext, 0)
count, logs, err := logRepository.Find(utils.ObjectToMap(searchLogCommand))
if err != nil {
return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var result = make([]*dto.VerifiedStepLogDto, 0)
for _, m := range logs {
var item = &dto.VerifiedStepLogDto{}
item.Load(m)
result = append(result, item)
}
if err := transactionContext.CommitTransaction(); err != nil {
return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
return count, map[string]interface{}{
"logs": result,
}, nil
}
// 更新日志服务
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type CreateMappingRuleCommand struct {
// 名称
Name string `cname:"名称" json:"name" valid:"Required"`
// 表Id
TableId int `json:"tableId" valid:"Required"`
// 文件ID
FileId int `json:"fileId" valid:"Required"`
// 校验文件列
MappingFields []*domain.MappingField `json:"mappingFields"`
}
func (createMappingRuleCommand *CreateMappingRuleCommand) Valid(validation *validation.Validation) {
}
func (createMappingRuleCommand *CreateMappingRuleCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(createMappingRuleCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(createMappingRuleCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type PrepareCommand struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
// 文件ID
FileId int `cname:"文件ID" json:"fileId" valid:"Required"`
}
func (prepareCommand *PrepareCommand) Valid(validation *validation.Validation) {
}
func (prepareCommand *PrepareCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(prepareCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(prepareCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type RemoveMappingRuleCommand struct {
// 匹配规则ID
MappingRuleId int `cname:"匹配规则ID" json:"mappingRuleId" valid:"Required"`
}
func (removeMappingRuleCommand *RemoveMappingRuleCommand) Valid(validation *validation.Validation) {
}
func (removeMappingRuleCommand *RemoveMappingRuleCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(removeMappingRuleCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(removeMappingRuleCommand).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
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type SearchCommand struct {
// 表ID
TableId int `cname:"表ID" json:"tableId,omitempty"`
Context *domain.Context
}
func (searchCommand *SearchCommand) Valid(validation *validation.Validation) {
}
func (searchCommand *SearchCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(searchCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(searchCommand).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
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type UpdateMappingRuleCommand struct {
// 匹配规则ID
MappingRuleId int `cname:"匹配规则ID" json:"mappingRuleId" valid:"Required"`
// 名称
Name string `cname:"名称" json:"name" valid:"Required"`
// 校验文件列
MappingFields []*domain.MappingField `cname:"匹配规则列表" json:"mappingFields" valid:"Required"`
}
func (updateMappingRuleCommand *UpdateMappingRuleCommand) Valid(validation *validation.Validation) {
}
func (updateMappingRuleCommand *UpdateMappingRuleCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateMappingRuleCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(updateMappingRuleCommand).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
}
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type MappingRuleDto struct {
// 匹配规则ID
MappingRuleId int `json:"mappingRuleId"`
// 名称
Name string `json:"name"`
// 表Id
TableId int `json:"tableId"`
// 文件ID
FileId int `json:"fileId"`
// 主表列
MainTableFields []*domain.Field `json:"mainTableFields"`
// 校验文件列
VerifiedFileFields []*domain.Field `json:"verifiedFileFields"`
// 校验文件列
MappingFields []*domain.MappingField `json:"mappingFields"`
}
func (d *MappingRuleDto) Load(m *domain.MappingRule) {
d.MappingRuleId = m.MappingRuleId
d.Name = m.Name
d.TableId = m.TableId
d.FileId = m.FileId
d.MainTableFields = m.MainTableFields
d.VerifiedFileFields = m.VerifiedFileFields
d.MappingFields = m.MappingFields
}
func (d *MappingRuleDto) LoadFromTableAndFile(m *domain.Table, f *domain.File, fm *domain.Table) {
d.MappingRuleId = 0
d.Name = m.Name
d.TableId = m.TableId
d.FileId = f.FileId
d.MainTableFields = m.Fields(false)
d.VerifiedFileFields = fm.Fields(false)
d.MappingFields = domain.NewMappingFields(d.MainTableFields, d.VerifiedFileFields)
}
... ...
package query
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type GetMappingRuleQuery struct {
// 匹配规则ID
MappingRuleId int `cname:"匹配规则ID" json:"mappingRuleId" valid:"Required"`
}
func (getMappingRuleQuery *GetMappingRuleQuery) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
}
func (getMappingRuleQuery *GetMappingRuleQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(getMappingRuleQuery)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(getMappingRuleQuery).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
}
... ...
package query
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type ListMappingRuleQuery struct {
// 查询偏离量
Offset int `cname:"查询偏离量" json:"offset" valid:"Required"`
// 查询限制
Limit int `cname:"查询限制" json:"limit" valid:"Required"`
}
func (listMappingRuleQuery *ListMappingRuleQuery) Valid(validation *validation.Validation) {
validation.SetError("CustomValid", "未实现的自定义认证")
}
func (listMappingRuleQuery *ListMappingRuleQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(listMappingRuleQuery)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(listMappingRuleQuery).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
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/utils/tool_funs"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/mappingRule/command"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/mappingRule/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/mappingRule/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"time"
)
// 匹配规则服务
type MappingRuleService struct {
}
// 创建匹配规则服务
func (mappingRuleService *MappingRuleService) CreateMappingRule(ctx *domain.Context, cmd *command.CreateMappingRuleCommand) (interface{}, error) {
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()
}()
mappingRuleRepository, _, _ := factory.FastPgMappingRule(transactionContext, 0)
_, mainTable, err := factory.FastPgTable(transactionContext, cmd.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, file, err := factory.FastPgFile(transactionContext, cmd.FileId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, fileTable, err := factory.FastPgTable(transactionContext, file.FileInfo.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name}); e == nil && duplicateRule != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复")
}
newMappingRule := &domain.MappingRule{
Name: cmd.Name,
TableId: cmd.TableId,
FileId: cmd.FileId,
MainTableFields: mainTable.Fields(false),
VerifiedFileFields: fileTable.Fields(false),
MappingFields: cmd.MappingFields,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
Context: ctx,
}
if newMappingRule, err = mappingRuleRepository.Save(newMappingRule); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
// 返回匹配规则服务
func (mappingRuleService *MappingRuleService) GetMappingRule(getMappingRuleQuery *query.GetMappingRuleQuery) (interface{}, error) {
if err := getMappingRuleQuery.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()
}()
var mappingRuleRepository domain.MappingRuleRepository
if value, err := factory.CreateMappingRuleRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
mappingRuleRepository = value
}
mappingRule, err := mappingRuleRepository.FindOne(map[string]interface{}{"mappingRuleId": getMappingRuleQuery.MappingRuleId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if mappingRule == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getMappingRuleQuery.MappingRuleId)))
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return mappingRule, nil
}
}
// 返回匹配规则服务列表
func (mappingRuleService *MappingRuleService) ListMappingRule(listMappingRuleQuery *query.ListMappingRuleQuery) (interface{}, error) {
if err := listMappingRuleQuery.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()
}()
var mappingRuleRepository domain.MappingRuleRepository
if value, err := factory.CreateMappingRuleRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
mappingRuleRepository = value
}
if count, mappingRules, err := mappingRuleRepository.Find(tool_funs.SimpleStructToMap(listMappingRuleQuery)); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"count": count,
"mappingRules": mappingRules,
}, nil
}
}
// 匹配规则预准备(新建规则)
func (mappingRuleService *MappingRuleService) Prepare(prepareCommand *command.PrepareCommand) (interface{}, error) {
if err := prepareCommand.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()
}()
_, mainTable, err := factory.FastPgTable(transactionContext, prepareCommand.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, file, err := factory.FastPgFile(transactionContext, prepareCommand.FileId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, fileTable, err := factory.FastPgTable(transactionContext, file.FileInfo.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
ruleDto := dto.MappingRuleDto{}
ruleDto.LoadFromTableAndFile(mainTable, file, fileTable)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return ruleDto, nil
}
// 移除匹配规则服务
func (mappingRuleService *MappingRuleService) RemoveMappingRule(removeMappingRuleCommand *command.RemoveMappingRuleCommand) (interface{}, error) {
if err := removeMappingRuleCommand.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 mappingRuleRepository domain.MappingRuleRepository
if value, err := factory.CreateMappingRuleRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
mappingRuleRepository = value
}
mappingRule, err := mappingRuleRepository.FindOne(map[string]interface{}{"mappingRuleId": removeMappingRuleCommand.MappingRuleId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if mappingRule == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeMappingRuleCommand.MappingRuleId)))
}
if _, err := mappingRuleRepository.Remove(mappingRule); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct {
}{}, nil
}
// 搜索规则
func (mappingRuleService *MappingRuleService) Search(searchCommand *command.SearchCommand) (interface{}, error) {
if err := searchCommand.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()
}()
mappingRuleRepository, _, _ := factory.FastPgMappingRule(transactionContext, 0)
count, rules, err := mappingRuleRepository.Find(utils.ObjectToMap(searchCommand))
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var result = make([]*dto.MappingRuleDto, 0)
for _, r := range rules {
var item = &dto.MappingRuleDto{}
item.Load(r)
result = append(result, item)
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"count": count,
"rules": result,
}, nil
}
// 更新匹配规则服务
func (mappingRuleService *MappingRuleService) UpdateMappingRule(ctx *domain.Context, cmd *command.UpdateMappingRuleCommand) (interface{}, error) {
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()
}()
mappingRuleRepository, mappingRule, err := factory.FastPgMappingRule(transactionContext, cmd.MappingRuleId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, file, err := factory.FastPgFile(transactionContext, mappingRule.FileId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
_, fileTable, err := factory.FastPgTable(transactionContext, file.FileInfo.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if duplicateRule, e := mappingRuleRepository.FindOne(map[string]interface{}{"context": ctx, "name": cmd.Name}); e == nil && duplicateRule != nil && duplicateRule.MappingRuleId != cmd.MappingRuleId {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "方案名称重复")
}
mappingRule.Name = cmd.Name
mappingRule.MappingFields = cmd.MappingFields
mappingRule.VerifiedFileFields = fileTable.Fields(false)
mappingRule.UpdatedAt = time.Now()
if mappingRule, err = mappingRuleRepository.Save(mappingRule); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
func NewMappingRuleService(options map[string]interface{}) *MappingRuleService {
newMappingRuleService := &MappingRuleService{}
return newMappingRuleService
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type AddTableStructCommand struct {
// 表Id
TableId int `cname:"表Id" json:"parentTableId" valid:"Required"`
Name string `json:"name"`
// 数据列
Fields []*domain.Field `json:"fields"`
}
func (updateTableCommand *AddTableStructCommand) Valid(validation *validation.Validation) {
}
func (updateTableCommand *AddTableStructCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(updateTableCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type BatchEditSubTableCommand struct {
// 表Id
TableId string `cname:"表Id" json:"tableId" valid:"Required"`
}
func (batchEditSubTableCommand *BatchEditSubTableCommand) Valid(validation *validation.Validation) {
}
func (batchEditSubTableCommand *BatchEditSubTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(batchEditSubTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(batchEditSubTableCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type CopyDataTableCommand struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
// 表名
TableName string `cname:"表名" json:"tableName" valid:"Required"`
}
func (copyDataTableCommand *CopyDataTableCommand) Valid(validation *validation.Validation) {
}
func (copyDataTableCommand *CopyDataTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(copyDataTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(copyDataTableCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type CreateTableCommand struct {
// 名称
Name string `cname:"名称" json:"name" valid:"Required"`
}
func (createTableCommand *CreateTableCommand) Valid(validation *validation.Validation) {
}
func (createTableCommand *CreateTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(createTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(createTableCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type RemoveTableCommand struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
}
func (removeTableCommand *RemoveTableCommand) Valid(validation *validation.Validation) {
}
func (removeTableCommand *RemoveTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(removeTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(removeTableCommand).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
}
... ...
package command
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type SplitDataTableCommand struct {
// 表Id
TableId string `cname:"表Id" json:"tableId" valid:"Required"`
}
func (splitDataTableCommand *SplitDataTableCommand) Valid(validation *validation.Validation) {
}
func (splitDataTableCommand *SplitDataTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(splitDataTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(splitDataTableCommand).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
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type UpdateTableCommand struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
Name string `json:"name"`
// 数据列
Fields []*domain.Field `json:"fields"`
}
func (updateTableCommand *UpdateTableCommand) Valid(validation *validation.Validation) {
}
func (updateTableCommand *UpdateTableCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(updateTableCommand).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
}
... ...
package command
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type UpdateTableStructCommand struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
Name string `json:"name"`
// 数据列
Fields []*domain.Field `json:"fields"`
}
func (updateTableCommand *UpdateTableStructCommand) Valid(validation *validation.Validation) {
}
func (updateTableCommand *UpdateTableStructCommand) ValidateCommand() error {
valid := validation.Validation{}
b, err := valid.Valid(updateTableCommand)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(updateTableCommand).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
}
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type TableDetailDto struct {
// 表Id
TableId int `json:"tableId"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
TableType string `json:"tableType"`
// 名称
Name string `json:"name"`
// 父级ID
ParentId int `json:"parentId"`
// 主表字段
MainTableFields []*domain.Field `json:"mainTableFields"`
// 手动添加的列
ManualFields []*domain.Field `json:"manualFields"`
// 数据列
Fields []*domain.Field `json:"fields"`
}
func (d *TableDetailDto) Load(m *domain.Table, mainTable *domain.Table) {
d.TableId = m.TableId
d.TableType = m.TableType
d.Name = m.Name
d.ParentId = m.ParentId
if m.TableType == domain.MainTable.ToString() || m.TableType == domain.SideTable.ToString() {
d.MainTableFields = m.Fields(false)
} else if mainTable != nil {
d.MainTableFields = mainTable.Fields(false)
}
d.Fields = m.Fields(false)
d.ManualFields = m.ManualFields
}
... ...
package dto
import "gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
type TableDto struct {
// 表Id
TableId int `json:"tableId"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
TableType string `json:"tableType"`
// 名称
Name string `json:"name"`
// 父级ID
ParentId int `json:"parentId"`
}
func (d *TableDto) Load(m *domain.Table) {
d.TableId = m.TableId
d.TableType = m.TableType
d.Name = m.Name
d.ParentId = m.ParentId
}
... ...
package query
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type GetTableQuery struct {
// 表Id
TableId int `cname:"表Id" json:"tableId" valid:"Required"`
}
func (getTableQuery *GetTableQuery) Valid(validation *validation.Validation) {
}
func (getTableQuery *GetTableQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(getTableQuery)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(getTableQuery).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
}
... ...
package query
import (
"fmt"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type ListTableQuery struct {
// 查询偏离量
Offset int `cname:"查询偏离量" json:"offset" valid:"Required"`
// 查询限制
Limit int `cname:"查询限制" json:"limit" valid:"Required"`
}
func (listTableQuery *ListTableQuery) Valid(validation *validation.Validation) {
}
func (listTableQuery *ListTableQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(listTableQuery)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(listTableQuery).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
}
... ...
package query
import (
"fmt"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"reflect"
"strings"
"github.com/beego/beego/v2/core/validation"
)
type SearchTableQuery struct {
// 表名称
Name string `cname:"表名称" json:"name"`
// 表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表
TableTypes []string `cname:"表类型 MainTable:主表 SideTable:副表 SubTable:分表 ExcelTable:Excel表" json:"tableTypes"`
// 父级ID
ParentId int `cname:"父级ID" json:"parentId"`
// 父级ID
ParentTableId int `cname:"父级ID" json:"parentTableId"`
Context *domain.Context
}
func (searchQuery *SearchTableQuery) Valid(validation *validation.Validation) {
if searchQuery.ParentTableId > 0 && searchQuery.ParentId == 0 {
searchQuery.ParentId = searchQuery.ParentTableId
}
}
func (searchQuery *SearchTableQuery) ValidateQuery() error {
valid := validation.Validation{}
b, err := valid.Valid(searchQuery)
if err != nil {
return err
}
if !b {
elem := reflect.TypeOf(searchQuery).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
}
... ...
package service
import (
"fmt"
"github.com/linmadan/egglib-go/core/application"
"github.com/linmadan/egglib-go/utils/tool_funs"
"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"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/dto"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/application/table/query"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
)
// 表服务
type TableService struct {
}
// 批量编辑分表
func (tableService *TableService) BatchEditSubTable(batchEditSubTableCommand *command.BatchEditSubTableCommand) (interface{}, error) {
if err := batchEditSubTableCommand.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()
}()
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
}
// 表复制
func (tableService *TableService) CopyDataTable(ctx *domain.Context, cmd *command.CopyDataTableCommand) (interface{}, error) {
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()
}()
copyDataTableService, err := factory.CreateCopyDataTableService(transactionContext)
if _, err = copyDataTableService.CopyTable(ctx, cmd.TableId, cmd.TableName); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
// 创建表服务
func (tableService *TableService) CreateTable(createTableCommand *command.CreateTableCommand) (interface{}, error) {
if err := createTableCommand.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()
}()
newTable := &domain.Table{
Name: createTableCommand.Name,
}
var tableRepository domain.TableRepository
if value, err := factory.CreateTableRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
tableRepository = value
}
if table, err := tableRepository.Save(newTable); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return table, nil
}
}
// 返回表服务
func (tableService *TableService) GetTable(getTableQuery *query.GetTableQuery) (interface{}, error) {
if err := getTableQuery.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()
}()
_, table, err := factory.FastPgTable(transactionContext, getTableQuery.TableId)
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
var mainTable *domain.Table
if table.ParentId != 0 {
_, mainTable, _ = factory.FastPgTable(transactionContext, table.ParentId)
}
tableDetailDto := dto.TableDetailDto{}
tableDetailDto.Load(table, mainTable)
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return tableDetailDto, nil
}
// 返回表服务列表
func (tableService *TableService) ListTable(listTableQuery *query.ListTableQuery) (interface{}, error) {
if err := listTableQuery.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()
}()
var tableRepository domain.TableRepository
if value, err := factory.CreateTableRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
tableRepository = value
}
if count, tables, err := tableRepository.Find(tool_funs.SimpleStructToMap(listTableQuery)); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return map[string]interface{}{
"count": count,
"tables": tables,
}, nil
}
}
// 移除表服务
func (tableService *TableService) RemoveTable(ctx *domain.Context, removeTableCommand *command.RemoveTableCommand) (interface{}, error) {
if err := removeTableCommand.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()
}()
deleteDataTableService, _ := factory.CreateDeleteDataTableService(transactionContext)
if _, err := deleteDataTableService.DeleteTable(ctx, removeTableCommand.TableId); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
// 表搜索
func (tableService *TableService) Search(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)
count, 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())
}
return map[string]interface{}{
"count": count,
"tables": result,
}, nil
}
// 表拆分
func (tableService *TableService) SplitDataTable(splitDataTableCommand *command.SplitDataTableCommand) (interface{}, error) {
if err := splitDataTableCommand.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()
}()
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return nil, nil
}
// 更新表服务
func (tableService *TableService) UpdateTable(updateTableCommand *command.UpdateTableCommand) (interface{}, error) {
if err := updateTableCommand.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 tableRepository domain.TableRepository
if value, err := factory.CreateTableRepository(map[string]interface{}{
"transactionContext": transactionContext,
}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
tableRepository = value
}
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": updateTableCommand.TableId})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if table == nil {
return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateTableCommand.TableId)))
}
if err := table.Update(tool_funs.SimpleStructToMap(updateTableCommand)); err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
if table, err := tableRepository.Save(table); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return table, nil
}
}
// 更新表服务
func (tableService *TableService) UpdateTableStruct(ctx *domain.Context, cmd *command.UpdateTableStructCommand) (interface{}, error) {
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()
}()
UpdateTableStructService, _ := factory.CreateUpdateTableStructService(transactionContext)
if _, err := UpdateTableStructService.UpdateTableStruct(ctx, cmd.TableId, cmd.Fields, cmd.Name); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
// 更新表服务
func (tableService *TableService) AddTableStruct(ctx *domain.Context, cmd *command.AddTableStructCommand) (interface{}, error) {
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()
}()
AddTableStructService, _ := factory.CreateAddTableStructService(transactionContext)
if _, err := AddTableStructService.AddTableStruct(ctx, cmd.TableId, cmd.Fields, cmd.Name); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err := transactionContext.CommitTransaction(); err != nil {
return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
}
return struct{}{}, nil
}
func NewTableService(options map[string]interface{}) *TableService {
newTableService := &TableService{}
return newTableService
}
... ...
package constant
import "fmt"
var STARROCKS_DB_NAME = "character_library_standard"
var STARROCKS_USER = "root"
var STARROCKS_PASSWORD = "eagle1010"
var STARROCKS_HOST = "118.178.239.45"
var STARROCKS_PORT = "9030"
var STARROCKS_MYSQL_DATA_SOURCE = ""
func init() {
STARROCKS_HOST = Configurator.DefaultString("STARROCKS_HOST", STARROCKS_HOST)
STARROCKS_PORT = Configurator.DefaultString("STARROCKS_PORT", STARROCKS_PORT)
STARROCKS_DB_NAME = Configurator.DefaultString("STARROCKS_DB_NAME", STARROCKS_DB_NAME)
STARROCKS_USER = Configurator.DefaultString("STARROCKS_USER", STARROCKS_USER)
STARROCKS_PASSWORD = Configurator.DefaultString("STARROCKS_PASSWORD", STARROCKS_PASSWORD)
STARROCKS_MYSQL_DATA_SOURCE = fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8&parseTime=True&loc=Local",
STARROCKS_USER, STARROCKS_PASSWORD, STARROCKS_HOST, STARROCKS_PORT, STARROCKS_DB_NAME)
}
... ...
package domain
type Context struct {
// 公司
CompanyId int `json:"companyId"`
// 操作人
OperatorId int `json:"operatorId"`
// 操作人名称
OperatorName string `json:"operatorName"`
// 租户 (个人、企业)
TenantId int `json:"tenantId"`
}
... ...
package domain
type DataTable struct {
Fields []*Field
Data [][]string
Total int
}
... ...
package domain
type LoadDataTableService interface {
Load(fileId int) (interface{}, error)
Load(ctx *Context, fileId int) (interface{}, error)
GetFileId() int
}
type FlushDataTableService interface {
Flush(fileId int, table *Table) (interface{}, error)
Flush(ctx *Context, fileId int, table *Table) (interface{}, error)
}
type DeleteFileService interface {
Delete(files ...*File) error
Delete(ctx *Context, files ...*File) error
}
type GenerateMainTableService interface {
GenerateTable(fileId int, tableName string) (interface{}, error)
GenerateTable(ctx *Context, fileId int, tableName string) (interface{}, error)
}
type CopyDataTableService interface {
CopyTable(ctx *Context, tableId int, tableName string) (interface{}, error)
}
type DeleteDataTableService interface {
DeleteTable(ctx *Context, tableId int) (interface{}, error)
DeleteTables(ctx *Context, tables ...*Table) error
}
type UpdateTableStructService interface {
UpdateTableStruct(ctx *Context, tableId int, fields []*Field, name string) (interface{}, error)
}
type AddTableStructService interface {
AddTableStruct(ctx *Context, parentTableId int, fields []*Field, name string) (interface{}, error)
}
... ...
... ... @@ -75,6 +75,14 @@ var (
Datetime SQLType = "datetime"
)
var SQLTypeMap = map[string]string{
String.ToString(): "文本",
Int.ToString(): "整数",
Float.ToString(): "小数",
Date.ToString(): "日期",
Datetime.ToString(): "日期时间",
}
type FileType string
func (t FileType) ToString() string {
... ...
package domain
import "fmt"
// Field 字段
type Field struct {
// 字段Id
... ... @@ -17,3 +19,73 @@ type Field struct {
// 标识 1:主表字段 2:手动添加
Flag int `json:"flag"`
}
func (f *Field) Valid() error {
if _, ok := SQLTypeMap[f.SQLType]; !ok {
return fmt.Errorf("unknown sql type:%v", f.SQLType)
}
if f.Index == 0 && f.Flag == ManualField {
return fmt.Errorf("field:%v index is 0", f.Name)
}
return nil
}
type Fields []*Field
func (fields Fields) ToMap() map[string]*Field {
m := make(map[string]*Field)
for i := range fields {
m[fields[i].Name] = fields[i]
}
return m
}
func (fields Fields) Select(options map[string]interface{}) []*Field {
var result []*Field
for _, field := range fields {
if v, ok := options["flag"]; ok {
if v.(int) != field.Flag {
continue
}
}
result = append(result, field)
}
return result
}
func ValidFields(fields []*Field) error {
m := (Fields)(fields).ToMap()
if len(m) != len(fields) {
return fmt.Errorf("列名重复发")
}
for _, f := range fields {
if err := f.Valid(); err != nil {
return err
}
}
return nil
}
func FieldsChange(oldFields []*Field, newFields []*Field) (reserve []*Field, delete []*Field, add []*Field) {
var oldFieldsMap = (Fields)(oldFields).ToMap()
var newFieldsMap = (Fields)(newFields).ToMap()
for _, f := range newFields {
if _, ok := oldFieldsMap[f.Name]; ok {
reserve = append(reserve, f)
continue
} else {
add = append(add, f)
continue
}
}
for _, f := range oldFields {
if _, ok := newFieldsMap[f.Name]; !ok {
delete = append(delete, f)
continue
}
}
return
}
... ...
... ... @@ -17,7 +17,7 @@ type File struct {
// 源文件Id(FileType为TemporaryFile或VerifiedFile时有值)
SourceFileId int `json:"sourceFileId"`
// 操作人
Operator string `json:"operator"`
// Operator string `json:"operator"`
// 创建时间
CreatedAt time.Time `json:"createdAt"`
// 更新时间
... ... @@ -26,6 +26,8 @@ type File struct {
DeletedAt time.Time `json:"deletedAt"`
// 版本
Version int `json:"version"`
// 扩展
Context *Context `json:"context"`
}
type FileRepository interface {
... ... @@ -51,7 +53,7 @@ func FileName(fileName string) string {
return strings.Split(base, ".")[0]
}
func (file *File) CopyTo(fileType FileType) *File {
func (file *File) CopyTo(fileType FileType, ctx *Context) *File {
t := &File{
FileType: fileType.ToString(),
FileInfo: &FileInfo{
... ... @@ -64,7 +66,8 @@ func (file *File) CopyTo(fileType FileType) *File {
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
SourceFileId: file.FileId,
Operator: file.Operator,
//Operator: file.Operator,
Context: ctx,
}
return t
}
... ...
... ... @@ -24,6 +24,8 @@ type Log struct {
OperatorName string `json:"operatorName"`
// 创建时间
CreatedAt time.Time `json:"createdAt"`
// 扩展
Context *Context `json:"context"`
}
type LogRepository interface {
... ...
... ... @@ -12,17 +12,24 @@ type LogEntry struct {
Content string `json:"content"`
// 操作人名称
OperatorName string `json:"operatorName"`
ctx *Context `json:"-"`
}
func (l LogEntry) Entry() LogEntry {
return l
}
func NewLogEntry(fileOrTableName string, objectType string, operationType OperationType, operatorName string) LogEntry {
func (l LogEntry) Context() *Context {
return l.ctx
}
func NewLogEntry(fileOrTableName string, objectType string, operationType OperationType, ctx *Context) LogEntry {
return LogEntry{
ObjectName: fileOrTableName,
ObjectType: objectType,
OperationType: operationType.ToString(),
OperatorName: operatorName,
OperatorName: ctx.OperatorName,
ctx: ctx,
}
}
... ...
package domain
import "time"
// 匹配规则配置
type MappingRule struct {
// 匹配规则ID
MappingRuleId int `json:"mappingRuleId"`
// 名称
Name string `json:"name"`
// 表Id
TableId int `json:"tableId"`
// 文件ID
FileId int `json:"fileId"`
// 主表列
MainTableFields []*Field `json:"mainTableFields"`
// 校验文件列
VerifiedFileFields []*Field `json:"verifiedFileFields"`
// 校验文件列
MappingFields []*MappingField `json:"mappingFields"`
// 创建时间
CreatedAt time.Time `json:"createdAt"`
// 更新时间
UpdatedAt time.Time `json:"updatedAt"`
// 删除时间
DeletedAt time.Time `json:"deletedAt"`
// 扩展
Context *Context `json:"context"`
}
type MappingRuleRepository interface {
Save(mappingRule *MappingRule) (*MappingRule, error)
Remove(mappingRule *MappingRule) (*MappingRule, error)
FindOne(queryOptions map[string]interface{}) (*MappingRule, error)
Find(queryOptions map[string]interface{}) (int64, []*MappingRule, error)
}
func (mappingRule *MappingRule) Identify() interface{} {
if mappingRule.MappingRuleId == 0 {
return nil
}
return mappingRule.MappingRuleId
}
func (mappingRule *MappingRule) Update(data map[string]interface{}) error {
return nil
}
type MappingField struct {
MainTableField *Field `json:"mainTableField"`
VerifiedFileFieldName string `json:"verifiedFileFieldName"`
}
func NewMappingFields(all []*Field, some []*Field) []*MappingField {
var result []*MappingField
//allMap :=(Fields)(all).ToMap()
someMap := (Fields)(some).ToMap()
for _, f := range all {
item := &MappingField{
MainTableField: f,
}
if v, ok := someMap[f.Name]; ok {
item.VerifiedFileFieldName = v.Name
}
result = append(result, item)
}
return result
}
... ...
... ... @@ -31,8 +31,11 @@ type Table struct {
// 版本
Version int `json:"version"`
fields []*Field // 所有列 // PKs + DataFields + ManualFields
// 业务字段
RowCount int `json:"rowCount,omitempty"`
// 扩展
Context *Context `json:"context"`
}
type TableRepository interface {
... ... @@ -49,6 +52,26 @@ func (table *Table) Identify() interface{} {
return table.TableId
}
func (table *Table) WithContext(ctx *Context) *Table {
table.Context = ctx
return table
}
func (table *Table) Update(data map[string]interface{}) error {
return nil
}
func (t *Table) Fields(includePK bool) []*Field {
var fields []*Field
if len(t.fields) == 0 {
if includePK {
fields = append(fields, t.PK)
}
fields = append(fields, t.DataFields...)
if t.TableType == SubTable.ToString() {
fields = append(fields, t.ManualFields...)
}
t.fields = fields
}
return t.fields
}
... ...
package domain
// 用户对象
type User struct {
// 用户Id 用户唯一标识
Id int `json:"id"`
// 用户姓名
Name string `json:"name"`
}
... ...
... ... @@ -11,8 +11,14 @@ func ChangeStepLogOwner(ptr *pgTransaction.TransactionContext, from int, to int)
return err
}
func LogDelete(ptr *pgTransaction.TransactionContext, sourceId int, logType domain.LogType) error {
func LogDirectDelete(ptr *pgTransaction.TransactionContext, sourceId int, logType domain.LogType) error {
sql := "delete from metadata.logs where source_id = ? and log_type = ?"
_, err := ptr.PgTx.Exec(sql, sourceId, logType)
return err
}
//func LogSoftDelete(ptr *pgTransaction.TransactionContext, sourceIds []int, logType domain.LogType) error {
// sql := "update metadata.logs set deleted_at = now() where source_id in(?) and log_type = ?"
// _, err := ptr.PgTx.Exec(sql, pg.In(sourceIds), logType)
// return err
//}
... ...
package domainService
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
)
type AddTableStructService struct {
transactionContext *pgTransaction.TransactionContext
}
func NewAddTableStructService(transactionContext *pgTransaction.TransactionContext) (*AddTableStructService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &AddTableStructService{
transactionContext: transactionContext,
}, nil
}
}
func (ptr *AddTableStructService) AddTableStruct(ctx *domain.Context, parentTableId int, fields []*domain.Field, name string) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
mainTable, err := tableRepository.FindOne(map[string]interface{}{"tableId": parentTableId})
if err != nil {
return nil, err
}
if !(mainTable.TableType == domain.MainTable.ToString() || mainTable.TableType == domain.SideTable.ToString()) {
return nil, fmt.Errorf("只有主表、副表允许新建分表")
}
// 验证表名是否重复
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"tableType": domain.SubTable.ToString(), "tableName": name})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
fields = MappingFields(mainTable, fields)
dataFields := (domain.Fields)(fields).Select(map[string]interface{}{"flag": 1})
manualFields := (domain.Fields)(fields).Select(map[string]interface{}{"flag": 2})
table := NewTable(domain.SubTable, name, fields, mainTable.RowCount).WithContext(ctx)
table.DataFieldIndex = mainTable.DataFieldIndex
table.DataFields = dataFields
table.ManualFields = manualFields
table.ParentId = parentTableId
reserves, deletes, adds := domain.FieldsChange(table.Fields(false), fields)
if err = domain.ValidFields(fields); err != nil {
return nil, err
}
if _, err = tableRepository.Save(table); err != nil {
return nil, err
}
if _, err = tableRepository.Save(mainTable); err != nil {
return nil, err
}
// Log
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, table.TableId, &SpiltMainTableLog{
LogEntry: domain.NewLogEntry(table.Name, table.TableType, domain.SpiltMainTable, ctx),
Reserve: reserves,
Delete: deletes,
Add: adds,
SourceTableName: mainTable.Name,
}); err != nil {
return nil, err
}
// 通知底层
return struct{}{}, nil
}
... ...
package domainService
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
)
type CopyDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func NewCopyDataTableService(transactionContext *pgTransaction.TransactionContext) (*CopyDataTableService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &CopyDataTableService{
transactionContext: transactionContext,
}, nil
}
}
func (ptr *CopyDataTableService) CopyTable(ctx *domain.Context, tableId int, tableName string) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": tableId})
if err != nil {
return nil, err
}
// 验证表名是否重复
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"tableType": domain.SideTable.ToString(), "tableName": tableName})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
sideTable := NewTable(domain.SideTable, tableName, table.DataFields, table.RowCount).WithContext(ctx)
sideTable.ParentId = table.TableId
if sideTable, err = tableRepository.Save(sideTable); err != nil {
return nil, err
}
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, sideTable.TableId, &CopyTableLog{
LogEntry: domain.NewLogEntry(sideTable.Name, sideTable.TableType, domain.CopyTable, ctx),
SourceTableName: table.Name,
}); err != nil {
return nil, err
}
// 通知底层
return nil, nil
}
... ...
package domainService
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
)
type DeleteDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func NewDeleteDataTableService(transactionContext *pgTransaction.TransactionContext) (*DeleteDataTableService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &DeleteDataTableService{
transactionContext: transactionContext,
}, nil
}
}
func (ptr *DeleteDataTableService) DeleteTable(ctx *domain.Context, tableId int) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": tableId})
if err != nil {
return nil, err
}
var subTables []*domain.Table
if table.TableType == domain.MainTable.ToString() {
_, subTables, err = tableRepository.Find(map[string]interface{}{"parentId": tableId, "tableTypes": []string{domain.SubTable.ToString()}})
if err != nil {
return nil, err
}
}
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, table.TableId, &DeleteTableLog{
LogEntry: domain.NewLogEntry(table.Name, table.TableType, domain.DeleteTable, ctx),
SourceTableName: table.Name,
RowCount: table.RowCount,
SubTables: subTables,
}); err != nil {
return nil, err
}
if err := ptr.DeleteTables(ctx, table); err != nil {
return nil, err
}
if err := ptr.DeleteTables(ctx, subTables...); err != nil {
return nil, err
}
// 通知底层
return nil, nil
}
func (ptr *DeleteDataTableService) DeleteTables(ctx *domain.Context, tables ...*domain.Table) error {
// delete table
if len(tables) == 0 {
return nil
}
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
var tableIds []int
for _, t := range tables {
if _, err := tableRepository.Remove(t); err != nil {
return err
}
tableIds = append(tableIds, t.TableId)
}
// delete log
//if err := dao.LogSoftDelete(ptr.transactionContext, tableIds, domain.CommonLog); err != nil {
// return err
//}
return nil
}
... ...
... ... @@ -21,7 +21,7 @@ func NewDeleteFileService(transactionContext *pgTransaction.TransactionContext)
}
}
func (ptr *DeleteFileService) Delete(files ...*domain.File) error {
func (ptr *DeleteFileService) Delete(ctx *domain.Context, files ...*domain.File) error {
for _, file := range files {
if err := ptr.delete(file); err != nil {
return err
... ... @@ -42,7 +42,7 @@ func (ptr *DeleteFileService) delete(file *domain.File) error {
}
}
// delete log
if err := dao.LogDelete(ptr.transactionContext, file.FileId, domain.VerifiedStepLog); err != nil {
if err := dao.LogDirectDelete(ptr.transactionContext, file.FileId, domain.VerifiedStepLog); err != nil {
return err
}
return nil
... ...
... ... @@ -15,7 +15,7 @@ type FlushDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func (ptr *FlushDataTableService) Flush(fileId int, table *domain.Table) (interface{}, error) {
func (ptr *FlushDataTableService) Flush(ctx *domain.Context, fileId int, table *domain.Table) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
if err != nil {
... ... @@ -26,23 +26,22 @@ func (ptr *FlushDataTableService) Flush(fileId int, table *domain.Table) (interf
return nil, fmt.Errorf("源文件不存在")
}
// New Table
table = NewTable(domain.ExcelTable, file.FileInfo.Name, table.DataFields, table.RowCount)
table = NewTable(domain.ExcelTable, file.FileInfo.Name, table.DataFields, table.RowCount).WithContext(ctx)
// 来自源文件的
// 临时文件 -》校验文件
switch sourceFile.FileType {
case domain.SourceFile.ToString():
if err = ptr.flushSourceFile(table, file, sourceFile, fileRepository); err != nil {
if err = ptr.flushSourceFile(ctx, table, file, sourceFile, fileRepository); err != nil {
return nil, err
}
case domain.VerifiedFile.ToString():
if err = ptr.flushVerifiedFile(table, file, sourceFile, fileRepository); err != nil {
if err = ptr.flushVerifiedFile(ctx, table, file, sourceFile, fileRepository); err != nil {
return nil, err
}
}
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, file.FileId, &FileVerifyLog{
LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.VerifiedFile.ToString(), domain.FileVerify, ""),
LogEntry: domain.NewLogEntry(file.FileInfo.Name, domain.VerifiedFile.ToString(), domain.FileVerify, ctx),
Total: table.RowCount,
}); err != nil {
return nil, err
... ... @@ -52,7 +51,7 @@ func (ptr *FlushDataTableService) Flush(fileId int, table *domain.Table) (interf
return struct{}{}, nil
}
func (ptr *FlushDataTableService) flushSourceFile(table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
func (ptr *FlushDataTableService) flushSourceFile(ctx *domain.Context, table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
var err error
// 新增
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
... ... @@ -65,22 +64,18 @@ func (ptr *FlushDataTableService) flushSourceFile(table *domain.Table, file *dom
if file, err = fileRepository.Save(file); err != nil {
return err
}
// 删除跟源文件有关系的校验文件
//if err = dao.FileDeleteBySourceFileId(ptr.transactionContext, sourceFile.FileId, domain.VerifiedFile, file.FileId); err != nil {
// return err
//}
_, files, err := fileRepository.Find(map[string]interface{}{"sourceFileId": sourceFile.FileId, "fileType": domain.VerifiedFile.ToString(), "notInFileIds": []int{file.FileId}})
_, files, err := fileRepository.Find(map[string]interface{}{"context": ctx, "sourceFileId": sourceFile.FileId, "fileType": domain.VerifiedFile.ToString(), "notInFileIds": []int{file.FileId}})
if err != nil {
return err
}
deleteFileService, _ := NewDeleteFileService(ptr.transactionContext)
if err = deleteFileService.Delete(files...); err != nil {
if err = deleteFileService.Delete(ctx, files...); err != nil {
return err
}
return nil
}
func (ptr *FlushDataTableService) flushVerifiedFile(table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
func (ptr *FlushDataTableService) flushVerifiedFile(ctx *domain.Context, table *domain.Table, file *domain.File, sourceFile *domain.File, fileRepository domain.FileRepository) error {
var err error
temporaryFileTableId := table.TableId
// 校验文件对应的表更新
... ... @@ -128,7 +123,7 @@ func NewTable(tableType domain.TableType, fileName string, dataFields []*domain.
table.PK = PK()
table.DataFieldIndex = len(dataFields)
for i, field := range dataFields {
table.DataFields = append(table.DataFields, DataField(field.Name, field.SQLType, domain.MainTableField, i))
table.DataFields = append(table.DataFields, DataField(field.Name, field.SQLType, domain.MainTableField, i+1))
}
table.ManualFields = make([]*domain.Field, 0)
table.CreatedAt = time.Now()
... ... @@ -157,7 +152,7 @@ func DataField(name string, sqlType string, flag int, index int) *domain.Field {
return &domain.Field{
Index: index,
Name: name,
SQLName: fieldName(index + 1),
SQLName: fieldName(index),
SQLType: sqlType,
Description: "",
Flag: flag,
... ... @@ -165,5 +160,5 @@ func DataField(name string, sqlType string, flag int, index int) *domain.Field {
}
func fieldName(index int) string {
return fmt.Sprintf("col%02d", index)
return fmt.Sprintf("col%d", index)
}
... ...
... ... @@ -11,7 +11,7 @@ type GenerateMainTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func (ptr *GenerateMainTableService) GenerateTable(fileId int, tableName string) (interface{}, error) {
func (ptr *GenerateMainTableService) GenerateTable(ctx *domain.Context, fileId int, tableName string) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
if err != nil {
... ... @@ -23,12 +23,24 @@ func (ptr *GenerateMainTableService) GenerateTable(fileId int, tableName string)
if err != nil {
return nil, fmt.Errorf("文件未校验")
}
duplicateTable, err := tableRepository.FindOne(map[string]interface{}{"context": ctx, "tableType": domain.MainTable.ToString(), "tableName": tableName})
if err == nil && duplicateTable != nil {
return nil, fmt.Errorf("表名称重复")
}
mainTable := NewTable(domain.MainTable, tableName, table.DataFields, table.RowCount)
mainTable := NewTable(domain.MainTable, tableName, table.DataFields, table.RowCount).WithContext(ctx)
_, err = tableRepository.Save(mainTable)
if err != nil {
return nil, err
}
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, mainTable.TableId, &GenerateMainTableLog{
LogEntry: domain.NewLogEntry(tableName, domain.MainTable.ToString(), domain.GenerateMainTable, ctx),
FileName: file.FileInfo.Name,
}); err != nil {
return nil, err
}
return struct{}{}, nil
}
... ...
... ... @@ -12,7 +12,7 @@ type LoadDataTableService struct {
transactionContext *pgTransaction.TransactionContext
}
func (ptr *LoadDataTableService) Load(fileId int) (interface{}, error) {
func (ptr *LoadDataTableService) Load(ctx *domain.Context, fileId int) (interface{}, error) {
fileRepository, _ := repository.NewFileRepository(ptr.transactionContext)
file, err := fileRepository.FindOne(map[string]interface{}{"fileId": fileId})
if err != nil {
... ... @@ -21,7 +21,7 @@ func (ptr *LoadDataTableService) Load(fileId int) (interface{}, error) {
// Copy to TemporaryFile
if file.FileType != domain.TemporaryFile.ToString() {
file = file.CopyTo(domain.TemporaryFile)
file = file.CopyTo(domain.TemporaryFile, ctx)
if file, err = fileRepository.Save(file); err != nil {
return nil, err
}
... ...
... ... @@ -5,6 +5,7 @@ import (
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
"strings"
"time"
)
... ... @@ -40,6 +41,7 @@ func (ptr *PGLogService) Log(logType domain.LogType, sourceId int, logEntry Log)
Content: logEntry.Content(),
OperatorName: entry.OperatorName,
CreatedAt: time.Now(),
Context: logEntry.Context(),
}
_, err := logRepository.Save(log)
return err
... ... @@ -52,6 +54,7 @@ func (ptr *PGLogService) NewLogEntry() domain.LogEntry {
type Log interface {
Content() string
Entry() domain.LogEntry
Context() *domain.Context
}
var _ Log = (*FileUploadSuccessLog)(nil)
... ... @@ -91,3 +94,116 @@ func (l *FileVerifyLog) Content() string {
}
return msg
}
// 3.主表生成日志
type GenerateMainTableLog struct {
domain.LogEntry
// 表名
TableName string
// 文件名
FileName string
}
func (l *GenerateMainTableLog) Content() string {
msg := fmt.Sprintf("来源校验文件:%v", l.FileName)
return msg
}
// 4.主表拆分
type SpiltMainTableLog struct {
domain.LogEntry
Reserve []*domain.Field
Delete []*domain.Field
Add []*domain.Field
// 表名
SourceTableName string
}
func (l *SpiltMainTableLog) Content() string {
var msg string
msg += fmt.Sprintf("来源表:%v", l.SourceTableName)
msg += l.makeMsg(" 删除字段", l.Delete)
msg += l.makeMsg(" 保留字段", l.Reserve)
msg += l.makeMsg(" 添加字段", l.Add)
return msg
}
func (l *SpiltMainTableLog) makeMsg(title string, fields []*domain.Field) string {
if len(l.fieldNames(fields)) > 0 {
return fmt.Sprintf("%s: %s ", title, strings.Join(l.fieldNames(fields), "、"))
}
return ""
}
func (l *SpiltMainTableLog) fieldNames(fields []*domain.Field) []string {
names := make([]string, 0)
for _, f := range fields {
names = append(names, f.Name)
}
return names
}
// 5.分表编辑
type SubTableEditLog struct {
domain.LogEntry
Reserve []*domain.Field
Delete []*domain.Field
Add []*domain.Field
}
func (l *SubTableEditLog) Content() string {
var msg string
msg += l.makeMsg("删除字段", l.Delete)
msg += l.makeMsg("保留字段", l.Reserve)
msg += l.makeMsg("添加字段", l.Add)
return msg
}
func (l *SubTableEditLog) makeMsg(title string, fields []*domain.Field) string {
if len(l.fieldNames(fields)) > 0 {
return fmt.Sprintf("%s: %s ", title, strings.Join(l.fieldNames(fields), "、"))
}
return ""
}
func (l *SubTableEditLog) fieldNames(fields []*domain.Field) []string {
names := make([]string, 0)
for _, f := range fields {
names = append(names, f.Name)
}
return names
}
// 6.表复制日志
type CopyTableLog struct {
domain.LogEntry
// 表名
SourceTableName string
}
func (l *CopyTableLog) Content() string {
msg := fmt.Sprintf("来源表:%v", l.SourceTableName)
return msg
}
// 8.表删除日志
type DeleteTableLog struct {
domain.LogEntry
// 表名
SourceTableName string
RowCount int
SubTables []*domain.Table
}
func (l *DeleteTableLog) Content() string {
msg := fmt.Sprintf("共计%v条数据", l.RowCount)
var tables []string
for _, t := range l.SubTables {
tables = append(tables, t.Name+"分表")
}
if len(tables) > 0 {
msg += fmt.Sprintf(",(存在分表)同步删除%s", strings.Join(tables, "/"))
}
return msg
}
... ...
package domainService
import (
"fmt"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/repository"
"time"
)
type UpdateTableStructService struct {
transactionContext *pgTransaction.TransactionContext
}
func NewUpdateTableStructService(transactionContext *pgTransaction.TransactionContext) (*UpdateTableStructService, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &UpdateTableStructService{
transactionContext: transactionContext,
}, nil
}
}
func (ptr *UpdateTableStructService) UpdateTableStruct(ctx *domain.Context, tableId int, fields []*domain.Field, name string) (interface{}, error) {
tableRepository, _ := repository.NewTableRepository(ptr.transactionContext)
table, err := tableRepository.FindOne(map[string]interface{}{"tableId": tableId})
if err != nil {
return nil, err
}
if table.TableType != domain.SubTable.ToString() {
return nil, fmt.Errorf("只有分表允许编辑表结构")
}
mainTable, err := tableRepository.FindOne(map[string]interface{}{"tableId": table.ParentId})
if err != nil {
return nil, fmt.Errorf("主表不存在")
}
fields = MappingFields(mainTable, fields)
reserves, deletes, adds := domain.FieldsChange(table.Fields(false), fields)
dataFields := (domain.Fields)(fields).Select(map[string]interface{}{"flag": 1})
manualFields := (domain.Fields)(fields).Select(map[string]interface{}{"flag": 2})
table.DataFieldIndex = mainTable.DataFieldIndex
table.DataFields = dataFields
table.ManualFields = manualFields
table.UpdatedAt = time.Now()
if err = domain.ValidFields(fields); err != nil {
return nil, err
}
if _, err = tableRepository.Save(table); err != nil {
return nil, err
}
if _, err = tableRepository.Save(mainTable); err != nil {
return nil, err
}
// Log
// 日志
if err = FastLog(ptr.transactionContext, domain.CommonLog, table.TableId, &SubTableEditLog{
LogEntry: domain.NewLogEntry(table.Name, table.TableType, domain.EditSubTable, ctx),
Reserve: reserves,
Delete: deletes,
Add: adds,
}); err != nil {
return nil, err
}
// 通知底层
return struct{}{}, nil
}
func MappingFields(table *domain.Table, fields []*domain.Field) []*domain.Field {
tableFields := table.Fields(false)
tableFieldsMap := (domain.Fields)(tableFields).ToMap()
for i := range fields {
f := fields[i]
if v, ok := tableFieldsMap[fields[i].Name]; ok {
fields[i].Name = v.Name
fields[i].SQLName = v.SQLName
fields[i].Index = v.Index
fields[i].SQLType = v.SQLType
fields[i].Description = v.Description
fields[i].Flag = v.Flag
} else {
if f.Flag == domain.ManualField && f.Index == 0 {
table.DataFieldIndex += 1
fields[i] = DataField(f.Name, f.SQLType, domain.ManualField, table.DataFieldIndex)
}
}
}
return fields
}
... ...
... ... @@ -28,6 +28,7 @@ func Init() {
(*models.File)(nil),
(*models.Table)(nil),
(*models.Log)(nil),
(*models.MappingRule)(nil),
} {
err := DB.Model(model).CreateTable(&orm.CreateTableOptions{
Temp: false,
... ...
... ... @@ -16,7 +16,7 @@ type File struct {
// 源文件Id(FileType为TemporaryFile或VerifiedFile时有值)
SourceFileId int `comment:"源文件Id(FileType为TemporaryFile或VerifiedFile时有值)"`
// 操作人
Operator string `comment:"操作人"`
//Operator string `comment:"操作人"`
// 创建时间
CreatedAt time.Time `comment:"创建时间"`
// 更新时间
... ... @@ -25,4 +25,6 @@ type File struct {
DeletedAt time.Time `pg:",soft_delete" comment:"删除时间"`
// 版本
Version int `comment:"版本"`
// 扩展
Context *domain.Context `json:"context"`
}
... ...
... ... @@ -27,4 +27,6 @@ type Log struct {
OperatorName string `json:"operatorName"`
// 创建时间
CreatedAt time.Time `comment:"创建时间"`
// 扩展
Context *domain.Context `json:"context"`
}
... ...
package models
import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"time"
)
type MappingRule struct {
tableName string `comment:"匹配规则配置" pg:"metadata.mapping_rules,alias:mapping_rule"`
// 匹配规则ID
MappingRuleId int `comment:"匹配规则ID" pg:"pk:mapping_rule_id"`
// 名称
Name string `comment:"名称"`
// 表Id
TableId int `comment:"表Id"`
// 文件ID
FileId int `comment:"文件ID"`
// 主表列
MainTableFields []*domain.Field `comment:"主表列"`
// 校验文件列
VerifiedFileFields []*domain.Field `comment:"校验文件列"`
// 校验文件列
MappingFields []*domain.MappingField `comment:"校验文件列"`
// 创建时间
CreatedAt time.Time `comment:"创建时间"`
// 更新时间
UpdatedAt time.Time `comment:"更新时间"`
// 删除时间
DeletedAt time.Time `comment:"删除时间"`
// 扩展
Context *domain.Context `json:"context"`
}
... ...
... ... @@ -33,4 +33,8 @@ type Table struct {
DeletedAt time.Time `pg:",soft_delete" comment:"删除时间"`
// 版本
Version int `comment:"版本"`
// 行数
RowCount int `comment:"行数"`
// 扩展
Context *domain.Context `json:"context"`
}
... ...
... ... @@ -11,10 +11,11 @@ func TransformToFileDomainModelFromPgModels(fileModel *models.File) (*domain.Fil
FileType: fileModel.FileType,
FileInfo: fileModel.FileInfo,
SourceFileId: fileModel.SourceFileId,
Operator: fileModel.Operator,
CreatedAt: fileModel.CreatedAt,
UpdatedAt: fileModel.UpdatedAt,
DeletedAt: fileModel.DeletedAt,
Version: fileModel.Version,
//Operator: fileModel.Operator,
CreatedAt: fileModel.CreatedAt,
UpdatedAt: fileModel.UpdatedAt,
DeletedAt: fileModel.DeletedAt,
Version: fileModel.Version,
Context: fileModel.Context,
}, nil
}
... ...
... ... @@ -17,5 +17,6 @@ func TransformToLogDomainModelFromPgModels(logModel *models.Log) (*domain.Log, e
Content: logModel.Content,
OperatorName: logModel.OperatorName,
CreatedAt: logModel.CreatedAt,
Context: logModel.Context,
}, nil
}
... ...
package transform
import (
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models"
)
func TransformToMappingRuleDomainModelFromPgModels(mappingRuleModel *models.MappingRule) (*domain.MappingRule, error) {
return &domain.MappingRule{
MappingRuleId: mappingRuleModel.MappingRuleId,
Name: mappingRuleModel.Name,
TableId: mappingRuleModel.TableId,
FileId: mappingRuleModel.FileId,
MainTableFields: mappingRuleModel.MainTableFields,
VerifiedFileFields: mappingRuleModel.VerifiedFileFields,
MappingFields: mappingRuleModel.MappingFields,
CreatedAt: mappingRuleModel.CreatedAt,
UpdatedAt: mappingRuleModel.UpdatedAt,
DeletedAt: mappingRuleModel.DeletedAt,
Context: mappingRuleModel.Context,
}, nil
}
... ...
... ... @@ -20,5 +20,7 @@ func TransformToTableDomainModelFromPgModels(tableModel *models.Table) (*domain.
UpdatedAt: tableModel.UpdatedAt,
DeletedAt: tableModel.DeletedAt,
Version: tableModel.Version,
RowCount: tableModel.RowCount,
Context: tableModel.Context,
}, nil
}
... ...
... ... @@ -29,11 +29,12 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error)
"file_type",
"file_info",
"source_file_id",
"operator",
//"operator",
"created_at",
"updated_at",
"deleted_at",
"version",
"context",
}
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "file_id", "deleted_at"))
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "file_id", "deleted_at"))
... ... @@ -48,20 +49,22 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error)
&file.FileType,
&file.FileInfo,
&file.SourceFileId,
&file.Operator,
//&file.Operator,
&file.CreatedAt,
&file.UpdatedAt,
&file.DeletedAt,
&file.Version,
&file.Context,
),
fmt.Sprintf("INSERT INTO metadata.files (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
file.FileType,
file.FileInfo,
file.SourceFileId,
file.Operator,
//file.Operator,
file.CreatedAt,
file.UpdatedAt,
file.Version,
file.Context,
); err != nil {
return file, err
}
... ... @@ -74,20 +77,22 @@ func (repository *FileRepository) Save(file *domain.File) (*domain.File, error)
&file.FileType,
&file.FileInfo,
&file.SourceFileId,
&file.Operator,
//&file.Operator,
&file.CreatedAt,
&file.UpdatedAt,
&file.DeletedAt,
&file.Version,
&file.Context,
),
fmt.Sprintf("UPDATE metadata.files SET %s WHERE file_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
file.FileType,
file.FileInfo,
file.SourceFileId,
file.Operator,
//file.Operator,
file.CreatedAt,
file.UpdatedAt,
file.Version,
file.Context,
file.Identify(),
oldVersion,
); err != nil {
... ... @@ -128,6 +133,7 @@ func (repository *FileRepository) Find(queryOptions map[string]interface{}) (int
var fileModels []*models.File
files := make([]*domain.File, 0)
query := sqlbuilder.BuildQuery(tx.Model(&fileModels), queryOptions)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption("file_id > ?", "lastId")
query.SetWhereByQueryOption("file_type = ?", "fileType")
query.SetWhereByQueryOption(fmt.Sprintf("file_info->>'name' like '%%%v%%'", queryOptions["fileName"]), "fileName")
... ...
... ... @@ -3,6 +3,9 @@ package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/go-pg/pg/v10/orm"
"github.com/linmadan/egglib-go/utils/xtime"
"time"
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
... ... @@ -36,6 +39,7 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
"operator_name",
"created_at",
"entry",
"context",
}
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id"))
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "log_id"))
... ... @@ -56,6 +60,7 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
&log.OperatorName,
&log.CreatedAt,
&log.Entry,
&log.Context,
),
fmt.Sprintf("INSERT INTO metadata.logs (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
log.LogType,
... ... @@ -67,6 +72,7 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
log.OperatorName,
log.CreatedAt,
log.Entry,
log.Context,
); err != nil {
return log, err
}
... ... @@ -83,6 +89,7 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
&log.OperatorName,
&log.CreatedAt,
&log.Entry,
&log.Context,
),
fmt.Sprintf("UPDATE metadata.logs SET %s WHERE log_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
log.LogType,
... ... @@ -93,7 +100,8 @@ func (repository *LogRepository) Save(log *domain.Log) (*domain.Log, error) {
log.Content,
log.OperatorName,
log.CreatedAt,
&log.Entry,
log.Entry,
log.Context,
log.Identify(),
); err != nil {
return log, err
... ... @@ -133,6 +141,29 @@ func (repository *LogRepository) Find(queryOptions map[string]interface{}) (int6
var logModels []*models.Log
logs := make([]*domain.Log, 0)
query := sqlbuilder.BuildQuery(tx.Model(&logModels), queryOptions)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption(" log_type = ?", "logType")
query.SetWhereByQueryOption(" source_id = ?", "sourceId")
if v, ok := queryOptions["inSourceId"]; ok && len(v.([]int)) > 0 {
query.Where("source_id in (?)", pg.In(v.([]int)))
}
if v, ok := queryOptions["matchContent"]; ok && len(v.(string)) > 0 {
query.WhereGroup(func(query *orm.Query) (*orm.Query, error) {
matchContent := v.(string)
query.WhereOr(fmt.Sprintf("content like '%%%v%%'", matchContent))
query.WhereOr(fmt.Sprintf("operator_name like '%%%v%%'", matchContent))
query.WhereOr(fmt.Sprintf("object_name like '%%%v%%'", matchContent))
return query, nil
})
}
if v, ok := queryOptions["beginTime"]; ok && !xtime.IsZero(v.(time.Time)) {
query.SetWhereByQueryOption(" created_at >= ?", "beginTime")
}
if v, ok := queryOptions["endTime"]; ok && !xtime.IsZero(v.(time.Time)) {
query.SetWhereByQueryOption(" created_at < ?", "endTime")
}
query.SetOffsetAndLimit(20)
query.SetOrderDirect("log_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
... ...
package repository
import (
"fmt"
"github.com/go-pg/pg/v10"
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
"github.com/linmadan/egglib-go/utils/snowflake"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/models"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/pg/transform"
)
type MappingRuleRepository struct {
transactionContext *pgTransaction.TransactionContext
}
func (repository *MappingRuleRepository) nextIdentify() (int64, error) {
IdWorker, err := snowflake.NewIdWorker(1)
if err != nil {
return 0, err
}
id, err := IdWorker.NextId()
return id, err
}
func (repository *MappingRuleRepository) Save(mappingRule *domain.MappingRule) (*domain.MappingRule, error) {
sqlBuildFields := []string{
"mapping_rule_id",
"name",
"table_id",
"file_id",
"main_table_fields",
"verified_file_fields",
"mapping_fields",
"created_at",
"updated_at",
"deleted_at",
"context",
}
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "mapping_rule_id", "deleted_at"))
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "mapping_rule_id", "deleted_at"))
returningFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlBuildFields)
updateFields := sqlbuilder.RemoveSqlFields(sqlBuildFields, "mapping_rule_id", "deleted_at")
updateFieldsSnippet := sqlbuilder.SqlUpdateFieldsSnippet(updateFields)
tx := repository.transactionContext.PgTx
if mappingRule.Identify() == nil {
if _, err := tx.QueryOne(
pg.Scan(
&mappingRule.MappingRuleId,
&mappingRule.Name,
&mappingRule.TableId,
&mappingRule.FileId,
&mappingRule.MainTableFields,
&mappingRule.VerifiedFileFields,
&mappingRule.MappingFields,
&mappingRule.CreatedAt,
&mappingRule.UpdatedAt,
&mappingRule.DeletedAt,
&mappingRule.Context,
),
fmt.Sprintf("INSERT INTO metadata.mapping_rules (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
//mappingRule.MappingRuleId,
mappingRule.Name,
mappingRule.TableId,
mappingRule.FileId,
mappingRule.MainTableFields,
mappingRule.VerifiedFileFields,
mappingRule.MappingFields,
mappingRule.CreatedAt,
mappingRule.UpdatedAt,
mappingRule.Context,
//mappingRule.DeletedAt,
); err != nil {
return mappingRule, err
}
} else {
if _, err := tx.QueryOne(
pg.Scan(
&mappingRule.MappingRuleId,
&mappingRule.Name,
&mappingRule.TableId,
&mappingRule.FileId,
&mappingRule.MainTableFields,
&mappingRule.VerifiedFileFields,
&mappingRule.MappingFields,
&mappingRule.CreatedAt,
&mappingRule.UpdatedAt,
&mappingRule.DeletedAt,
&mappingRule.Context,
),
fmt.Sprintf("UPDATE metadata.mapping_rules SET %s WHERE mapping_rule_id=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
//mappingRule.MappingRuleId,
mappingRule.Name,
mappingRule.TableId,
mappingRule.FileId,
mappingRule.MainTableFields,
mappingRule.VerifiedFileFields,
mappingRule.MappingFields,
mappingRule.CreatedAt,
mappingRule.UpdatedAt,
mappingRule.Context,
//mappingRule.DeletedAt,
mappingRule.Identify(),
); err != nil {
return mappingRule, err
}
}
return mappingRule, nil
}
func (repository *MappingRuleRepository) Remove(mappingRule *domain.MappingRule) (*domain.MappingRule, error) {
tx := repository.transactionContext.PgTx
mappingRuleModel := new(models.MappingRule)
mappingRuleModel.MappingRuleId = mappingRule.Identify().(int)
if _, err := tx.Model(mappingRuleModel).WherePK().Delete(); err != nil {
return mappingRule, err
}
return mappingRule, nil
}
func (repository *MappingRuleRepository) FindOne(queryOptions map[string]interface{}) (*domain.MappingRule, error) {
tx := repository.transactionContext.PgTx
mappingRuleModel := new(models.MappingRule)
query := sqlbuilder.BuildQuery(tx.Model(mappingRuleModel), queryOptions)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption("name = ?", "name")
query.SetWhereByQueryOption("mapping_rule.mapping_rule_id = ?", "mappingRuleId")
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
} else {
return nil, err
}
}
if mappingRuleModel.MappingRuleId == 0 {
return nil, nil
} else {
return transform.TransformToMappingRuleDomainModelFromPgModels(mappingRuleModel)
}
}
func (repository *MappingRuleRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.MappingRule, error) {
tx := repository.transactionContext.PgTx
var mappingRuleModels []*models.MappingRule
mappingRules := make([]*domain.MappingRule, 0)
query := sqlbuilder.BuildQuery(tx.Model(&mappingRuleModels), queryOptions)
WhereContext(query, queryOptions)
//query.SetOffsetAndLimit(20)
query.SetWhereByQueryOption("table_id = ?", "tableId")
query.SetOrderDirect("mapping_rule_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
return 0, mappingRules, err
} else {
for _, mappingRuleModel := range mappingRuleModels {
if mappingRule, err := transform.TransformToMappingRuleDomainModelFromPgModels(mappingRuleModel); err != nil {
return 0, mappingRules, err
} else {
mappingRules = append(mappingRules, mappingRule)
}
}
return int64(count), mappingRules, nil
}
}
func NewMappingRuleRepository(transactionContext *pgTransaction.TransactionContext) (*MappingRuleRepository, error) {
if transactionContext == nil {
return nil, fmt.Errorf("transactionContext参数不能为nil")
} else {
return &MappingRuleRepository{
transactionContext: transactionContext,
}, nil
}
}
... ...
package repository
import (
"github.com/linmadan/egglib-go/persistent/pg/sqlbuilder"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
)
func WhereContext(query *sqlbuilder.Query, queryOptions map[string]interface{}) {
if _, ok := queryOptions["context"]; !ok {
return
}
context := queryOptions["context"].(*domain.Context)
query.Where("context->'companyId'='?'", context.CompanyId)
}
... ...
... ... @@ -39,6 +39,8 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
"updated_at",
"deleted_at",
"version",
"row_count",
"context",
}
insertFieldsSnippet := sqlbuilder.SqlFieldsSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id", "deleted_at"))
insertPlaceHoldersSnippet := sqlbuilder.SqlPlaceHoldersSnippet(sqlbuilder.RemoveSqlFields(sqlBuildFields, "table_id", "deleted_at"))
... ... @@ -62,6 +64,8 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
&table.UpdatedAt,
&table.DeletedAt,
&table.Version,
&table.RowCount,
&table.Context,
),
fmt.Sprintf("INSERT INTO metadata.tables (%s) VALUES (%s) RETURNING %s", insertFieldsSnippet, insertPlaceHoldersSnippet, returningFieldsSnippet),
table.TableType,
... ... @@ -75,6 +79,8 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
table.CreatedAt,
table.UpdatedAt,
table.Version,
table.RowCount,
table.Context,
); err != nil {
return table, err
}
... ... @@ -96,6 +102,8 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
&table.UpdatedAt,
&table.DeletedAt,
&table.Version,
&table.RowCount,
&table.Context,
),
fmt.Sprintf("UPDATE metadata.tables SET %s WHERE table_id=? and version=? RETURNING %s", updateFieldsSnippet, returningFieldsSnippet),
table.TableType,
... ... @@ -109,8 +117,10 @@ func (repository *TableRepository) Save(table *domain.Table) (*domain.Table, err
table.CreatedAt,
table.UpdatedAt,
table.Version,
oldVersion,
table.RowCount,
table.Context,
table.Identify(),
oldVersion,
); err != nil {
return table, err
}
... ... @@ -130,7 +140,11 @@ func (repository *TableRepository) FindOne(queryOptions map[string]interface{})
tx := repository.transactionContext.PgTx
tableModel := new(models.Table)
query := sqlbuilder.BuildQuery(tx.Model(tableModel), queryOptions)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption("table_id = ?", "tableId")
query.SetWhereByQueryOption(`table_type = ?`, "tableType")
query.SetWhereByQueryOption("name = ?", "tableName")
query.SetWhereByQueryOption("parent_id = ?", "parentId")
if err := query.First(); err != nil {
if err.Error() == "pg: no rows in result set" {
return nil, fmt.Errorf("没有此资源")
... ... @@ -149,7 +163,15 @@ func (repository *TableRepository) Find(queryOptions map[string]interface{}) (in
var tableModels []*models.Table
tables := make([]*domain.Table, 0)
query := sqlbuilder.BuildQuery(tx.Model(&tableModels), queryOptions)
query.SetOffsetAndLimit(20)
WhereContext(query, queryOptions)
query.SetWhereByQueryOption(fmt.Sprintf("name like '%%%v%%'", queryOptions["name"]), "name")
query.SetWhereByQueryOption("parent_id = ?", "parentId")
if v, ok := queryOptions["tableTypes"]; ok && len(v.([]string)) > 0 {
query.Where(`table_type in (?)`, pg.In(v.([]string)))
}
//query.SetOffsetAndLimit(20)
query.SetOrderDirect("table_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
return 0, tables, err
... ...
package starrocks
import (
"database/sql"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/domain"
)
func Query(params QueryOptions, queryFunc func(params QueryOptions) (*sql.Rows, error)) (*domain.DataTable, error) {
rows, err := queryFunc(params)
if err != nil {
return nil, err
}
dataTable := &domain.DataTable{}
dataTable.Data, _ = ScanRows(rows)
return nil, nil
}
type QueryOptions struct {
TableName string
Select []*domain.Field
Where []string
Order []string
Offset int
Limit int
}
type Condition struct {
Field *domain.Field
}
... ...
package starrocks
import (
"database/sql"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
"reflect"
)
func ScanRows(rows *sql.Rows) ([][]string, error) {
defer rows.Close()
var results [][]string
cols, err := rows.Columns()
if err != nil {
log.Logger.Error(err.Error())
return nil, err
}
for rows.Next() {
var row = make([]interface{}, 0)
generic := reflect.TypeOf(row).Elem()
for _ = range cols {
row = append(row, reflect.New(generic).Interface())
}
err := rows.Scan(row...)
if err != nil {
log.Logger.Error(err.Error())
return nil, err
}
var rowStrings = make([]string, len(cols))
for i := range row {
rowStrings[i] = utils.AssertString(*(row[i].(*interface{})))
}
results = append(results, rowStrings)
}
return results, nil
}
... ...
package starrocks
import (
"github.com/linmadan/egglib-go/utils/json"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/constant"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/character-library-metadata-bastion/pkg/log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"reflect"
)
var DB *gorm.DB
func Init() error {
var err error
DB, err = gorm.Open(mysql.Open(constant.STARROCKS_MYSQL_DATA_SOURCE), &gorm.Config{})
//Test1()
return err
}
func Test() {
//var result [][]interface{}
//query := DB.Raw("select * from sales_performance_area_belongs").Select(&result)
//if query.Error != nil {
// log.Logger.Error(query.Error.Error())
//}
//if len(result) > 0 {
//
//}
//rows, err := DB.Raw("select * from sales_performance_area_belongs").Rows()
rows, err := DB.Table("sales_performance_area_categorys").Rows()
if err != nil {
log.Logger.Error(err.Error())
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
log.Logger.Error(err.Error())
}
var results [][]interface{}
for rows.Next() {
// 1
var row = make([]interface{}, 0)
generic := reflect.TypeOf(row).Elem()
for _ = range cols {
row = append(row, reflect.New(generic).Interface())
}
err := rows.Scan(row...)
if err != nil {
log.Logger.Error(err.Error())
}
for i := range row {
row[i] = utils.AssertString(*(row[i].(*interface{})))
}
results = append(results, row)
// 2
//var row = make([]interface{}, len(cols))
//var rowp = make([]interface{}, len(cols))
//
//for i := range cols {
// rowp[i] = &row[i]
//}
//err := rows.Scan(rowp...)
//if err != nil {
// log.Logger.Error(err.Error())
//}
//results = append(results, rowp)
// 3
//var row = make([]interface{}, 0)
//var value string
//generic := reflect.TypeOf(value)
//
//for _ = range cols {
// row = append(row, reflect.New(generic).Interface())
//}
//err := rows.Scan(row...)
//if err != nil {
// log.Logger.Error(err.Error())
//}
//results = append(results, row)
}
log.Logger.Debug(json.MarshalToString(results))
}
func Test1() {
rows, err := DB.Table("sales_performance_area_categorys").Rows()
if err != nil {
log.Logger.Error(err.Error())
}
data, _ := ScanRows(rows)
log.Logger.Debug(json.MarshalToString(data))
}
... ...