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