package main import ( "database/sql" "encoding/json" "fmt" "log" "net/http" "time" "git.x2erp.com/qdy/go-base/types" // 注意:这里要使用 factory 包的正确导入路径(和你原代码一致) "git.x2erp.com/qdy/go-db/factory" "github.com/gorilla/mux" ) // 全局变量,只初始化一次(复用原逻辑,确保工厂和DB连接单例) var dbFactory *factory.DBFactory var db *sql.DB // QueryRequest 请求结构体(接收前端SQL参数) type QueryRequest struct { SQL string `json:"sql"` } func main() { var err error // 1. 创建数据库工厂(只执行一次) dbFactory, err = factory.NewDBFactory() if err != nil { log.Fatalf("Failed to create DB factory: %v", err) } // 2. 显示基础信息(保留原日志输出) drivers := dbFactory.GetAvailableDrivers() fmt.Printf("Available database drivers: %v\n", drivers) config := dbFactory.GetConfig() fmt.Printf("Using database type: %s\n", config.Database.Type) fmt.Printf("Database host: %s:%d\n", config.Database.Host, config.Database.Port) fmt.Printf("Database name: %s\n", config.Database.Database) // 3. 创建数据库连接(全局复用) db, err = dbFactory.CreateDB() if err != nil { log.Fatalf("Failed to create database connection: %v", err) } defer db.Close() // 4. 测试连接(保留原校验逻辑) if err := testConnection(db, config.Database.Type); err != nil { log.Fatalf("Database connection test failed: %v", err) } else { fmt.Println("Database connection test passed!") } // 5. 启动HTTP服务 startHTTPServer() } // 启动HTTP服务器(简化,直接使用全局DB连接) func startHTTPServer() { router := mux.NewRouter() // 核心路由:SQL查询(POST)- 直接返回 types.QueryResult router.HandleFunc("/api/query", queryHandler).Methods("POST") // 辅助路由:健康检查、数据库信息(保留原功能) router.HandleFunc("/api/health", healthHandler).Methods("GET") router.HandleFunc("/api/info", infoHandler).Methods("GET") // 服务器配置(保留原超时设置) server := &http.Server{ Addr: ":8080", Handler: router, ReadTimeout: 30 * time.Second, WriteTimeout: 30 * time.Second, IdleTimeout: 60 * time.Second, } // 启动日志(保留原格式) fmt.Println("Database microservice starting on :8080") fmt.Println("Endpoints:") fmt.Println(" POST /api/query - Execute SQL query (return types.QueryResult)") fmt.Println(" GET /api/health - Health check") fmt.Println(" GET /api/info - Database info") log.Fatal(server.ListenAndServe()) } // queryHandler SQL查询处理(核心修改) // 1. 修复 factory.QuickQueryToJSON 调用(确保导入路径正确) // 2. 直接返回 types.QueryResult,不二次封装 func queryHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") // 1. 解析请求参数 var req QueryRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { // 参数错误时,返回 types.QueryResult 格式的错误响应 json.NewEncoder(w).Encode(&types.QueryResult{ Success: false, Error: fmt.Sprintf("Invalid request body: %v", err), Data: nil, }) return } // 2. 校验SQL非空 if req.SQL == "" { json.NewEncoder(w).Encode(&types.QueryResult{ Success: false, Error: "SQL statement cannot be empty", Data: nil, }) return } // 3. 核心逻辑:调用 factory.QuickQueryToJSON(确保工厂包导出了该方法) // 注意:如果仍提示 undefined,检查 factory 包是否真的导出了 QuickQueryToJSON(首字母大写) result := factory.QuickQueryToJSON(db, req.SQL) // 4. 直接返回结果(types.QueryResult 原生格式) json.NewEncoder(w).Encode(result) } // healthHandler 健康检查(修复语法错误,保持返回格式统一) func healthHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") // 校验DB连接状态 err := db.Ping() success := err == nil // 标准 if-else 赋值状态 var status string if success { status = "UP" } else { status = "DOWN" } // 返回 types.QueryResult 格式(和查询接口保持一致) json.NewEncoder(w).Encode(&types.QueryResult{ Success: success, Data: map[string]interface{}{ "status": status, "time": time.Now().Format(time.RFC3339), "database": dbFactory.GetConfig().Database.Type, }, Error: func() string { if err != nil { return err.Error() } return "" }(), }) } // infoHandler 数据库信息(返回 types.QueryResult 格式) func infoHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") config := dbFactory.GetConfig() drivers := dbFactory.GetAvailableDrivers() // 直接返回 types.QueryResult 格式 json.NewEncoder(w).Encode(&types.QueryResult{ Success: true, Data: map[string]interface{}{ "database_type": config.Database.Type, "database_host": fmt.Sprintf("%s:%d", config.Database.Host, config.Database.Port), "database_name": config.Database.Database, "available_drivers": drivers, "service_time": time.Now().Format(time.RFC3339), }, Error: "", }) } // testConnection 测试数据库连接(保留原逻辑) func testConnection(db *sql.DB, dbType string) error { var query string switch dbType { case "mysql", "postgres", "sqlserver": query = "SELECT 1" case "oracle": query = "SELECT 1 FROM DUAL" default: query = "SELECT 1" } var result int err := db.QueryRow(query).Scan(&result) if err != nil { return fmt.Errorf("test query failed: %v", err) } if result != 1 { return fmt.Errorf("unexpected test result: %d", result) } return nil }