package cabana import ( "context" "gorm.io/gorm" ) type txContextKey struct{} // withTx returns ctx carrying the transaction a write is running in. func withTx(ctx context.Context, tx *gorm.DB) context.Context { if tx == nil { return ctx } return context.WithValue(ctx, txContextKey{}, tx) } // TxFromContext returns the database transaction a write route is running in, // for the context handed to a lifecycle hook (pact.FormBeforeCreate and the // other Form and Relation hooks) or a scope (pact.FormExtendQuery) that runs // inside it. A hook that has to read the database should use this handle // instead of the application pool: it then sees the same snapshot as the write // and does not take a second connection while the transaction holds row locks. // The handle is valid only until the hook returns. The second result is false // on routes that do not run in a transaction, such as the list. func TxFromContext(ctx context.Context) (*gorm.DB, bool) { if ctx == nil { return nil, false } tx, ok := ctx.Value(txContextKey{}).(*gorm.DB) return tx, ok && tx != nil }