feat: 同步数据库时标记已删除数据库 (#4185)

Refs #4165
pull/4190/head
ssongliu 9 months ago committed by GitHub
parent be36103475
commit 0f9b0d5d82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -41,7 +41,7 @@ type MysqlDBInfo struct {
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
Permission string `json:"permission"` Permission string `json:"permission"`
BackupCount int `json:"backupCount"` IsDelete bool `json:"isDelete"`
Description string `json:"description"` Description string `json:"description"`
} }

@ -20,7 +20,7 @@ type PostgresqlDBInfo struct {
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
SuperUser bool `json:"superUser"` SuperUser bool `json:"superUser"`
BackupCount int `json:"backupCount"` IsDelete bool `json:"isDelete"`
Description string `json:"description"` Description string `json:"description"`
} }

@ -9,5 +9,6 @@ type DatabaseMysql struct {
Username string `json:"username" gorm:"type:varchar(256);not null"` Username string `json:"username" gorm:"type:varchar(256);not null"`
Password string `json:"password" gorm:"type:varchar(256);not null"` Password string `json:"password" gorm:"type:varchar(256);not null"`
Permission string `json:"permission" gorm:"type:varchar(256);not null"` Permission string `json:"permission" gorm:"type:varchar(256);not null"`
IsDelete bool `json:"isDelete" gorm:"type:varchar(64)"`
Description string `json:"description" gorm:"type:varchar(256);"` Description string `json:"description" gorm:"type:varchar(256);"`
} }

@ -8,6 +8,7 @@ type DatabasePostgresql struct {
Format string `json:"format" gorm:"type:varchar(64);not null"` Format string `json:"format" gorm:"type:varchar(64);not null"`
Username string `json:"username" gorm:"type:varchar(256);not null"` Username string `json:"username" gorm:"type:varchar(256);not null"`
Password string `json:"password" gorm:"type:varchar(256);not null"` Password string `json:"password" gorm:"type:varchar(256);not null"`
SuperUser bool `json:"superUser" gorm:"type:varchar(64)" ` SuperUser bool `json:"superUser" gorm:"type:varchar(64)"`
IsDelete bool `json:"isDelete" gorm:"type:varchar(64)"`
Description string `json:"description" gorm:"type:varchar(256);"` Description string `json:"description" gorm:"type:varchar(256);"`
} }

@ -190,11 +190,13 @@ func (u *MysqlService) LoadFromRemote(req dto.MysqlLoadDB) error {
if err != nil { if err != nil {
return err return err
} }
deleteList := databases
for _, data := range datas { for _, data := range datas {
hasOld := false hasOld := false
for _, oldData := range databases { for i := 0; i < len(databases); i++ {
if strings.EqualFold(oldData.Name, data.Name) && strings.EqualFold(oldData.MysqlName, data.MysqlName) { if strings.EqualFold(databases[i].Name, data.Name) && strings.EqualFold(databases[i].MysqlName, data.MysqlName) {
hasOld = true hasOld = true
deleteList = append(deleteList[:i], deleteList[i+1:]...)
break break
} }
} }
@ -208,6 +210,9 @@ func (u *MysqlService) LoadFromRemote(req dto.MysqlLoadDB) error {
} }
} }
} }
for _, delItem := range deleteList {
_ = mysqlRepo.Update(delItem.ID, map[string]interface{}{"is_delete": true})
}
return nil return nil
} }

