2022-02-09 13:23:32 +04:00
package sqlstore
import (
"context"
2022-07-28 16:40:26 +04:00
"encoding/json"
2022-02-09 13:23:32 +04:00
"errors"
"time"
"github.com/grafana/grafana/pkg/models"
2022-06-30 09:31:54 -04:00
"github.com/grafana/grafana/pkg/services/dashboards"
2022-02-09 13:23:32 +04:00
)
func ( ss * SQLStore ) GetThumbnail ( ctx context . Context , query * models . GetDashboardThumbnailCommand ) ( * models . DashboardThumbnail , error ) {
err := ss . WithDbSession ( ctx , func ( sess * DBSession ) error {
result , err := findThumbnailByMeta ( sess , query . DashboardThumbnailMeta )
if err != nil {
return err
}
query . Result = result
return nil
})
return query . Result , err
}
2022-07-28 16:40:26 +04:00
func marshalDatasourceUids ( dsUids [] string ) ( string , error ) {
if dsUids == nil {
return "" , nil
}
b , err := json . Marshal ( dsUids )
if err != nil {
return "" , err
}
return string ( b ), nil
}
2022-02-09 13:23:32 +04:00
func ( ss * SQLStore ) SaveThumbnail ( ctx context . Context , cmd * models . SaveDashboardThumbnailCommand ) ( * models . DashboardThumbnail , error ) {
err := ss . WithTransactionalDbSession ( ctx , func ( sess * DBSession ) error {
existing , err := findThumbnailByMeta ( sess , cmd . DashboardThumbnailMeta )
2022-06-30 09:31:54 -04:00
if err != nil && ! errors . Is ( err , dashboards . ErrDashboardThumbnailNotFound ) {
2022-02-09 13:23:32 +04:00
return err
}
2022-07-28 16:40:26 +04:00
dsUids , err := marshalDatasourceUids ( cmd . DatasourceUIDs )
if err != nil {
return err
}
2022-02-09 13:23:32 +04:00
if existing != nil {
existing . Image = cmd . Image
existing . MimeType = cmd . MimeType
existing . Updated = time . Now ()
existing . DashboardVersion = cmd . DashboardVersion
2022-07-28 16:40:26 +04:00
existing . DsUIDs = dsUids
2022-02-09 13:23:32 +04:00
existing . State = models . ThumbnailStateDefault
_ , err = sess . ID ( existing . Id ). Update ( existing )
cmd . Result = existing
return err
}
thumb := & models . DashboardThumbnail {}
dash , err := findDashboardIdByThumbMeta ( sess , cmd . DashboardThumbnailMeta )
if err != nil {
return err
}
thumb . Updated = time . Now ()
thumb . Theme = cmd . Theme
thumb . Kind = cmd . Kind
thumb . Image = cmd . Image
2022-07-28 16:40:26 +04:00
thumb . DsUIDs = dsUids
2022-02-09 13:23:32 +04:00
thumb . MimeType = cmd . MimeType
thumb . DashboardId = dash . Id
thumb . DashboardVersion = cmd . DashboardVersion
thumb . State = models . ThumbnailStateDefault
thumb . PanelId = cmd . PanelID
_ , err = sess . Insert ( thumb )
cmd . Result = thumb
return err
})
return cmd . Result , err
}
func ( ss * SQLStore ) UpdateThumbnailState ( ctx context . Context , cmd * models . UpdateThumbnailStateCommand ) error {
err := ss . WithTransactionalDbSession ( ctx , func ( sess * DBSession ) error {
existing , err := findThumbnailByMeta ( sess , cmd . DashboardThumbnailMeta )
if err != nil {
return err
}
existing . State = cmd . State
_ , err = sess . ID ( existing . Id ). Update ( existing )
return err
})
return err
}
2022-02-16 21:49:50 +04:00
func ( ss * SQLStore ) FindThumbnailCount ( ctx context . Context , cmd * models . FindDashboardThumbnailCountCommand ) ( int64 , error ) {
err := ss . WithDbSession ( ctx , func ( sess * DBSession ) error {
count , err := sess . Count ( & models . DashboardThumbnail {})
if err != nil {
return err
}
cmd . Result = count
return nil
})
return cmd . Result , err
}
2022-02-09 13:23:32 +04:00
func ( ss * SQLStore ) FindDashboardsWithStaleThumbnails ( ctx context . Context , cmd * models . FindDashboardsWithStaleThumbnailsCommand ) ([] * models . DashboardWithStaleThumbnail , error ) {
err := ss . WithDbSession ( ctx , func ( sess * DBSession ) error {
sess . Table ( "dashboard" )
2022-02-10 22:45:00 +04:00
sess . Join ( "LEFT" , "dashboard_thumbnail" , "dashboard.id = dashboard_thumbnail.dashboard_id AND dashboard_thumbnail.theme = ? AND dashboard_thumbnail.kind = ?" , cmd . Theme , cmd . Kind )
2022-02-09 13:23:32 +04:00
sess . Where ( "dashboard.is_folder = ?" , dialect . BooleanStr ( false ))
2022-07-28 16:40:26 +04:00
query := "(dashboard.version != dashboard_thumbnail.dashboard_version " +
"OR dashboard_thumbnail.state = ? " +
"OR dashboard_thumbnail.id IS NULL"
args := [] interface {}{ models . ThumbnailStateStale }
if cmd . IncludeThumbnailsWithEmptyDsUIDs {
2022-07-28 21:50:02 +04:00
query += " OR dashboard_thumbnail.ds_uids = ? OR dashboard_thumbnail.ds_uids IS NULL"
2022-07-28 16:40:26 +04:00
args = append ( args , "" )
}
sess . Where ( query + ")" , args ... )
2022-02-09 13:23:32 +04:00
if ! cmd . IncludeManuallyUploadedThumbnails {
sess . Where ( "(dashboard_thumbnail.id is not null AND dashboard_thumbnail.dashboard_version != ?) " +
"OR dashboard_thumbnail.id is null " +
"OR dashboard_thumbnail.state = ?" , models . DashboardVersionForManualThumbnailUpload , models . ThumbnailStateStale )
}
sess . Where ( "(dashboard_thumbnail.id IS NULL OR dashboard_thumbnail.state != ?)" , models . ThumbnailStateLocked )
sess . Cols ( "dashboard.id" ,
"dashboard.uid" ,
"dashboard.org_id" ,
"dashboard.version" ,
"dashboard.slug" )
2022-07-28 16:40:26 +04:00
var result = make ([] * models . DashboardWithStaleThumbnail , 0 )
err := sess . Find ( & result )
2022-02-09 13:23:32 +04:00
if err != nil {
return err
}
2022-07-28 16:40:26 +04:00
cmd . Result = result
2022-02-09 13:23:32 +04:00
return err
})
return cmd . Result , err
}
func findThumbnailByMeta ( sess * DBSession , meta models . DashboardThumbnailMeta ) ( * models . DashboardThumbnail , error ) {
result := & models . DashboardThumbnail {}
sess . Table ( "dashboard_thumbnail" )
sess . Join ( "INNER" , "dashboard" , "dashboard.id = dashboard_thumbnail.dashboard_id" )
sess . Where ( "dashboard.uid = ? AND dashboard.org_id = ? AND panel_id = ? AND kind = ? AND theme = ?" , meta . DashboardUID , meta . OrgId , meta . PanelID , meta . Kind , meta . Theme )
sess . Cols ( "dashboard_thumbnail.id" ,
"dashboard_thumbnail.dashboard_id" ,
"dashboard_thumbnail.panel_id" ,
"dashboard_thumbnail.image" ,
"dashboard_thumbnail.dashboard_version" ,
"dashboard_thumbnail.state" ,
"dashboard_thumbnail.kind" ,
2022-07-28 16:40:26 +04:00
"dashboard_thumbnail.ds_uids" ,
2022-02-09 13:23:32 +04:00
"dashboard_thumbnail.mime_type" ,
"dashboard_thumbnail.theme" ,
"dashboard_thumbnail.updated" )
exists , err := sess . Get ( result )
if ! exists {
2022-06-30 09:31:54 -04:00
return nil , dashboards . ErrDashboardThumbnailNotFound
2022-02-09 13:23:32 +04:00
}
if err != nil {
return nil , err
}
return result , nil
}
type dash struct {
Id int64
}
func findDashboardIdByThumbMeta ( sess * DBSession , meta models . DashboardThumbnailMeta ) ( * dash , error ) {
result := & dash {}
sess . Table ( "dashboard" ). Where ( "dashboard.uid = ? AND dashboard.org_id = ?" , meta . DashboardUID , meta . OrgId ). Cols ( "id" )
exists , err := sess . Get ( result )
if err != nil {
return nil , err
}
if ! exists {
2022-06-30 09:31:54 -04:00
return nil , dashboards . ErrDashboardNotFound
2022-02-09 13:23:32 +04:00
}
return result , err
}