mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2024-11-25 03:29:13 +08:00
feat: 远程数据库支持添加 mariadb (#2139)
This commit is contained in:
parent
66c824a841
commit
149d44dbbe
@ -244,6 +244,7 @@ type DatabaseInfo struct {
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Name string `json:"name" validate:"max=256"`
|
||||
From string `json:"from"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Address string `json:"address"`
|
||||
Port uint `json:"port"`
|
||||
@ -263,7 +264,7 @@ type DatabaseOption struct {
|
||||
|
||||
type DatabaseCreate struct {
|
||||
Name string `json:"name" validate:"required,max=256"`
|
||||
Type string `json:"type" validate:"required,oneof=mysql"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
From string `json:"from" validate:"required,oneof=local remote"`
|
||||
Version string `json:"version" validate:"required"`
|
||||
Address string `json:"address"`
|
||||
|
@ -2,6 +2,8 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"gorm.io/gorm"
|
||||
@ -18,9 +20,8 @@ type IDatabaseRepo interface {
|
||||
Get(opts ...DBOption) (model.Database, error)
|
||||
WithByFrom(from string) DBOption
|
||||
WithoutByFrom(from string) DBOption
|
||||
WithByMysqlList() DBOption
|
||||
WithAppInstallID(appInstallID uint) DBOption
|
||||
WithType(dbType string) DBOption
|
||||
WithTypeList(dbType string) DBOption
|
||||
}
|
||||
|
||||
func NewIDatabaseRepo() IDatabaseRepo {
|
||||
@ -59,12 +60,6 @@ func (d *DatabaseRepo) GetList(opts ...DBOption) ([]model.Database, error) {
|
||||
return databases, err
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithByMysqlList() DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("type = ? OR type = ?", "mysql", "mariadb")
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithByFrom(from string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`from` = ?", from)
|
||||
@ -77,9 +72,18 @@ func (d *DatabaseRepo) WithoutByFrom(from string) DBOption {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DatabaseRepo) WithType(dbType string) DBOption {
|
||||
func (d *DatabaseRepo) WithTypeList(dbType string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("`type` = ?", dbType)
|
||||
types := strings.Split(dbType, ",")
|
||||
if len(types) == 1 {
|
||||
return g.Where("`type` = ?", dbType)
|
||||
}
|
||||
for _, ty := range types {
|
||||
if len(ty) != 0 {
|
||||
g.Or("`type` = ?", ty)
|
||||
}
|
||||
}
|
||||
return g
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,7 +428,7 @@ func (a *AppInstallService) SyncAll(systemInit bool) error {
|
||||
func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
||||
var res []response.AppService
|
||||
if DatabaseKeys[key] {
|
||||
dbs, _ := databaseRepo.GetList(databaseRepo.WithByFrom("local"), databaseRepo.WithType(key))
|
||||
dbs, _ := databaseRepo.GetList(databaseRepo.WithByFrom("local"), commonRepo.WithByType(key))
|
||||
if len(dbs) == 0 {
|
||||
return res, nil
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/mysql"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/mysql/client"
|
||||
@ -30,7 +29,7 @@ func NewIDatabaseService() IDatabaseService {
|
||||
|
||||
func (u *DatabaseService) SearchWithPage(search dto.DatabaseSearch) (int64, interface{}, error) {
|
||||
total, dbs, err := databaseRepo.Page(search.Page, search.PageSize,
|
||||
commonRepo.WithByType(search.Type),
|
||||
databaseRepo.WithTypeList(search.Type),
|
||||
commonRepo.WithLikeName(search.Info),
|
||||
databaseRepo.WithoutByFrom("local"),
|
||||
)
|
||||
@ -58,13 +57,7 @@ func (u *DatabaseService) Get(name string) (dto.DatabaseInfo, error) {
|
||||
}
|
||||
|
||||
func (u *DatabaseService) List(dbType string) ([]dto.DatabaseOption, error) {
|
||||
var opts []repo.DBOption
|
||||
if dbType == "mysql" {
|
||||
opts = append(opts, databaseRepo.WithByMysqlList())
|
||||
} else {
|
||||
opts = append(opts, commonRepo.WithByType(dbType))
|
||||
}
|
||||
dbs, err := databaseRepo.GetList(opts...)
|
||||
dbs, err := databaseRepo.GetList(databaseRepo.WithTypeList(dbType))
|
||||
var datas []dto.DatabaseOption
|
||||
for _, db := range dbs {
|
||||
var item dto.DatabaseOption
|
||||
|
@ -147,7 +147,7 @@ func (r *Local) ChangePassword(info PasswordChangeInfo) error {
|
||||
for _, user := range userlist {
|
||||
passwordChangeSql := fmt.Sprintf("set password for %s = password('%s')", user, info.Password)
|
||||
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
|
||||
passwordChangeSql = fmt.Sprintf("alter user %s identified by '%s';", user, info.Password)
|
||||
passwordChangeSql = fmt.Sprintf("ALTER USER %s IDENTIFIED BY '%s';", user, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(passwordChangeSql, info.Timeout); err != nil {
|
||||
return err
|
||||
|
@ -152,7 +152,7 @@ func (r *Remote) ChangePassword(info PasswordChangeInfo) error {
|
||||
for _, user := range userlist {
|
||||
passwordChangeSql := fmt.Sprintf("set password for %s = password('%s')", user, info.Password)
|
||||
if !strings.HasPrefix(info.Version, "5.7") && !strings.HasPrefix(info.Version, "5.6") {
|
||||
passwordChangeSql = fmt.Sprintf("ALTER USER %s IDENTIFIED WITH mysql_native_password BY '%s';", user, info.Password)
|
||||
passwordChangeSql = fmt.Sprintf("ALTER USER %s IDENTIFIED BY '%s';", user, info.Password)
|
||||
}
|
||||
if err := r.ExecSQL(passwordChangeSql, info.Timeout); err != nil {
|
||||
return err
|
||||
|
@ -354,7 +354,7 @@ const message = {
|
||||
localDB: 'Local DB',
|
||||
address: 'DB address',
|
||||
version: 'DB version',
|
||||
versionHelper: 'Currently, only versions 5.6, 5.7, and 8.0 are supported',
|
||||
versionHelper: 'Currently, only versions {0} are supported',
|
||||
userHelper: 'The root user or a database user with root privileges can access the remote database.',
|
||||
|
||||
selectFile: 'Select file',
|
||||
|
@ -346,7 +346,7 @@ const message = {
|
||||
localDB: '本地數據庫',
|
||||
address: '數據庫地址',
|
||||
version: '數據庫版本',
|
||||
versionHelper: '當前僅支持 5.6 5.7 8.0 三個版本',
|
||||
versionHelper: '當前僅支持 {0} 三個版本',
|
||||
userHelper: 'root 用戶或者擁有 root 權限的數據庫用戶',
|
||||
|
||||
selectFile: '選擇文件',
|
||||
|
@ -346,7 +346,7 @@ const message = {
|
||||
localDB: '本地数据库',
|
||||
address: '数据库地址',
|
||||
version: '数据库版本',
|
||||
versionHelper: '当前仅支持 5.6 5.7 8.0 三个版本',
|
||||
versionHelper: '当前仅支持 {0} 版本',
|
||||
userHelper: 'root 用户或者拥有 root 权限的数据库用户',
|
||||
|
||||
selectFile: '选择文件',
|
||||
|
@ -386,7 +386,7 @@ const checkExist = (data: App.CheckInstalled) => {
|
||||
};
|
||||
|
||||
const loadDBOptions = async () => {
|
||||
const res = await listDatabases('mysql');
|
||||
const res = await listDatabases('mysql,mariadb');
|
||||
let datas = res.data || [];
|
||||
dbOptionsLocal.value = [];
|
||||
dbOptionsRemote.value = [];
|
||||
|
@ -121,7 +121,7 @@ const search = async (column?: any) => {
|
||||
page: paginationConfig.currentPage,
|
||||
pageSize: paginationConfig.pageSize,
|
||||
info: searchName.value,
|
||||
type: 'mysql',
|
||||
type: 'mysql,mariadb',
|
||||
orderBy: paginationConfig.orderBy,
|
||||
order: paginationConfig.order,
|
||||
};
|
||||
|
@ -19,13 +19,29 @@
|
||||
/>
|
||||
<el-tag v-else>{{ dialogData.rowData!.name }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.table.type')" prop="type">
|
||||
<el-select v-model="dialogData.rowData!.type" @change="changeType">
|
||||
<div>
|
||||
<el-option value="mysql" label="MySQL" />
|
||||
<el-option value="mariadb" label="Mariadb" />
|
||||
</div>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.version')" prop="version">
|
||||
<el-select @change="isOK = false" v-model="dialogData.rowData!.version">
|
||||
<el-option value="5.6" label="5.6" />
|
||||
<el-option value="5.7" label="5.7" />
|
||||
<el-option value="8.0" label="8.0" />
|
||||
<div v-if="dialogData.rowData!.type === 'mysql'">
|
||||
<el-option value="5.6" label="5.6" />
|
||||
<el-option value="5.7" label="5.7" />
|
||||
<el-option value="8.x" label="8.x" />
|
||||
</div>
|
||||
<el-option v-else value="10.x" label="10.x" />
|
||||
</el-select>
|
||||
<span class="input-help">{{ $t('database.versionHelper') }}</span>
|
||||
<span v-if="dialogData.rowData!.type === 'mysql'" class="input-help">
|
||||
{{ $t('database.versionHelper', ['5.6 5.7 8.x']) }}
|
||||
</span>
|
||||
<span v-else class="input-help">
|
||||
{{ $t('database.versionHelper', ['10.x']) }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('database.address')" prop="address">
|
||||
<el-input @change="isOK = false" clearable v-model.trim="dialogData.rowData!.address" />
|
||||
@ -112,26 +128,19 @@ const rules = reactive({
|
||||
type FormInstance = InstanceType<typeof ElForm>;
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const changeType = () => {
|
||||
dialogData.value.rowData.version = dialogData.value.rowData.type === 'mysql' ? '5.6' : '10.x';
|
||||
isOK.value = false;
|
||||
};
|
||||
|
||||
const onSubmit = async (formEl: FormInstance | undefined, operation: string) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let param = {
|
||||
id: dialogData.value.rowData.id,
|
||||
name: dialogData.value.rowData.name,
|
||||
type: 'mysql',
|
||||
version: dialogData.value.rowData.version,
|
||||
from: 'remote',
|
||||
address: dialogData.value.rowData.address,
|
||||
port: dialogData.value.rowData.port,
|
||||
username: dialogData.value.rowData.username,
|
||||
password: dialogData.value.rowData.password,
|
||||
description: dialogData.value.rowData.description,
|
||||
};
|
||||
dialogData.value.rowData.from = 'remote';
|
||||
loading.value = true;
|
||||
|
||||
if (operation === 'check') {
|
||||
await checkDatabase(param)
|
||||
await checkDatabase(dialogData.value.rowData)
|
||||
.then((res) => {
|
||||
loading.value = false;
|
||||
if (res.data) {
|
||||
@ -148,7 +157,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
|
||||
}
|
||||
|
||||
if (operation === 'create') {
|
||||
await addDatabase(param)
|
||||
await addDatabase(dialogData.value.rowData)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
@ -160,7 +169,7 @@ const onSubmit = async (formEl: FormInstance | undefined, operation: string) =>
|
||||
});
|
||||
}
|
||||
if (operation === 'edit') {
|
||||
await editDatabase(param)
|
||||
await editDatabase(dialogData.value.rowData)
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
|
||||
|
Loading…
Reference in New Issue
Block a user