mirror of https://github.com/grafana/grafana
Chore: SQL store split for annotations (#55089)
* Chore: SQL store split for annotations * Apply suggestion from code reviewpull/55092/head^2
parent
469f915b8c
commit
754eea20b3
@ -0,0 +1,44 @@ |
|||||||
|
package annotationsimpl |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log" |
||||||
|
"github.com/grafana/grafana/pkg/services/annotations" |
||||||
|
"github.com/grafana/grafana/pkg/services/sqlstore/db" |
||||||
|
"github.com/grafana/grafana/pkg/setting" |
||||||
|
) |
||||||
|
|
||||||
|
type RepositoryImpl struct { |
||||||
|
store store |
||||||
|
} |
||||||
|
|
||||||
|
func ProvideService(db db.DB, cfg *setting.Cfg) *RepositoryImpl { |
||||||
|
return &RepositoryImpl{ |
||||||
|
store: &SQLAnnotationRepo{ |
||||||
|
cfg: cfg, |
||||||
|
db: db, |
||||||
|
log: log.New("annotations"), |
||||||
|
}, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (r *RepositoryImpl) Save(ctx context.Context, item *annotations.Item) error { |
||||||
|
return r.store.Add(ctx, item) |
||||||
|
} |
||||||
|
|
||||||
|
func (r *RepositoryImpl) Update(ctx context.Context, item *annotations.Item) error { |
||||||
|
return r.store.Update(ctx, item) |
||||||
|
} |
||||||
|
|
||||||
|
func (r *RepositoryImpl) Find(ctx context.Context, query *annotations.ItemQuery) ([]*annotations.ItemDTO, error) { |
||||||
|
return r.store.Get(ctx, query) |
||||||
|
} |
||||||
|
|
||||||
|
func (r *RepositoryImpl) Delete(ctx context.Context, params *annotations.DeleteParams) error { |
||||||
|
return r.store.Delete(ctx, params) |
||||||
|
} |
||||||
|
|
||||||
|
func (r *RepositoryImpl) FindTags(ctx context.Context, query *annotations.TagsQuery) (annotations.FindTagsResult, error) { |
||||||
|
return r.store.GetTags(ctx, query) |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
package annotationsimpl |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/annotations" |
||||||
|
) |
||||||
|
|
||||||
|
type store interface { |
||||||
|
Add(ctx context.Context, item *annotations.Item) error |
||||||
|
Update(ctx context.Context, item *annotations.Item) error |
||||||
|
Get(ctx context.Context, query *annotations.ItemQuery) ([]*annotations.ItemDTO, error) |
||||||
|
Delete(ctx context.Context, params *annotations.DeleteParams) error |
||||||
|
GetTags(ctx context.Context, query *annotations.TagsQuery) (annotations.FindTagsResult, error) |
||||||
|
} |
||||||
@ -0,0 +1,83 @@ |
|||||||
|
package annotationstest |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"sync" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/annotations" |
||||||
|
) |
||||||
|
|
||||||
|
type fakeAnnotationsRepo struct { |
||||||
|
mtx sync.Mutex |
||||||
|
annotations map[int64]annotations.Item |
||||||
|
} |
||||||
|
|
||||||
|
func NewFakeAnnotationsRepo() *fakeAnnotationsRepo { |
||||||
|
return &fakeAnnotationsRepo{ |
||||||
|
annotations: map[int64]annotations.Item{}, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Delete(_ context.Context, params *annotations.DeleteParams) error { |
||||||
|
repo.mtx.Lock() |
||||||
|
defer repo.mtx.Unlock() |
||||||
|
|
||||||
|
if params.Id != 0 { |
||||||
|
delete(repo.annotations, params.Id) |
||||||
|
} else { |
||||||
|
for _, v := range repo.annotations { |
||||||
|
if params.DashboardId == v.DashboardId && params.PanelId == v.PanelId { |
||||||
|
delete(repo.annotations, v.Id) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Save(ctx context.Context, item *annotations.Item) error { |
||||||
|
repo.mtx.Lock() |
||||||
|
defer repo.mtx.Unlock() |
||||||
|
|
||||||
|
if item.Id == 0 { |
||||||
|
item.Id = int64(len(repo.annotations) + 1) |
||||||
|
} |
||||||
|
repo.annotations[item.Id] = *item |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Update(_ context.Context, item *annotations.Item) error { |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Find(_ context.Context, query *annotations.ItemQuery) ([]*annotations.ItemDTO, error) { |
||||||
|
repo.mtx.Lock() |
||||||
|
defer repo.mtx.Unlock() |
||||||
|
|
||||||
|
if annotation, has := repo.annotations[query.AnnotationId]; has { |
||||||
|
return []*annotations.ItemDTO{{Id: annotation.Id, DashboardId: annotation.DashboardId}}, nil |
||||||
|
} |
||||||
|
annotations := []*annotations.ItemDTO{{Id: 1, DashboardId: 0}} |
||||||
|
return annotations, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) FindTags(_ context.Context, query *annotations.TagsQuery) (annotations.FindTagsResult, error) { |
||||||
|
result := annotations.FindTagsResult{ |
||||||
|
Tags: []*annotations.TagsDTO{}, |
||||||
|
} |
||||||
|
return result, nil |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Len() int { |
||||||
|
repo.mtx.Lock() |
||||||
|
defer repo.mtx.Unlock() |
||||||
|
|
||||||
|
return len(repo.annotations) |
||||||
|
} |
||||||
|
|
||||||
|
func (repo *fakeAnnotationsRepo) Items() map[int64]annotations.Item { |
||||||
|
repo.mtx.Lock() |
||||||
|
defer repo.mtx.Unlock() |
||||||
|
|
||||||
|
return repo.annotations |
||||||
|
} |
||||||
@ -0,0 +1,135 @@ |
|||||||
|
package annotations |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson" |
||||||
|
"github.com/grafana/grafana/pkg/services/user" |
||||||
|
) |
||||||
|
|
||||||
|
type ItemQuery struct { |
||||||
|
OrgId int64 `json:"orgId"` |
||||||
|
From int64 `json:"from"` |
||||||
|
To int64 `json:"to"` |
||||||
|
UserId int64 `json:"userId"` |
||||||
|
AlertId int64 `json:"alertId"` |
||||||
|
DashboardId int64 `json:"dashboardId"` |
||||||
|
DashboardUid string `json:"dashboardUID"` |
||||||
|
PanelId int64 `json:"panelId"` |
||||||
|
AnnotationId int64 `json:"annotationId"` |
||||||
|
Tags []string `json:"tags"` |
||||||
|
Type string `json:"type"` |
||||||
|
MatchAny bool `json:"matchAny"` |
||||||
|
SignedInUser *user.SignedInUser |
||||||
|
|
||||||
|
Limit int64 `json:"limit"` |
||||||
|
} |
||||||
|
|
||||||
|
// TagsQuery is the query for a tags search.
|
||||||
|
type TagsQuery struct { |
||||||
|
OrgID int64 `json:"orgId"` |
||||||
|
Tag string `json:"tag"` |
||||||
|
|
||||||
|
Limit int64 `json:"limit"` |
||||||
|
} |
||||||
|
|
||||||
|
// Tag is the DB result of a tags search.
|
||||||
|
type Tag struct { |
||||||
|
Key string |
||||||
|
Value string |
||||||
|
Count int64 |
||||||
|
} |
||||||
|
|
||||||
|
// TagsDTO is the frontend DTO for Tag.
|
||||||
|
type TagsDTO struct { |
||||||
|
Tag string `json:"tag"` |
||||||
|
Count int64 `json:"count"` |
||||||
|
} |
||||||
|
|
||||||
|
// FindTagsResult is the result of a tags search.
|
||||||
|
type FindTagsResult struct { |
||||||
|
Tags []*TagsDTO `json:"tags"` |
||||||
|
} |
||||||
|
|
||||||
|
// GetAnnotationTagsResponse is a response struct for FindTagsResult.
|
||||||
|
type GetAnnotationTagsResponse struct { |
||||||
|
Result FindTagsResult `json:"result"` |
||||||
|
} |
||||||
|
|
||||||
|
type DeleteParams struct { |
||||||
|
OrgId int64 |
||||||
|
Id int64 |
||||||
|
DashboardId int64 |
||||||
|
PanelId int64 |
||||||
|
} |
||||||
|
|
||||||
|
type Item struct { |
||||||
|
Id int64 `json:"id"` |
||||||
|
OrgId int64 `json:"orgId"` |
||||||
|
UserId int64 `json:"userId"` |
||||||
|
DashboardId int64 `json:"dashboardId"` |
||||||
|
PanelId int64 `json:"panelId"` |
||||||
|
Text string `json:"text"` |
||||||
|
AlertId int64 `json:"alertId"` |
||||||
|
PrevState string `json:"prevState"` |
||||||
|
NewState string `json:"newState"` |
||||||
|
Epoch int64 `json:"epoch"` |
||||||
|
EpochEnd int64 `json:"epochEnd"` |
||||||
|
Created int64 `json:"created"` |
||||||
|
Updated int64 `json:"updated"` |
||||||
|
Tags []string `json:"tags"` |
||||||
|
Data *simplejson.Json `json:"data"` |
||||||
|
|
||||||
|
// needed until we remove it from db
|
||||||
|
Type string |
||||||
|
Title string |
||||||
|
} |
||||||
|
|
||||||
|
func (i Item) TableName() string { |
||||||
|
return "annotation" |
||||||
|
} |
||||||
|
|
||||||
|
type ItemDTO struct { |
||||||
|
Id int64 `json:"id"` |
||||||
|
AlertId int64 `json:"alertId"` |
||||||
|
AlertName string `json:"alertName"` |
||||||
|
DashboardId int64 `json:"dashboardId"` |
||||||
|
DashboardUID *string `json:"dashboardUID"` |
||||||
|
PanelId int64 `json:"panelId"` |
||||||
|
UserId int64 `json:"userId"` |
||||||
|
NewState string `json:"newState"` |
||||||
|
PrevState string `json:"prevState"` |
||||||
|
Created int64 `json:"created"` |
||||||
|
Updated int64 `json:"updated"` |
||||||
|
Time int64 `json:"time"` |
||||||
|
TimeEnd int64 `json:"timeEnd"` |
||||||
|
Text string `json:"text"` |
||||||
|
Tags []string `json:"tags"` |
||||||
|
Login string `json:"login"` |
||||||
|
Email string `json:"email"` |
||||||
|
AvatarUrl string `json:"avatarUrl"` |
||||||
|
Data *simplejson.Json `json:"data"` |
||||||
|
} |
||||||
|
|
||||||
|
type annotationType int |
||||||
|
|
||||||
|
const ( |
||||||
|
Organization annotationType = iota |
||||||
|
Dashboard |
||||||
|
) |
||||||
|
|
||||||
|
func (a annotationType) String() string { |
||||||
|
switch a { |
||||||
|
case Organization: |
||||||
|
return "organization" |
||||||
|
case Dashboard: |
||||||
|
return "dashboard" |
||||||
|
default: |
||||||
|
return "" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (annotation *ItemDTO) GetType() annotationType { |
||||||
|
if annotation.DashboardId != 0 { |
||||||
|
return Dashboard |
||||||
|
} |
||||||
|
return Organization |
||||||
|
} |
||||||
Loading…
Reference in new issue