@ -216,11 +216,13 @@ func (u *PostgresqlService) LoadFromRemote(database string) error {
if err != nil { if err != nil {
return err return err
} }
deleteList := databases
for _, data := range datas { for _, data := range datas {
hasOld := false hasOld := false
for _, oldData := range databases { for i := 0; i < len(databases); i++ {
if strings.EqualFold(oldData.Name, data.Name) && strings.EqualFold(oldData.PostgresqlName, data.PostgresqlName) { if strings.EqualFold(databases[i].Name, data.Name) && strings.EqualFold(databases[i].PostgresqlName, data.PostgresqlName) {
hasOld = true hasOld = true
deleteList = append(deleteList[:i], deleteList[i+1:]...)
break break
} }
} }
@ -234,6 +236,9 @@ func (u *PostgresqlService) LoadFromRemote(database string) error {
} }
} }
} }
for _, delItem := range deleteList {
_ = postgresqlRepo.Update(delItem.ID, map[string]interface{}{"is_delete": true})
}
return nil return nil
} }

@ -74,6 +74,7 @@ func Init() {
migrations.UpdateWebDavConf, migrations.UpdateWebDavConf,
migrations.AddSnapshotIgnore, migrations.AddSnapshotIgnore,
migrations.AddDatabaseIsDelete,
}) })
if err := m.Migrate(); err != nil { if err := m.Migrate(); err != nil {
global.LOG.Error(err) global.LOG.Error(err)

@ -15,3 +15,13 @@ var AddSnapshotIgnore = &gormigrate.Migration{
return nil return nil
}, },
} }
var AddDatabaseIsDelete = &gormigrate.Migration{
ID: "20240314-add-database-is-delete",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.DatabaseMysql{}, &model.DatabasePostgresql{}); err != nil {
return err
}
return nil
},
}

