-
Notifications
You must be signed in to change notification settings - Fork 1
/
readonlyDictionary.go
167 lines (138 loc) · 3.87 KB
/
readonlyDictionary.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
package collections
import (
"database/sql/driver"
"encoding/json"
"github.com/farseer-go/fs/parse"
"sync"
)
// ReadonlyDictionary 只读字典
type ReadonlyDictionary[TKey comparable, TValue any] struct {
// source array
source map[TKey]TValue
lock *sync.RWMutex
}
// NewReadonlyDictionary 创建一个字典
func NewReadonlyDictionary[TKey comparable, TValue any]() ReadonlyDictionary[TKey, TValue] {
return ReadonlyDictionary[TKey, TValue]{
source: make(map[TKey]TValue),
lock: &sync.RWMutex{},
}
}
// NewReadonlyDictionaryFromMap 创建一个字典
func NewReadonlyDictionaryFromMap[TKey comparable, TValue any](source map[TKey]TValue) ReadonlyDictionary[TKey, TValue] {
if source == nil {
source = make(map[TKey]TValue)
}
return ReadonlyDictionary[TKey, TValue]{
source: source,
lock: &sync.RWMutex{},
}
}
// Values 获取字典的value
func (receiver ReadonlyDictionary[TKey, TValue]) Values() List[TValue] {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
lst := NewList[TValue]()
for _, v := range receiver.source {
lst.Add(v)
}
return lst
}
// Keys 获取字典的Keys
func (receiver ReadonlyDictionary[TKey, TValue]) Keys() List[TKey] {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
lst := NewList[TKey]()
for k := range receiver.source {
lst.Add(k)
}
return lst
}
// Count 获取字典数量
func (receiver ReadonlyDictionary[TKey, TValue]) Count() int {
if receiver.lock == nil {
return 0
}
receiver.lock.RLock()
defer receiver.lock.RUnlock()
return len(receiver.source)
}
// ContainsKey 是否存在KEY
func (receiver ReadonlyDictionary[TKey, TValue]) ContainsKey(key TKey) bool {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
_, exists := receiver.source[key]
return exists
}
// ContainsValue 是否存在指定的Value
func (receiver ReadonlyDictionary[TKey, TValue]) ContainsValue(value TValue) bool {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
for _, itemValue := range receiver.source {
if parse.IsEqual(value, itemValue) {
return true
}
}
return false
}
// GetValue 获取指定KEY的Value
func (receiver ReadonlyDictionary[TKey, TValue]) GetValue(key TKey) TValue {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
return receiver.source[key]
}
// ToMap 转成map对象
func (receiver ReadonlyDictionary[TKey, TValue]) ToMap() map[TKey]TValue {
receiver.lock.RLock()
defer receiver.lock.RUnlock()
return receiver.source
}
// Value return json value, implement driver.Valuer interface
func (receiver ReadonlyDictionary[TKey, TValue]) Value() (driver.Value, error) {
if receiver.source == nil {
return nil, nil
}
ba, err := receiver.MarshalJSON()
return string(ba), err
}
// MarshalJSON to output non base64 encoded []byte
// 此处不能用指针,否则json序列化时不执行
func (receiver ReadonlyDictionary[TKey, TValue]) MarshalJSON() ([]byte, error) {
if receiver.source == nil || receiver.lock == nil {
return []byte("{}"), nil
}
receiver.lock.RLock()
defer receiver.lock.RUnlock()
return json.Marshal(receiver.source)
}
// GormDataType gorm common data type
func (receiver ReadonlyDictionary[TKey, TValue]) GormDataType() string {
return "JSON"
}
// IsNil 是否未初始化
func (receiver ReadonlyDictionary[TKey, TValue]) IsNil() bool {
if receiver.lock == nil {
return true
}
receiver.lock.RLock()
defer receiver.lock.RUnlock()
return receiver.source == nil
}
// ToDictionary 返回只写字典
func (receiver ReadonlyDictionary[TKey, TValue]) ToDictionary() Dictionary[TKey, TValue] {
return NewDictionaryFromMap(receiver.source)
}
//// GormDBDataType gorm db data type
//func (Dictionary[TKey, TValue]) GormDBDataType(db *gorm.DB, field *schema.Field) string {
// switch db.Dialector.Name() {
// case "sqlite":
// return "JSON"
// case "mysql":
// return "JSON"
// case "postgres":
// return "JSONB"
// case "sqlserver":
// return "NVARCHAR(MAX)"
// }
// return ""
//}