-
Notifications
You must be signed in to change notification settings - Fork 11
/
wizard.go
109 lines (96 loc) · 2.51 KB
/
wizard.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
package wizard
import (
"github.com/evalphobia/wizard/errors"
)
// Cluster is interface for [StandardCluster | ShardCluster]
type Cluster interface {
SelectByKey(interface{}) *StandardCluster
Master() *Node
Masters() []*Node
Slave() *Node
Slaves() []*Node
}
// Wizard manages all the database cluster for your app
type Wizard struct {
clusters map[interface{}]Cluster
defaultCluster Cluster
}
// NewWizard returns initialized empty Wizard
func NewWizard() *Wizard {
return &Wizard{
clusters: make(map[interface{}]Cluster),
}
}
// SetDefault set default cluster
// if default is set, this cluster acts like catchall, handles all the other tables.
func (w *Wizard) SetDefault(c Cluster) {
w.defaultCluster = c
}
// HasDefault checks default cluster is set or not
func (w *Wizard) HasDefault() bool {
return w.defaultCluster != nil
}
// getCluster returns the cluster by name mapping
func (w *Wizard) getCluster(obj interface{}) Cluster {
c, ok := w.clusters[NormalizeValue(obj)]
switch {
case ok:
return c
case w.HasDefault():
return w.defaultCluster
default:
return nil
}
}
// RegisterTables adds cluster and tables for name mapping
func (w *Wizard) RegisterTables(c Cluster, list ...interface{}) error {
for _, obj := range list {
v := NormalizeValue(obj)
if _, ok := w.clusters[v]; ok {
return errors.NewErrAlreadyRegistared(v)
}
w.clusters[v] = c
}
return nil
}
// setCluster set the cluster with name mapping
func (w *Wizard) setCluster(c Cluster, obj interface{}) {
w.clusters[NormalizeValue(obj)] = c
}
// CreateCluster set and returns the new StandardCluster
func (w *Wizard) CreateCluster(obj interface{}, db interface{}) *StandardCluster {
c := NewCluster(db)
w.setCluster(c, obj)
return c
}
// CreateShardCluster set and returns the new ShardCluster
func (w *Wizard) CreateShardCluster(obj interface{}, slot int64) *ShardCluster {
if slot < 1 {
slot = 1
}
c := &ShardCluster{
slotsize: slot,
}
w.setCluster(c, obj)
return c
}
// Select returns StandardCluster by name mapping (and implicit hash slot from struct field)
func (w *Wizard) Select(obj interface{}) *StandardCluster {
c := w.getCluster(obj)
switch v := c.(type) {
case *StandardCluster:
return v
case *ShardCluster:
return v.SelectByKey(getShardKey(obj))
default:
return nil
}
}
// SelectByKey returns StandardCluster by name mapping and shard key
func (w *Wizard) SelectByKey(obj interface{}, key interface{}) *StandardCluster {
c := w.getCluster(obj)
if c == nil {
return nil
}
return c.SelectByKey(key)
}