at main 6.4 kB view raw
1// Code generated by ent, DO NOT EDIT. 2 3package ent 4 5import ( 6 "context" 7 "sync" 8 9 "entgo.io/ent/dialect" 10) 11 12// Tx is a transactional client that is created by calling Client.Tx(). 13type Tx struct { 14 config 15 // Operation is the client for interacting with the Operation builders. 16 Operation *OperationClient 17 // SyncStatus is the client for interacting with the SyncStatus builders. 18 SyncStatus *SyncStatusClient 19 20 // lazily loaded. 21 client *Client 22 clientOnce sync.Once 23 // ctx lives for the life of the transaction. It is 24 // the same context used by the underlying connection. 25 ctx context.Context 26} 27 28type ( 29 // Committer is the interface that wraps the Commit method. 30 Committer interface { 31 Commit(context.Context, *Tx) error 32 } 33 34 // The CommitFunc type is an adapter to allow the use of ordinary 35 // function as a Committer. If f is a function with the appropriate 36 // signature, CommitFunc(f) is a Committer that calls f. 37 CommitFunc func(context.Context, *Tx) error 38 39 // CommitHook defines the "commit middleware". A function that gets a Committer 40 // and returns a Committer. For example: 41 // 42 // hook := func(next ent.Committer) ent.Committer { 43 // return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error { 44 // // Do some stuff before. 45 // if err := next.Commit(ctx, tx); err != nil { 46 // return err 47 // } 48 // // Do some stuff after. 49 // return nil 50 // }) 51 // } 52 // 53 CommitHook func(Committer) Committer 54) 55 56// Commit calls f(ctx, m). 57func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error { 58 return f(ctx, tx) 59} 60 61// Commit commits the transaction. 62func (tx *Tx) Commit() error { 63 txDriver := tx.config.driver.(*txDriver) 64 var fn Committer = CommitFunc(func(context.Context, *Tx) error { 65 return txDriver.tx.Commit() 66 }) 67 txDriver.mu.Lock() 68 hooks := append([]CommitHook(nil), txDriver.onCommit...) 69 txDriver.mu.Unlock() 70 for i := len(hooks) - 1; i >= 0; i-- { 71 fn = hooks[i](fn) 72 } 73 return fn.Commit(tx.ctx, tx) 74} 75 76// OnCommit adds a hook to call on commit. 77func (tx *Tx) OnCommit(f CommitHook) { 78 txDriver := tx.config.driver.(*txDriver) 79 txDriver.mu.Lock() 80 txDriver.onCommit = append(txDriver.onCommit, f) 81 txDriver.mu.Unlock() 82} 83 84type ( 85 // Rollbacker is the interface that wraps the Rollback method. 86 Rollbacker interface { 87 Rollback(context.Context, *Tx) error 88 } 89 90 // The RollbackFunc type is an adapter to allow the use of ordinary 91 // function as a Rollbacker. If f is a function with the appropriate 92 // signature, RollbackFunc(f) is a Rollbacker that calls f. 93 RollbackFunc func(context.Context, *Tx) error 94 95 // RollbackHook defines the "rollback middleware". A function that gets a Rollbacker 96 // and returns a Rollbacker. For example: 97 // 98 // hook := func(next ent.Rollbacker) ent.Rollbacker { 99 // return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error { 100 // // Do some stuff before. 101 // if err := next.Rollback(ctx, tx); err != nil { 102 // return err 103 // } 104 // // Do some stuff after. 105 // return nil 106 // }) 107 // } 108 // 109 RollbackHook func(Rollbacker) Rollbacker 110) 111 112// Rollback calls f(ctx, m). 113func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error { 114 return f(ctx, tx) 115} 116 117// Rollback rollbacks the transaction. 118func (tx *Tx) Rollback() error { 119 txDriver := tx.config.driver.(*txDriver) 120 var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { 121 return txDriver.tx.Rollback() 122 }) 123 txDriver.mu.Lock() 124 hooks := append([]RollbackHook(nil), txDriver.onRollback...) 125 txDriver.mu.Unlock() 126 for i := len(hooks) - 1; i >= 0; i-- { 127 fn = hooks[i](fn) 128 } 129 return fn.Rollback(tx.ctx, tx) 130} 131 132// OnRollback adds a hook to call on rollback. 133func (tx *Tx) OnRollback(f RollbackHook) { 134 txDriver := tx.config.driver.(*txDriver) 135 txDriver.mu.Lock() 136 txDriver.onRollback = append(txDriver.onRollback, f) 137 txDriver.mu.Unlock() 138} 139 140// Client returns a Client that binds to current transaction. 141func (tx *Tx) Client() *Client { 142 tx.clientOnce.Do(func() { 143 tx.client = &Client{config: tx.config} 144 tx.client.init() 145 }) 146 return tx.client 147} 148 149func (tx *Tx) init() { 150 tx.Operation = NewOperationClient(tx.config) 151 tx.SyncStatus = NewSyncStatusClient(tx.config) 152} 153 154// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. 155// The idea is to support transactions without adding any extra code to the builders. 156// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. 157// Commit and Rollback are nop for the internal builders and the user must call one 158// of them in order to commit or rollback the transaction. 159// 160// If a closed transaction is embedded in one of the generated entities, and the entity 161// applies a query, for example: Operation.QueryXXX(), the query will be executed 162// through the driver which created this transaction. 163// 164// Note that txDriver is not goroutine safe. 165type txDriver struct { 166 // the driver we started the transaction from. 167 drv dialect.Driver 168 // tx is the underlying transaction. 169 tx dialect.Tx 170 // completion hooks. 171 mu sync.Mutex 172 onCommit []CommitHook 173 onRollback []RollbackHook 174} 175 176// newTx creates a new transactional driver. 177func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { 178 tx, err := drv.Tx(ctx) 179 if err != nil { 180 return nil, err 181 } 182 return &txDriver{tx: tx, drv: drv}, nil 183} 184 185// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls 186// from the internal builders. Should be called only by the internal builders. 187func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } 188 189// Dialect returns the dialect of the driver we started the transaction from. 190func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } 191 192// Close is a nop close. 193func (*txDriver) Close() error { return nil } 194 195// Commit is a nop commit for the internal builders. 196// User must call `Tx.Commit` in order to commit the transaction. 197func (*txDriver) Commit() error { return nil } 198 199// Rollback is a nop rollback for the internal builders. 200// User must call `Tx.Rollback` in order to rollback the transaction. 201func (*txDriver) Rollback() error { return nil } 202 203// Exec calls tx.Exec. 204func (tx *txDriver) Exec(ctx context.Context, query string, args, v any) error { 205 return tx.tx.Exec(ctx, query, args, v) 206} 207 208// Query calls tx.Query. 209func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error { 210 return tx.tx.Query(ctx, query, args, v) 211} 212 213var _ dialect.Driver = (*txDriver)(nil)