add sqlx_store into star service (#53430)

This commit is contained in:
ying-jeanne 2022-08-17 11:17:23 -05:00 committed by GitHub
parent 6d69d7acb8
commit c7212643c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 208 additions and 74 deletions

View File

@ -33,7 +33,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
setup := func() {
sqlStore = sqlstore.InitTestDB(t)
starService = starimpl.ProvideService(sqlStore)
starService = starimpl.ProvideService(sqlStore, sqlStore.Cfg)
dashboardStore = ProvideDashboardStore(sqlStore, testFeatureToggles)
savedFolder = insertTestDashboard(t, dashboardStore, "1 test dash folder", 1, 0, true, "prod", "webapp")
savedDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, savedFolder.Id, false, "prod", "webapp")

View File

@ -11,6 +11,7 @@ import (
type Session interface {
Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error
Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
NamedExec(ctx context.Context, query string, arg interface{}) (sql.Result, error)
}
type SessionDB struct {
@ -33,6 +34,10 @@ func (gs *SessionDB) Exec(ctx context.Context, query string, args ...interface{}
return gs.sqlxdb.ExecContext(ctx, gs.sqlxdb.Rebind(query), args...)
}
func (gs *SessionDB) NamedExec(ctx context.Context, query string, arg interface{}) (sql.Result, error) {
return gs.sqlxdb.NamedExecContext(ctx, gs.sqlxdb.Rebind(query), arg)
}
func (gs *SessionDB) driverName() string {
return gs.sqlxdb.DriverName()
}

View File

@ -5,9 +5,9 @@ import "errors"
var ErrCommandValidationFailed = errors.New("command missing required fields")
type Star struct {
ID int64 `xorm:"pk autoincr 'id'"`
UserID int64 `xorm:"user_id"`
DashboardID int64 `xorm:"dashboard_id"`
ID int64 `xorm:"pk autoincr 'id'" db:"id"`
UserID int64 `xorm:"user_id" db:"user_id"`
DashboardID int64 `xorm:"dashboard_id" db:"dashboard_id"`
}
// ----------------------

View File

@ -0,0 +1,62 @@
package starimpl
import (
"context"
"database/sql"
"errors"
"github.com/grafana/grafana/pkg/services/sqlstore/session"
"github.com/grafana/grafana/pkg/services/star"
)
type sqlxStore struct {
sess *session.SessionDB
}
func (s *sqlxStore) Get(ctx context.Context, query *star.IsStarredByUserQuery) (bool, error) {
var star_res star.Star
err := s.sess.Get(ctx, &star_res, "SELECT * from star where user_id=? and dashboard_id=?", query.UserID, query.DashboardID)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, nil
}
return false, err
}
return true, nil
}
func (s *sqlxStore) Insert(ctx context.Context, cmd *star.StarDashboardCommand) error {
entity := star.Star{
UserID: cmd.UserID,
DashboardID: cmd.DashboardID,
}
_, err := s.sess.NamedExec(ctx, `INSERT INTO star (user_id, dashboard_id) VALUES (:user_id, :dashboard_id)`, entity)
if err != nil {
return err
}
return err
}
func (s *sqlxStore) Delete(ctx context.Context, cmd *star.UnstarDashboardCommand) error {
_, err := s.sess.Exec(ctx, "DELETE FROM star WHERE user_id=? and dashboard_id=?", cmd.UserID, cmd.DashboardID)
return err
}
func (s *sqlxStore) DeleteByUser(ctx context.Context, userID int64) error {
_, err := s.sess.Exec(ctx, "DELETE FROM star WHERE user_id = ?", userID)
return err
}
func (s *sqlxStore) List(ctx context.Context, query *star.GetUserStarsQuery) (*star.GetUserStarsResult, error) {
userStars := make(map[int64]bool)
var stars = make([]star.Star, 0)
err := s.sess.Select(ctx, &stars, "SELECT * FROM star WHERE user_id=?", query.UserID)
if err != nil {
return nil, err
}
for _, star := range stars {
userStars[star.DashboardID] = true
}
return &star.GetUserStarsResult{UserStars: userStars}, err
}

View File

@ -0,0 +1,13 @@
package starimpl
import (
"testing"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
func TestIntegrationSQLxUserStarsDataAccess(t *testing.T) {
testIntegrationUserStarsDataAccess(t, func(ss *sqlstore.SQLStore) store {
return &sqlxStore{sess: ss.GetSqlxSession()}
})
}

View File

@ -5,13 +5,21 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/setting"
)
type Service struct {
store store
}
func ProvideService(db db.DB) star.Service {
func ProvideService(db db.DB, cfg *setting.Cfg) star.Service {
if cfg.IsFeatureToggleEnabled("newDBLibrary") {
return &Service{
store: &sqlxStore{
sess: db.GetSqlxSession(),
},
}
}
return &Service{
store: &sqlStore{
db: db,

View File

@ -3,8 +3,6 @@ package starimpl
import (
"context"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/star"
)
@ -15,64 +13,3 @@ type store interface {
DeleteByUser(context.Context, int64) error
List(context.Context, *star.GetUserStarsQuery) (*star.GetUserStarsResult, error)
}
type sqlStore struct {
db db.DB
}
func (s *sqlStore) Get(ctx context.Context, query *star.IsStarredByUserQuery) (bool, error) {
var isStarred bool
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := "SELECT 1 from star where user_id=? and dashboard_id=?"
results, err := sess.Query(rawSQL, query.UserID, query.DashboardID)
if err != nil {
return err
}
isStarred = len(results) != 0
return nil
})
return isStarred, err
}
func (s *sqlStore) Insert(ctx context.Context, cmd *star.StarDashboardCommand) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
entity := star.Star{
UserID: cmd.UserID,
DashboardID: cmd.DashboardID,
}
_, err := sess.Insert(&entity)
return err
})
}
func (s *sqlStore) Delete(ctx context.Context, cmd *star.UnstarDashboardCommand) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var rawSQL = "DELETE FROM star WHERE user_id=? and dashboard_id=?"
_, err := sess.Exec(rawSQL, cmd.UserID, cmd.DashboardID)
return err
})
}
func (s *sqlStore) DeleteByUser(ctx context.Context, userID int64) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var rawSQL = "DELETE FROM star WHERE user_id = ?"
_, err := sess.Exec(rawSQL, userID)
return err
})
}
func (s *sqlStore) List(ctx context.Context, query *star.GetUserStarsQuery) (*star.GetUserStarsResult, error) {
userStars := make(map[int64]bool)
err := s.db.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
var stars = make([]star.Star, 0)
err := dbSession.Where("user_id=?", query.UserID).Find(&stars)
for _, star := range stars {
userStars[star.DashboardID] = true
}
return err
})
return &star.GetUserStarsResult{UserStars: userStars}, err
}

