@ -8,6 +8,7 @@ import (
"xorm.io/xorm"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
@ -15,8 +16,6 @@ import (
"github.com/grafana/grafana/pkg/services/dashboards"
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/sqlstore/permissions"
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
@ -27,18 +26,24 @@ import (
)
type DashboardStore struct {
sqlS tore db . DB
store db . DB
cfg * setting . Cfg
log log . Logger
features featuremgmt . FeatureToggles
tagService tag . Service
}
type DashboardTag struct {
Id int64
DashboardId int64
Term string
}
// DashboardStore implements the Store interface
var _ dashboards . Store = ( * DashboardStore ) ( nil )
func ProvideDashboardStore ( sqlStore db . DB , cfg * setting . Cfg , features featuremgmt . FeatureToggles , tagService tag . Service ) * DashboardStore {
return & DashboardStore { sqlStore : sqlStore , cfg : cfg , log : log . New ( "dashboard-store" ) , features : features , tagService : tagService }
return & DashboardStore { store : sqlStore , cfg : cfg , log : log . New ( "dashboard-store" ) , features : features , tagService : tagService }
}
func ( d * DashboardStore ) emitEntityEvent ( ) bool {
@ -47,14 +52,14 @@ func (d *DashboardStore) emitEntityEvent() bool {
func ( d * DashboardStore ) ValidateDashboardBeforeSave ( ctx context . Context , dashboard * models . Dashboard , overwrite bool ) ( bool , error ) {
isParentFolderChanged := false
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
var err error
isParentFolderChanged , err = getExistingDashboardByIdOrUidForUpdate ( sess , dashboard , d . sqlS tore . GetDialect ( ) , overwrite )
isParentFolderChanged , err = getExistingDashboardByIdOrUidForUpdate ( sess , dashboard , d . store . GetDialect ( ) , overwrite )
if err != nil {
return err
}
isParentFolderChanged , err = getExistingDashboardByTitleAndFolder ( sess , dashboard , d . sqlS tore . GetDialect ( ) , overwrite ,
isParentFolderChanged , err = getExistingDashboardByTitleAndFolder ( sess , dashboard , d . store . GetDialect ( ) , overwrite ,
isParentFolderChanged )
if err != nil {
return err
@ -77,8 +82,8 @@ func (d *DashboardStore) GetFolderByTitle(ctx context.Context, orgID int64, titl
// there is a unique constraint on org_id, folder_id, title
// there are no nested folders so the parent folder id is always 0
dashboard := models . Dashboard { OrgId : orgID , FolderId : 0 , Title : title }
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . sqlS tore . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . store . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
if err != nil {
return err
}
@ -94,8 +99,8 @@ func (d *DashboardStore) GetFolderByTitle(ctx context.Context, orgID int64, titl
func ( d * DashboardStore ) GetFolderByID ( ctx context . Context , orgID int64 , id int64 ) ( * models . Folder , error ) {
dashboard := models . Dashboard { OrgId : orgID , FolderId : 0 , Id : id }
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . sqlS tore . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . store . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
if err != nil {
return err
}
@ -118,8 +123,8 @@ func (d *DashboardStore) GetFolderByUID(ctx context.Context, orgID int64, uid st
}
dashboard := models . Dashboard { OrgId : orgID , FolderId : 0 , Uid : uid }
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . sqlS tore . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
has , err := sess . Table ( & models . Dashboard { } ) . Where ( "is_folder = " + d . store . GetDialect ( ) . BooleanStr ( true ) ) . Where ( "folder_id=0" ) . Get ( & dashboard )
if err != nil {
return err
}
@ -138,7 +143,7 @@ func (d *DashboardStore) GetFolderByUID(ctx context.Context, orgID int64, uid st
func ( d * DashboardStore ) GetProvisionedDataByDashboardID ( ctx context . Context , dashboardID int64 ) ( * models . DashboardProvisioning , error ) {
var data models . DashboardProvisioning
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
_ , err := sess . Where ( "dashboard_id = ?" , dashboardID ) . Get ( & data )
return err
} )
@ -151,7 +156,7 @@ func (d *DashboardStore) GetProvisionedDataByDashboardID(ctx context.Context, da
func ( d * DashboardStore ) GetProvisionedDataByDashboardUID ( ctx context . Context , orgID int64 , dashboardUID string ) ( * models . DashboardProvisioning , error ) {
var provisionedDashboard models . DashboardProvisioning
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
var dashboard models . Dashboard
exists , err := sess . Where ( "org_id = ? AND uid = ?" , orgID , dashboardUID ) . Get ( & dashboard )
if err != nil {
@ -174,14 +179,14 @@ func (d *DashboardStore) GetProvisionedDataByDashboardUID(ctx context.Context, o
func ( d * DashboardStore ) GetProvisionedDashboardData ( ctx context . Context , name string ) ( [ ] * models . DashboardProvisioning , error ) {
var result [ ] * models . DashboardProvisioning
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
return sess . Where ( "name = ?" , name ) . Find ( & result )
} )
return result , err
}
func ( d * DashboardStore ) SaveProvisionedDashboard ( ctx context . Context , cmd models . SaveDashboardCommand , provisioning * models . DashboardProvisioning ) ( * models . Dashboard , error ) {
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
if err := saveDashboard ( sess , & cmd , d . emitEntityEvent ( ) ) ; err != nil {
return err
}
@ -197,14 +202,14 @@ func (d *DashboardStore) SaveProvisionedDashboard(ctx context.Context, cmd model
}
func ( d * DashboardStore ) SaveDashboard ( ctx context . Context , cmd models . SaveDashboardCommand ) ( * models . Dashboard , error ) {
err := d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
return saveDashboard ( sess , & cmd , d . emitEntityEvent ( ) )
} )
return cmd . Result , err
}
func ( d * DashboardStore ) UpdateDashboardACL ( ctx context . Context , dashboardID int64 , items [ ] * models . DashboardACL ) error {
return d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
// delete existing items
_ , err := sess . Exec ( "DELETE FROM dashboard_acl WHERE dashboard_id=?" , dashboardID )
if err != nil {
@ -234,7 +239,7 @@ func (d *DashboardStore) UpdateDashboardACL(ctx context.Context, dashboardID int
}
func ( d * DashboardStore ) SaveAlerts ( ctx context . Context , dashID int64 , alerts [ ] * models . Alert ) error {
return d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
existingAlerts , err := GetAlertsByDashboardId2 ( dashID , sess )
if err != nil {
return err
@ -255,14 +260,14 @@ func (d *DashboardStore) SaveAlerts(ctx context.Context, dashID int64, alerts []
// UnprovisionDashboard removes row in dashboard_provisioning for the dashboard making it seem as if manually created.
// The dashboard will still have `created_by = -1` to see it was not created by any particular user.
func ( d * DashboardStore ) UnprovisionDashboard ( ctx context . Context , id int64 ) error {
return d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
_ , err := sess . Where ( "dashboard_id = ?" , id ) . Delete ( & models . DashboardProvisioning { } )
return err
} )
}
func ( d * DashboardStore ) DeleteOrphanedProvisionedDashboards ( ctx context . Context , cmd * models . DeleteOrphanedProvisionedDashboardsCommand ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
var result [ ] * models . DashboardProvisioning
convertedReaderNames := make ( [ ] interface { } , len ( cmd . ReaderNames ) )
@ -286,7 +291,7 @@ func (d *DashboardStore) DeleteOrphanedProvisionedDashboards(ctx context.Context
} )
}
func getExistingDashboardByIdOrUidForUpdate ( sess * sqlstore . DB Session, dash * models . Dashboard , dialect migrator . Dialect , overwrite bool ) ( bool , error ) {
func getExistingDashboardByIdOrUidForUpdate ( sess * db . Session , dash * models . Dashboard , dialect migrator . Dialect , overwrite bool ) ( bool , error ) {
dashWithIdExists := false
isParentFolderChanged := false
var existingById models . Dashboard
@ -373,7 +378,7 @@ func getExistingDashboardByIdOrUidForUpdate(sess *sqlstore.DBSession, dash *mode
return isParentFolderChanged , nil
}
func getExistingDashboardByTitleAndFolder ( sess * sqlstore . DB Session, dash * models . Dashboard , dialect migrator . Dialect , overwrite ,
func getExistingDashboardByTitleAndFolder ( sess * db . Session , dash * models . Dashboard , dialect migrator . Dialect , overwrite ,
isParentFolderChanged bool ) ( bool , error ) {
var existing models . Dashboard
exists , err := sess . Where ( "org_id=? AND slug=? AND (is_folder=? OR folder_id=?)" , dash . OrgId , dash . Slug ,
@ -407,7 +412,7 @@ func getExistingDashboardByTitleAndFolder(sess *sqlstore.DBSession, dash *models
return isParentFolderChanged , nil
}
func saveDashboard ( sess * sqlstore . DB Session, cmd * models . SaveDashboardCommand , emitEntityEvent bool ) error {
func saveDashboard ( sess * db . Session , cmd * models . SaveDashboardCommand , emitEntityEvent bool ) error {
dash := cmd . GetDashboardModel ( )
userId := cmd . UserId
@ -510,7 +515,7 @@ func saveDashboard(sess *sqlstore.DBSession, cmd *models.SaveDashboardCommand, e
tags := dash . GetTags ( )
if len ( tags ) > 0 {
for _ , tag := range tags {
if _ , err := sess . Insert ( & sqlstore . DashboardTag { DashboardId : dash . Id , Term : tag } ) ; err != nil {
if _ , err := sess . Insert ( DashboardTag { DashboardId : dash . Id , Term : tag } ) ; err != nil {
return err
}
}
@ -527,7 +532,7 @@ func saveDashboard(sess *sqlstore.DBSession, cmd *models.SaveDashboardCommand, e
return nil
}
func generateNewDashboardUid ( sess * sqlstore . DB Session, orgId int64 ) ( string , error ) {
func generateNewDashboardUid ( sess * db . Session , orgId int64 ) ( string , error ) {
for i := 0 ; i < 3 ; i ++ {
uid := util . GenerateShortUID ( )
@ -544,7 +549,7 @@ func generateNewDashboardUid(sess *sqlstore.DBSession, orgId int64) (string, err
return "" , dashboards . ErrDashboardFailedGenerateUniqueUid
}
func saveProvisionedData ( sess * sqlstore . DB Session, provisioning * models . DashboardProvisioning , dashboard * models . Dashboard ) error {
func saveProvisionedData ( sess * db . Session , provisioning * models . DashboardProvisioning , dashboard * models . Dashboard ) error {
result := & models . DashboardProvisioning { }
exist , err := sess . Where ( "dashboard_id=? AND name = ?" , dashboard . Id , provisioning . Name ) . Get ( result )
@ -564,7 +569,7 @@ func saveProvisionedData(sess *sqlstore.DBSession, provisioning *models.Dashboar
return err
}
func GetAlertsByDashboardId2 ( dashboardId int64 , sess * sqlstore . DB Session) ( [ ] * models . Alert , error ) {
func GetAlertsByDashboardId2 ( dashboardId int64 , sess * db . Session ) ( [ ] * models . Alert , error ) {
alerts := make ( [ ] * models . Alert , 0 )
err := sess . Where ( "dashboard_id = ?" , dashboardId ) . Find ( & alerts )
@ -576,7 +581,7 @@ func GetAlertsByDashboardId2(dashboardId int64, sess *sqlstore.DBSession) ([]*mo
}
func ( d * DashboardStore ) updateAlerts ( ctx context . Context , existingAlerts [ ] * models . Alert , alerts [ ] * models . Alert , log log . Logger ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
for _ , alert := range alerts {
update := false
var alertToUpdate * models . Alert
@ -636,7 +641,7 @@ func (d *DashboardStore) updateAlerts(ctx context.Context, existingAlerts []*mod
} )
}
func ( d * DashboardStore ) deleteMissingAlerts ( alerts [ ] * models . Alert , existingAlerts [ ] * models . Alert , sess * sqlstore . DB Session) error {
func ( d * DashboardStore ) deleteMissingAlerts ( alerts [ ] * models . Alert , existingAlerts [ ] * models . Alert , sess * db . Session ) error {
for _ , missingAlert := range alerts {
missing := true
@ -659,7 +664,7 @@ func (d *DashboardStore) deleteMissingAlerts(alerts []*models.Alert, existingAle
return nil
}
func ( d * DashboardStore ) deleteAlertByIdInternal ( alertId int64 , reason string , sess * sqlstore . DB Session) error {
func ( d * DashboardStore ) deleteAlertByIdInternal ( alertId int64 , reason string , sess * db . Session ) error {
d . log . Debug ( "Deleting alert" , "id" , alertId , "reason" , reason )
if _ , err := sess . Exec ( "DELETE FROM alert WHERE id = ?" , alertId ) ; err != nil {
@ -682,9 +687,9 @@ func (d *DashboardStore) deleteAlertByIdInternal(alertId int64, reason string, s
}
func ( d * DashboardStore ) GetDashboardsByPluginID ( ctx context . Context , query * models . GetDashboardsByPluginIdQuery ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( dbSession * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( dbSession * db . Session ) error {
var dashboards = make ( [ ] * models . Dashboard , 0 )
whereExpr := "org_id=? AND plugin_id=? AND is_folder=" + d . sqlS tore . GetDialect ( ) . BooleanStr ( false )
whereExpr := "org_id=? AND plugin_id=? AND is_folder=" + d . store . GetDialect ( ) . BooleanStr ( false )
err := dbSession . Where ( whereExpr , query . OrgId , query . PluginId ) . Find ( & dashboards )
query . Result = dashboards
@ -693,12 +698,12 @@ func (d *DashboardStore) GetDashboardsByPluginID(ctx context.Context, query *mod
}
func ( d * DashboardStore ) DeleteDashboard ( ctx context . Context , cmd * models . DeleteDashboardCommand ) error {
return d . sqlS tore . WithTransactionalDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithTransactionalDbSession ( ctx , func ( sess * db . Session ) error {
return d . deleteDashboard ( cmd , sess , d . emitEntityEvent ( ) )
} )
}
func ( d * DashboardStore ) deleteDashboard ( cmd * models . DeleteDashboardCommand , sess * sqlstore . DB Session, emitEntityEvent bool ) error {
func ( d * DashboardStore ) deleteDashboard ( cmd * models . DeleteDashboardCommand , sess * db . Session , emitEntityEvent bool ) error {
dashboard := models . Dashboard { Id : cmd . Id , OrgId : cmd . OrgId }
has , err := sess . Get ( & dashboard )
if err != nil {
@ -835,7 +840,7 @@ func createEntityEvent(dashboard *models.Dashboard, eventType store.EntityEventT
return entityEvent
}
func ( d * DashboardStore ) deleteAlertDefinition ( dashboardId int64 , sess * sqlstore . DB Session) error {
func ( d * DashboardStore ) deleteAlertDefinition ( dashboardId int64 , sess * db . Session ) error {
alerts := make ( [ ] * models . Alert , 0 )
if err := sess . Where ( "dashboard_id = ?" , dashboardId ) . Find ( & alerts ) ; err != nil {
return err
@ -853,7 +858,7 @@ func (d *DashboardStore) deleteAlertDefinition(dashboardId int64, sess *sqlstore
}
func ( d * DashboardStore ) GetDashboard ( ctx context . Context , query * models . GetDashboardQuery ) ( * models . Dashboard , error ) {
err := d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
if query . Id == 0 && len ( query . Slug ) == 0 && len ( query . Uid ) == 0 {
return dashboards . ErrDashboardIdentifierNotSet
}
@ -877,7 +882,7 @@ func (d *DashboardStore) GetDashboard(ctx context.Context, query *models.GetDash
}
func ( d * DashboardStore ) GetDashboardUIDById ( ctx context . Context , query * models . GetDashboardRefByIdQuery ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
var rawSQL = ` SELECT uid, slug from dashboard WHERE Id=? `
us := & models . DashboardRef { }
exists , err := sess . SQL ( rawSQL , query . Id ) . Get ( us )
@ -892,7 +897,7 @@ func (d *DashboardStore) GetDashboardUIDById(ctx context.Context, query *models.
}
func ( d * DashboardStore ) GetDashboards ( ctx context . Context , query * models . GetDashboardsQuery ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
if len ( query . DashboardIds ) == 0 && len ( query . DashboardUIds ) == 0 {
return models . ErrCommandValidationFailed
}
@ -916,7 +921,7 @@ func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindP
permissions . DashboardPermissionFilter {
OrgRole : query . SignedInUser . OrgRole ,
OrgId : query . SignedInUser . OrgID ,
Dialect : d . sqlS tore . GetDialect ( ) ,
Dialect : d . store . GetDialect ( ) ,
UserId : query . SignedInUser . UserID ,
PermissionLevel : query . Permission ,
} ,
@ -956,11 +961,11 @@ func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindP
}
if len ( query . Title ) > 0 {
filters = append ( filters , searchstore . TitleFilter { Dialect : d . sqlS tore . GetDialect ( ) , Title : query . Title } )
filters = append ( filters , searchstore . TitleFilter { Dialect : d . store . GetDialect ( ) , Title : query . Title } )
}
if len ( query . Type ) > 0 {
filters = append ( filters , searchstore . TypeFilter { Dialect : d . sqlS tore . GetDialect ( ) , Type : query . Type } )
filters = append ( filters , searchstore . TypeFilter { Dialect : d . store . GetDialect ( ) , Type : query . Type } )
}
if len ( query . FolderIds ) > 0 {
@ -968,7 +973,7 @@ func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindP
}
var res [ ] dashboards . DashboardSearchProjection
sb := & searchstore . Builder { Dialect : d . sqlS tore . GetDialect ( ) , Filters : filters }
sb := & searchstore . Builder { Dialect : d . store . GetDialect ( ) , Filters : filters }
limit := query . Limit
if limit < 1 {
@ -982,7 +987,7 @@ func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindP
sql , params := sb . ToSQL ( limit , page )
err := d . sqlS tore . WithDbSession ( ctx , func ( sess * sqlstore . DB Session) error {
err := d . store . WithDbSession ( ctx , func ( sess * db . Session ) error {
return sess . SQL ( sql , params ... ) . Find ( & res )
} )
@ -994,7 +999,7 @@ func (d *DashboardStore) FindDashboards(ctx context.Context, query *models.FindP
}
func ( d * DashboardStore ) GetDashboardTags ( ctx context . Context , query * models . GetDashboardTagsQuery ) error {
return d . sqlS tore . WithDbSession ( ctx , func ( dbSession * sqlstore . DB Session) error {
return d . store . WithDbSession ( ctx , func ( dbSession * db . Session ) error {
sql := ` SELECT
COUNT ( * ) as count ,
term