144 lines
3.1 KiB
Go
144 lines
3.1 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"sync"
|
|
|
|
"qoobing.com/gomod/gorm"
|
|
"qoobing.com/gomod/log"
|
|
"qoobing.com/gomod/redis"
|
|
)
|
|
|
|
var (
|
|
modelsDb = map[string]*modelDb{}
|
|
modelsRedis = map[string]*modelRedis{}
|
|
defaultDbName = ""
|
|
defaultRedisName = ""
|
|
|
|
errNoModelFound = errorsWrap("named model(%s) not found")
|
|
errModeAlreadyInit = errorsWrap("named model(%s) already initilized")
|
|
errOpenDBFailed = errorsWrap("open database failed: %s")
|
|
errOpenRedisFailed = errorsWrap("open redis failed: %s")
|
|
errUnknownModelType = errorsWrap("unknown model type: %s")
|
|
)
|
|
|
|
func errorsWrap(base string) func(...any) error {
|
|
return func(v ...any) error {
|
|
return fmt.Errorf(base, v...)
|
|
}
|
|
}
|
|
|
|
type (
|
|
DbConfig = gorm.Config
|
|
RedisConfig = redis.Config
|
|
Configurable interface {
|
|
*DbConfig | *RedisConfig
|
|
}
|
|
)
|
|
|
|
type (
|
|
modelDb struct {
|
|
mu sync.Mutex
|
|
db *gorm.DB
|
|
dbCfg *gorm.Config
|
|
}
|
|
|
|
modelRedis struct {
|
|
mu sync.Mutex
|
|
redis redis.Conn
|
|
redisCfg *redis.Config
|
|
redisPool *redis.Pool
|
|
}
|
|
)
|
|
|
|
// Init init named database config & redis config
|
|
func Init[Config Configurable](name string, cfg Config) error {
|
|
var (
|
|
dbCfg *gorm.Config
|
|
redisCfg *redis.Config
|
|
inCfgType = reflect.TypeOf(cfg)
|
|
)
|
|
|
|
if inCfgType == reflect.TypeOf(dbCfg) {
|
|
dbCfg = reflect.ValueOf(cfg).Interface().(*gorm.Config)
|
|
_, ok := modelsDb[name]
|
|
if ok {
|
|
return errModeAlreadyInit("db:" + name)
|
|
}
|
|
db, err := gorm.NewDB(*dbCfg)
|
|
if err != nil {
|
|
return errOpenDBFailed(err)
|
|
}
|
|
modelsDb[name] = &modelDb{
|
|
db: db,
|
|
dbCfg: dbCfg,
|
|
}
|
|
if defaultDbName == "" || (defaultDbName != "" && name == "default") {
|
|
defaultDbName = name
|
|
}
|
|
log.Infof("success init model(%s) database:%s", name, dbCfg.GetSecDsn())
|
|
return nil
|
|
}
|
|
|
|
if inCfgType == reflect.TypeOf(redisCfg) {
|
|
redisCfg = reflect.ValueOf(cfg).Interface().(*redis.Config)
|
|
_, ok := modelsRedis[name]
|
|
if ok {
|
|
return errModeAlreadyInit("redis:" + name)
|
|
}
|
|
redisPool := redis.NewPool(*redisCfg)
|
|
if redisPool == nil {
|
|
return errOpenRedisFailed("new redis pool return nil")
|
|
}
|
|
modelsRedis[name] = &modelRedis{
|
|
redisPool: redisPool,
|
|
redisCfg: redisCfg,
|
|
}
|
|
if defaultRedisName == "" || (defaultRedisName != "" && name == "default") {
|
|
defaultRedisName = name
|
|
}
|
|
log.Infof("success init model(%s) database:%s", name, redisCfg.GetSecDsn())
|
|
return nil
|
|
}
|
|
|
|
log.Infof("failed init model(%s), unknown model type: %s", name, inCfgType.Name())
|
|
return errUnknownModelType(inCfgType.Name())
|
|
}
|
|
|
|
func Db() *gorm.DB {
|
|
return DbOf(defaultDbName)
|
|
}
|
|
|
|
func DbOf(name string) *gorm.DB {
|
|
m, ok := modelsDb[name]
|
|
if !ok {
|
|
panic(errNoModelFound(name))
|
|
}
|
|
return gorm.NewSession(m.db)
|
|
}
|
|
|
|
func Redis() redis.Conn {
|
|
return RedisOf(defaultRedisName)
|
|
}
|
|
|
|
func RedisOf(name string) redis.Conn {
|
|
m, ok := modelsRedis[name]
|
|
if !ok {
|
|
panic(errNoModelFound(name))
|
|
}
|
|
return m.redisPool.Get()
|
|
}
|
|
|
|
func RedisPool() *redis.Pool {
|
|
return RedisPoolOf(defaultRedisName)
|
|
}
|
|
|
|
func RedisPoolOf(name string) *redis.Pool {
|
|
m, ok := modelsRedis[name]
|
|
if !ok {
|
|
panic(errNoModelFound(name))
|
|
}
|
|
return m.redisPool
|
|
}
|