Lunny Xiao
7455014823
names with upper charactor on postgres will need quotes Fix bug Add new quote parameter on tests Fix bug Fix tests Fix quotes fix test Improve quote policy Reviewed-on: xorm/xorm#1567
222 lines
5.1 KiB
Go
222 lines
5.1 KiB
Go
// 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/xorm/caches"
|
|
"xorm.io/xorm/dialects"
|
|
"xorm.io/xorm/log"
|
|
"xorm.io/xorm/names"
|
|
)
|
|
|
|
// 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 names.Mapper) {
|
|
eg.Engine.SetColumnMapper(mapper)
|
|
for i := 0; i < len(eg.slaves); i++ {
|
|
eg.slaves[i].SetColumnMapper(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 caches.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 interface{}) {
|
|
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 log.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 names.Mapper) {
|
|
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
|
|
}
|
|
|
|
func (eg *EngineGroup) SetQuotePolicy(quotePolicy dialects.QuotePolicy) {
|
|
eg.Engine.SetQuotePolicy(quotePolicy)
|
|
for i := 0; i < len(eg.slaves); i++ {
|
|
eg.slaves[i].SetQuotePolicy(quotePolicy)
|
|
}
|
|
}
|
|
|
|
// SetTableMapper set the table name mapping rule
|
|
func (eg *EngineGroup) SetTableMapper(mapper names.Mapper) {
|
|
eg.Engine.SetTableMapper(mapper)
|
|
for i := 0; i < len(eg.slaves); i++ {
|
|
eg.slaves[i].SetTableMapper(mapper)
|
|
}
|
|
}
|
|
|
|
// 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
|
|
}
|