Aucune description
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

get_mysql_columns.go 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package dbs
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "git.x2erp.com/qdy/go-svc-mcp/internal/mcp"
  8. )
  9. func init() {
  10. mcp.Register("get_mysql_columns", "根据表名称获取MySQL表的所有字段相关信息",
  11. map[string]interface{}{
  12. "type": "object",
  13. "properties": map[string]interface{}{
  14. "table_name": map[string]interface{}{
  15. "type": "string",
  16. "description": "表名称",
  17. },
  18. "schema": map[string]interface{}{
  19. "type": "string",
  20. "description": "数据库名称(默认为当前数据库)",
  21. "default": "",
  22. },
  23. "include_comments": map[string]interface{}{
  24. "type": "boolean",
  25. "description": "是否包含字段注释",
  26. "default": true,
  27. },
  28. "database_key": map[string]interface{}{
  29. "type": "string",
  30. "description": "数据库配置键名:warehouse(仓库数据库)或 business(业务数据库),可选,默认使用主数据库",
  31. "enum": []string{"warehouse", "business"},
  32. "default": "",
  33. },
  34. },
  35. "required": []string{"table_name"},
  36. },
  37. func(input json.RawMessage, deps *mcp.ToolDependencies) (interface{}, error) {
  38. var params struct {
  39. TableName string `json:"table_name"`
  40. Schema string `json:"schema"`
  41. IncludeComments bool `json:"include_comments"`
  42. DatabaseKey string `json:"database_key"`
  43. }
  44. if len(input) > 0 {
  45. if err := json.Unmarshal(input, &params); err != nil {
  46. return nil, err
  47. }
  48. }
  49. // 获取数据库工厂
  50. dbFactory, err := GetDBFactory(params.DatabaseKey, deps)
  51. if err != nil {
  52. return nil, err
  53. }
  54. // 获取数据库类型,确保是MySQL
  55. dbType := dbFactory.GetDBType()
  56. if dbType != "mysql" {
  57. return nil, fmt.Errorf("数据库类型为 %s,此工具仅支持MySQL数据库", dbType)
  58. }
  59. // 获取当前数据库名称
  60. currentDatabase := dbFactory.GetDatabaseName()
  61. schema := strings.TrimSpace(params.Schema)
  62. if schema == "" {
  63. schema = currentDatabase
  64. }
  65. tableName := strings.TrimSpace(params.TableName)
  66. if tableName == "" {
  67. return nil, fmt.Errorf("表名称不能为空")
  68. }
  69. // 构建查询SQL
  70. var query string
  71. if params.IncludeComments {
  72. query = `
  73. SELECT
  74. ORDINAL_POSITION as column_id,
  75. COLUMN_NAME as column_name,
  76. COLUMN_TYPE as data_type,
  77. IS_NULLABLE as nullable,
  78. COLUMN_DEFAULT as column_default,
  79. COLUMN_COMMENT as column_comment,
  80. CHARACTER_MAXIMUM_LENGTH as character_maximum_length,
  81. NUMERIC_PRECISION as numeric_precision,
  82. NUMERIC_SCALE as numeric_scale,
  83. DATA_TYPE as simple_data_type,
  84. COLUMN_KEY as column_key,
  85. EXTRA as extra
  86. FROM information_schema.COLUMNS
  87. WHERE TABLE_SCHEMA = ?
  88. AND TABLE_NAME = ?
  89. ORDER BY ORDINAL_POSITION`
  90. } else {
  91. query = `
  92. SELECT
  93. ORDINAL_POSITION as column_id,
  94. COLUMN_NAME as column_name,
  95. COLUMN_TYPE as data_type,
  96. IS_NULLABLE as nullable,
  97. COLUMN_DEFAULT as column_default,
  98. CHARACTER_MAXIMUM_LENGTH as character_maximum_length,
  99. NUMERIC_PRECISION as numeric_precision,
  100. NUMERIC_SCALE as numeric_scale,
  101. DATA_TYPE as simple_data_type,
  102. COLUMN_KEY as column_key,
  103. EXTRA as extra
  104. FROM information_schema.COLUMNS
  105. WHERE TABLE_SCHEMA = ?
  106. AND TABLE_NAME = ?
  107. ORDER BY ORDINAL_POSITION`
  108. }
  109. // 执行查询
  110. results, err := dbFactory.QuerySliceMapWithParams(query, schema, tableName)
  111. if err != nil {
  112. return nil, fmt.Errorf("查询表字段信息失败: %v", err)
  113. }
  114. if len(results) == 0 {
  115. // 尝试查询表是否存在
  116. tableExistsQuery := `SELECT COUNT(*) as table_count FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`
  117. tableCheckResults, err := dbFactory.QuerySliceMapWithParams(tableExistsQuery, schema, tableName)
  118. if err == nil && len(tableCheckResults) > 0 {
  119. if count, ok := tableCheckResults[0]["table_count"].(int64); ok && count == 0 {
  120. return nil, fmt.Errorf("表 '%s' 不存在于数据库 '%s' 中", tableName, schema)
  121. }
  122. }
  123. return nil, fmt.Errorf("表 '%s' 存在但没有字段信息或表为空", tableName)
  124. }
  125. // 处理字段信息
  126. for i := range results {
  127. // 处理nullable字段
  128. if nullable, ok := results[i]["nullable"].(string); ok {
  129. results[i]["is_nullable"] = nullable == "YES"
  130. }
  131. // 处理注释字段
  132. if params.IncludeComments {
  133. if comment, ok := results[i]["column_comment"]; ok && comment == nil {
  134. results[i]["column_comment"] = ""
  135. }
  136. }
  137. // 处理默认值
  138. if defaultValue, ok := results[i]["column_default"]; ok && defaultValue == nil {
  139. results[i]["column_default"] = ""
  140. }
  141. // 确定是否为键
  142. if columnKey, ok := results[i]["column_key"].(string); ok {
  143. results[i]["is_primary_key"] = columnKey == "PRI"
  144. results[i]["is_unique_key"] = columnKey == "UNI"
  145. delete(results[i], "column_key")
  146. }
  147. // 构建完整数据类型
  148. if dataType, ok := results[i]["data_type"].(string); ok {
  149. results[i]["full_data_type"] = dataType
  150. }
  151. }
  152. // 获取表注释
  153. tableCommentQuery := `SELECT TABLE_COMMENT as table_comment FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`
  154. commentResults, err := dbFactory.QuerySliceMapWithParams(tableCommentQuery, schema, tableName)
  155. tableComment := ""
  156. if err == nil && len(commentResults) > 0 {
  157. if comment, ok := commentResults[0]["table_comment"].(string); ok {
  158. tableComment = comment
  159. }
  160. }
  161. return map[string]interface{}{
  162. "tenant_id": deps.ReqCtx.TenantID,
  163. "user_id": deps.ReqCtx.UserID,
  164. "database_type": dbType,
  165. "database_name": dbFactory.GetDatabaseName(),
  166. "schema": schema,
  167. "table_name": tableName,
  168. "table_comment": tableComment,
  169. "include_comments": params.IncludeComments,
  170. "columns": results,
  171. "total_columns": len(results),
  172. "timestamp": time.Now().Format(time.RFC3339),
  173. }, nil
  174. },
  175. )
  176. }