Files
db/engine/engine.go
T
what ac81f1ff0b feat: 新增 SQLite3 虚拟表框架及方言扩展
- 新增 dialect/sqlite3/vtab 包,提供干净的虚拟表接口(Module/Table/Cursor)
- 适配层自动将 BestIndex 约束与 Filter 值绑定(ConstraintInfo.Value),无需手动编解码 IdxStr
- 支持 OpLIMIT/OpOFFSET 约束下推
- 新增 SupportsDistinct 方言选项,控制 SELECT 级和表达式级 DISTINCT 生成
- sqlite3 方言注册 IF() 函数支持
2026-04-18 13:41:41 +08:00

89 lines
1.5 KiB
Go

package engine
import (
"database/sql"
"errors"
"fmt"
"git.fsdpf.net/go/db"
sqlite3dialect "git.fsdpf.net/go/db/dialect/sqlite3"
sqlite3vtab "git.fsdpf.net/go/db/dialect/sqlite3/vtab"
)
type Engine struct {
configs map[string]DBConfig
dbs map[string]*sql.DB
}
var _engine *Engine
func init() {
_engine = &Engine{
configs: make(map[string]DBConfig),
dbs: make(map[string]*sql.DB),
}
}
func (e Engine) Connection(name string) *db.Database {
cfg, ok := e.configs[name]
if !ok {
panic(errors.New(fmt.Sprintf("Database connection %s not configured.", name)))
}
_db, ok := e.dbs[name]
if !ok {
_db = e.MakeConnection(cfg)
e.dbs[name] = _db
}
return db.New(cfg.Driver, _db)
}
func (e Engine) MakeConnection(cfg DBConfig) (db *sql.DB) {
dsn := cfg.ToDSN()
driverName := cfg.Driver
switch cfg.Driver {
case "mysql":
case "sqlite3":
driverName = sqlite3dialect.DriverWithIF
case "vtable":
driverName = sqlite3vtab.DriverName
case "sqlserver":
case "postgres":
case "duckdb":
default:
panic(fmt.Sprintf("Unsupported driver: %s", cfg.Driver))
}
db, err := sql.Open(driverName, dsn)
if err != nil {
panic(err)
}
if err := db.Ping(); err != nil {
panic(err)
}
return db
}
func Open(cfgs map[string]DBConfig) Engine {
for n, cfg := range cfgs {
_engine.configs[n] = cfg
}
return *_engine
}
func Mock(cfgs map[string]MockDBConfig) Engine {
for k, cfg := range cfgs {
_engine.dbs[k] = cfg.Mock
_engine.configs[k] = DBConfig{Driver: cfg.Driver}
}
return *_engine
}