123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- // Copyright 2017 The Xorm Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package xorm
- import (
- "context"
- "time"
- "xorm.io/core"
- )
- // EngineGroup defines an engine group
- type EngineGroup struct {
- *Engine
- slaves []*Engine
- policy GroupPolicy
- }
- // NewEngineGroup creates a new engine group
- func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) {
- var eg EngineGroup
- if len(policies) > 0 {
- eg.policy = policies[0]
- } else {
- eg.policy = RoundRobinPolicy()
- }
- driverName, ok1 := args1.(string)
- conns, ok2 := args2.([]string)
- if ok1 && ok2 {
- engines := make([]*Engine, len(conns))
- for i, conn := range conns {
- engine, err := NewEngine(driverName, conn)
- if err != nil {
- return nil, err
- }
- engine.engineGroup = &eg
- engines[i] = engine
- }
- eg.Engine = engines[0]
- eg.slaves = engines[1:]
- return &eg, nil
- }
- master, ok3 := args1.(*Engine)
- slaves, ok4 := args2.([]*Engine)
- if ok3 && ok4 {
- master.engineGroup = &eg
- for i := 0; i < len(slaves); i++ {
- slaves[i].engineGroup = &eg
- }
- eg.Engine = master
- eg.slaves = slaves
- return &eg, nil
- }
- return nil, ErrParamsType
- }
- // Close the engine
- func (eg *EngineGroup) Close() error {
- err := eg.Engine.Close()
- if err != nil {
- return err
- }
- for i := 0; i < len(eg.slaves); i++ {
- err := eg.slaves[i].Close()
- if err != nil {
- return err
- }
- }
- return nil
- }
- // Context returned a group session
- func (eg *EngineGroup) Context(ctx context.Context) *Session {
- sess := eg.NewSession()
- sess.isAutoClose = true
- return sess.Context(ctx)
- }
- // NewSession returned a group session
- func (eg *EngineGroup) NewSession() *Session {
- sess := eg.Engine.NewSession()
- sess.sessionType = groupSession
- return sess
- }
- // Master returns the master engine
- func (eg *EngineGroup) Master() *Engine {
- return eg.Engine
- }
- // Ping tests if database is alive
- func (eg *EngineGroup) Ping() error {
- if err := eg.Engine.Ping(); err != nil {
- return err
- }
- for _, slave := range eg.slaves {
- if err := slave.Ping(); err != nil {
- return err
- }
- }
- return nil
- }
- // SetColumnMapper set the column name mapping rule
- func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) {
- eg.Engine.ColumnMapper = mapper
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].ColumnMapper = mapper
- }
- }
- // SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
- func (eg *EngineGroup) SetConnMaxLifetime(d time.Duration) {
- eg.Engine.SetConnMaxLifetime(d)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].SetConnMaxLifetime(d)
- }
- }
- // SetDefaultCacher set the default cacher
- func (eg *EngineGroup) SetDefaultCacher(cacher core.Cacher) {
- eg.Engine.SetDefaultCacher(cacher)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].SetDefaultCacher(cacher)
- }
- }
- // SetLogger set the new logger
- func (eg *EngineGroup) SetLogger(logger core.ILogger) {
- eg.Engine.SetLogger(logger)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].SetLogger(logger)
- }
- }
- // SetLogLevel sets the logger level
- func (eg *EngineGroup) SetLogLevel(level core.LogLevel) {
- eg.Engine.SetLogLevel(level)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].SetLogLevel(level)
- }
- }
- // SetMapper set the name mapping rules
- func (eg *EngineGroup) SetMapper(mapper core.IMapper) {
- eg.Engine.SetMapper(mapper)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].SetMapper(mapper)
- }
- }
- // SetMaxIdleConns set the max idle connections on pool, default is 2
- func (eg *EngineGroup) SetMaxIdleConns(conns int) {
- eg.Engine.db.SetMaxIdleConns(conns)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].db.SetMaxIdleConns(conns)
- }
- }
- // SetMaxOpenConns is only available for go 1.2+
- func (eg *EngineGroup) SetMaxOpenConns(conns int) {
- eg.Engine.db.SetMaxOpenConns(conns)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].db.SetMaxOpenConns(conns)
- }
- }
- // SetPolicy set the group policy
- func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup {
- eg.policy = policy
- return eg
- }
- // SetTableMapper set the table name mapping rule
- func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) {
- eg.Engine.TableMapper = mapper
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].TableMapper = mapper
- }
- }
- // ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO
- func (eg *EngineGroup) ShowExecTime(show ...bool) {
- eg.Engine.ShowExecTime(show...)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].ShowExecTime(show...)
- }
- }
- // ShowSQL show SQL statement or not on logger if log level is great than INFO
- func (eg *EngineGroup) ShowSQL(show ...bool) {
- eg.Engine.ShowSQL(show...)
- for i := 0; i < len(eg.slaves); i++ {
- eg.slaves[i].ShowSQL(show...)
- }
- }
- // Slave returns one of the physical databases which is a slave according the policy
- func (eg *EngineGroup) Slave() *Engine {
- switch len(eg.slaves) {
- case 0:
- return eg.Engine
- case 1:
- return eg.slaves[0]
- }
- return eg.policy.Slave(eg)
- }
- // Slaves returns all the slaves
- func (eg *EngineGroup) Slaves() []*Engine {
- return eg.slaves
- }
|