mirror of
https://github.com/rancher/steve.git
synced 2025-09-03 08:25:13 +00:00
sql: use a closure to wrap transactions (#469)
This introduces the a `WithTransaction` function, which is then used for all transactional work in Steve. Because `WithTransaction` takes care of all `Begin`s, `Commit`s and `Rollback`s, it eliminates the problem where forgotten open transactions can block all other operations (with long stalling and `SQLITE_BUSY` errors). This also: - merges together the disparate `DBClient` interfaces in one only `db.Client` interface with one unexported non-test implementation. I found this much easier to follow - refactors the transaction package in order to make it as minimal as possible, and as close to the wrapped `sql.Tx` and `sql.Stmt` functions as possible, in order to reduce cognitive load when working with this part of the codebase - simplifies tests accordingly - adds a couple of known files to `.gitignore` Credits to @tomleb for suggesting the approach: https://github.com/rancher/lasso/pull/121#pullrequestreview-2515872507
This commit is contained in:
@@ -1,125 +1,24 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/rancher/steve/pkg/sqlcache/db (interfaces: TXClient,Rows)
|
||||
// Source: github.com/rancher/steve/pkg/sqlcache/db (interfaces: Rows,Client)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen --build_flags=--mod=mod -package informer -destination ./db_mocks_test.go github.com/rancher/steve/pkg/sqlcache/db TXClient,Rows
|
||||
// mockgen --build_flags=--mod=mod -package informer -destination ./db_mocks_test.go github.com/rancher/steve/pkg/sqlcache/db Rows,Client
|
||||
//
|
||||
|
||||
// Package informer is a generated GoMock package.
|
||||
package informer
|
||||
|
||||
import (
|
||||
context "context"
|
||||
sql "database/sql"
|
||||
reflect "reflect"
|
||||
|
||||
db "github.com/rancher/steve/pkg/sqlcache/db"
|
||||
transaction "github.com/rancher/steve/pkg/sqlcache/db/transaction"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockTXClient is a mock of TXClient interface.
|
||||
type MockTXClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockTXClientMockRecorder
|
||||
}
|
||||
|
||||
// MockTXClientMockRecorder is the mock recorder for MockTXClient.
|
||||
type MockTXClientMockRecorder struct {
|
||||
mock *MockTXClient
|
||||
}
|
||||
|
||||
// NewMockTXClient creates a new mock instance.
|
||||
func NewMockTXClient(ctrl *gomock.Controller) *MockTXClient {
|
||||
mock := &MockTXClient{ctrl: ctrl}
|
||||
mock.recorder = &MockTXClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockTXClient) EXPECT() *MockTXClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Cancel mocks base method.
|
||||
func (m *MockTXClient) Cancel() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Cancel")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Cancel indicates an expected call of Cancel.
|
||||
func (mr *MockTXClientMockRecorder) Cancel() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cancel", reflect.TypeOf((*MockTXClient)(nil).Cancel))
|
||||
}
|
||||
|
||||
// Commit mocks base method.
|
||||
func (m *MockTXClient) Commit() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Commit")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Commit indicates an expected call of Commit.
|
||||
func (mr *MockTXClientMockRecorder) Commit() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockTXClient)(nil).Commit))
|
||||
}
|
||||
|
||||
// Exec mocks base method.
|
||||
func (m *MockTXClient) Exec(arg0 string, arg1 ...any) error {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{arg0}
|
||||
for _, a := range arg1 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "Exec", varargs...)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Exec indicates an expected call of Exec.
|
||||
func (mr *MockTXClientMockRecorder) Exec(arg0 any, arg1 ...any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{arg0}, arg1...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Exec", reflect.TypeOf((*MockTXClient)(nil).Exec), varargs...)
|
||||
}
|
||||
|
||||
// Stmt mocks base method.
|
||||
func (m *MockTXClient) Stmt(arg0 *sql.Stmt) transaction.Stmt {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Stmt", arg0)
|
||||
ret0, _ := ret[0].(transaction.Stmt)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Stmt indicates an expected call of Stmt.
|
||||
func (mr *MockTXClientMockRecorder) Stmt(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stmt", reflect.TypeOf((*MockTXClient)(nil).Stmt), arg0)
|
||||
}
|
||||
|
||||
// StmtExec mocks base method.
|
||||
func (m *MockTXClient) StmtExec(arg0 transaction.Stmt, arg1 ...any) error {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{arg0}
|
||||
for _, a := range arg1 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "StmtExec", varargs...)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// StmtExec indicates an expected call of StmtExec.
|
||||
func (mr *MockTXClientMockRecorder) StmtExec(arg0 any, arg1 ...any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{arg0}, arg1...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StmtExec", reflect.TypeOf((*MockTXClient)(nil).StmtExec), varargs...)
|
||||
}
|
||||
|
||||
// MockRows is a mock of Rows interface.
|
||||
type MockRows struct {
|
||||
ctrl *gomock.Controller
|
||||
@@ -202,3 +101,161 @@ func (mr *MockRowsMockRecorder) Scan(arg0 ...any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scan", reflect.TypeOf((*MockRows)(nil).Scan), arg0...)
|
||||
}
|
||||
|
||||
// MockClient is a mock of Client interface.
|
||||
type MockClient struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockClientMockRecorder
|
||||
}
|
||||
|
||||
// MockClientMockRecorder is the mock recorder for MockClient.
|
||||
type MockClientMockRecorder struct {
|
||||
mock *MockClient
|
||||
}
|
||||
|
||||
// NewMockClient creates a new mock instance.
|
||||
func NewMockClient(ctrl *gomock.Controller) *MockClient {
|
||||
mock := &MockClient{ctrl: ctrl}
|
||||
mock.recorder = &MockClientMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockClient) EXPECT() *MockClientMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CloseStmt mocks base method.
|
||||
func (m *MockClient) CloseStmt(arg0 db.Closable) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CloseStmt", arg0)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CloseStmt indicates an expected call of CloseStmt.
|
||||
func (mr *MockClientMockRecorder) CloseStmt(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseStmt", reflect.TypeOf((*MockClient)(nil).CloseStmt), arg0)
|
||||
}
|
||||
|
||||
// NewConnection mocks base method.
|
||||
func (m *MockClient) NewConnection() error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "NewConnection")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// NewConnection indicates an expected call of NewConnection.
|
||||
func (mr *MockClientMockRecorder) NewConnection() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConnection", reflect.TypeOf((*MockClient)(nil).NewConnection))
|
||||
}
|
||||
|
||||
// Prepare mocks base method.
|
||||
func (m *MockClient) Prepare(arg0 string) *sql.Stmt {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Prepare", arg0)
|
||||
ret0, _ := ret[0].(*sql.Stmt)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Prepare indicates an expected call of Prepare.
|
||||
func (mr *MockClientMockRecorder) Prepare(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Prepare", reflect.TypeOf((*MockClient)(nil).Prepare), arg0)
|
||||
}
|
||||
|
||||
// QueryForRows mocks base method.
|
||||
func (m *MockClient) QueryForRows(arg0 context.Context, arg1 transaction.Stmt, arg2 ...any) (*sql.Rows, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []any{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "QueryForRows", varargs...)
|
||||
ret0, _ := ret[0].(*sql.Rows)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// QueryForRows indicates an expected call of QueryForRows.
|
||||
func (mr *MockClientMockRecorder) QueryForRows(arg0, arg1 any, arg2 ...any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
varargs := append([]any{arg0, arg1}, arg2...)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryForRows", reflect.TypeOf((*MockClient)(nil).QueryForRows), varargs...)
|
||||
}
|
||||
|
||||
// ReadInt mocks base method.
|
||||
func (m *MockClient) ReadInt(arg0 db.Rows) (int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReadInt", arg0)
|
||||
ret0, _ := ret[0].(int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ReadInt indicates an expected call of ReadInt.
|
||||
func (mr *MockClientMockRecorder) ReadInt(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadInt", reflect.TypeOf((*MockClient)(nil).ReadInt), arg0)
|
||||
}
|
||||
|
||||
// ReadObjects mocks base method.
|
||||
func (m *MockClient) ReadObjects(arg0 db.Rows, arg1 reflect.Type, arg2 bool) ([]any, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReadObjects", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]any)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ReadObjects indicates an expected call of ReadObjects.
|
||||
func (mr *MockClientMockRecorder) ReadObjects(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadObjects", reflect.TypeOf((*MockClient)(nil).ReadObjects), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// ReadStrings mocks base method.
|
||||
func (m *MockClient) ReadStrings(arg0 db.Rows) ([]string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ReadStrings", arg0)
|
||||
ret0, _ := ret[0].([]string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ReadStrings indicates an expected call of ReadStrings.
|
||||
func (mr *MockClientMockRecorder) ReadStrings(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadStrings", reflect.TypeOf((*MockClient)(nil).ReadStrings), arg0)
|
||||
}
|
||||
|
||||
// Upsert mocks base method.
|
||||
func (m *MockClient) Upsert(arg0 transaction.Client, arg1 *sql.Stmt, arg2 string, arg3 any, arg4 bool) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Upsert", arg0, arg1, arg2, arg3, arg4)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// Upsert indicates an expected call of Upsert.
|
||||
func (mr *MockClientMockRecorder) Upsert(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Upsert", reflect.TypeOf((*MockClient)(nil).Upsert), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// WithTransaction mocks base method.
|
||||
func (m *MockClient) WithTransaction(arg0 context.Context, arg1 bool, arg2 db.WithTransactionFunction) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "WithTransaction", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// WithTransaction indicates an expected call of WithTransaction.
|
||||
func (mr *MockClientMockRecorder) WithTransaction(arg0, arg1, arg2 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithTransaction", reflect.TypeOf((*MockClient)(nil).WithTransaction), arg0, arg1, arg2)
|
||||
}
|
||||
|
Reference in New Issue
Block a user