| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- package factory
-
- import (
- "database/sql"
- "fmt"
- "io"
- "os"
- "path/filepath"
-
- "git.x2erp.com/qdy/go-base/types"
- "git.x2erp.com/qdy/go-db/drivers"
- "gopkg.in/yaml.v2"
- )
-
- // Config 总配置
- type Config struct {
- Database drivers.DBConfig `yaml:"database"`
- }
-
- // DBFactory 数据库工厂
- type DBFactory struct {
- config *Config
- }
-
- // NewDBFactory 创建数据库工厂
- func NewDBFactory() (*DBFactory, error) {
- configFile, err := findConfigFile()
- if err != nil {
- return nil, err
- }
-
- fmt.Printf("✅ Using config file: %s\n", configFile)
-
- // 读取配置文件
- data, err := os.ReadFile(configFile)
- if err != nil {
- return nil, fmt.Errorf("failed to read config file %s: %v", configFile, err)
- }
-
- var config Config
- err = yaml.Unmarshal(data, &config)
- if err != nil {
- return nil, fmt.Errorf("failed to parse config file: %v", err)
- }
-
- return &DBFactory{config: &config}, nil
- }
-
- // findConfigFile 查找配置文件
- func findConfigFile() (string, error) {
- // 1. 首先尝试可执行文件同目录
- exePath, err := os.Executable()
- if err == nil {
- exeDir := filepath.Dir(exePath)
- configFile := filepath.Join(exeDir, "db.yaml")
- if _, err := os.Stat(configFile); err == nil {
- return configFile, nil
- }
- }
-
- // 2. 尝试环境变量指定的路径
- envConfigPath := os.Getenv("DB_CONFIG_PATH")
- if envConfigPath != "" {
- if _, err := os.Stat(envConfigPath); err == nil {
- return envConfigPath, nil
- }
- return "", fmt.Errorf("DB_CONFIG_PATH file not found: %s", envConfigPath)
- }
-
- // 3. 如果都没有找到,返回错误
- exeDir := "unknown"
- if exePath, err := os.Executable(); err == nil {
- exeDir = filepath.Dir(exePath)
- }
-
- return "", fmt.Errorf(`No configuration file found!
-
- Tried locations:
- 1. Executable directory: %s/db.yaml
- 2. Environment variable: DB_CONFIG_PATH
-
- Solutions:
- - Place db.yaml in the same directory as the executable
- - Or set DB_CONFIG_PATH environment variable to config file path
-
- Example:
- export DB_CONFIG_PATH=/path/to/your/db.yaml`, exeDir)
- }
-
- // CreateDB 创建数据库连接
- func (f *DBFactory) CreateDB() (*sql.DB, error) {
- dbType := f.config.Database.Type
-
- // 获取对应的驱动
- dbDriver, err := drivers.Get(dbType)
- if err != nil {
- return nil, fmt.Errorf("failed to get database driver: %v", err)
- }
-
- // 创建数据库连接
- db, err := dbDriver.Open(f.config.Database)
- if err != nil {
- return nil, fmt.Errorf("failed to open database connection: %v", err)
- }
-
- return db, nil
- }
-
- // GetConfig 获取配置信息
- func (f *DBFactory) GetConfig() *Config {
- return f.config
- }
-
- // GetAvailableDrivers 获取可用的数据库驱动
- func (f *DBFactory) GetAvailableDrivers() []string {
- return drivers.GetAllDrivers()
- }
-
- // CreateQueryExecutor 创建查询执行器(新增方法)
- func (f *DBFactory) CreateQueryExecutor(db *sql.DB) *QueryExecutor {
- return NewQueryExecutor(db)
- }
-
- // -------------- 对外暴露的初始化方法(核心入口)--------------
- // NewDBQuery 初始化查询实例(对外提供唯一初始化入口)
- // db: 已初始化的数据库连接(由调用方传入,解耦数据库配置)
- func NewDBQuery(db *sql.DB) *QueryExecutor {
- // 直接复用原文件的构造函数,对外隐藏实现细节
- return NewQueryExecutor(db)
- }
-
- // QuickQueryToJSON 快捷查询,直接返回 JSON 字节流
- func QuickQueryToJSON(db *sql.DB, sql string) *types.QueryResult {
- return NewDBQuery(db).QueryToJSON(sql)
- }
-
- // QuickQueryToCSV 快捷查询,直接返回 CSV 字符串(包含表头)
- func QuickQueryToCSV(db *sql.DB, sql string) *types.QueryResult {
- return NewDBQuery(db).QueryToCSV(sql)
- }
-
- // QuickExecuteWithColumns 快捷查询,返回完整结果(含列信息)
- func QuickExecuteWithColumns(db *sql.DB, sql string) *types.QueryResult {
- return NewDBQuery(db).ExecuteQueryWithColumns(sql)
- }
-
- // QuickExecuteDataOnly 快捷查询,返回纯数据(性能优先)
- func QuickExecuteDataOnly(db *sql.DB, sql string) *types.QueryResult {
- return NewDBQuery(db).ExecuteQueryDataOnly(sql)
- }
-
- // QuickExecuteCSV 快捷查询,返回 CSV 格式结果(支持自定义是否包含表头)
- func QuickExecuteCSV(db *sql.DB, sql string, includeHeader bool) *types.QueryResult {
- return NewDBQuery(db).ExecuteQueryCSV(sql, includeHeader)
- }
-
- // QuickExecuteCSVStream 快捷流式输出 CSV(直接写入 io.Writer,适合大文件)
- func QuickExecuteCSVStream(db *sql.DB, sql string, w io.Writer, includeHeader bool) (int, error) {
- return NewDBQuery(db).ExecuteQueryCSVStream(sql, w, includeHeader)
- }
|