diff --git a/pkg/api/org.go b/pkg/api/org.go index 797cf7de76b..2512938837b 100644 --- a/pkg/api/org.go +++ b/pkg/api/org.go @@ -10,7 +10,6 @@ import ( "github.com/grafana/grafana/pkg/api/response" "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" @@ -95,7 +94,7 @@ func (hs *HTTPServer) CreateOrg(c *models.ReqContext) response.Response { } cmd.UserId = c.UserId - if err := sqlstore.CreateOrg(c.Req.Context(), &cmd); err != nil { + if err := hs.SQLStore.CreateOrg(c.Req.Context(), &cmd); err != nil { if errors.Is(err, models.ErrOrgNameTaken) { return response.Error(409, "Organization name taken", err) } diff --git a/pkg/services/provisioning/dashboards/config_reader_test.go b/pkg/services/provisioning/dashboards/config_reader_test.go index 7d04ae7d2d6..899654eda0d 100644 --- a/pkg/services/provisioning/dashboards/config_reader_test.go +++ b/pkg/services/provisioning/dashboards/config_reader_test.go @@ -36,7 +36,7 @@ func TestDashboardsAsConfig(t *testing.T) { for i := 1; i <= 2; i++ { orgCommand := models.CreateOrgCommand{Name: fmt.Sprintf("Main Org. %v", i)} - err := sqlstore.CreateOrg(context.Background(), &orgCommand) + err := store.CreateOrg(context.Background(), &orgCommand) require.NoError(t, err) } diff --git a/pkg/services/provisioning/notifiers/config_reader_test.go b/pkg/services/provisioning/notifiers/config_reader_test.go index c8cae8b6886..8c78a108a37 100644 --- a/pkg/services/provisioning/notifiers/config_reader_test.go +++ b/pkg/services/provisioning/notifiers/config_reader_test.go @@ -39,7 +39,7 @@ func TestNotificationAsConfig(t *testing.T) { for i := 1; i < 5; i++ { orgCommand := models.CreateOrgCommand{Name: fmt.Sprintf("Main Org. %v", i)} - err := sqlstore.CreateOrg(context.Background(), &orgCommand) + err := sqlStore.CreateOrg(context.Background(), &orgCommand) require.NoError(t, err) } diff --git a/pkg/services/serviceaccounts/api/api_test.go b/pkg/services/serviceaccounts/api/api_test.go index c017b3dee0d..b60e5361da7 100644 --- a/pkg/services/serviceaccounts/api/api_test.go +++ b/pkg/services/serviceaccounts/api/api_test.go @@ -42,7 +42,7 @@ func TestServiceAccountsAPI_CreateServiceAccount(t *testing.T) { }() orgCmd := &models.CreateOrgCommand{Name: "Some Test Org"} - err := sqlstore.CreateOrg(context.Background(), orgCmd) + err := store.CreateOrg(context.Background(), orgCmd) require.Nil(t, err) type testCreateSATestCase struct { diff --git a/pkg/services/sqlstore/alert_notification.go b/pkg/services/sqlstore/alert_notification.go index ee780c53a44..24aa1a6aacd 100644 --- a/pkg/services/sqlstore/alert_notification.go +++ b/pkg/services/sqlstore/alert_notification.go @@ -479,7 +479,7 @@ func (ss *SQLStore) UpdateAlertNotificationWithUid(ctx context.Context, cmd *mod } func (ss *SQLStore) SetAlertNotificationStateToCompleteCommand(ctx context.Context, cmd *models.SetAlertNotificationStateToCompleteCommand) error { - return inTransactionCtx(ctx, func(sess *DBSession) error { + return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error { version := cmd.Version var current models.AlertNotificationState if _, err := sess.ID(cmd.Id).Get(¤t); err != nil { @@ -544,7 +544,7 @@ func (ss *SQLStore) SetAlertNotificationStateToPendingCommand(ctx context.Contex } func (ss *SQLStore) GetOrCreateAlertNotificationState(ctx context.Context, cmd *models.GetOrCreateNotificationStateQuery) error { - return inTransactionCtx(ctx, func(sess *DBSession) error { + return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error { nj := &models.AlertNotificationState{} exist, err := getAlertNotificationState(ctx, sess, cmd, nj) diff --git a/pkg/services/sqlstore/annotation.go b/pkg/services/sqlstore/annotation.go index 83f3e0f319f..05da314540d 100644 --- a/pkg/services/sqlstore/annotation.go +++ b/pkg/services/sqlstore/annotation.go @@ -42,7 +42,7 @@ func NewSQLAnnotationRepo(sql *SQLStore) SQLAnnotationRepo { } func (r *SQLAnnotationRepo) Save(item *annotations.Item) error { - return inTransaction(func(sess *DBSession) error { + return r.sql.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error { tags := models.ParseTagPairs(item.Tags) item.Tags = models.JoinTagPairs(tags) item.Created = timeNow().UnixNano() / int64(time.Millisecond) diff --git a/pkg/services/sqlstore/annotation_cleanup.go b/pkg/services/sqlstore/annotation_cleanup.go index 0f9a181777b..24c06071da5 100644 --- a/pkg/services/sqlstore/annotation_cleanup.go +++ b/pkg/services/sqlstore/annotation_cleanup.go @@ -13,6 +13,7 @@ import ( type AnnotationCleanupService struct { batchSize int64 log log.Logger + sqlstore *SQLStore } const ( @@ -92,7 +93,7 @@ func (acs *AnnotationCleanupService) executeUntilDoneOrCancelled(ctx context.Con return totalAffected, ctx.Err() default: var affected int64 - err := withDbSession(ctx, x, func(session *DBSession) error { + err := withDbSession(ctx, acs.sqlstore.engine, func(session *DBSession) error { res, err := session.Exec(sql) if err != nil { return err diff --git a/pkg/services/sqlstore/annotation_cleanup_test.go b/pkg/services/sqlstore/annotation_cleanup_test.go index b98792284c1..e3e0e4efa3d 100644 --- a/pkg/services/sqlstore/annotation_cleanup_test.go +++ b/pkg/services/sqlstore/annotation_cleanup_test.go @@ -87,7 +87,7 @@ func TestAnnotationCleanUp(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - cleaner := &AnnotationCleanupService{batchSize: 1, log: log.New("test-logger")} + cleaner := &AnnotationCleanupService{batchSize: 1, log: log.New("test-logger"), sqlstore: fakeSQL} affectedAnnotations, affectedAnnotationTags, err := cleaner.CleanAnnotations(context.Background(), test.cfg) require.NoError(t, err) @@ -142,7 +142,7 @@ func TestOldAnnotationsAreDeletedFirst(t *testing.T) { require.NoError(t, err, "cannot insert annotation") // run the clean up task to keep one annotation. - cleaner := &AnnotationCleanupService{batchSize: 1, log: log.New("test-logger")} + cleaner := &AnnotationCleanupService{batchSize: 1, log: log.New("test-logger"), sqlstore: fakeSQL} _, err = cleaner.cleanAnnotations(context.Background(), setting.AnnotationCleanupSettings{MaxCount: 1}, alertAnnotationType) require.NoError(t, err) diff --git a/pkg/services/sqlstore/mockstore/mockstore.go b/pkg/services/sqlstore/mockstore/mockstore.go index f8b7deac7bf..6a1c9a56651 100644 --- a/pkg/services/sqlstore/mockstore/mockstore.go +++ b/pkg/services/sqlstore/mockstore/mockstore.go @@ -117,6 +117,9 @@ func (m *SQLStoreMock) GetOrgByNameHandler(ctx context.Context, query *models.Ge func (m *SQLStoreMock) CreateOrgWithMember(name string, userID int64) (models.Org, error) { return *m.ExpectedOrg, nil } +func (m *SQLStoreMock) CreateOrg(ctx context.Context, cmd *models.CreateOrgCommand) error { + return m.ExpectedError +} func (m *SQLStoreMock) UpdateOrg(ctx context.Context, cmd *models.UpdateOrgCommand) error { return m.ExpectedError diff --git a/pkg/services/sqlstore/org.go b/pkg/services/sqlstore/org.go index 1cdd72a938a..af65873fb47 100644 --- a/pkg/services/sqlstore/org.go +++ b/pkg/services/sqlstore/org.go @@ -149,8 +149,8 @@ func (ss *SQLStore) CreateOrgWithMember(name string, userID int64) (models.Org, return createOrg(name, userID, ss.engine) } -func CreateOrg(ctx context.Context, cmd *models.CreateOrgCommand) error { - org, err := createOrg(cmd.Name, cmd.UserId, x) +func (ss *SQLStore) CreateOrg(ctx context.Context, cmd *models.CreateOrgCommand) error { + org, err := createOrg(cmd.Name, cmd.UserId, ss.engine) if err != nil { return err } diff --git a/pkg/services/sqlstore/org_test.go b/pkg/services/sqlstore/org_test.go index a86b268776e..ea002c51de5 100644 --- a/pkg/services/sqlstore/org_test.go +++ b/pkg/services/sqlstore/org_test.go @@ -27,7 +27,7 @@ func TestAccountDataAccess(t *testing.T) { for i := 1; i < 4; i++ { cmd = &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)} - err = CreateOrg(context.Background(), cmd) + err = sqlStore.CreateOrg(context.Background(), cmd) require.NoError(t, err) ids = append(ids, cmd.Result.Id) @@ -44,7 +44,7 @@ func TestAccountDataAccess(t *testing.T) { sqlStore = InitTestDB(t) for i := 1; i < 4; i++ { cmd := &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)} - err := CreateOrg(context.Background(), cmd) + err := sqlStore.CreateOrg(context.Background(), cmd) require.NoError(t, err) } diff --git a/pkg/services/sqlstore/quota_test.go b/pkg/services/sqlstore/quota_test.go index 8358ce2baa2..f6c68284555 100644 --- a/pkg/services/sqlstore/quota_test.go +++ b/pkg/services/sqlstore/quota_test.go @@ -49,7 +49,7 @@ func TestQuotaCommandsAndQueries(t *testing.T) { UserId: 1, } - err := CreateOrg(context.Background(), &userCmd) + err := sqlStore.CreateOrg(context.Background(), &userCmd) require.NoError(t, err) orgId = userCmd.Result.Id diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 7baa450cb99..f4833d90235 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -32,7 +32,6 @@ import ( ) var ( - x *xorm.Engine dialect migrator.Dialect sqlog log.Logger = log.New("sqlstore") @@ -101,13 +100,11 @@ func newSQLStore(cfg *setting.Cfg, cacheService *localcache.CacheService, engine ss.Dialect = migrator.NewDialect(ss.engine) - // temporarily still set global var - x = ss.engine dialect = ss.Dialect // Init repo instances annotations.SetRepository(&SQLAnnotationRepo{sql: ss}) - annotations.SetAnnotationCleaner(&AnnotationCleanupService{batchSize: ss.Cfg.AnnotationCleanupJobBatchSize, log: log.New("annotationcleaner")}) + annotations.SetAnnotationCleaner(&AnnotationCleanupService{batchSize: ss.Cfg.AnnotationCleanupJobBatchSize, log: log.New("annotationcleaner"), sqlstore: ss}) // if err := ss.Reset(); err != nil { // return nil, err diff --git a/pkg/services/sqlstore/store.go b/pkg/services/sqlstore/store.go index 8871a68d8fb..1de411c4bc0 100644 --- a/pkg/services/sqlstore/store.go +++ b/pkg/services/sqlstore/store.go @@ -19,6 +19,7 @@ type Store interface { HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error SearchDashboardSnapshots(ctx context.Context, query *models.GetDashboardSnapshotsQuery) error GetOrgByName(name string) (*models.Org, error) + CreateOrg(ctx context.Context, cmd *models.CreateOrgCommand) error CreateOrgWithMember(name string, userID int64) (models.Org, error) UpdateOrg(ctx context.Context, cmd *models.UpdateOrgCommand) error UpdateOrgAddress(ctx context.Context, cmd *models.UpdateOrgAddressCommand) error diff --git a/pkg/services/sqlstore/team.go b/pkg/services/sqlstore/team.go index d78c1aa873e..d8325604d7f 100644 --- a/pkg/services/sqlstore/team.go +++ b/pkg/services/sqlstore/team.go @@ -351,7 +351,7 @@ func getTeamMember(sess *DBSession, orgId int64, teamId int64, userId int64) (mo // UpdateTeamMember updates a team member func (ss *SQLStore) UpdateTeamMember(ctx context.Context, cmd *models.UpdateTeamMemberCommand) error { - return inTransaction(func(sess *DBSession) error { + return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error { return updateTeamMember(sess, cmd.OrgId, cmd.TeamId, cmd.UserId, cmd.Permission) }) } @@ -437,7 +437,7 @@ func updateTeamMember(sess *DBSession, orgID, teamID, userID int64, permission m // RemoveTeamMember removes a member from a team func (ss *SQLStore) RemoveTeamMember(ctx context.Context, cmd *models.RemoveTeamMemberCommand) error { - return inTransaction(func(sess *DBSession) error { + return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error { return removeTeamMember(sess, cmd) }) } diff --git a/pkg/services/sqlstore/transactions.go b/pkg/services/sqlstore/transactions.go index 7accf1a844c..341427527a7 100644 --- a/pkg/services/sqlstore/transactions.go +++ b/pkg/services/sqlstore/transactions.go @@ -32,8 +32,8 @@ func (ss *SQLStore) inTransactionWithRetry(ctx context.Context, fn func(ctx cont }, retry) } -func inTransactionWithRetry(callback DBTransactionFunc, retry int) error { - return inTransactionWithRetryCtx(context.Background(), x, callback, retry) +func inTransactionWithRetry(callback DBTransactionFunc, engine *xorm.Engine, retry int) error { + return inTransactionWithRetryCtx(context.Background(), engine, callback, retry) } func inTransactionWithRetryCtx(ctx context.Context, engine *xorm.Engine, callback DBTransactionFunc, retry int) error { @@ -68,7 +68,7 @@ func inTransactionWithRetryCtx(ctx context.Context, engine *xorm.Engine, callbac time.Sleep(time.Millisecond * time.Duration(10)) sqlog.Info("Database locked, sleeping then retrying", "error", err, "retry", retry) - return inTransactionWithRetry(callback, retry+1) + return inTransactionWithRetry(callback, engine, retry+1) } if err != nil { @@ -91,11 +91,3 @@ func inTransactionWithRetryCtx(ctx context.Context, engine *xorm.Engine, callbac return nil } - -func inTransaction(callback DBTransactionFunc) error { - return inTransactionWithRetry(callback, 0) -} - -func inTransactionCtx(ctx context.Context, callback DBTransactionFunc) error { - return inTransactionWithRetryCtx(ctx, x, callback, 0) -} diff --git a/pkg/services/sqlstore/user_test.go b/pkg/services/sqlstore/user_test.go index f91e70134ff..bd971fa6f66 100644 --- a/pkg/services/sqlstore/user_test.go +++ b/pkg/services/sqlstore/user_test.go @@ -80,7 +80,7 @@ func TestUserDataAccess(t *testing.T) { }() orgCmd := &models.CreateOrgCommand{Name: "Some Test Org"} - err := CreateOrg(context.Background(), orgCmd) + err := ss.CreateOrg(context.Background(), orgCmd) require.Nil(t, err) cmd := models.CreateUserCommand{