mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-09 08:13:29 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
@@ -51,6 +51,22 @@ func (damengColumnsMetadataConn) QueryContext(_ context.Context, query string, _
|
||||
failAutoIncrementQuery := damengColumnsMetadataQueryState.failAutoIncrementQuery
|
||||
damengColumnsMetadataQueryState.Unlock()
|
||||
|
||||
if strings.Contains(query, "DBMS_METADATA.GET_DDL") {
|
||||
return &damengColumnsMetadataRows{
|
||||
columns: []string{"DDL"},
|
||||
values: [][]driver.Value{{`CREATE TABLE "BIZ"."ORDERS" (
|
||||
"ID" NUMBER NOT NULL
|
||||
)`}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if strings.Contains(query, "all_tab_comments") {
|
||||
return &damengColumnsMetadataRows{
|
||||
columns: []string{"TABLE_COMMENT"},
|
||||
values: [][]driver.Value{{"订单'归档"}},
|
||||
}, nil
|
||||
}
|
||||
|
||||
if strings.Contains(query, "SYS.SYSCOLUMNS") {
|
||||
if failAutoIncrementQuery {
|
||||
return nil, errors.New("insufficient privilege for SYS.SYSCOLUMNS")
|
||||
@@ -174,6 +190,33 @@ func TestDamengGetColumnsKeepsBaseMetadataWhenAutoIncrementQueryFails(t *testing
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamengGetCreateStatementAppendsTableComment(t *testing.T) {
|
||||
resetDamengColumnsMetadataQueryState(t, false)
|
||||
|
||||
damengDB := &DamengDB{conn: openDamengColumnsMetadataDB(t)}
|
||||
ddl, err := damengDB.GetCreateStatement("biz", "orders")
|
||||
if err != nil {
|
||||
t.Fatalf("GetCreateStatement returned error: %v", err)
|
||||
}
|
||||
|
||||
for _, want := range []string{
|
||||
`CREATE TABLE "BIZ"."ORDERS"`,
|
||||
`COMMENT ON TABLE "BIZ"."ORDERS" IS '订单''归档';`,
|
||||
} {
|
||||
if !strings.Contains(ddl, want) {
|
||||
t.Fatalf("expected DDL to contain %q, got: %s", want, ddl)
|
||||
}
|
||||
}
|
||||
|
||||
queries := damengColumnsMetadataQueries()
|
||||
if len(queries) != 2 || !strings.Contains(queries[1], "all_tab_comments") {
|
||||
t.Fatalf("expected DDL and table comment metadata queries, got=%v", queries)
|
||||
}
|
||||
if !strings.Contains(queries[1], "owner = 'BIZ'") || !strings.Contains(queries[1], "table_name = 'ORDERS'") {
|
||||
t.Fatalf("expected normalized schema and table comment predicates, got=%s", queries[1])
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamengGetIndexesUsesIndexOwnerJoinAndMapsColumnOrder(t *testing.T) {
|
||||
resetDamengColumnsMetadataQueryState(t, false)
|
||||
|
||||
|
||||
@@ -305,7 +305,17 @@ func (d *DamengDB) GetCreateStatement(dbName, tableName string) (string, error)
|
||||
|
||||
if len(data) > 0 {
|
||||
if val, ok := data[0]["DDL"]; ok {
|
||||
return fmt.Sprintf("%v", val), nil
|
||||
ddl := fmt.Sprintf("%v", val)
|
||||
commentData, _, commentErr := d.Query(buildDamengTableCommentQuery(dbName, tableName))
|
||||
if commentErr != nil {
|
||||
logger.Warnf("达梦 GetCreateStatement 表注释元数据查询失败,已返回基础 DDL:%v", commentErr)
|
||||
return ddl, nil
|
||||
}
|
||||
if len(commentData) == 0 {
|
||||
return ddl, nil
|
||||
}
|
||||
comment := getDamengRowString(commentData[0], "TABLE_COMMENT", "COMMENT", "COMMENTS")
|
||||
return appendDamengTableCommentDDL(ddl, dbName, tableName, comment), nil
|
||||
}
|
||||
}
|
||||
return "", localizedDatabaseRuntimeError("db.backend.error.create_table_statement_not_found", nil)
|
||||
|
||||
@@ -148,6 +148,43 @@ func buildDamengColumnsQuery(dbName, tableName string) string {
|
||||
ORDER BY c.column_id`, upperDBName, upperTableName, upperDBName, upperTableName, upperDBName, upperTableName)
|
||||
}
|
||||
|
||||
func buildDamengTableCommentQuery(dbName, tableName string) string {
|
||||
upperTableName := strings.ReplaceAll(strings.ToUpper(strings.TrimSpace(tableName)), "'", "''")
|
||||
upperDBName := strings.ReplaceAll(strings.ToUpper(strings.TrimSpace(dbName)), "'", "''")
|
||||
if upperDBName == "" {
|
||||
return fmt.Sprintf(`SELECT comments AS "TABLE_COMMENT"
|
||||
FROM user_tab_comments
|
||||
WHERE table_name = '%s' AND comments IS NOT NULL`, upperTableName)
|
||||
}
|
||||
return fmt.Sprintf(`SELECT comments AS "TABLE_COMMENT"
|
||||
FROM all_tab_comments
|
||||
WHERE owner = '%s' AND table_name = '%s' AND comments IS NOT NULL`, upperDBName, upperTableName)
|
||||
}
|
||||
|
||||
func appendDamengTableCommentDDL(ddl, dbName, tableName, comment string) string {
|
||||
baseDDL := strings.TrimSpace(ddl)
|
||||
comment = strings.TrimSpace(comment)
|
||||
if baseDDL == "" || comment == "" || strings.Contains(strings.ToUpper(baseDDL), "COMMENT ON TABLE ") {
|
||||
return baseDDL
|
||||
}
|
||||
|
||||
quoteIdentifier := func(value string) string {
|
||||
value = strings.ToUpper(strings.TrimSpace(value))
|
||||
return `"` + strings.ReplaceAll(value, `"`, `""`) + `"`
|
||||
}
|
||||
tableRef := quoteIdentifier(tableName)
|
||||
if strings.TrimSpace(dbName) != "" {
|
||||
tableRef = quoteIdentifier(dbName) + "." + tableRef
|
||||
}
|
||||
|
||||
baseDDL = strings.TrimRight(baseDDL, " \t\r\n")
|
||||
if !strings.HasSuffix(baseDDL, ";") && !strings.HasSuffix(baseDDL, "/") {
|
||||
baseDDL += ";"
|
||||
}
|
||||
escapedComment := strings.ReplaceAll(comment, "'", "''")
|
||||
return fmt.Sprintf("%s\n\nCOMMENT ON TABLE %s IS '%s';", baseDDL, tableRef, escapedComment)
|
||||
}
|
||||
|
||||
// buildDamengAutoIncrementColumnsQuery reads the stable system-table flag that
|
||||
// records both IDENTITY and AUTO_INCREMENT columns. It intentionally remains a
|
||||
// separate query so restricted accounts can still load base column metadata.
|
||||
|
||||
@@ -146,6 +146,37 @@ func TestBuildDamengColumnsQuery_IncludesColumnCommentsJoin(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDamengTableCommentQueryUsesSchemaAppropriateDictionaryView(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
userQuery := buildDamengTableCommentQuery("", "orders")
|
||||
if !strings.Contains(userQuery, "FROM user_tab_comments") || !strings.Contains(userQuery, "table_name = 'ORDERS'") {
|
||||
t.Fatalf("expected current-schema table comment query, got: %s", userQuery)
|
||||
}
|
||||
|
||||
allQuery := buildDamengTableCommentQuery("biz", "orders")
|
||||
if !strings.Contains(allQuery, "FROM all_tab_comments") || !strings.Contains(allQuery, "owner = 'BIZ'") || !strings.Contains(allQuery, "table_name = 'ORDERS'") {
|
||||
t.Fatalf("expected schema table comment query, got: %s", allQuery)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendDamengTableCommentDDLAvoidsDuplicateAndEscapesLiteral(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ddl := appendDamengTableCommentDDL(`CREATE TABLE "BIZ"."ORDERS" ("ID" NUMBER)`, "biz", "orders", "订单'归档")
|
||||
if !strings.Contains(ddl, `COMMENT ON TABLE "BIZ"."ORDERS" IS '订单''归档';`) {
|
||||
t.Fatalf("expected escaped table comment DDL, got: %s", ddl)
|
||||
}
|
||||
if !strings.Contains(ddl, "(\"ID\" NUMBER);\n\nCOMMENT ON TABLE") {
|
||||
t.Fatalf("expected create statement terminator before table comment, got: %s", ddl)
|
||||
}
|
||||
|
||||
duplicated := appendDamengTableCommentDDL(ddl, "biz", "orders", "新备注")
|
||||
if duplicated != ddl {
|
||||
t.Fatalf("expected existing table comment DDL to remain unchanged, got: %s", duplicated)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDamengColumnDefinitions_MapsComment(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user