-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathengin.go
244 lines (213 loc) · 5.45 KB
/
engin.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
package gorose
import (
"database/sql"
"fmt"
)
// TAGNAME ...
var TAGNAME = "gorose"
// IGNORE ...
var IGNORE = "-"
type cluster struct {
master []*sql.DB
masterSize int
slave []*sql.DB
slaveSize int
}
// Engin ...
type Engin struct {
config *ConfigCluster
driver string
prefix string
dbs *cluster
logger ILogger
}
var _ IEngin = (*Engin)(nil)
// NewEngin : init Engin struct pointer
// NewEngin : 初始化 Engin 结构体对象指针
func NewEngin(conf ...interface{}) (e *Engin, err error) {
engin := new(Engin)
if len(conf) == 0 {
return
}
// 使用默认的log, 如果自定义了logger, 则只需要调用 Use() 方法即可覆盖
engin.Use(DefaultLogger())
switch conf[0].(type) {
// 传入的是单个配置
case *Config:
err = engin.bootSingle(conf[0].(*Config))
// 传入的是集群配置
case *ConfigCluster:
engin.config = conf[0].(*ConfigCluster)
err = engin.bootCluster()
default:
panic(fmt.Sprint("Open() need *gorose.Config or *gorose.ConfigCluster param, also can empty for build sql string only, but ",
conf, " given"))
}
return engin, err
}
// Use ...
func (c *Engin) Use(closers ...func(e *Engin)) {
for _, closer := range closers {
closer(c)
}
}
// Ping ...
func (c *Engin) Ping() error {
//for _,item := range c.dbs.master {
//
//}
return c.GetQueryDB().Ping()
}
// TagName 自定义结构体对应的orm字段,默认gorose
func (c *Engin) TagName(arg string) {
//c.tagName = arg
TAGNAME = arg
}
// IgnoreName 自定义结构体对应的orm忽略字段名字,默认-
func (c *Engin) IgnoreName(arg string) {
//c.ignoreName = arg
IGNORE = arg
}
// SetPrefix 设置表前缀
func (c *Engin) SetPrefix(pre string) {
c.prefix = pre
}
// GetPrefix 获取前缀
func (c *Engin) GetPrefix() string {
return c.prefix
}
// GetDriver ...
func (c *Engin) GetDriver() string {
return c.driver
}
// GetQueryDB : get a slave db for using query operation
// GetQueryDB : 获取一个从库用来做查询操作
func (c *Engin) GetQueryDB() *sql.DB {
if c.dbs.slaveSize == 0 {
return c.GetExecuteDB()
}
var randint = getRandomInt(c.dbs.slaveSize)
return c.dbs.slave[randint]
}
// GetExecuteDB : get a master db for using execute operation
// GetExecuteDB : 获取一个主库用来做查询之外的操作
func (c *Engin) GetExecuteDB() *sql.DB {
if c.dbs.masterSize == 0 {
return nil
}
var randint = getRandomInt(c.dbs.masterSize)
return c.dbs.master[randint]
}
// GetLogger ...
func (c *Engin) GetLogger() ILogger {
return c.logger
}
// SetLogger ...
func (c *Engin) SetLogger(lg ILogger) {
c.logger = lg
}
func (c *Engin) bootSingle(conf *Config) error {
// 如果传入的是单一配置, 则转换成集群配置, 方便统一管理
var cc = new(ConfigCluster)
cc.Master = append(cc.Master, *conf)
c.config = cc
return c.bootCluster()
}
func (c *Engin) bootCluster() error {
//fmt.Println(len(c.config.Slave))
if len(c.config.Slave) > 0 {
for _, item := range c.config.Slave {
if c.config.Driver != "" {
item.Driver = c.config.Driver
}
if c.config.Prefix != "" {
item.Prefix = c.config.Prefix
}
db, err := c.bootReal(item)
if err != nil {
return err
}
if c.dbs == nil {
c.dbs = new(cluster)
}
c.dbs.slave = append(c.dbs.slave, db)
c.dbs.slaveSize++
c.driver = item.Driver
}
}
var pre, dr string
if len(c.config.Master) > 0 {
for _, item := range c.config.Master {
if c.config.Driver != "" {
item.Driver = c.config.Driver
}
if c.config.Prefix != "" {
item.Prefix = c.config.Prefix
}
db, err := c.bootReal(item)
if err != nil {
return err
}
if c.dbs == nil {
c.dbs = new(cluster)
}
c.dbs.master = append(c.dbs.master, db)
c.dbs.masterSize = c.dbs.masterSize + 1
c.driver = item.Driver
//fmt.Println(c.dbs.masterSize)
if item.Prefix != "" {
pre = item.Prefix
}
if item.Driver != "" {
dr = item.Driver
}
}
}
// 如果config没有设置prefix,且configcluster设置了prefix,则使用cluster的prefix
if pre != "" && c.prefix == "" {
c.prefix = pre
}
// 如果config没有设置driver,且configcluster设置了driver,则使用cluster的driver
if dr != "" && c.driver == "" {
c.driver = dr
}
return nil
}
// boot sql driver
func (c *Engin) bootReal(dbConf Config) (db *sql.DB, err error) {
//db, err = sql.Open("mysql", "root:root@tcp(localhost:3306)/test?charset=utf8mb4")
// 开始驱动
db, err = sql.Open(dbConf.Driver, dbConf.Dsn)
if err != nil {
return
}
// 检查是否可以ping通
err = db.Ping()
if err != nil {
return
}
// 连接池设置
if dbConf.SetMaxOpenConns > 0 {
db.SetMaxOpenConns(dbConf.SetMaxOpenConns)
}
if dbConf.SetMaxIdleConns > 0 {
db.SetMaxIdleConns(dbConf.SetMaxIdleConns)
}
return
}
// NewSession 获取session实例
// 这是一个语法糖, 为了方便使用(engin.NewSession())添加的
// 添加后会让engin和session耦合, 如果不想耦合, 就删掉此方法
// 删掉这个方法后,可以使用 gorose.NewSession(gorose.IEngin)
// 通过 gorose.IEngin 依赖注入的方式, 达到解耦的目的
func (c *Engin) NewSession() ISession {
return NewSession(c)
}
// NewOrm 获取orm实例
// 这是一个语法糖, 为了方便使用(engin.NewOrm())添加的
// 添加后会让engin和 orm 耦合, 如果不想耦合, 就删掉此方法
// 删掉这个方法后,可以使用 gorose.NewOrm(gorose.NewSession(gorose.IEngin))
// 通过 gorose.ISession 依赖注入的方式, 达到解耦的目的
func (c *Engin) NewOrm() IOrm {
return NewOrm(c)
}