mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-22 08:53:46 +08:00
✨ feat(table-copy): 新增整表复制与自动副本命名
- 在表概览及新旧侧栏右键菜单接入复制整表入口与确认、进度和刷新反馈 - 按 source_copyN 原子创建目标表并复制列、索引、默认值及全部数据 - 处理 PostgreSQL 生成列、identity/serial 序列校准与失败清理 - 限定安全数据源与连接保护策略,阻止分区表、RLS 及引用型存储引擎 - 加固 MySQL/PostgreSQL 元数据标识符处理并补齐六语种文案 - 增加后端、能力矩阵、菜单接线和国际化回归测试
This commit is contained in:
@@ -231,12 +231,7 @@ func (m *MariaDB) GetCreateStatement(dbName, tableName string) (string, error) {
|
||||
}
|
||||
|
||||
func (m *MariaDB) GetColumns(dbName, tableName string) ([]connection.ColumnDefinition, error) {
|
||||
query := fmt.Sprintf("SHOW FULL COLUMNS FROM `%s`.`%s`", dbName, tableName)
|
||||
if dbName == "" {
|
||||
query = fmt.Sprintf("SHOW FULL COLUMNS FROM `%s`", tableName)
|
||||
}
|
||||
|
||||
data, _, err := m.Query(query)
|
||||
data, _, err := m.Query(buildMySQLShowFullColumnsQuery(dbName, tableName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1071,6 +1071,10 @@ func buildMySQLShowCreateTableQuery(dbName, tableName string) string {
|
||||
return "SHOW CREATE TABLE " + mysqlQualifiedTableIdentifier(dbName, tableName)
|
||||
}
|
||||
|
||||
func buildMySQLShowFullColumnsQuery(dbName, tableName string) string {
|
||||
return "SHOW FULL COLUMNS FROM " + mysqlQualifiedTableIdentifier(dbName, tableName)
|
||||
}
|
||||
|
||||
func (m *MySQLDB) GetCreateStatement(dbName, tableName string) (string, error) {
|
||||
data, _, err := m.Query(buildMySQLShowCreateTableQuery(dbName, tableName))
|
||||
if err != nil {
|
||||
@@ -1086,12 +1090,7 @@ func (m *MySQLDB) GetCreateStatement(dbName, tableName string) (string, error) {
|
||||
}
|
||||
|
||||
func (m *MySQLDB) GetColumns(dbName, tableName string) ([]connection.ColumnDefinition, error) {
|
||||
query := fmt.Sprintf("SHOW FULL COLUMNS FROM `%s`.`%s`", dbName, tableName)
|
||||
if dbName == "" {
|
||||
query = fmt.Sprintf("SHOW FULL COLUMNS FROM `%s`", tableName)
|
||||
}
|
||||
|
||||
data, _, err := m.Query(query)
|
||||
data, _, err := m.Query(buildMySQLShowFullColumnsQuery(dbName, tableName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -193,3 +193,52 @@ func TestBuildMySQLShowCreateTableQueryNormalizesQuotedIdentifiers(t *testing.T)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildMySQLShowFullColumnsQueryEscapesIdentifiers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dbName string
|
||||
tableName string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "plain qualified table",
|
||||
dbName: "app",
|
||||
tableName: "users",
|
||||
want: "SHOW FULL COLUMNS FROM `app`.`users`",
|
||||
},
|
||||
{
|
||||
name: "backticks cannot terminate identifiers",
|
||||
dbName: "app`prod",
|
||||
tableName: "audit`log",
|
||||
want: "SHOW FULL COLUMNS FROM `app``prod`.`audit``log`",
|
||||
},
|
||||
{
|
||||
name: "quoted qualified table overrides database",
|
||||
dbName: "ignored",
|
||||
tableName: `"sales.region"."daily.order"`,
|
||||
want: "SHOW FULL COLUMNS FROM `sales.region`.`daily.order`",
|
||||
},
|
||||
{
|
||||
name: "quoted dotted table remains one identifier",
|
||||
dbName: "app",
|
||||
tableName: "`audit.logs`",
|
||||
want: "SHOW FULL COLUMNS FROM `app`.`audit.logs`",
|
||||
},
|
||||
{
|
||||
name: "table without database",
|
||||
tableName: "standalone",
|
||||
want: "SHOW FULL COLUMNS FROM `standalone`",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := buildMySQLShowFullColumnsQuery(tt.dbName, tt.tableName); got != tt.want {
|
||||
t.Fatalf("buildMySQLShowFullColumnsQuery(%q,%q)=%q,want=%q", tt.dbName, tt.tableName, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user