@ -17818,6 +17818,9 @@ const docTemplate = `{
"sessionTimeout": { "sessionTimeout": {
"type": "string" "type": "string"
}, },
"snapshotIgnore": {
"type": "string"
},
"ssl": { "ssl": {
"type": "string" "type": "string"
}, },

@ -17811,6 +17811,9 @@
"sessionTimeout": { "sessionTimeout": {
"type": "string" "type": "string"
}, },
"snapshotIgnore": {
"type": "string"
},
"ssl": { "ssl": {
"type": "string" "type": "string"
}, },

@ -2538,6 +2538,8 @@ definitions:
type: string type: string
sessionTimeout: sessionTimeout:
type: string type: string
snapshotIgnore:
type: string
ssl: ssl:
type: string type: string
sslType: sslType:

@ -23,6 +23,7 @@ export namespace Database {
username: string; username: string;
password: string; password: string;
permission: string; permission: string;
isDelete: string;
description: string; description: string;
} }
export interface BaseInfo { export interface BaseInfo {
@ -207,6 +208,7 @@ export namespace Database {
username: string; username: string;
password: string; password: string;
superUser: boolean; superUser: boolean;
isDelete: string;
description: string; description: string;
} }
export interface ChangeInfo { export interface ChangeInfo {

@ -364,6 +364,7 @@ const message = {
goUpgrade: 'Go for upgrade', goUpgrade: 'Go for upgrade',
goInstall: 'Go for install', goInstall: 'Go for install',
source: 'Source', source: 'Source',
isDelete: 'Deleted',
permission: 'Permission', permission: 'Permission',
permissionForIP: 'IP', permissionForIP: 'IP',
permissionAll: 'All of them(%)', permissionAll: 'All of them(%)',
@ -388,7 +389,7 @@ const message = {
portHelper: portHelper:
'This port is the exposed port of the container. You need to save the modification separately and restart the container!', 'This port is the exposed port of the container. You need to save the modification separately and restart the container!',
loadFromRemote: 'Load from server', loadFromRemote: 'Sync from Server',
userBind: 'Bind User', userBind: 'Bind User',
pgBindHelper: pgBindHelper:
'This operation is used to create a new user and bind it to the target database. Currently, selecting users already existing in the database is not supported.', 'This operation is used to create a new user and bind it to the target database. Currently, selecting users already existing in the database is not supported.',

@ -360,6 +360,7 @@ const message = {
goUpgrade: '', goUpgrade: '',
goInstall: '', goInstall: '',
source: '', source: '',
isDelete: '',
permission: '', permission: '',
permissionForIP: ' IP', permissionForIP: ' IP',
permissionAll: '(%)', permissionAll: '(%)',
@ -380,7 +381,7 @@ const message = {
confChange: '', confChange: '',
confNotFound: '', confNotFound: '',
loadFromRemote: '', loadFromRemote: '',
userBind: '使', userBind: '使',
pgBindHelper: '使使', pgBindHelper: '使使',
pgSuperUser: '使', pgSuperUser: '使',

@ -360,6 +360,7 @@ const message = {
goUpgrade: '', goUpgrade: '',
goInstall: '', goInstall: '',
source: '', source: '',
isDelete: '',
permission: '', permission: '',
permissionForIP: ' IP', permissionForIP: ' IP',
permissionAll: '(%)', permissionAll: '(%)',
@ -380,7 +381,7 @@ const message = {
confChange: '', confChange: '',
confNotFound: '', confNotFound: '',
loadFromRemote: '', loadFromRemote: '',
userBind: '', userBind: '',
pgBindHelper: '', pgBindHelper: '',
pgSuperUser: '', pgSuperUser: '',

@ -113,8 +113,19 @@
</template> </template>
<template #main v-if="currentDB"> <template #main v-if="currentDB">
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">
<el-table-column :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column :label="$t('commons.table.name')" prop="name" sortable min-width="90">
<el-table-column :label="$t('commons.login.username')" prop="username"> <template #default="{ row }">
<Tooltip v-if="!row.isDelete" :islink="false" :text="row.name" />
<div v-else>
<span v-if="row.name.length < 15">{{ row.name }}</span>
<el-tooltip v-else :content="row.name">{{ row.name.substring(0, 10) }}...</el-tooltip>
<el-tag round type="info" class="ml-1" size="small">
{{ $t('database.isDelete') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column :label="$t('commons.login.username')" show-overflow-tooltip prop="username">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex items-center" v-if="row.username"> <div class="flex items-center" v-if="row.username">
<span> <span>
@ -122,7 +133,13 @@
</span> </span>
</div> </div>
<div v-else> <div v-else>
<el-button style="margin-left: -3px" type="primary" link @click="onBind(row)"> <el-button
:disabled="row.isDelete"
style="margin-left: -3px"
type="primary"
link
@click="onBind(row)"
>
{{ $t('database.userBind') }} {{ $t('database.userBind') }}
</el-button> </el-button>
</div> </div>
@ -159,7 +176,13 @@
</div> </div>
</div> </div>
<div v-if="row.password === '' && row.username"> <div v-if="row.password === '' && row.username">
<el-button style="margin-left: -3px" link type="primary" @click="onChangePassword(row)"> <el-button
:disabled="row.isDelete"
style="margin-left: -3px"
link
type="primary"
@click="onChangePassword(row)"
>
{{ $t('database.passwordHelper') }} {{ $t('database.passwordHelper') }}
</el-button> </el-button>
</div> </div>
@ -542,7 +565,7 @@ const buttons = [
{ {
label: i18n.global.t('database.changePassword'), label: i18n.global.t('database.changePassword'),
disabled: (row: Database.MysqlDBInfo) => { disabled: (row: Database.MysqlDBInfo) => {
return !row.username; return !row.username || row.isDelete;
}, },
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
onChangePassword(row); onChangePassword(row);
@ -551,7 +574,7 @@ const buttons = [
{ {
label: i18n.global.t('database.permission'), label: i18n.global.t('database.permission'),
disabled: (row: Database.MysqlDBInfo) => { disabled: (row: Database.MysqlDBInfo) => {
return !row.password; return !row.password || row.isDelete;
}, },
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
let param = { let param = {
@ -576,6 +599,9 @@ const buttons = [
}, },
{ {
label: i18n.global.t('database.backupList'), label: i18n.global.t('database.backupList'),
disabled: (row: Database.MysqlDBInfo) => {
return row.isDelete;
},
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
let params = { let params = {
type: currentDB.value.type, type: currentDB.value.type,
@ -587,6 +613,9 @@ const buttons = [
}, },
{ {
label: i18n.global.t('database.loadBackup'), label: i18n.global.t('database.loadBackup'),
disabled: (row: Database.MysqlDBInfo) => {
return row.isDelete;
},
click: (row: Database.MysqlDBInfo) => { click: (row: Database.MysqlDBInfo) => {
let params = { let params = {
type: currentDB.value.type, type: currentDB.value.type,

@ -90,7 +90,18 @@
</template> </template>
<template #main v-if="currentDB"> <template #main v-if="currentDB">
<ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data"> <ComplexTable :pagination-config="paginationConfig" @sort-change="search" @search="search" :data="data">
<el-table-column :label="$t('commons.table.name')" prop="name" sortable /> <el-table-column :label="$t('commons.table.name')" prop="name" sortable>
<template #default="{ row }">
<Tooltip v-if="!row.isDelete" :islink="false" :text="row.name" />
<div v-else>
<span v-if="row.name.length < 15">{{ row.name }}</span>
<el-tooltip v-else :content="row.name">{{ row.name.substring(0, 10) }}...</el-tooltip>
<el-tag round type="info" class="ml-1" size="small">
{{ $t('database.isDelete') }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column :label="$t('commons.login.username')" prop="username"> <el-table-column :label="$t('commons.login.username')" prop="username">
<template #default="{ row }"> <template #default="{ row }">
<div class="flex items-center" v-if="row.username"> <div class="flex items-center" v-if="row.username">
@ -99,7 +110,13 @@
</span> </span>
</div> </div>
<div v-else> <div v-else>
<el-button style="margin-left: -3px" type="primary" link @click="onBind(row)"> <el-button
:disabled="row.isDelete"
style="margin-left: -3px"
type="primary"
link
@click="onBind(row)"
>
{{ $t('database.userBind') }} {{ $t('database.userBind') }}
</el-button> </el-button>
</div> </div>
@ -498,7 +515,7 @@ const buttons = [
{ {
label: i18n.global.t('database.changePassword'), label: i18n.global.t('database.changePassword'),
disabled: (row: Database.PostgresqlDBInfo) => { disabled: (row: Database.PostgresqlDBInfo) => {
return !row.username; return !row.username || row.isDelete;
}, },
click: (row: Database.PostgresqlDBInfo) => { click: (row: Database.PostgresqlDBInfo) => {
onChangePassword(row); onChangePassword(row);
@ -507,7 +524,7 @@ const buttons = [
{ {
label: i18n.global.t('database.permission'), label: i18n.global.t('database.permission'),
disabled: (row: Database.PostgresqlDBInfo) => { disabled: (row: Database.PostgresqlDBInfo) => {
return !row.username; return !row.username || row.isDelete;
}, },
click: (row: Database.PostgresqlDBInfo) => { click: (row: Database.PostgresqlDBInfo) => {
let param = { let param = {
@ -521,6 +538,9 @@ const buttons = [
}, },
{ {
label: i18n.global.t('database.backupList'), label: i18n.global.t('database.backupList'),
disabled: (row: Database.PostgresqlDBInfo) => {
return row.isDelete;
},
click: (row: Database.PostgresqlDBInfo) => { click: (row: Database.PostgresqlDBInfo) => {
let params = { let params = {
type: currentDB.value.type, type: currentDB.value.type,
@ -532,6 +552,9 @@ const buttons = [
}, },
{ {
label: i18n.global.t('database.loadBackup'), label: i18n.global.t('database.loadBackup'),
disabled: (row: Database.PostgresqlDBInfo) => {
return row.isDelete;
},
click: (row: Database.PostgresqlDBInfo) => { click: (row: Database.PostgresqlDBInfo) => {
let params = { let params = {
type: currentDB.value.type, type: currentDB.value.type,

Loading…
Cancel
Save