mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 23:40:24 +08:00
refactor: code review
This commit is contained in:
@@ -55,20 +55,25 @@
|
|||||||
<el-input v-model="form.params" placeholder="其他连接参数,形如: key1=value1&key2=value2"></el-input>
|
<el-input v-model="form.params" placeholder="其他连接参数,形如: key1=value1&key2=value2"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="database" label="数据库名:" required>
|
<el-form-item prop="database" label="数据库名:" required>
|
||||||
<el-select
|
<el-col :span="19">
|
||||||
@change="changeDatabase"
|
<el-select
|
||||||
@focus="getAllDatabase"
|
@change="changeDatabase"
|
||||||
v-model="databaseList"
|
v-model="databaseList"
|
||||||
multiple
|
multiple
|
||||||
collapse-tags
|
collapse-tags
|
||||||
collapse-tags-tooltip
|
collapse-tags-tooltip
|
||||||
filterable
|
filterable
|
||||||
allow-create
|
allow-create
|
||||||
placeholder="请确保数据库实例信息填写完整后选择数据库"
|
placeholder="请确保数据库实例信息填写完整后获取库名"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
>
|
>
|
||||||
<el-option v-for="db in allDatabases" :key="db" :label="db" :value="db" />
|
<el-option v-for="db in allDatabases" :key="db" :label="db" :value="db" />
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col style="text-align: center" :span="1"><el-divider direction="vertical" border-style="dashed" /></el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-link @click="getAllDatabase" :underline="false" type="success">获取库名</el-link>
|
||||||
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="enableSshTunnel" label="SSH隧道:">
|
<el-form-item prop="enableSshTunnel" label="SSH隧道:">
|
||||||
@@ -264,12 +269,10 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getAllDatabase = async () => {
|
const getAllDatabase = async () => {
|
||||||
if (state.allDatabases.length != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const reqForm = { ...state.form };
|
const reqForm = { ...state.form };
|
||||||
reqForm.password = await RsaEncrypt(reqForm.password);
|
reqForm.password = await RsaEncrypt(reqForm.password);
|
||||||
state.allDatabases = await dbApi.getAllDatabase.request(reqForm);
|
state.allDatabases = await dbApi.getAllDatabase.request(reqForm);
|
||||||
|
ElMessage.success('获取成功, 请选择需要管理操作的数据库')
|
||||||
};
|
};
|
||||||
|
|
||||||
const getDbPwd = async () => {
|
const getDbPwd = async () => {
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onAddHashValue = () => {
|
const onAddHashValue = () => {
|
||||||
state.hashValues.push({ field: '', value: '' });
|
state.hashValues.unshift({ field: '', value: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveValue = async () => {
|
const saveValue = async () => {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onAddSetValue = () => {
|
const onAddSetValue = () => {
|
||||||
state.value.push({ value: '' });
|
state.value.unshift({ value: '' });
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
app:
|
|
||||||
name: mayfly-go
|
|
||||||
version: 1.2.3
|
|
||||||
|
|
||||||
server:
|
server:
|
||||||
# debug release test
|
# debug release test
|
||||||
model: release
|
model: release
|
||||||
|
|||||||
@@ -97,19 +97,19 @@ func (d *Db) DeleteDb(rc *ctx.ReqCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) TableInfos(rc *ctx.ReqCtx) {
|
func (d *Db) TableInfos(rc *ctx.ReqCtx) {
|
||||||
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetTableInfos()
|
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetMeta().GetTableInfos()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) TableIndex(rc *ctx.ReqCtx) {
|
func (d *Db) TableIndex(rc *ctx.ReqCtx) {
|
||||||
tn := rc.GinCtx.Query("tableName")
|
tn := rc.GinCtx.Query("tableName")
|
||||||
biz.NotEmpty(tn, "tableName不能为空")
|
biz.NotEmpty(tn, "tableName不能为空")
|
||||||
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetTableIndex(tn)
|
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetMeta().GetTableIndex(tn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) GetCreateTableDdl(rc *ctx.ReqCtx) {
|
func (d *Db) GetCreateTableDdl(rc *ctx.ReqCtx) {
|
||||||
tn := rc.GinCtx.Query("tableName")
|
tn := rc.GinCtx.Query("tableName")
|
||||||
biz.NotEmpty(tn, "tableName不能为空")
|
biz.NotEmpty(tn, "tableName不能为空")
|
||||||
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetCreateTableDdl(tn)
|
rc.ResData = d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetMeta().GetCreateTableDdl(tn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Db) ExecSql(rc *ctx.ReqCtx) {
|
func (d *Db) ExecSql(rc *ctx.ReqCtx) {
|
||||||
@@ -237,11 +237,12 @@ func (d *Db) DumpSql(rc *ctx.ReqCtx) {
|
|||||||
writer.WriteString(fmt.Sprintf("\n-- 导出数据库: %s ", db))
|
writer.WriteString(fmt.Sprintf("\n-- 导出数据库: %s ", db))
|
||||||
writer.WriteString("\n-- ----------------------------\n")
|
writer.WriteString("\n-- ----------------------------\n")
|
||||||
|
|
||||||
|
dbmeta := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx)).GetMeta()
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
if needStruct {
|
if needStruct {
|
||||||
writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表结构: %s \n-- ----------------------------\n", table))
|
writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表结构: %s \n-- ----------------------------\n", table))
|
||||||
writer.WriteString(fmt.Sprintf("DROP TABLE IF EXISTS `%s`;\n", table))
|
writer.WriteString(fmt.Sprintf("DROP TABLE IF EXISTS `%s`;\n", table))
|
||||||
writer.WriteString(dbInstance.GetCreateTableDdl(table)[0]["Create Table"].(string) + ";\n")
|
writer.WriteString(dbmeta.GetCreateTableDdl(table)[0]["Create Table"].(string) + ";\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !needData {
|
if !needData {
|
||||||
@@ -303,7 +304,7 @@ func (d *Db) DumpSql(rc *ctx.ReqCtx) {
|
|||||||
func (d *Db) TableMA(rc *ctx.ReqCtx) {
|
func (d *Db) TableMA(rc *ctx.ReqCtx) {
|
||||||
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
||||||
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
||||||
rc.ResData = dbi.GetTableMetedatas()
|
rc.ResData = dbi.GetMeta().GetTables()
|
||||||
}
|
}
|
||||||
|
|
||||||
// @router /api/db/:dbId/c-metadata [get]
|
// @router /api/db/:dbId/c-metadata [get]
|
||||||
@@ -314,16 +315,17 @@ func (d *Db) ColumnMA(rc *ctx.ReqCtx) {
|
|||||||
|
|
||||||
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
||||||
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
||||||
rc.ResData = dbi.GetColumnMetadatas(tn)
|
rc.ResData = dbi.GetMeta().GetColumns(tn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @router /api/db/:dbId/hint-tables [get]
|
// @router /api/db/:dbId/hint-tables [get]
|
||||||
func (d *Db) HintTables(rc *ctx.ReqCtx) {
|
func (d *Db) HintTables(rc *ctx.ReqCtx) {
|
||||||
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
dbi := d.DbApp.GetDbInstance(GetIdAndDb(rc.GinCtx))
|
||||||
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
biz.ErrIsNilAppendErr(d.ProjectApp.CanAccess(rc.LoginAccount.Id, dbi.ProjectId), "%s")
|
||||||
// 获取所有表
|
|
||||||
tables := dbi.GetTableMetedatas()
|
|
||||||
|
|
||||||
|
dm := dbi.GetMeta()
|
||||||
|
// 获取所有表
|
||||||
|
tables := dm.GetTables()
|
||||||
tableNames := make([]string, 0)
|
tableNames := make([]string, 0)
|
||||||
for _, v := range tables {
|
for _, v := range tables {
|
||||||
tableNames = append(tableNames, v["tableName"].(string))
|
tableNames = append(tableNames, v["tableName"].(string))
|
||||||
@@ -338,7 +340,7 @@ func (d *Db) HintTables(rc *ctx.ReqCtx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取所有表下的所有列信息
|
// 获取所有表下的所有列信息
|
||||||
columnMds := dbi.GetColumnMetadatas(tableNames...)
|
columnMds := dm.GetColumns(tableNames...)
|
||||||
for _, v := range columnMds {
|
for _, v := range columnMds {
|
||||||
tName := v["tableName"].(string)
|
tName := v["tableName"].(string)
|
||||||
if res[tName] == nil {
|
if res[tName] == nil {
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ func (d *dbAppImpl) Delete(id uint64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *dbAppImpl) GetDatabases(ed *entity.Db) []string {
|
func (d *dbAppImpl) GetDatabases(ed *entity.Db) []string {
|
||||||
|
ed.Network = ed.GetNetwork()
|
||||||
databases := make([]string, 0)
|
databases := make([]string, 0)
|
||||||
var dbConn *sql.DB
|
var dbConn *sql.DB
|
||||||
var metaDb string
|
var metaDb string
|
||||||
@@ -422,6 +423,18 @@ func (d *DbInstance) Exec(sql string) (int64, error) {
|
|||||||
return res.RowsAffected()
|
return res.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取数据库元信息实现接口
|
||||||
|
func (di *DbInstance) GetMeta() DbMetadata {
|
||||||
|
dbType := di.Type
|
||||||
|
if dbType == entity.DbTypeMysql {
|
||||||
|
return &MysqlMetadata{di: di}
|
||||||
|
}
|
||||||
|
if dbType == entity.DbTypePostgres {
|
||||||
|
return &PgsqlMetadata{di: di}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 关闭连接
|
// 关闭连接
|
||||||
func (d *DbInstance) Close() {
|
func (d *DbInstance) Close() {
|
||||||
if d.db != nil {
|
if d.db != nil {
|
||||||
@@ -458,8 +471,32 @@ func CloseDb(dbId uint64, db string) {
|
|||||||
dbCache.Delete(GetDbCacheKey(dbId, db))
|
dbCache.Delete(GetDbCacheKey(dbId, db))
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------元数据-------------------------------------------
|
// -----------------------------------元数据-------------------------------------------
|
||||||
|
// 数据库元信息接口(表、列等元信息)
|
||||||
|
type DbMetadata interface {
|
||||||
|
// 获取表基础元信息, 如表名等
|
||||||
|
GetTables() []map[string]interface{}
|
||||||
|
|
||||||
|
// 获取列元信息, 如列名等
|
||||||
|
GetColumns(tableNames ...string) []map[string]interface{}
|
||||||
|
|
||||||
|
// 获取表主键字段名,默认第一个字段
|
||||||
|
GetPrimaryKey(tablename string) string
|
||||||
|
|
||||||
|
// 获取表信息,比GetTables获取更详细的表信息
|
||||||
|
GetTableInfos() []map[string]interface{}
|
||||||
|
|
||||||
|
// 获取表索引信息
|
||||||
|
GetTableIndex(tableName string) []map[string]interface{}
|
||||||
|
|
||||||
|
// 获取建表ddl
|
||||||
|
GetCreateTableDdl(tableName string) []map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认每次查询列元信息数量
|
||||||
|
const DEFAULT_COLUMN_SIZE = 2000
|
||||||
|
|
||||||
|
// ---------------------------------- mysql元数据 -----------------------------------
|
||||||
const (
|
const (
|
||||||
// mysql 表信息元数据
|
// mysql 表信息元数据
|
||||||
MYSQL_TABLE_MA = `SELECT table_name tableName, engine, table_comment tableComment,
|
MYSQL_TABLE_MA = `SELECT table_name tableName, engine, table_comment tableComment,
|
||||||
@@ -478,9 +515,6 @@ const (
|
|||||||
FROM information_schema.STATISTICS
|
FROM information_schema.STATISTICS
|
||||||
WHERE table_schema = (SELECT database()) AND table_name = '%s' LIMIT 500`
|
WHERE table_schema = (SELECT database()) AND table_name = '%s' LIMIT 500`
|
||||||
|
|
||||||
// 默认每次查询列元信息数量
|
|
||||||
DEFAULT_COLUMN_SIZE = 2000
|
|
||||||
|
|
||||||
// mysql 列信息元数据
|
// mysql 列信息元数据
|
||||||
MYSQL_COLUMN_MA = `SELECT table_name tableName, column_name columnName, column_type columnType,
|
MYSQL_COLUMN_MA = `SELECT table_name tableName, column_name columnName, column_type columnType,
|
||||||
column_comment columnComment, column_key columnKey, extra, is_nullable nullable from information_schema.columns
|
column_comment columnComment, column_key columnKey, extra, is_nullable nullable from information_schema.columns
|
||||||
@@ -491,6 +525,74 @@ const (
|
|||||||
WHERE table_name in (%s) AND table_schema = (SELECT database())`
|
WHERE table_name in (%s) AND table_schema = (SELECT database())`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type MysqlMetadata struct {
|
||||||
|
di *DbInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表基础元信息, 如表名等
|
||||||
|
func (mm *MysqlMetadata) GetTables() []map[string]interface{} {
|
||||||
|
_, res, _ := mm.di.SelectData(MYSQL_TABLE_MA)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取列元信息, 如列名等
|
||||||
|
func (mm *MysqlMetadata) GetColumns(tableNames ...string) []map[string]interface{} {
|
||||||
|
var sql, tableName string
|
||||||
|
for i := 0; i < len(tableNames); i++ {
|
||||||
|
if i != 0 {
|
||||||
|
tableName = tableName + ", "
|
||||||
|
}
|
||||||
|
tableName = tableName + "'" + tableNames[i] + "'"
|
||||||
|
}
|
||||||
|
|
||||||
|
pageNum := 1
|
||||||
|
// 如果大于一个表,则统计列数并分页获取
|
||||||
|
if len(tableNames) > 1 {
|
||||||
|
countSql := fmt.Sprintf(MYSQL_COLOUMN_MA_COUNT, tableName)
|
||||||
|
_, countRes, _ := mm.di.SelectData(countSql)
|
||||||
|
// 查询出所有列信息总数,手动分页获取所有数据
|
||||||
|
maCount := int(countRes[0]["maNum"].(int64))
|
||||||
|
// 计算需要查询的页数
|
||||||
|
pageNum = maCount / DEFAULT_COLUMN_SIZE
|
||||||
|
if maCount%DEFAULT_COLUMN_SIZE > 0 {
|
||||||
|
pageNum++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]map[string]interface{}, 0)
|
||||||
|
for index := 0; index < pageNum; index++ {
|
||||||
|
sql = fmt.Sprintf(MYSQL_COLUMN_MA, tableName, index*DEFAULT_COLUMN_SIZE, DEFAULT_COLUMN_SIZE)
|
||||||
|
_, result, err := mm.di.SelectData(sql)
|
||||||
|
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
|
||||||
|
res = append(res, result...)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表主键字段名,默认第一个字段
|
||||||
|
func (mm *MysqlMetadata) GetPrimaryKey(tablename string) string {
|
||||||
|
return mm.GetColumns(tablename)[0]["columnName"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表信息,比GetTableMetedatas获取更详细的表信息
|
||||||
|
func (mm *MysqlMetadata) GetTableInfos() []map[string]interface{} {
|
||||||
|
_, res, _ := mm.di.SelectData(MYSQL_TABLE_INFO)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表索引信息
|
||||||
|
func (mm *MysqlMetadata) GetTableIndex(tableName string) []map[string]interface{} {
|
||||||
|
_, res, _ := mm.di.SelectData(MYSQL_INDEX_INFO)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取建表ddl
|
||||||
|
func (mm *MysqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} {
|
||||||
|
_, res, _ := mm.di.SelectData(fmt.Sprintf("show create table %s ", tableName))
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------- pgsql元数据 -----------------------------------
|
||||||
const (
|
const (
|
||||||
// postgres 表信息元数据
|
// postgres 表信息元数据
|
||||||
PGSQL_TABLE_MA = `SELECT obj_description(c.oid) AS "tableComment", c.relname AS "tableName" FROM pg_class c
|
PGSQL_TABLE_MA = `SELECT obj_description(c.oid) AS "tableComment", c.relname AS "tableName" FROM pg_class c
|
||||||
@@ -537,18 +639,18 @@ const (
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *DbInstance) GetTableMetedatas() []map[string]interface{} {
|
type PgsqlMetadata struct {
|
||||||
var sql string
|
di *DbInstance
|
||||||
if d.Type == entity.DbTypeMysql {
|
}
|
||||||
sql = MYSQL_TABLE_MA
|
|
||||||
} else if d.Type == "postgres" {
|
// 获取表基础元信息, 如表名等
|
||||||
sql = PGSQL_TABLE_MA
|
func (pm *PgsqlMetadata) GetTables() []map[string]interface{} {
|
||||||
}
|
_, res, _ := pm.di.SelectData(PGSQL_TABLE_MA)
|
||||||
_, res, _ := d.SelectData(sql)
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbInstance) GetColumnMetadatas(tableNames ...string) []map[string]interface{} {
|
// 获取列元信息, 如列名等
|
||||||
|
func (pm *PgsqlMetadata) GetColumns(tableNames ...string) []map[string]interface{} {
|
||||||
var sql, tableName string
|
var sql, tableName string
|
||||||
for i := 0; i < len(tableNames); i++ {
|
for i := 0; i < len(tableNames); i++ {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
@@ -557,68 +659,48 @@ func (d *DbInstance) GetColumnMetadatas(tableNames ...string) []map[string]inter
|
|||||||
tableName = tableName + "'" + tableNames[i] + "'"
|
tableName = tableName + "'" + tableNames[i] + "'"
|
||||||
}
|
}
|
||||||
|
|
||||||
var countSqlTmp string
|
pageNum := 1
|
||||||
var sqlTmp string
|
// 如果大于一个表,则统计列数并分页获取
|
||||||
if d.Type == entity.DbTypeMysql {
|
if len(tableNames) > 1 {
|
||||||
countSqlTmp = MYSQL_COLOUMN_MA_COUNT
|
countSql := fmt.Sprintf(PGSQL_COLUMN_MA_COUNT, tableName)
|
||||||
sqlTmp = MYSQL_COLUMN_MA
|
_, countRes, _ := pm.di.SelectData(countSql)
|
||||||
} else if d.Type == entity.DbTypePostgres {
|
// 查询出所有列信息总数,手动分页获取所有数据
|
||||||
countSqlTmp = PGSQL_COLUMN_MA_COUNT
|
maCount := int(countRes[0]["maNum"].(int64))
|
||||||
sqlTmp = PGSQL_COLUMN_MA
|
// 计算需要查询的页数
|
||||||
}
|
pageNum = maCount / DEFAULT_COLUMN_SIZE
|
||||||
|
if maCount%DEFAULT_COLUMN_SIZE > 0 {
|
||||||
countSql := fmt.Sprintf(countSqlTmp, tableName)
|
pageNum++
|
||||||
_, countRes, _ := d.SelectData(countSql)
|
}
|
||||||
// 查询出所有列信息总数,手动分页获取所有数据
|
|
||||||
maCount := int(countRes[0]["maNum"].(int64))
|
|
||||||
// 计算需要查询的页数
|
|
||||||
pageNum := maCount / DEFAULT_COLUMN_SIZE
|
|
||||||
if maCount%DEFAULT_COLUMN_SIZE > 0 {
|
|
||||||
pageNum++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]map[string]interface{}, 0)
|
res := make([]map[string]interface{}, 0)
|
||||||
for index := 0; index < pageNum; index++ {
|
for index := 0; index < pageNum; index++ {
|
||||||
sql = fmt.Sprintf(sqlTmp, tableName, index*DEFAULT_COLUMN_SIZE, DEFAULT_COLUMN_SIZE)
|
sql = fmt.Sprintf(PGSQL_COLUMN_MA, tableName, index*DEFAULT_COLUMN_SIZE, DEFAULT_COLUMN_SIZE)
|
||||||
_, result, err := d.SelectData(sql)
|
_, result, err := pm.di.SelectData(sql)
|
||||||
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
|
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
|
||||||
res = append(res, result...)
|
res = append(res, result...)
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取表的主键,目前默认第一列为主键
|
// 获取表主键字段名,默认第一个字段
|
||||||
func (d *DbInstance) GetPrimaryKey(tablename string) string {
|
func (pm *PgsqlMetadata) GetPrimaryKey(tablename string) string {
|
||||||
return d.GetColumnMetadatas(tablename)[0]["columnName"].(string)
|
return pm.GetColumns(tablename)[0]["columnName"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbInstance) GetTableInfos() []map[string]interface{} {
|
// 获取表信息,比GetTables获取更详细的表信息
|
||||||
var sql string
|
func (pm *PgsqlMetadata) GetTableInfos() []map[string]interface{} {
|
||||||
if d.Type == entity.DbTypeMysql {
|
_, res, _ := pm.di.SelectData(PGSQL_TABLE_INFO)
|
||||||
sql = MYSQL_TABLE_INFO
|
|
||||||
} else if d.Type == entity.DbTypePostgres {
|
|
||||||
sql = PGSQL_TABLE_INFO
|
|
||||||
}
|
|
||||||
_, res, _ := d.SelectData(sql)
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbInstance) GetTableIndex(tableName string) []map[string]interface{} {
|
// 获取表索引信息
|
||||||
var sql string
|
func (pm *PgsqlMetadata) GetTableIndex(tableName string) []map[string]interface{} {
|
||||||
if d.Type == entity.DbTypeMysql {
|
_, res, _ := pm.di.SelectData(PGSQL_INDEX_INFO)
|
||||||
sql = fmt.Sprintf(MYSQL_INDEX_INFO, tableName)
|
|
||||||
} else if d.Type == entity.DbTypePostgres {
|
|
||||||
sql = fmt.Sprintf(PGSQL_INDEX_INFO, tableName)
|
|
||||||
}
|
|
||||||
_, res, _ := d.SelectData(sql)
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DbInstance) GetCreateTableDdl(tableName string) []map[string]interface{} {
|
// 获取建表ddl
|
||||||
var sql string
|
func (mm *PgsqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} {
|
||||||
if d.Type == entity.DbTypeMysql {
|
return nil
|
||||||
sql = fmt.Sprintf("show create table %s ", tableName)
|
|
||||||
}
|
|
||||||
_, res, _ := d.SelectData(sql)
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package application
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"mayfly-go/internal/devops/domain/entity"
|
"mayfly-go/internal/devops/domain/entity"
|
||||||
"mayfly-go/internal/devops/domain/repository"
|
"mayfly-go/internal/devops/domain/repository"
|
||||||
"mayfly-go/internal/devops/infrastructure/persistence"
|
"mayfly-go/internal/devops/infrastructure/persistence"
|
||||||
@@ -89,7 +90,7 @@ func doUpdate(update *sqlparser.Update, dbInstance *DbInstance, dbSqlExec *entit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取表主键列名,排除使用别名
|
// 获取表主键列名,排除使用别名
|
||||||
primaryKey := dbInstance.GetPrimaryKey(tableName)
|
primaryKey := dbInstance.GetMeta().GetPrimaryKey(tableName)
|
||||||
|
|
||||||
updateColumnsAndPrimaryKey := strings.Join(updateColumns, ",") + "," + primaryKey
|
updateColumnsAndPrimaryKey := strings.Join(updateColumns, ",") + "," + primaryKey
|
||||||
// 查询要更新字段数据的旧值,以及主键值
|
// 查询要更新字段数据的旧值,以及主键值
|
||||||
|
|||||||
@@ -5,7 +5,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
starter.PrintBanner()
|
|
||||||
starter.InitDb()
|
|
||||||
starter.RunWebServer()
|
starter.RunWebServer()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package config
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
type App struct {
|
const (
|
||||||
Name string `yaml:"name"`
|
AppName = "mayfly-go"
|
||||||
Version string `yaml:"version"`
|
Version = "v1.2.5"
|
||||||
}
|
)
|
||||||
|
|
||||||
func (a *App) GetAppInfo() string {
|
func GetAppInfo() string {
|
||||||
return fmt.Sprintf("[%s:%s]", a.Name, a.Version)
|
return fmt.Sprintf("[%s:%s]", AppName, Version)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ import (
|
|||||||
// 配置文件映射对象
|
// 配置文件映射对象
|
||||||
var Conf *Config
|
var Conf *Config
|
||||||
|
|
||||||
func init() {
|
func Init() {
|
||||||
configFilePath := flag.String("e", "./config.yml", "配置文件路径,默认为可执行文件目录")
|
configFilePath := flag.String("e", "./config.yml", "配置文件路径,默认为可执行文件目录")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
// 获取启动参数中,配置文件的绝对路径
|
// 获取启动参数中,配置文件的绝对路径
|
||||||
path, _ := filepath.Abs(*configFilePath)
|
path, _ := filepath.Abs(*configFilePath)
|
||||||
startConfigParam = &CmdConfigParam{ConfigFilePath: path}
|
startConfigParam := &CmdConfigParam{ConfigFilePath: path}
|
||||||
// 读取配置文件信息
|
// 读取配置文件信息
|
||||||
yc := &Config{}
|
yc := &Config{}
|
||||||
if err := utils.LoadYml(startConfigParam.ConfigFilePath, yc); err != nil {
|
if err := utils.LoadYml(startConfigParam.ConfigFilePath, yc); err != nil {
|
||||||
@@ -32,12 +32,8 @@ type CmdConfigParam struct {
|
|||||||
ConfigFilePath string // -e 配置文件路径
|
ConfigFilePath string // -e 配置文件路径
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动可执行文件时的参数
|
|
||||||
var startConfigParam *CmdConfigParam
|
|
||||||
|
|
||||||
// yaml配置文件映射对象
|
// yaml配置文件映射对象
|
||||||
type Config struct {
|
type Config struct {
|
||||||
App *App `yaml:"app"`
|
|
||||||
Server *Server `yaml:"server"`
|
Server *Server `yaml:"server"`
|
||||||
Jwt *Jwt `yaml:"jwt"`
|
Jwt *Jwt `yaml:"jwt"`
|
||||||
Aes *Aes `yaml:"aes"`
|
Aes *Aes `yaml:"aes"`
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ import (
|
|||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func InitTokenConfig() {
|
||||||
JwtKey = config.Conf.Jwt.Key
|
JwtKey = config.Conf.Jwt.Key
|
||||||
ExpTime = config.Conf.Jwt.ExpireTime
|
ExpTime = config.Conf.Jwt.ExpireTime
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
JwtKey string
|
||||||
|
ExpTime uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
// 创建用户token
|
// 创建用户token
|
||||||
@@ -27,7 +32,8 @@ func CreateToken(userId uint64, username string) string {
|
|||||||
"username": username,
|
"username": username,
|
||||||
"exp": time.Now().Add(time.Minute * time.Duration(ExpTime)).Unix(),
|
"exp": time.Now().Add(time.Minute * time.Duration(ExpTime)).Unix(),
|
||||||
})
|
})
|
||||||
// 如果jwt key为空,则随机生成字符串
|
|
||||||
|
// 如果配置文件中的jwt key为空,则随机生成字符串
|
||||||
if JwtKey == "" {
|
if JwtKey == "" {
|
||||||
JwtKey = utils.RandString(32)
|
JwtKey = utils.RandString(32)
|
||||||
global.Log.Infof("config.yml未配置jwt.key, 随机生成key为: %s", JwtKey)
|
global.Log.Infof("config.yml未配置jwt.key, 随机生成key为: %s", JwtKey)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
var Log = logrus.New()
|
var Log = logrus.New()
|
||||||
|
|
||||||
func init() {
|
func Init() {
|
||||||
Log.SetFormatter(new(LogFormatter))
|
Log.SetFormatter(new(LogFormatter))
|
||||||
Log.SetReportCaller(true)
|
Log.SetReportCaller(true)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
package starter
|
package starter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"mayfly-go/pkg/config"
|
||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func PrintBanner() {
|
func printBanner() {
|
||||||
global.Log.Print(`
|
global.Log.Print(fmt.Sprintf(`
|
||||||
__ _
|
__ _
|
||||||
_ __ ___ __ _ _ _ / _| |_ _ __ _ ___
|
_ __ ___ __ _ _ _ / _| |_ _ __ _ ___
|
||||||
| '_ ' _ \ / _' | | | | |_| | | | |_____ / _' |/ _ \
|
| '_ ' _ \ / _' | | | | |_| | | | |_____ / _' |/ _ \
|
||||||
| | | | | | (_| | |_| | _| | |_| |_____| (_| | (_) |
|
| | | | | | (_| | |_| | _| | |_| |_____| (_| | (_) | version: %s
|
||||||
|_| |_| |_|\__,_|\__, |_| |_|\__, | \__, |\___/
|
|_| |_| |_|\__,_|\__, |_| |_|\__, | \__, |\___/
|
||||||
|___/ |___/ |___/
|
|___/ |___/ |___/ `, config.Version))
|
||||||
`)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import (
|
|||||||
"gorm.io/gorm/schema"
|
"gorm.io/gorm/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitDb() {
|
func initDb() {
|
||||||
global.Db = GormMysql()
|
global.Db = gormMysql()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GormMysql() *gorm.DB {
|
func gormMysql() *gorm.DB {
|
||||||
m := config.Conf.Mysql
|
m := config.Conf.Mysql
|
||||||
if m == nil || m.Dbname == "" {
|
if m == nil || m.Dbname == "" {
|
||||||
global.Log.Panic("未找到数据库配置信息")
|
global.Log.Panic("未找到数据库配置信息")
|
||||||
|
|||||||
23
server/pkg/starter/run.go
Normal file
23
server/pkg/starter/run.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package starter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"mayfly-go/pkg/config"
|
||||||
|
"mayfly-go/pkg/ctx"
|
||||||
|
"mayfly-go/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RunWebServer() {
|
||||||
|
// 初始化config.yml配置文件映射信息
|
||||||
|
config.Init()
|
||||||
|
// 初始化日志配置信息
|
||||||
|
logger.Init()
|
||||||
|
// 初始化jwt key与expire time等
|
||||||
|
ctx.InitTokenConfig()
|
||||||
|
|
||||||
|
// 打印banner
|
||||||
|
printBanner()
|
||||||
|
// 初始化并赋值数据库全局变量
|
||||||
|
initDb()
|
||||||
|
// 运行web服务
|
||||||
|
runWebServer()
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"mayfly-go/pkg/global"
|
"mayfly-go/pkg/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RunWebServer() {
|
func runWebServer() {
|
||||||
// 权限处理器
|
// 权限处理器
|
||||||
ctx.UseBeforeHandlerInterceptor(ctx.PermissionHandler)
|
ctx.UseBeforeHandlerInterceptor(ctx.PermissionHandler)
|
||||||
// 日志处理器
|
// 日志处理器
|
||||||
@@ -21,11 +21,7 @@ func RunWebServer() {
|
|||||||
|
|
||||||
server := config.Conf.Server
|
server := config.Conf.Server
|
||||||
port := server.GetPort()
|
port := server.GetPort()
|
||||||
if app := config.Conf.App; app != nil {
|
global.Log.Infof("Listening and serving HTTP on %s", port)
|
||||||
global.Log.Infof("%s- Listening and serving HTTP on %s", app.GetAppInfo(), port)
|
|
||||||
} else {
|
|
||||||
global.Log.Infof("Listening and serving HTTP on %s", port)
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if server.Tls != nil && server.Tls.Enable {
|
if server.Tls != nil && server.Tls.Enable {
|
||||||
|
|||||||
Reference in New Issue
Block a user