Files
mayfly-go/server/internal/db/application/instance.go
kanzihuang ae3d2659aa 重构数据库备份与恢复模块 (#80)
* fix: 保存 LastResult 时截断字符串过长部分,以避免数据库报错

* refactor: 新增 entity.DbTaskBase 和 persistence.dbTaskBase, 用于实现数据库备份和恢复任务处理相关部分

* fix: aeskey变更后,解密密码出现数组越界访问错误

* fix: 时间属性为零值时,保存到 mysql 数据库报错

* refactor db.infrastructure.service.scheduler

* feat: 实现立即备份功能

* refactor db.infrastructure.service.db_instance

* refactor: 从数据库中获取数据库备份目录、mysql文件路径等配置信息

* fix: 数据库备份和恢复问题

* fix: 修改 .gitignore 文件,忽略数据库备份目录和数据库程序目录
2024-01-05 08:55:34 +08:00

113 lines
3.2 KiB
Go

package application
import (
"context"
"mayfly-go/internal/db/dbm"
"mayfly-go/internal/db/domain/entity"
"mayfly-go/internal/db/domain/repository"
"mayfly-go/pkg/base"
"mayfly-go/pkg/errorx"
"mayfly-go/pkg/model"
)
type Instance interface {
base.App[*entity.DbInstance]
// GetPageList 分页获取数据库实例
GetPageList(condition *entity.InstanceQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
Count(condition *entity.InstanceQuery) int64
TestConn(instanceEntity *entity.DbInstance) error
Save(ctx context.Context, instanceEntity *entity.DbInstance) error
// Delete 删除数据库信息
Delete(ctx context.Context, id uint64) error
// GetDatabases 获取数据库实例的所有数据库列表
GetDatabases(entity *entity.DbInstance) ([]string, error)
}
func newInstanceApp(instanceRepo repository.Instance) Instance {
app := new(instanceAppImpl)
app.Repo = instanceRepo
return app
}
type instanceAppImpl struct {
base.AppImpl[*entity.DbInstance, repository.Instance]
}
// GetPageList 分页获取数据库实例
func (app *instanceAppImpl) GetPageList(condition *entity.InstanceQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
return app.GetRepo().GetInstanceList(condition, pageParam, toEntity, orderBy...)
}
func (app *instanceAppImpl) Count(condition *entity.InstanceQuery) int64 {
return app.CountByCond(condition)
}
func (app *instanceAppImpl) TestConn(instanceEntity *entity.DbInstance) error {
instanceEntity.Network = instanceEntity.GetNetwork()
dbConn, err := toDbInfo(instanceEntity, 0, "", "").Conn()
if err != nil {
return err
}
dbConn.Close()
return nil
}
func (app *instanceAppImpl) Save(ctx context.Context, instanceEntity *entity.DbInstance) error {
// 默认tcp连接
instanceEntity.Network = instanceEntity.GetNetwork()
// 查找是否存在该库
oldInstance := &entity.DbInstance{
Host: instanceEntity.Host,
Port: instanceEntity.Port,
Username: instanceEntity.Username,
SshTunnelMachineId: instanceEntity.SshTunnelMachineId,
}
err := app.GetBy(oldInstance)
if instanceEntity.Id == 0 {
if instanceEntity.Password == "" {
return errorx.NewBiz("密码不能为空")
}
if err == nil {
return errorx.NewBiz("该数据库实例已存在")
}
if err := instanceEntity.PwdEncrypt(); err != nil {
return errorx.NewBiz(err.Error())
}
return app.Insert(ctx, instanceEntity)
}
// 如果存在该库,则校验修改的库是否为该库
if err == nil && oldInstance.Id != instanceEntity.Id {
return errorx.NewBiz("该数据库实例已存在")
}
if err := instanceEntity.PwdEncrypt(); err != nil {
return errorx.NewBiz(err.Error())
}
return app.UpdateById(ctx, instanceEntity)
}
func (app *instanceAppImpl) Delete(ctx context.Context, id uint64) error {
return app.DeleteById(ctx, id)
}
func (app *instanceAppImpl) GetDatabases(ed *entity.DbInstance) ([]string, error) {
ed.Network = ed.GetNetwork()
metaDb := dbm.ToDbType(ed.Type).MetaDbName()
dbConn, err := toDbInfo(ed, 0, metaDb, "").Conn()
if err != nil {
return nil, err
}
defer dbConn.Close()
return dbConn.GetDialect().GetDbNames()
}