2018-03-07 01:05:01 +00:00
|
|
|
package bolt
|
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/boltdb/bolt"
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
|
|
)
|
|
|
|
|
|
|
|
// changeIntervalToDuration
|
|
|
|
// Before, we supported queries that included `GROUP BY :interval:`
|
|
|
|
// After, we only support queries with `GROUP BY time(:interval:)`
|
|
|
|
// thereby allowing non_negative_derivative(_____, :interval)
|
|
|
|
var changeIntervalToDuration = Migration{
|
|
|
|
ID: "59b0cda4fc7909ff84ee5c4f9cb4b655b6a26620",
|
|
|
|
Up: up,
|
|
|
|
Down: down,
|
|
|
|
}
|
|
|
|
|
2018-03-08 07:09:56 +00:00
|
|
|
func updateDashboard(board *Dashboard) {
|
|
|
|
for _, cell := range board.Cells {
|
|
|
|
for _, query := range cell.Queries {
|
|
|
|
query.Command = strings.Replace(query.Command, ":interval:", "time(:interval:)", -1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-04 00:25:48 +00:00
|
|
|
var up = func(db *bolt.DB) error {
|
2018-03-08 07:09:56 +00:00
|
|
|
// For each dashboard
|
2018-03-07 01:05:01 +00:00
|
|
|
err := db.Update(func(tx *bolt.Tx) error {
|
2018-03-08 07:09:56 +00:00
|
|
|
bucket := tx.Bucket(dashboardBucket)
|
2018-03-07 01:05:01 +00:00
|
|
|
err := bucket.ForEach(func(id, data []byte) error {
|
|
|
|
board := &Dashboard{}
|
|
|
|
|
|
|
|
err := proto.Unmarshal(data, board)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("unmarshaling error: ", err)
|
|
|
|
}
|
|
|
|
|
2018-03-08 07:09:56 +00:00
|
|
|
// Migrate the dashboard
|
|
|
|
updateDashboard(board)
|
2018-03-07 01:05:01 +00:00
|
|
|
|
2018-04-04 00:25:48 +00:00
|
|
|
data, err = proto.Marshal(board)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("marshaling error: ", err)
|
|
|
|
}
|
2018-03-07 01:05:01 +00:00
|
|
|
|
2018-04-04 00:25:48 +00:00
|
|
|
err = bucket.Put(id, data)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("error updating dashboard: ", err)
|
|
|
|
}
|
2018-03-07 01:05:01 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal("error updating dashboards: ", err)
|
|
|
|
}
|
2018-03-08 07:09:56 +00:00
|
|
|
|
|
|
|
return nil
|
2018-03-07 01:05:01 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-04-04 00:25:48 +00:00
|
|
|
var down = func(db *bolt.DB) error {
|
2018-03-07 01:05:01 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-04-04 00:25:48 +00:00
|
|
|
/*
|
|
|
|
Import protobuf types and bucket names that are pertinent to this migration.
|
|
|
|
This isolates the migration from the codebase, and prevents a future change
|
|
|
|
to a type definition from invalidating the migration functions.
|
|
|
|
*/
|
2018-03-08 07:09:56 +00:00
|
|
|
var dashboardBucket = []byte("Dashoard")
|
2018-03-07 01:05:01 +00:00
|
|
|
|
|
|
|
type Dashboard struct {
|
2018-03-08 07:09:56 +00:00
|
|
|
ID int64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
|
2018-04-05 22:44:27 +00:00
|
|
|
Name []byte `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
|
2018-03-08 07:09:56 +00:00
|
|
|
Cells []*DashboardCell `protobuf:"bytes,3,rep,name=cells" json:"cells,omitempty"`
|
2018-04-05 22:44:27 +00:00
|
|
|
Templates []byte `protobuf:"bytes,4,rep,name=templates" json:"templates,omitempty"`
|
|
|
|
Organization []byte `protobuf:"bytes,5,opt,name=Organization,proto3" json:"Organization,omitempty"`
|
2018-03-07 01:05:01 +00:00
|
|
|
}
|
2018-03-08 07:09:56 +00:00
|
|
|
|
|
|
|
func (*Dashboard) ProtoMessage() {}
|
|
|
|
func (m *Dashboard) Reset() { *m = Dashboard{} }
|
|
|
|
func (m *Dashboard) String() string { return proto.CompactTextString(m) }
|
|
|
|
|
2018-03-07 01:05:01 +00:00
|
|
|
type DashboardCell struct {
|
2018-04-04 00:25:48 +00:00
|
|
|
X int32 `protobuf:"varint,1,opt,name=x,proto3" json:"x,omitempty"`
|
|
|
|
Y int32 `protobuf:"varint,2,opt,name=y,proto3" json:"y,omitempty"`
|
|
|
|
W int32 `protobuf:"varint,3,opt,name=w,proto3" json:"w,omitempty"`
|
|
|
|
H int32 `protobuf:"varint,4,opt,name=h,proto3" json:"h,omitempty"`
|
|
|
|
Queries []*Query `protobuf:"bytes,5,rep,name=queries" json:"queries,omitempty"`
|
2018-04-05 22:44:27 +00:00
|
|
|
Name []byte `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`
|
|
|
|
Type []byte `protobuf:"bytes,7,opt,name=type,proto3" json:"type,omitempty"`
|
|
|
|
ID []byte `protobuf:"bytes,8,opt,name=ID,proto3" json:"ID,omitempty"`
|
|
|
|
Axes []byte `protobuf:"bytes,9,rep,name=axes" json:"axes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value"`
|
|
|
|
Colors []byte `protobuf:"bytes,10,rep,name=colors" json:"colors,omitempty"`
|
|
|
|
Legend []byte `protobuf:"bytes,11,opt,name=legend" json:"legend,omitempty"`
|
|
|
|
TableOptions []byte `protobuf:"bytes,12,opt,name=tableOptions" json:"tableOptions,omitempty"`
|
2018-03-07 01:05:01 +00:00
|
|
|
}
|
2018-03-08 07:09:56 +00:00
|
|
|
|
|
|
|
func (m *DashboardCell) Reset() { *m = DashboardCell{} }
|
|
|
|
func (m *DashboardCell) String() string { return proto.CompactTextString(m) }
|
|
|
|
func (*DashboardCell) ProtoMessage() {}
|
|
|
|
|
2018-03-07 01:05:01 +00:00
|
|
|
type Query struct {
|
2018-03-08 07:09:56 +00:00
|
|
|
Command string `protobuf:"bytes,1,opt,name=Command,proto3" json:"Command,omitempty"`
|
2018-04-05 22:44:27 +00:00
|
|
|
DB []byte `protobuf:"bytes,2,opt,name=DB,proto3" json:"DB,omitempty"`
|
|
|
|
RP []byte `protobuf:"bytes,3,opt,name=RP,proto3" json:"RP,omitempty"`
|
|
|
|
GroupBys []byte `protobuf:"bytes,4,rep,name=GroupBys" json:"GroupBys,omitempty"`
|
|
|
|
Wheres []byte `protobuf:"bytes,5,rep,name=Wheres" json:"Wheres,omitempty"`
|
|
|
|
Label []byte `protobuf:"bytes,6,opt,name=Label,proto3" json:"Label,omitempty"`
|
|
|
|
Range []byte `protobuf:"bytes,7,opt,name=Range" json:"Range,omitempty"`
|
|
|
|
Source []byte `protobuf:"bytes,8,opt,name=Source,proto3" json:"Source,omitempty"`
|
|
|
|
Shifts []byte `protobuf:"bytes,9,rep,name=Shifts" json:"Shifts,omitempty"`
|
2018-03-07 01:05:01 +00:00
|
|
|
}
|
2018-03-08 07:09:56 +00:00
|
|
|
|
|
|
|
func (m *Query) Reset() { *m = Query{} }
|
|
|
|
func (m *Query) String() string { return proto.CompactTextString(m) }
|
|
|
|
func (*Query) ProtoMessage() {}
|