Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

main.go 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. package main
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "time"
  9. "git.x2erp.com/qdy/go-base/types"
  10. // 注意:这里要使用 factory 包的正确导入路径(和你原代码一致)
  11. "git.x2erp.com/qdy/go-db/factory"
  12. "github.com/gorilla/mux"
  13. )
  14. // 全局变量,只初始化一次(复用原逻辑,确保工厂和DB连接单例)
  15. var dbFactory *factory.DBFactory
  16. var db *sql.DB
  17. // QueryRequest 请求结构体(接收前端SQL参数)
  18. type QueryRequest struct {
  19. SQL string `json:"sql"`
  20. }
  21. func main() {
  22. var err error
  23. // 1. 创建数据库工厂(只执行一次)
  24. dbFactory, err = factory.NewDBFactory()
  25. if err != nil {
  26. log.Fatalf("Failed to create DB factory: %v", err)
  27. }
  28. // 2. 显示基础信息(保留原日志输出)
  29. drivers := dbFactory.GetAvailableDrivers()
  30. fmt.Printf("Available database drivers: %v\n", drivers)
  31. config := dbFactory.GetConfig()
  32. fmt.Printf("Using database type: %s\n", config.Database.Type)
  33. fmt.Printf("Database host: %s:%d\n", config.Database.Host, config.Database.Port)
  34. fmt.Printf("Database name: %s\n", config.Database.Database)
  35. // 3. 创建数据库连接(全局复用)
  36. db, err = dbFactory.CreateDB()
  37. if err != nil {
  38. log.Fatalf("Failed to create database connection: %v", err)
  39. }
  40. defer db.Close()
  41. // 4. 测试连接(保留原校验逻辑)
  42. if err := testConnection(db, config.Database.Type); err != nil {
  43. log.Fatalf("Database connection test failed: %v", err)
  44. } else {
  45. fmt.Println("Database connection test passed!")
  46. }
  47. // 5. 启动HTTP服务
  48. startHTTPServer()
  49. }
  50. // 启动HTTP服务器(简化,直接使用全局DB连接)
  51. func startHTTPServer() {
  52. router := mux.NewRouter()
  53. // 核心路由:SQL查询(POST)- 直接返回 types.QueryResult
  54. router.HandleFunc("/api/query", queryHandler).Methods("POST")
  55. // 辅助路由:健康检查、数据库信息(保留原功能)
  56. router.HandleFunc("/api/health", healthHandler).Methods("GET")
  57. router.HandleFunc("/api/info", infoHandler).Methods("GET")
  58. // 服务器配置(保留原超时设置)
  59. server := &http.Server{
  60. Addr: ":8080",
  61. Handler: router,
  62. ReadTimeout: 30 * time.Second,
  63. WriteTimeout: 30 * time.Second,
  64. IdleTimeout: 60 * time.Second,
  65. }
  66. // 启动日志(保留原格式)
  67. fmt.Println("Database microservice starting on :8080")
  68. fmt.Println("Endpoints:")
  69. fmt.Println(" POST /api/query - Execute SQL query (return types.QueryResult)")
  70. fmt.Println(" GET /api/health - Health check")
  71. fmt.Println(" GET /api/info - Database info")
  72. log.Fatal(server.ListenAndServe())
  73. }
  74. // queryHandler SQL查询处理(核心修改)
  75. // 1. 修复 factory.QuickQueryToJSON 调用(确保导入路径正确)
  76. // 2. 直接返回 types.QueryResult,不二次封装
  77. func queryHandler(w http.ResponseWriter, r *http.Request) {
  78. w.Header().Set("Content-Type", "application/json")
  79. // 1. 解析请求参数
  80. var req QueryRequest
  81. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  82. // 参数错误时,返回 types.QueryResult 格式的错误响应
  83. json.NewEncoder(w).Encode(&types.QueryResult{
  84. Success: false,
  85. Error: fmt.Sprintf("Invalid request body: %v", err),
  86. Data: nil,
  87. })
  88. return
  89. }
  90. // 2. 校验SQL非空
  91. if req.SQL == "" {
  92. json.NewEncoder(w).Encode(&types.QueryResult{
  93. Success: false,
  94. Error: "SQL statement cannot be empty",
  95. Data: nil,
  96. })
  97. return
  98. }
  99. // 3. 核心逻辑:调用 factory.QuickQueryToJSON(确保工厂包导出了该方法)
  100. // 注意:如果仍提示 undefined,检查 factory 包是否真的导出了 QuickQueryToJSON(首字母大写)
  101. result := factory.QuickQueryToJSON(db, req.SQL)
  102. // 4. 直接返回结果(types.QueryResult 原生格式)
  103. json.NewEncoder(w).Encode(result)
  104. }
  105. // healthHandler 健康检查(修复语法错误,保持返回格式统一)
  106. func healthHandler(w http.ResponseWriter, r *http.Request) {
  107. w.Header().Set("Content-Type", "application/json")
  108. // 校验DB连接状态
  109. err := db.Ping()
  110. success := err == nil
  111. // 标准 if-else 赋值状态
  112. var status string
  113. if success {
  114. status = "UP"
  115. } else {
  116. status = "DOWN"
  117. }
  118. // 返回 types.QueryResult 格式(和查询接口保持一致)
  119. json.NewEncoder(w).Encode(&types.QueryResult{
  120. Success: success,
  121. Data: map[string]interface{}{
  122. "status": status,
  123. "time": time.Now().Format(time.RFC3339),
  124. "database": dbFactory.GetConfig().Database.Type,
  125. },
  126. Error: func() string {
  127. if err != nil {
  128. return err.Error()
  129. }
  130. return ""
  131. }(),
  132. })
  133. }
  134. // infoHandler 数据库信息(返回 types.QueryResult 格式)
  135. func infoHandler(w http.ResponseWriter, r *http.Request) {
  136. w.Header().Set("Content-Type", "application/json")
  137. config := dbFactory.GetConfig()
  138. drivers := dbFactory.GetAvailableDrivers()
  139. // 直接返回 types.QueryResult 格式
  140. json.NewEncoder(w).Encode(&types.QueryResult{
  141. Success: true,
  142. Data: map[string]interface{}{
  143. "database_type": config.Database.Type,
  144. "database_host": fmt.Sprintf("%s:%d", config.Database.Host, config.Database.Port),
  145. "database_name": config.Database.Database,
  146. "available_drivers": drivers,
  147. "service_time": time.Now().Format(time.RFC3339),
  148. },
  149. Error: "",
  150. })
  151. }
  152. // testConnection 测试数据库连接(保留原逻辑)
  153. func testConnection(db *sql.DB, dbType string) error {
  154. var query string
  155. switch dbType {
  156. case "mysql", "postgres", "sqlserver":
  157. query = "SELECT 1"
  158. case "oracle":
  159. query = "SELECT 1 FROM DUAL"
  160. default:
  161. query = "SELECT 1"
  162. }
  163. var result int
  164. err := db.QueryRow(query).Scan(&result)
  165. if err != nil {
  166. return fmt.Errorf("test query failed: %v", err)
  167. }
  168. if result != 1 {
  169. return fmt.Errorf("unexpected test result: %d", result)
  170. }
  171. return nil
  172. }