-
-
Notifications
You must be signed in to change notification settings - Fork 57
/
entity_repository_go1.18.go
275 lines (214 loc) · 10.1 KB
/
entity_repository_go1.18.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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
//go:build go1.18
// +build go1.18
package rel
import (
"context"
"reflect"
)
type EntityRepository[T any] interface {
// Repository returns base Repository wrapped by this EntityRepository.
Repository() Repository
// Iterate through a collection of entities from database in batches.
// This function returns iterator that can be used to loop all entities.
// Limit, Offset and Sort query is automatically ignored.
Iterate(ctx context.Context, query Query, option ...IteratorOption) EntityIterator[T]
// Aggregate over the given field.
// Supported aggregate: count, sum, avg, max, min.
// Any select, group, offset, limit and sort query will be ignored automatically.
// If complex aggregation is needed, consider using All instead.
Aggregate(ctx context.Context, aggregate string, field string, queriers ...Querier) (int, error)
// MustAggregate over the given field.
// Supported aggregate: count, sum, avg, max, min.
// Any select, group, offset, limit and sort query will be ignored automatically.
// If complex aggregation is needed, consider using All instead.
// It'll panic if any error occurred.
MustAggregate(ctx context.Context, aggregate string, field string, queriers ...Querier) int
// Count entities that match the query.
Count(ctx context.Context, queriers ...Querier) (int, error)
// MustCount entities that match the query.
// It'll panic if any error occurred.
MustCount(ctx context.Context, queriers ...Querier) int
// Find a entity that match the query.
// If no result found, it'll return not found error.
Find(ctx context.Context, queriers ...Querier) (T, error)
// MustFind a entity that match the query.
// If no result found, it'll panic.
MustFind(ctx context.Context, queriers ...Querier) T
// FindAll entities that match the query.
FindAll(ctx context.Context, queriers ...Querier) ([]T, error)
// MustFindAll entities that match the query.
// It'll panic if any error occurred.
MustFindAll(ctx context.Context, queriers ...Querier) []T
// FindAndCountAll entities that match the query.
// This is a convenient method that combines FindAll and Count. It's useful when dealing with queries related to pagination.
// Limit and Offset property will be ignored when performing count query.
FindAndCountAll(ctx context.Context, queriers ...Querier) ([]T, int, error)
// MustFindAndCountAll entities that match the query.
// This is a convenient method that combines FindAll and Count. It's useful when dealing with queries related to pagination.
// Limit and Offset property will be ignored when performing count query.
// It'll panic if any error occurred.
MustFindAndCountAll(ctx context.Context, queriers ...Querier) ([]T, int)
// Insert a entity to database.
Insert(ctx context.Context, entity *T, mutators ...Mutator) error
// MustInsert an entity to database.
// It'll panic if any error occurred.
MustInsert(ctx context.Context, entity *T, mutators ...Mutator)
// InsertAll entities.
// Does not supports application cascade insert.
InsertAll(ctx context.Context, entities *[]T, mutators ...Mutator) error
// MustInsertAll entities.
// It'll panic if any error occurred.
// Does not supports application cascade insert.
MustInsertAll(ctx context.Context, entities *[]T, mutators ...Mutator)
// Update a entity in database.
// It'll panic if any error occurred.
Update(ctx context.Context, entity *T, mutators ...Mutator) error
// MustUpdate a entity in database.
// It'll panic if any error occurred.
MustUpdate(ctx context.Context, entity *T, mutators ...Mutator)
// Delete a entity.
Delete(ctx context.Context, entity *T, mutators ...Mutator) error
// MustDelete a entity.
// It'll panic if any error occurred.
MustDelete(ctx context.Context, entity *T, mutators ...Mutator)
// DeleteAll entities.
// Does not supports application cascade delete.
DeleteAll(ctx context.Context, entities *[]T) error
// MustDeleteAll entities.
// It'll panic if any error occurred.
// Does not supports application cascade delete.
MustDeleteAll(ctx context.Context, entities *[]T)
// Preload association with given query.
// If association is already loaded, this will do nothing.
// To force preloading even though association is already loaeded, add `Reload(true)` as query.
Preload(ctx context.Context, entity *T, field string, queriers ...Querier) error
// MustPreload association with given query.
// It'll panic if any error occurred.
MustPreload(ctx context.Context, entity *T, field string, queriers ...Querier)
// Preload association with given query.
// If association is already loaded, this will do nothing.
// To force preloading even though association is already loaeded, add `Reload(true)` as query.
PreloadAll(ctx context.Context, entities *[]T, field string, queriers ...Querier) error
// MustPreload association with given query.
// It'll panic if any error occurred.
MustPreloadAll(ctx context.Context, entities *[]T, field string, queriers ...Querier)
// Transaction performs transaction with given function argument.
// Transaction scope/connection is automatically passed using context.
Transaction(ctx context.Context, fn func(ctx context.Context) error) error
}
type entityRepository[T any] struct {
repository Repository
}
func (er entityRepository[T]) Repository() Repository {
return er.repository
}
func (er entityRepository[T]) Iterate(ctx context.Context, query Query, option ...IteratorOption) EntityIterator[T] {
if query.Table == "" {
var entity T
query.Table = getDocumentMeta(reflect.TypeOf(entity), true).Table()
}
return newEntityIterator[T](er.repository.Iterate(ctx, query, option...))
}
func (er entityRepository[T]) Aggregate(ctx context.Context, aggregate string, field string, queriers ...Querier) (int, error) {
var (
entity T
documentMeta = getDocumentMeta(reflect.TypeOf(entity), true)
query = Build(documentMeta.table, queriers...)
)
return er.repository.Aggregate(ctx, query, aggregate, field)
}
func (er entityRepository[T]) MustAggregate(ctx context.Context, aggregate string, field string, queriers ...Querier) int {
result, err := er.Aggregate(ctx, aggregate, field, queriers...)
must(err)
return result
}
func (er entityRepository[T]) Count(ctx context.Context, queriers ...Querier) (int, error) {
var (
entity T
documentMeta = getDocumentMeta(reflect.TypeOf(entity), true)
)
return er.repository.Count(ctx, documentMeta.Table(), queriers...)
}
func (er entityRepository[T]) MustCount(ctx context.Context, queriers ...Querier) int {
result, err := er.Count(ctx, queriers...)
must(err)
return result
}
func (er entityRepository[T]) Find(ctx context.Context, queriers ...Querier) (T, error) {
var entity T
return entity, er.repository.Find(ctx, &entity, queriers...)
}
func (er entityRepository[T]) MustFind(ctx context.Context, queriers ...Querier) T {
entity, err := er.Find(ctx, queriers...)
must(err)
return entity
}
func (er entityRepository[T]) FindAll(ctx context.Context, queriers ...Querier) ([]T, error) {
var entities []T
return entities, er.repository.FindAll(ctx, &entities, queriers...)
}
func (er entityRepository[T]) MustFindAll(ctx context.Context, queriers ...Querier) []T {
entities, err := er.FindAll(ctx, queriers...)
must(err)
return entities
}
func (er entityRepository[T]) FindAndCountAll(ctx context.Context, queriers ...Querier) ([]T, int, error) {
var entities []T
count, err := er.repository.FindAndCountAll(ctx, &entities, queriers...)
return entities, count, err
}
func (er entityRepository[T]) MustFindAndCountAll(ctx context.Context, queriers ...Querier) ([]T, int) {
entities, count, err := er.FindAndCountAll(ctx, queriers...)
must(err)
return entities, count
}
func (er entityRepository[T]) Insert(ctx context.Context, entity *T, mutators ...Mutator) error {
return er.repository.Insert(ctx, entity, mutators...)
}
func (er entityRepository[T]) MustInsert(ctx context.Context, entity *T, mutators ...Mutator) {
er.repository.MustInsert(ctx, entity, mutators...)
}
func (er entityRepository[T]) InsertAll(ctx context.Context, entities *[]T, mutators ...Mutator) error {
return er.repository.InsertAll(ctx, entities, mutators...)
}
func (er entityRepository[T]) MustInsertAll(ctx context.Context, entities *[]T, mutators ...Mutator) {
er.repository.MustInsertAll(ctx, entities, mutators...)
}
func (er entityRepository[T]) Update(ctx context.Context, entity *T, mutators ...Mutator) error {
return er.repository.Update(ctx, entity, mutators...)
}
func (er entityRepository[T]) MustUpdate(ctx context.Context, entity *T, mutators ...Mutator) {
er.repository.MustUpdate(ctx, entity, mutators...)
}
func (er entityRepository[T]) Delete(ctx context.Context, entity *T, mutators ...Mutator) error {
return er.repository.Delete(ctx, entity, mutators...)
}
func (er entityRepository[T]) MustDelete(ctx context.Context, entity *T, mutators ...Mutator) {
er.repository.MustDelete(ctx, entity, mutators...)
}
func (er entityRepository[T]) DeleteAll(ctx context.Context, entities *[]T) error {
return er.repository.DeleteAll(ctx, entities)
}
func (er entityRepository[T]) MustDeleteAll(ctx context.Context, entities *[]T) {
er.repository.MustDeleteAll(ctx, entities)
}
func (er entityRepository[T]) Preload(ctx context.Context, entity *T, field string, queriers ...Querier) error {
return er.repository.Preload(ctx, entity, field, queriers...)
}
func (er entityRepository[T]) MustPreload(ctx context.Context, entity *T, field string, queriers ...Querier) {
er.repository.MustPreload(ctx, entity, field, queriers...)
}
func (er entityRepository[T]) PreloadAll(ctx context.Context, entities *[]T, field string, queriers ...Querier) error {
return er.repository.Preload(ctx, entities, field, queriers...)
}
func (er entityRepository[T]) MustPreloadAll(ctx context.Context, entities *[]T, field string, queriers ...Querier) {
er.repository.MustPreload(ctx, entities, field, queriers...)
}
func (er entityRepository[T]) Transaction(ctx context.Context, fn func(ctx context.Context) error) error {
return er.repository.Transaction(ctx, fn)
}
func NewEntityRepository[T any](repository Repository) EntityRepository[T] {
return entityRepository[T]{
repository: repository,
}
}