dashboard.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package sqlstore
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/go-xorm/xorm"
  6. "github.com/grafana/grafana/pkg/bus"
  7. m "github.com/grafana/grafana/pkg/models"
  8. )
  9. func init() {
  10. bus.AddHandler("sql", SaveDashboard)
  11. bus.AddHandler("sql", GetDashboard)
  12. bus.AddHandler("sql", DeleteDashboard)
  13. bus.AddHandler("sql", SearchDashboards)
  14. bus.AddHandler("sql", GetDashboardTags)
  15. }
  16. func SaveDashboard(cmd *m.SaveDashboardCommand) error {
  17. return inTransaction(func(sess *xorm.Session) error {
  18. dash := cmd.GetDashboardModel()
  19. // try get existing dashboard
  20. existing := m.Dashboard{Slug: dash.Slug, OrgId: dash.OrgId}
  21. hasExisting, err := sess.Get(&existing)
  22. if err != nil {
  23. return err
  24. }
  25. if hasExisting {
  26. // another dashboard with same name
  27. if dash.Id != existing.Id {
  28. if cmd.Overwrite {
  29. dash.Id = existing.Id
  30. } else {
  31. return m.ErrDashboardWithSameNameExists
  32. }
  33. }
  34. // check for is someone else has written in between
  35. if dash.Version != existing.Version {
  36. if cmd.Overwrite {
  37. dash.Version = existing.Version
  38. } else {
  39. return m.ErrDashboardVersionMismatch
  40. }
  41. }
  42. }
  43. if dash.Id == 0 {
  44. _, err = sess.Insert(dash)
  45. } else {
  46. dash.Version += 1
  47. dash.Data["version"] = dash.Version
  48. _, err = sess.Id(dash.Id).Update(dash)
  49. }
  50. // delete existing tabs
  51. _, err = sess.Exec("DELETE FROM dashboard_tag WHERE dashboard_id=?", dash.Id)
  52. if err != nil {
  53. return err
  54. }
  55. // insert new tags
  56. tags := dash.GetTags()
  57. if len(tags) > 0 {
  58. for _, tag := range tags {
  59. if _, err := sess.Insert(&DashboardTag{DashboardId: dash.Id, Term: tag}); err != nil {
  60. return err
  61. }
  62. }
  63. }
  64. cmd.Result = dash
  65. return err
  66. })
  67. }
  68. func GetDashboard(query *m.GetDashboardQuery) error {
  69. dashboard := m.Dashboard{Slug: query.Slug, OrgId: query.OrgId}
  70. has, err := x.Get(&dashboard)
  71. if err != nil {
  72. return err
  73. } else if has == false {
  74. return m.ErrDashboardNotFound
  75. }
  76. dashboard.Data["id"] = dashboard.Id
  77. query.Result = &dashboard
  78. return nil
  79. }
  80. type DashboardSearchProjection struct {
  81. Id int64
  82. Title string
  83. Slug string
  84. Term string
  85. }
  86. func SearchDashboards(query *m.SearchDashboardsQuery) error {
  87. var sql bytes.Buffer
  88. params := make([]interface{}, 0)
  89. sql.WriteString(`SELECT
  90. dashboard.id,
  91. dashboard.title,
  92. dashboard.slug,
  93. dashboard_tag.term
  94. FROM dashboard
  95. LEFT OUTER JOIN dashboard_tag on dashboard_tag.dashboard_id = dashboard.id`)
  96. if query.IsStarred {
  97. sql.WriteString(" INNER JOIN star on star.dashboard_id = dashboard.id")
  98. }
  99. sql.WriteString(` WHERE dashboard.org_id=?`)
  100. params = append(params, query.OrgId)
  101. if query.IsStarred {
  102. sql.WriteString(` AND star.user_id=?`)
  103. params = append(params, query.UserId)
  104. }
  105. if len(query.Title) > 0 {
  106. sql.WriteString(" AND dashboard.title LIKE ?")
  107. params = append(params, "%"+query.Title+"%")
  108. }
  109. if len(query.Tag) > 0 {
  110. sql.WriteString(" AND dashboard_tag.term=?")
  111. params = append(params, query.Tag)
  112. }
  113. if query.Limit == 0 || query.Limit > 10000 {
  114. query.Limit = 300
  115. }
  116. sql.WriteString(fmt.Sprintf(" LIMIT %d", query.Limit))
  117. var res []DashboardSearchProjection
  118. err := x.Sql(sql.String(), params...).Find(&res)
  119. if err != nil {
  120. return err
  121. }
  122. query.Result = make([]*m.DashboardSearchHit, 0)
  123. hits := make(map[int64]*m.DashboardSearchHit)
  124. for _, item := range res {
  125. hit, exists := hits[item.Id]
  126. if !exists {
  127. hit = &m.DashboardSearchHit{
  128. Id: item.Id,
  129. Title: item.Title,
  130. Slug: item.Slug,
  131. Tags: []string{},
  132. }
  133. query.Result = append(query.Result, hit)
  134. hits[item.Id] = hit
  135. }
  136. if len(item.Term) > 0 {
  137. hit.Tags = append(hit.Tags, item.Term)
  138. }
  139. }
  140. return err
  141. }
  142. func GetDashboardTags(query *m.GetDashboardTagsQuery) error {
  143. sql := `SELECT
  144. COUNT(*) as count,
  145. term
  146. FROM dashboard
  147. INNER JOIN dashboard_tag on dashboard_tag.dashboard_id = dashboard.id
  148. WHERE dashboard.org_id=?
  149. GROUP BY term`
  150. query.Result = make([]*m.DashboardTagCloudItem, 0)
  151. sess := x.Sql(sql, query.OrgId)
  152. err := sess.Find(&query.Result)
  153. return err
  154. }
  155. func DeleteDashboard(cmd *m.DeleteDashboardCommand) error {
  156. sess := x.NewSession()
  157. defer sess.Close()
  158. rawSql := "DELETE FROM dashboard WHERE org_id=? and slug=?"
  159. _, err := sess.Exec(rawSql, cmd.OrgId, cmd.Slug)
  160. return err
  161. }