View File

@ -9,13 +9,15 @@ import (
"github.com/stretchr/testify/require"
)
func TestIntegrationUserStarsDataAccess(t *testing.T) {
type getStore func(*sqlstore.SQLStore) store
func testIntegrationUserStarsDataAccess(t *testing.T, fn getStore) {
if testing.Short() {
t.Skip("skipping integration test")
}
t.Run("Testing User Stars Data Access", func(t *testing.T) {
ss := sqlstore.InitTestDB(t)
starStore := sqlStore{db: ss}
starStore := fn(ss)
t.Run("Given saved star", func(t *testing.T) {
cmd := star.StarDashboardCommand{
@ -25,14 +27,14 @@ func TestIntegrationUserStarsDataAccess(t *testing.T) {
err := starStore.Insert(context.Background(), &cmd)
require.NoError(t, err)
t.Run("IsStarredByUser should return true when starred", func(t *testing.T) {
t.Run("Get should return true when starred", func(t *testing.T) {
query := star.IsStarredByUserQuery{UserID: 12, DashboardID: 10}
isStarred, err := starStore.Get(context.Background(), &query)
require.NoError(t, err)
require.True(t, isStarred)
})
t.Run("IsStarredByUser should return false when not starred", func(t *testing.T) {
t.Run("Get should return false when not starred", func(t *testing.T) {
query := star.IsStarredByUserQuery{UserID: 12, DashboardID: 12}
isStarred, err := starStore.Get(context.Background(), &query)
require.NoError(t, err)
@ -57,9 +59,33 @@ func TestIntegrationUserStarsDataAccess(t *testing.T) {
})
})
t.Run("delete by user", func(t *testing.T) {
err := starStore.DeleteByUser(context.Background(), 1)
t.Run("DeleteByUser should remove the star for user", func(t *testing.T) {
star1 := star.StarDashboardCommand{
DashboardID: 10,
UserID: 12,
}
err := starStore.Insert(context.Background(), &star1)
require.NoError(t, err)
star2 := star.StarDashboardCommand{
DashboardID: 11,
UserID: 12,
}
err = starStore.Insert(context.Background(), &star2)
require.NoError(t, err)
star3 := star.StarDashboardCommand{
DashboardID: 11,
UserID: 11,
}
err = starStore.Insert(context.Background(), &star3)
require.NoError(t, err)
err = starStore.DeleteByUser(context.Background(), 12)
require.NoError(t, err)
res, err := starStore.List(context.Background(), &star.GetUserStarsQuery{UserID: 12})
require.NoError(t, err)
require.Equal(t, 0, len(res.UserStars))
res, err = starStore.List(context.Background(), &star.GetUserStarsQuery{UserID: 11})
require.NoError(t, err)
require.Equal(t, 1, len(res.UserStars))
})
})
}

View File

@ -0,0 +1,70 @@
package starimpl
import (
"context"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/star"
)
type sqlStore struct {
db db.DB
}
func (s *sqlStore) Get(ctx context.Context, query *star.IsStarredByUserQuery) (bool, error) {
var isStarred bool
err := s.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
rawSQL := "SELECT 1 from star where user_id=? and dashboard_id=?"
results, err := sess.Query(rawSQL, query.UserID, query.DashboardID)
if err != nil {
return err
}
isStarred = len(results) != 0
return nil
})
return isStarred, err
}
func (s *sqlStore) Insert(ctx context.Context, cmd *star.StarDashboardCommand) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
entity := star.Star{
UserID: cmd.UserID,
DashboardID: cmd.DashboardID,
}
_, err := sess.Insert(&entity)
return err
})
}
func (s *sqlStore) Delete(ctx context.Context, cmd *star.UnstarDashboardCommand) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var rawSQL = "DELETE FROM star WHERE user_id=? and dashboard_id=?"
_, err := sess.Exec(rawSQL, cmd.UserID, cmd.DashboardID)
return err
})
}
func (s *sqlStore) DeleteByUser(ctx context.Context, userID int64) error {
return s.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var rawSQL = "DELETE FROM star WHERE user_id = ?"
_, err := sess.Exec(rawSQL, userID)
return err
})
}
func (s *sqlStore) List(ctx context.Context, query *star.GetUserStarsQuery) (*star.GetUserStarsResult, error) {
userStars := make(map[int64]bool)
err := s.db.WithDbSession(ctx, func(dbSession *sqlstore.DBSession) error {
var stars = make([]star.Star, 0)
err := dbSession.Where("user_id=?", query.UserID).Find(&stars)
for _, star := range stars {
userStars[star.DashboardID] = true
}
return err
})
return &star.GetUserStarsResult{UserStars: userStars}, err
}

View File

@ -0,0 +1,13 @@
package starimpl
import (
"testing"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
func TestIntegrationXormUserStarsDataAccess(t *testing.T) {
testIntegrationUserStarsDataAccess(t, func(ss *sqlstore.SQLStore) store {
return &sqlStore{db: ss}
})
}