diff --git a/pkg/services/folder/folderimpl/sqlstore.go b/pkg/services/folder/folderimpl/sqlstore.go index b10e650fe7a..de4b18348df 100644 --- a/pkg/services/folder/folderimpl/sqlstore.go +++ b/pkg/services/folder/folderimpl/sqlstore.go @@ -2,11 +2,13 @@ package folderimpl import ( "context" + "encoding/binary" "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" + "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/setting" ) @@ -25,7 +27,22 @@ func ProvideStore(db db.DB, cfg *setting.Cfg, features featuremgmt.FeatureManage } func (ss *sqlStore) Create(ctx context.Context, cmd *folder.CreateFolderCommand) (*folder.Folder, error) { - panic("not implemented") + foldr := &folder.Folder{ + OrgID: cmd.OrgID, + UID: cmd.UID, + ParentUID: cmd.ParentUID, + Title: cmd.Title, + Description: cmd.Description, + } + err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { + folderID, err := sess.Insert(foldr) + if err != nil { + return err + } + foldr.ID = folderID + return nil + }) + return foldr, err } func (ss *sqlStore) Delete(ctx context.Context, uid string, orgID int64) error { @@ -60,14 +77,69 @@ func (ss *sqlStore) Get(ctx context.Context, cmd *folder.GetFolderQuery) (*folde } func (ss *sqlStore) GetParents(ctx context.Context, cmd *folder.GetParentsQuery) ([]*folder.Folder, error) { - panic("not implemented") + var folders []*folder.Folder + if ss.db.GetDBType() == migrator.MySQL { + return ss.getParentsMySQL(ctx, cmd) + } + + recQuery := + `WITH RecQry AS ( + SELECT * + FROM folder + UNION ALL + SELECT f.* + FROM folder f INNER JOIN RecQry r + ON f.parent_uid = r.uid + ) + SELECT * + FROM RecQry` + + err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { + res, err := sess.Query(recQuery) + if err != nil { + return err + } + + for _, row := range res { + folders = append(folders, &folder.Folder{ + ID: int64(binary.BigEndian.Uint64(row["id"])), + OrgID: int64(binary.BigEndian.Uint64(row["org_id"])), + UID: string(row["uid"]), + ParentUID: string(row["parent_uid"]), + Title: string(row["title"]), + Description: string(row["description"]), + // CreatedBy: int64(binary.BigEndian.Uint64(row["created_by"])), + }) + } + return nil + }) + return nil, err } func (ss *sqlStore) GetChildren(ctx context.Context, cmd *folder.GetTreeQuery) ([]*folder.Folder, error) { var folders []*folder.Folder + err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { err := sess.Where("parent_uid=? AND org_id=?", cmd.UID, cmd.OrgID).Find(folders) return err }) return folders, err } + +func (ss *sqlStore) getParentsMySQL(ctx context.Context, cmd *folder.GetParentsQuery) ([]*folder.Folder, error) { + var foldrs []*folder.Folder + var foldr *folder.Folder + err := ss.db.WithDbSession(ctx, func(sess *db.Session) error { + uid := cmd.UID + for uid != folder.GeneralFolderUID && len(foldrs) < 8 { + err := sess.Where("uid=?", uid).Find(foldr) + if err != nil { + return err + } + foldrs = append(foldrs, foldr) + uid = foldr.ParentUID + } + return nil + }) + return foldrs, err +} diff --git a/pkg/services/folder/model.go b/pkg/services/folder/model.go index 962daee3c8e..2d27d668279 100644 --- a/pkg/services/folder/model.go +++ b/pkg/services/folder/model.go @@ -42,17 +42,18 @@ func NewFolder(title string, description string) *Folder { // CreateFolderCommand captures the information required by the folder service // to create a folder. type CreateFolderCommand struct { - UID string `json:"uid"` + UID string `json:"uid" xorm:"uid"` + OrgID int64 `json:"orgId" xorm:"org_id"` Title string `json:"title"` Description string `json:"description"` - ParentUID string `json:"parent_uid"` + ParentUID string `json:"parent_uid" xorm:"parent_uid"` } // UpdateFolderCommand captures the information required by the folder service // to update a folder. Use Move to update a folder's parent folder. type UpdateFolderCommand struct { Folder *Folder `json:"folder"` // The extant folder - NewUID *string `json:"uid"` + NewUID *string `json:"uid" xorm:"uid"` NewTitle *string `json:"title"` NewDescription *string `json:"description"` } @@ -67,7 +68,7 @@ type MoveFolderCommand struct { // DeleteFolderCommand captures the information required by the folder service // to delete a folder. type DeleteFolderCommand struct { - UID string `json:"uid"` + UID string `json:"uid" xorm:"uid"` } // GetFolderQuery is used for all folder Get requests. Only one of UID, ID, or @@ -83,15 +84,15 @@ type GetFolderQuery struct { // GetParentsQuery captures the information required by the folder service to // return a list of all parent folders of a given folder. type GetParentsQuery struct { - UID string + UID string `xorm:"uid"` } // GetTreeCommand captures the information required by the folder service to // return a list of child folders of the given folder. type GetTreeQuery struct { - UID string - OrgID int64 + UID string `xorm:"uid"` + OrgID int64 `xorm:"org_id"` Depth int64 // Pagination options