|
|
@@ -3,7 +3,6 @@ package sqlstore
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"errors"
|
|
|
- "time"
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
|
"github.com/grafana/grafana/pkg/components/formatter"
|
|
|
@@ -26,7 +25,6 @@ func init() {
|
|
|
bus.AddHandler("sql", CompareDashboardVersionsCommand)
|
|
|
bus.AddHandler("sql", GetDashboardVersion)
|
|
|
bus.AddHandler("sql", GetDashboardVersions)
|
|
|
- bus.AddHandler("sql", RestoreDashboardVersion)
|
|
|
}
|
|
|
|
|
|
// CompareDashboardVersionsCommand computes the JSON diff of two versions,
|
|
|
@@ -118,76 +116,6 @@ func GetDashboardVersions(query *m.GetDashboardVersionsQuery) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// RestoreDashboardVersion restores the dashboard data to the given version.
|
|
|
-func RestoreDashboardVersion(cmd *m.RestoreDashboardVersionCommand) error {
|
|
|
- return inTransaction(func(sess *DBSession) error {
|
|
|
- // check if dashboard version exists in dashboard_version table
|
|
|
- //
|
|
|
- // normally we could use the getDashboardVersion func here, but since
|
|
|
- // we're in a transaction, we need to run the queries using the
|
|
|
- // session instead of using the global `x`, so we copy those functions
|
|
|
- // here, replacing `x` with `sess`
|
|
|
- dashboardVersion := m.DashboardVersion{}
|
|
|
- has, err := sess.Where("dashboard_id=? AND version=?", cmd.DashboardId, cmd.Version).Get(&dashboardVersion)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if !has {
|
|
|
- return m.ErrDashboardVersionNotFound
|
|
|
- }
|
|
|
-
|
|
|
- dashboardVersion.Data.Set("id", dashboardVersion.DashboardId)
|
|
|
-
|
|
|
- dashboard := m.Dashboard{Id: cmd.DashboardId}
|
|
|
- // Get the dashboard version
|
|
|
- if has, err = sess.Get(&dashboard); err != nil {
|
|
|
- return err
|
|
|
- } else if !has {
|
|
|
- return m.ErrDashboardNotFound
|
|
|
- }
|
|
|
-
|
|
|
- version, err := getMaxVersion(sess, dashboard.Id)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // revert and save to a new dashboard version
|
|
|
- dashboard.Data = dashboardVersion.Data
|
|
|
- dashboard.Updated = time.Now()
|
|
|
- dashboard.UpdatedBy = cmd.UserId
|
|
|
- dashboard.Version = version
|
|
|
- dashboard.Data.Set("version", dashboard.Version)
|
|
|
-
|
|
|
- // Update dashboard
|
|
|
- if affectedRows, err := sess.Id(dashboard.Id).Update(dashboard); err != nil {
|
|
|
- return err
|
|
|
- } else if affectedRows == 0 {
|
|
|
- return m.ErrDashboardNotFound
|
|
|
- }
|
|
|
-
|
|
|
- // save that version a new version
|
|
|
- dashVersion := &m.DashboardVersion{
|
|
|
- DashboardId: dashboard.Id,
|
|
|
- ParentVersion: cmd.Version,
|
|
|
- RestoredFrom: cmd.Version,
|
|
|
- Version: dashboard.Version,
|
|
|
- Created: time.Now(),
|
|
|
- CreatedBy: dashboard.UpdatedBy,
|
|
|
- Message: "",
|
|
|
- Data: dashboard.Data,
|
|
|
- }
|
|
|
-
|
|
|
- if affectedRows, err := sess.Insert(dashVersion); err != nil {
|
|
|
- return err
|
|
|
- } else if affectedRows == 0 {
|
|
|
- return m.ErrDashboardNotFound
|
|
|
- }
|
|
|
-
|
|
|
- cmd.Result = &dashboard
|
|
|
- return nil
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
// getDashboardVersion is a helper function that gets the dashboard version for
|
|
|
// the given dashboard ID and version ID.
|
|
|
func getDashboardVersion(dashboardId int64, version int) (*m.DashboardVersion, error) {
|
|
|
@@ -243,31 +171,3 @@ func getDiff(originalDash, newDash *m.DashboardVersion) (interface{}, diff.Diff,
|
|
|
err = json.Unmarshal(leftBytes, &left)
|
|
|
return left, jsonDiff, nil
|
|
|
}
|
|
|
-
|
|
|
-type version struct {
|
|
|
- Max int
|
|
|
-}
|
|
|
-
|
|
|
-// getMaxVersion returns the highest version number in the `dashboard_version`
|
|
|
-// table.
|
|
|
-//
|
|
|
-// This is necessary because sqlite3 doesn't support autoincrement in the same
|
|
|
-// way that Postgres or MySQL do, so we use this to get around that. Since it's
|
|
|
-// impossible to delete a version in Grafana, this is believed to be a
|
|
|
-// safe-enough alternative.
|
|
|
-func getMaxVersion(sess *DBSession, dashboardId int64) (int, error) {
|
|
|
- v := version{}
|
|
|
- has, err := sess.Table("dashboard_version").
|
|
|
- Select("MAX(version) AS max").
|
|
|
- Where("dashboard_id = ?", dashboardId).
|
|
|
- Get(&v)
|
|
|
- if !has {
|
|
|
- return 0, m.ErrDashboardNotFound
|
|
|
- }
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
-
|
|
|
- v.Max++
|
|
|
- return v.Max, nil
|
|
|
-}
|