engine_group.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright 2017 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "strings"
  7. "github.com/xormplus/core"
  8. )
  9. type EngineGroup struct {
  10. *Engine
  11. slaves []*Engine
  12. policy GroupPolicy
  13. }
  14. func NewEngineGroup(args1 interface{}, args2 interface{}, policies ...GroupPolicy) (*EngineGroup, error) {
  15. var eg EngineGroup
  16. if len(policies) > 0 {
  17. eg.policy = policies[0]
  18. } else {
  19. eg.policy = NewRandomPolicy()
  20. }
  21. driverName, ok1 := args1.(string)
  22. dataSourceNames, ok2 := args2.(string)
  23. if ok1 && ok2 {
  24. conns := strings.Split(dataSourceNames, ";")
  25. engines := make([]*Engine, len(conns))
  26. for i, conn := range conns {
  27. engine, err := NewEngine(driverName, conn)
  28. if err != nil {
  29. return nil, err
  30. }
  31. engine.engineGroup = &eg
  32. engines[i] = engine
  33. }
  34. eg.Engine = engines[0]
  35. eg.slaves = engines[1:]
  36. return &eg, nil
  37. }
  38. master, ok3 := args1.(*Engine)
  39. slaves, ok4 := args2.([]*Engine)
  40. if ok3 && ok4 {
  41. master.engineGroup = &eg
  42. for i := 0; i < len(slaves); i++ {
  43. slaves[i].engineGroup = &eg
  44. }
  45. eg.Engine = master
  46. eg.slaves = slaves
  47. return &eg, nil
  48. }
  49. return nil, ErrParamsType
  50. }
  51. func (eg *EngineGroup) SetPolicy(policy GroupPolicy) *EngineGroup {
  52. eg.policy = policy
  53. return eg
  54. }
  55. func (eg *EngineGroup) Master() *Engine {
  56. return eg.Engine
  57. }
  58. // Slave returns one of the physical databases which is a slave according the policy
  59. func (eg *EngineGroup) Slave() *Engine {
  60. switch len(eg.slaves) {
  61. case 0:
  62. return eg.Engine
  63. case 1:
  64. return eg.slaves[0]
  65. }
  66. return eg.policy.Slave(eg)
  67. }
  68. func (eg *EngineGroup) Slaves() []*Engine {
  69. return eg.slaves
  70. }
  71. func (eg *EngineGroup) GetSlave(i int) *Engine {
  72. return eg.slaves[i]
  73. }
  74. // ShowSQL show SQL statement or not on logger if log level is great than INFO
  75. func (eg *EngineGroup) ShowSQL(show ...bool) {
  76. eg.Engine.ShowSQL(show...)
  77. for i := 0; i < len(eg.slaves); i++ {
  78. eg.slaves[i].ShowSQL(show...)
  79. }
  80. }
  81. // ShowExecTime show SQL statement and execute time or not on logger if log level is great than INFO
  82. func (eg *EngineGroup) ShowExecTime(show ...bool) {
  83. eg.Engine.ShowExecTime(show...)
  84. for i := 0; i < len(eg.slaves); i++ {
  85. eg.slaves[i].ShowExecTime(show...)
  86. }
  87. }
  88. // SetMapper set the name mapping rules
  89. func (eg *EngineGroup) SetMapper(mapper core.IMapper) {
  90. eg.Engine.SetMapper(mapper)
  91. for i := 0; i < len(eg.slaves); i++ {
  92. eg.slaves[i].SetMapper(mapper)
  93. }
  94. }
  95. // SetLogger set the new logger
  96. func (eg *EngineGroup) SetLogger(logger core.ILogger) {
  97. eg.Engine.SetLogger(logger)
  98. for i := 0; i < len(eg.slaves); i++ {
  99. eg.slaves[i].SetLogger(logger)
  100. }
  101. }
  102. // SetTableMapper set the table name mapping rule
  103. func (eg *EngineGroup) SetTableMapper(mapper core.IMapper) {
  104. eg.Engine.TableMapper = mapper
  105. for i := 0; i < len(eg.slaves); i++ {
  106. eg.slaves[i].TableMapper = mapper
  107. }
  108. }
  109. // SetColumnMapper set the column name mapping rule
  110. func (eg *EngineGroup) SetColumnMapper(mapper core.IMapper) {
  111. eg.Engine.ColumnMapper = mapper
  112. for i := 0; i < len(eg.slaves); i++ {
  113. eg.slaves[i].ColumnMapper = mapper
  114. }
  115. }
  116. // SetMaxOpenConns is only available for go 1.2+
  117. func (eg *EngineGroup) SetMaxOpenConns(conns int) {
  118. eg.Engine.db.SetMaxOpenConns(conns)
  119. for i := 0; i < len(eg.slaves); i++ {
  120. eg.slaves[i].db.SetMaxOpenConns(conns)
  121. }
  122. }
  123. // SetMaxIdleConns set the max idle connections on pool, default is 2
  124. func (eg *EngineGroup) SetMaxIdleConns(conns int) {
  125. eg.Engine.db.SetMaxIdleConns(conns)
  126. for i := 0; i < len(eg.slaves); i++ {
  127. eg.slaves[i].db.SetMaxIdleConns(conns)
  128. }
  129. }
  130. // Close the engine
  131. func (eg *EngineGroup) Close() error {
  132. err := eg.Engine.Close()
  133. if err != nil {
  134. return err
  135. }
  136. for i := 0; i < len(eg.slaves); i++ {
  137. err := eg.slaves[i].Close()
  138. if err != nil {
  139. return err
  140. }
  141. }
  142. return nil
  143. }
  144. // Ping tests if database is alive
  145. func (eg *EngineGroup) Ping() error {
  146. if err := eg.Engine.Ping(); err != nil {
  147. return err
  148. }
  149. for _, slave := range eg.slaves {
  150. if err := slave.Ping(); err != nil {
  151. return err
  152. }
  153. }
  154. return nil
  155. }