refactoring: moved compare dashboard version command out of sqlstore, the code in this command did not use any sql operations and was more high level, could be moved out and use existing queries to get the versions

This commit is contained in:
Torkel Ödegaard
2017-06-06 00:14:40 +02:00
parent e43d09e15b
commit e2061312f5
7 changed files with 156 additions and 198 deletions

View File

@@ -0,0 +1,124 @@
package dashdiffs
import (
"encoding/json"
"errors"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
diff "github.com/yudai/gojsondiff"
deltaFormatter "github.com/yudai/gojsondiff/formatter"
)
type DiffType int
const (
DiffJSON DiffType = iota
DiffBasic
DiffDelta
)
var (
// ErrUnsupportedDiffType occurs when an invalid diff type is used.
ErrUnsupportedDiffType = errors.New("dashdiff: unsupported diff type")
// ErrNilDiff occurs when two compared interfaces are identical.
ErrNilDiff = errors.New("dashdiff: diff is nil")
)
type Options struct {
OrgId int64
DashboardId int64
BaseVersion int
NewVersion int
DiffType DiffType
}
type Result struct {
Delta []byte `json:"delta"`
}
// CompareDashboardVersionsCommand computes the JSON diff of two versions,
// assigning the delta of the diff to the `Delta` field.
func GetVersionDiff(options *Options) (*Result, error) {
baseVersionQuery := models.GetDashboardVersionQuery{
DashboardId: options.DashboardId,
Version: options.BaseVersion,
}
if err := bus.Dispatch(&baseVersionQuery); err != nil {
return nil, err
}
newVersionQuery := models.GetDashboardVersionQuery{
DashboardId: options.DashboardId,
Version: options.NewVersion,
}
if err := bus.Dispatch(&newVersionQuery); err != nil {
return nil, err
}
left, jsonDiff, err := getDiff(baseVersionQuery.Result, newVersionQuery.Result)
if err != nil {
return nil, err
}
result := &Result{}
switch options.DiffType {
case DiffDelta:
deltaOutput, err := deltaFormatter.NewDeltaFormatter().Format(jsonDiff)
if err != nil {
return nil, err
}
result.Delta = []byte(deltaOutput)
case DiffJSON:
jsonOutput, err := NewJSONFormatter(left).Format(jsonDiff)
if err != nil {
return nil, err
}
result.Delta = []byte(jsonOutput)
case DiffBasic:
basicOutput, err := NewBasicFormatter(left).Format(jsonDiff)
if err != nil {
return nil, err
}
result.Delta = basicOutput
default:
return nil, ErrUnsupportedDiffType
}
return result, nil
}
// getDiff computes the diff of two dashboard versions.
func getDiff(originalDash, newDash *models.DashboardVersion) (interface{}, diff.Diff, error) {
leftBytes, err := simplejson.NewFromAny(originalDash).Encode()
if err != nil {
return nil, nil, err
}
rightBytes, err := simplejson.NewFromAny(newDash).Encode()
if err != nil {
return nil, nil, err
}
jsonDiff, err := diff.New().Compare(leftBytes, rightBytes)
if err != nil {
return nil, nil, err
}
if !jsonDiff.Modified() {
return nil, nil, ErrNilDiff
}
left := make(map[string]interface{})
err = json.Unmarshal(leftBytes, &left)
return left, jsonDiff, nil
}

View File

@@ -1,4 +1,4 @@
package formatter
package dashdiffs
import (
"bytes"
@@ -261,7 +261,7 @@ var (
line-display="{{ .LineStart }}{{ if .LineEnd }} - {{ .LineEnd }}{{ end }}"
switch-view="ctrl.getDiff('html')"
/>
{{ end }}
{{ end }}
</div>
@@ -286,7 +286,7 @@ var (
<li class="diff-change-group">
<span class="bullet-position-container">
<div class="diff-change-item diff-change-title">{{ getChange .Change }} {{ .Key }}</div>
<div class="diff-change-item">
{{ if .Old }}
<div class="change list-change diff-label">{{ .Old }}</div>
@@ -312,7 +312,7 @@ var (
tplSummary = `{{ define "summary" -}}
<div class="diff-group-name">
<i class="diff-circle diff-circle-{{ getChange .Change }} fa fa-circle-o diff-list-circle"></i>
{{ if .Count }}
<strong>{{ .Count }}</strong>
{{ end }}

View File

@@ -1,4 +1,4 @@
package formatter
package dashdiffs
import (
"bytes"