generated from datumforge/go-template
-
Notifications
You must be signed in to change notification settings - Fork 5
/
tx.go
342 lines (313 loc) · 13.5 KB
/
tx.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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
// Code generated by ent, DO NOT EDIT.
package generated
import (
"context"
"sync"
"entgo.io/ent/dialect"
)
// Tx is a transactional client that is created by calling Client.Tx().
type Tx struct {
config
// APIToken is the client for interacting with the APIToken builders.
APIToken *APITokenClient
// DocumentData is the client for interacting with the DocumentData builders.
DocumentData *DocumentDataClient
// DocumentDataHistory is the client for interacting with the DocumentDataHistory builders.
DocumentDataHistory *DocumentDataHistoryClient
// EmailVerificationToken is the client for interacting with the EmailVerificationToken builders.
EmailVerificationToken *EmailVerificationTokenClient
// Entitlement is the client for interacting with the Entitlement builders.
Entitlement *EntitlementClient
// EntitlementHistory is the client for interacting with the EntitlementHistory builders.
EntitlementHistory *EntitlementHistoryClient
// Event is the client for interacting with the Event builders.
Event *EventClient
// EventHistory is the client for interacting with the EventHistory builders.
EventHistory *EventHistoryClient
// Feature is the client for interacting with the Feature builders.
Feature *FeatureClient
// FeatureHistory is the client for interacting with the FeatureHistory builders.
FeatureHistory *FeatureHistoryClient
// File is the client for interacting with the File builders.
File *FileClient
// FileHistory is the client for interacting with the FileHistory builders.
FileHistory *FileHistoryClient
// Group is the client for interacting with the Group builders.
Group *GroupClient
// GroupHistory is the client for interacting with the GroupHistory builders.
GroupHistory *GroupHistoryClient
// GroupMembership is the client for interacting with the GroupMembership builders.
GroupMembership *GroupMembershipClient
// GroupMembershipHistory is the client for interacting with the GroupMembershipHistory builders.
GroupMembershipHistory *GroupMembershipHistoryClient
// GroupSetting is the client for interacting with the GroupSetting builders.
GroupSetting *GroupSettingClient
// GroupSettingHistory is the client for interacting with the GroupSettingHistory builders.
GroupSettingHistory *GroupSettingHistoryClient
// Hush is the client for interacting with the Hush builders.
Hush *HushClient
// HushHistory is the client for interacting with the HushHistory builders.
HushHistory *HushHistoryClient
// Integration is the client for interacting with the Integration builders.
Integration *IntegrationClient
// IntegrationHistory is the client for interacting with the IntegrationHistory builders.
IntegrationHistory *IntegrationHistoryClient
// Invite is the client for interacting with the Invite builders.
Invite *InviteClient
// OauthProvider is the client for interacting with the OauthProvider builders.
OauthProvider *OauthProviderClient
// OauthProviderHistory is the client for interacting with the OauthProviderHistory builders.
OauthProviderHistory *OauthProviderHistoryClient
// OhAuthTooToken is the client for interacting with the OhAuthTooToken builders.
OhAuthTooToken *OhAuthTooTokenClient
// OrgMembership is the client for interacting with the OrgMembership builders.
OrgMembership *OrgMembershipClient
// OrgMembershipHistory is the client for interacting with the OrgMembershipHistory builders.
OrgMembershipHistory *OrgMembershipHistoryClient
// Organization is the client for interacting with the Organization builders.
Organization *OrganizationClient
// OrganizationHistory is the client for interacting with the OrganizationHistory builders.
OrganizationHistory *OrganizationHistoryClient
// OrganizationSetting is the client for interacting with the OrganizationSetting builders.
OrganizationSetting *OrganizationSettingClient
// OrganizationSettingHistory is the client for interacting with the OrganizationSettingHistory builders.
OrganizationSettingHistory *OrganizationSettingHistoryClient
// PasswordResetToken is the client for interacting with the PasswordResetToken builders.
PasswordResetToken *PasswordResetTokenClient
// PersonalAccessToken is the client for interacting with the PersonalAccessToken builders.
PersonalAccessToken *PersonalAccessTokenClient
// Subscriber is the client for interacting with the Subscriber builders.
Subscriber *SubscriberClient
// TFASetting is the client for interacting with the TFASetting builders.
TFASetting *TFASettingClient
// Template is the client for interacting with the Template builders.
Template *TemplateClient
// TemplateHistory is the client for interacting with the TemplateHistory builders.
TemplateHistory *TemplateHistoryClient
// User is the client for interacting with the User builders.
User *UserClient
// UserHistory is the client for interacting with the UserHistory builders.
UserHistory *UserHistoryClient
// UserSetting is the client for interacting with the UserSetting builders.
UserSetting *UserSettingClient
// UserSettingHistory is the client for interacting with the UserSettingHistory builders.
UserSettingHistory *UserSettingHistoryClient
// Webauthn is the client for interacting with the Webauthn builders.
Webauthn *WebauthnClient
// Webhook is the client for interacting with the Webhook builders.
Webhook *WebhookClient
// WebhookHistory is the client for interacting with the WebhookHistory builders.
WebhookHistory *WebhookHistoryClient
// lazily loaded.
client *Client
clientOnce sync.Once
// ctx lives for the life of the transaction. It is
// the same context used by the underlying connection.
ctx context.Context
}
type (
// Committer is the interface that wraps the Commit method.
Committer interface {
Commit(context.Context, *Tx) error
}
// The CommitFunc type is an adapter to allow the use of ordinary
// function as a Committer. If f is a function with the appropriate
// signature, CommitFunc(f) is a Committer that calls f.
CommitFunc func(context.Context, *Tx) error
// CommitHook defines the "commit middleware". A function that gets a Committer
// and returns a Committer. For example:
//
// hook := func(next ent.Committer) ent.Committer {
// return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error {
// // Do some stuff before.
// if err := next.Commit(ctx, tx); err != nil {
// return err
// }
// // Do some stuff after.
// return nil
// })
// }
//
CommitHook func(Committer) Committer
)
// Commit calls f(ctx, m).
func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error {
return f(ctx, tx)
}
// Commit commits the transaction.
func (tx *Tx) Commit() error {
txDriver := tx.config.driver.(*txDriver)
var fn Committer = CommitFunc(func(context.Context, *Tx) error {
return txDriver.tx.Commit()
})
txDriver.mu.Lock()
hooks := append([]CommitHook(nil), txDriver.onCommit...)
txDriver.mu.Unlock()
for i := len(hooks) - 1; i >= 0; i-- {
fn = hooks[i](fn)
}
return fn.Commit(tx.ctx, tx)
}
// OnCommit adds a hook to call on commit.
func (tx *Tx) OnCommit(f CommitHook) {
txDriver := tx.config.driver.(*txDriver)
txDriver.mu.Lock()
txDriver.onCommit = append(txDriver.onCommit, f)
txDriver.mu.Unlock()
}
type (
// Rollbacker is the interface that wraps the Rollback method.
Rollbacker interface {
Rollback(context.Context, *Tx) error
}
// The RollbackFunc type is an adapter to allow the use of ordinary
// function as a Rollbacker. If f is a function with the appropriate
// signature, RollbackFunc(f) is a Rollbacker that calls f.
RollbackFunc func(context.Context, *Tx) error
// RollbackHook defines the "rollback middleware". A function that gets a Rollbacker
// and returns a Rollbacker. For example:
//
// hook := func(next ent.Rollbacker) ent.Rollbacker {
// return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error {
// // Do some stuff before.
// if err := next.Rollback(ctx, tx); err != nil {
// return err
// }
// // Do some stuff after.
// return nil
// })
// }
//
RollbackHook func(Rollbacker) Rollbacker
)
// Rollback calls f(ctx, m).
func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error {
return f(ctx, tx)
}
// Rollback rollbacks the transaction.
func (tx *Tx) Rollback() error {
txDriver := tx.config.driver.(*txDriver)
var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error {
return txDriver.tx.Rollback()
})
txDriver.mu.Lock()
hooks := append([]RollbackHook(nil), txDriver.onRollback...)
txDriver.mu.Unlock()
for i := len(hooks) - 1; i >= 0; i-- {
fn = hooks[i](fn)
}
return fn.Rollback(tx.ctx, tx)
}
// OnRollback adds a hook to call on rollback.
func (tx *Tx) OnRollback(f RollbackHook) {
txDriver := tx.config.driver.(*txDriver)
txDriver.mu.Lock()
txDriver.onRollback = append(txDriver.onRollback, f)
txDriver.mu.Unlock()
}
// Client returns a Client that binds to current transaction.
func (tx *Tx) Client() *Client {
tx.clientOnce.Do(func() {
tx.client = &Client{config: tx.config}
tx.client.init()
})
return tx.client
}
func (tx *Tx) init() {
tx.APIToken = NewAPITokenClient(tx.config)
tx.DocumentData = NewDocumentDataClient(tx.config)
tx.DocumentDataHistory = NewDocumentDataHistoryClient(tx.config)
tx.EmailVerificationToken = NewEmailVerificationTokenClient(tx.config)
tx.Entitlement = NewEntitlementClient(tx.config)
tx.EntitlementHistory = NewEntitlementHistoryClient(tx.config)
tx.Event = NewEventClient(tx.config)
tx.EventHistory = NewEventHistoryClient(tx.config)
tx.Feature = NewFeatureClient(tx.config)
tx.FeatureHistory = NewFeatureHistoryClient(tx.config)
tx.File = NewFileClient(tx.config)
tx.FileHistory = NewFileHistoryClient(tx.config)
tx.Group = NewGroupClient(tx.config)
tx.GroupHistory = NewGroupHistoryClient(tx.config)
tx.GroupMembership = NewGroupMembershipClient(tx.config)
tx.GroupMembershipHistory = NewGroupMembershipHistoryClient(tx.config)
tx.GroupSetting = NewGroupSettingClient(tx.config)
tx.GroupSettingHistory = NewGroupSettingHistoryClient(tx.config)
tx.Hush = NewHushClient(tx.config)
tx.HushHistory = NewHushHistoryClient(tx.config)
tx.Integration = NewIntegrationClient(tx.config)
tx.IntegrationHistory = NewIntegrationHistoryClient(tx.config)
tx.Invite = NewInviteClient(tx.config)
tx.OauthProvider = NewOauthProviderClient(tx.config)
tx.OauthProviderHistory = NewOauthProviderHistoryClient(tx.config)
tx.OhAuthTooToken = NewOhAuthTooTokenClient(tx.config)
tx.OrgMembership = NewOrgMembershipClient(tx.config)
tx.OrgMembershipHistory = NewOrgMembershipHistoryClient(tx.config)
tx.Organization = NewOrganizationClient(tx.config)
tx.OrganizationHistory = NewOrganizationHistoryClient(tx.config)
tx.OrganizationSetting = NewOrganizationSettingClient(tx.config)
tx.OrganizationSettingHistory = NewOrganizationSettingHistoryClient(tx.config)
tx.PasswordResetToken = NewPasswordResetTokenClient(tx.config)
tx.PersonalAccessToken = NewPersonalAccessTokenClient(tx.config)
tx.Subscriber = NewSubscriberClient(tx.config)
tx.TFASetting = NewTFASettingClient(tx.config)
tx.Template = NewTemplateClient(tx.config)
tx.TemplateHistory = NewTemplateHistoryClient(tx.config)
tx.User = NewUserClient(tx.config)
tx.UserHistory = NewUserHistoryClient(tx.config)
tx.UserSetting = NewUserSettingClient(tx.config)
tx.UserSettingHistory = NewUserSettingHistoryClient(tx.config)
tx.Webauthn = NewWebauthnClient(tx.config)
tx.Webhook = NewWebhookClient(tx.config)
tx.WebhookHistory = NewWebhookHistoryClient(tx.config)
}
// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation.
// The idea is to support transactions without adding any extra code to the builders.
// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance.
// Commit and Rollback are nop for the internal builders and the user must call one
// of them in order to commit or rollback the transaction.
//
// If a closed transaction is embedded in one of the generated entities, and the entity
// applies a query, for example: APIToken.QueryXXX(), the query will be executed
// through the driver which created this transaction.
//
// Note that txDriver is not goroutine safe.
type txDriver struct {
// the driver we started the transaction from.
drv dialect.Driver
// tx is the underlying transaction.
tx dialect.Tx
// completion hooks.
mu sync.Mutex
onCommit []CommitHook
onRollback []RollbackHook
}
// newTx creates a new transactional driver.
func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) {
tx, err := drv.Tx(ctx)
if err != nil {
return nil, err
}
return &txDriver{tx: tx, drv: drv}, nil
}
// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls
// from the internal builders. Should be called only by the internal builders.
func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil }
// Dialect returns the dialect of the driver we started the transaction from.
func (tx *txDriver) Dialect() string { return tx.drv.Dialect() }
// Close is a nop close.
func (*txDriver) Close() error { return nil }
// Commit is a nop commit for the internal builders.
// User must call `Tx.Commit` in order to commit the transaction.
func (*txDriver) Commit() error { return nil }
// Rollback is a nop rollback for the internal builders.
// User must call `Tx.Rollback` in order to rollback the transaction.
func (*txDriver) Rollback() error { return nil }
// Exec calls tx.Exec.
func (tx *txDriver) Exec(ctx context.Context, query string, args, v any) error {
return tx.tx.Exec(ctx, query, args, v)
}
// Query calls tx.Query.
func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error {
return tx.tx.Query(ctx, query, args, v)
}
var _ dialect.Driver = (*txDriver)(nil)