github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/extend/orm/xorm.go (about) 1 package orm 2 3 import ( 4 "context" 5 "fmt" 6 "github.com/isyscore/isc-gobase/bean" 7 "github.com/isyscore/isc-gobase/config" 8 "github.com/isyscore/isc-gobase/constants" 9 "github.com/isyscore/isc-gobase/listener" 10 "github.com/isyscore/isc-gobase/logger" 11 "time" 12 "xorm.io/xorm" 13 "xorm.io/xorm/contexts" 14 "xorm.io/xorm/log" 15 ) 16 17 type GobaseXormHook interface { 18 BeforeProcess(c *contexts.ContextHook, driverName string) (context.Context, error) 19 AfterProcess(c *contexts.ContextHook, driverName string) error 20 } 21 22 var defaultXormHooks []DefaultXormHook 23 24 type DefaultXormHook struct { 25 driverName string 26 gobaseXormHook GobaseXormHook 27 } 28 29 func (defaultHook *DefaultXormHook)BeforeProcess(c *contexts.ContextHook) (context.Context, error) { 30 return defaultHook.gobaseXormHook.BeforeProcess(c, defaultHook.driverName) 31 } 32 33 func (defaultHook *DefaultXormHook)AfterProcess(c *contexts.ContextHook) error { 34 return defaultHook.gobaseXormHook.AfterProcess(c, defaultHook.driverName) 35 } 36 37 func init() { 38 defaultXormHooks = []DefaultXormHook{} 39 } 40 41 func NewXormDb() (*xorm.Engine, error) { 42 return doNewXormDb("", map[string]string{}) 43 } 44 45 func NewXormDbWithParams(params map[string]string) (*xorm.Engine, error) { 46 return doNewXormDb("", params) 47 } 48 49 func NewXormDbWithName(datasourceName string) (*xorm.Engine, error) { 50 return doNewXormDb(datasourceName, map[string]string{}) 51 } 52 53 func NewXormDbWithNameParams(datasourceName string, params map[string]string) (*xorm.Engine, error) { 54 return doNewXormDb(datasourceName, params) 55 } 56 57 func AddXormHook(hook GobaseXormHook) { 58 defaultXormHook := DefaultXormHook{gobaseXormHook: hook} 59 defaultXormHooks = append(defaultXormHooks, defaultXormHook) 60 xormDbs := bean.GetBeanWithNamePre(constants.BeanNameXormPre) 61 if xormDbs == nil { 62 return 63 } 64 for _, db := range xormDbs { 65 db.(*xorm.Engine).AddHook(&defaultXormHook) 66 } 67 } 68 69 func doNewXormDb(datasourceName string, params map[string]string) (*xorm.Engine, error) { 70 datasourceConfig := config.DatasourceConfig{} 71 targetDatasourceName := "base.datasource" 72 if datasourceName != "" { 73 targetDatasourceName = "base.datasource." + datasourceName 74 } 75 err := config.GetValueObject(targetDatasourceName, &datasourceConfig) 76 if err != nil { 77 logger.Warn("读取读取配置【datasource】异常") 78 return nil, err 79 } 80 81 var dsn = getDbDsn(datasourceConfig.DriverName, datasourceConfig) 82 var xormDb *xorm.Engine 83 xormDb, err = xorm.NewEngineWithParams(datasourceConfig.DriverName, dsn, params) 84 if err != nil { 85 logger.Warn("获取数据库db异常:%v", err.Error()) 86 return nil, err 87 } 88 89 for _, hook := range defaultXormHooks { 90 hook.driverName = datasourceConfig.DriverName 91 xormDb.AddHook(&hook) 92 } 93 94 maxIdleConns := config.GetValueInt("base.datasource.connect-pool.max-idle-conns") 95 if maxIdleConns != 0 { 96 // 设置空闲的最大连接数 97 xormDb.SetMaxIdleConns(maxIdleConns) 98 } 99 100 maxOpenConns := config.GetValueInt("base.datasource.connect-pool.max-open-conns") 101 if maxOpenConns != 0 { 102 // 设置数据库打开连接的最大数量 103 xormDb.SetMaxOpenConns(maxOpenConns) 104 } 105 106 maxLifeTime := config.GetValueString("base.datasource.connect-pool.max-life-time") 107 if maxLifeTime != "" { 108 // 设置连接可重复使用的最大时间 109 t, err := time.ParseDuration(maxLifeTime) 110 if err != nil { 111 logger.Warn("读取配置【base.datasource.connect-pool.max-life-time】异常", err) 112 } else { 113 xormDb.SetConnMaxLifetime(t) 114 } 115 } 116 117 xormDb.ShowSQL(true) 118 xormDb.SetLogger(&XormLoggerAdapter{}) 119 bean.AddBean(constants.BeanNameXormPre + datasourceName, xormDb) 120 121 // 添加orm的配置监听器 122 listener.AddListener(listener.EventOfConfigChange, ConfigChangeListenerOfOrm) 123 return xormDb, nil 124 } 125 126 func NewXormDbMasterSlave(masterDatasourceName string, slaveDatasourceNames []string, policies ...xorm.GroupPolicy) (*xorm.EngineGroup, error) { 127 masterDb, err := NewXormDbWithName(masterDatasourceName) 128 if err != nil { 129 logger.Warn("获取数据库 主节点【%v】失败,%v", masterDatasourceName, err.Error()) 130 return nil, err 131 } 132 133 var slaveDbs []*xorm.Engine 134 for _, slaveDatasource := range slaveDatasourceNames { 135 slaveDb, err := NewXormDbWithName(slaveDatasource) 136 if err != nil { 137 logger.Warn("获取数据库 从节点【%v】失败,%v", slaveDatasource, err.Error()) 138 return nil, err 139 } 140 141 slaveDbs = append(slaveDbs, slaveDb) 142 } 143 144 return xorm.NewEngineGroup(masterDb, slaveDbs, policies...) 145 } 146 147 // LoggerAdapter wraps a Logger interface as LoggerContext interface 148 type XormLoggerAdapter struct { 149 } 150 151 // BeforeSQL implements ContextLogger 152 func (l *XormLoggerAdapter) BeforeSQL(ctx log.LogContext) {} 153 154 // AfterSQL implements ContextLogger 155 func (l *XormLoggerAdapter) AfterSQL(ctx log.LogContext) { 156 var sessionPart string 157 v := ctx.Ctx.Value("__xorm_session_id") 158 if key, ok := v.(string); ok { 159 sessionPart = fmt.Sprintf(" [%s]", key) 160 } 161 if ctx.ExecuteTime > 0 { 162 logger.Group("orm").Debugf("[SQL]%s %s %v - %v", sessionPart, ctx.SQL, ctx.Args, ctx.ExecuteTime) 163 } else { 164 logger.Group("orm").Debugf("[SQL]%s %s %v", sessionPart, ctx.SQL, ctx.Args) 165 } 166 } 167 168 // Debugf implements ContextLogger 169 func (l *XormLoggerAdapter) Debugf(format string, v ...interface{}) { 170 logger.Group("orm").Debug(format, v) 171 } 172 173 // Errorf implements ContextLogger 174 func (l *XormLoggerAdapter) Errorf(format string, v ...interface{}) { 175 logger.Error(format, v) 176 } 177 178 // Infof implements ContextLogger 179 func (l *XormLoggerAdapter) Infof(format string, v ...interface{}) { 180 logger.Info(format, v) 181 } 182 183 // Warnf implements ContextLogger 184 func (l *XormLoggerAdapter) Warnf(format string, v ...interface{}) { 185 logger.Warn(format, v) 186 } 187 188 // Level implements ContextLogger 189 func (l *XormLoggerAdapter) Level() log.LogLevel { 190 return log.LOG_INFO 191 } 192 193 // SetLevel implements ContextLogger 194 func (l *XormLoggerAdapter) SetLevel(lv log.LogLevel) { 195 } 196 197 // ShowSQL implements ContextLogger 198 func (l *XormLoggerAdapter) ShowSQL(show ...bool) { 199 200 } 201 202 // IsShowSQL implements ContextLogger 203 func (l *XormLoggerAdapter) IsShowSQL() bool { 204 return true 205 } 206