diff --git a/bolt/dashboards.go b/bolt/dashboards.go index d67d7779d4..f912fa32ee 100644 --- a/bolt/dashboards.go +++ b/bolt/dashboards.go @@ -3,7 +3,6 @@ package bolt import ( "context" "strconv" - "strings" "github.com/boltdb/bolt" "github.com/influxdata/chronograf" @@ -73,45 +72,6 @@ func (d *DashboardsStore) Migrate(ctx context.Context, build chronograf.BuildInf } } - return d.migrationChangeIntervalToDuration(ctx) -} - -// migrationChangeIntervalToDuration (1.4.2) -// 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) -func (d *DashboardsStore) migrationChangeIntervalToDuration(ctx context.Context) error { - versionTimestamp := "20180228182849" - complete, err := d.client.BuildStore.IsMigrationComplete(versionTimestamp) - if err != nil { - return err - } - if complete { - return nil - } - - d.client.logger.Info("Running migrationChangeIntervalToDuration (", versionTimestamp, ")") - - boards, err := d.All(ctx) - if err != nil { - return err - } - - for _, board := range boards { - for i, cell := range board.Cells { - for i, query := range cell.Queries { - query.Command = strings.Replace(query.Command, ":interval:", "time(:interval:)", -1) - cell.Queries[i] = query - } - - board.Cells[i] = cell - } - - d.Update(ctx, board) - } - - d.client.BuildStore.MarkMigrationAsComplete(versionTimestamp) - return nil } diff --git a/bolt/migrations/base.go b/bolt/migrations/base.go new file mode 100644 index 0000000000..2f65a464f1 --- /dev/null +++ b/bolt/migrations/base.go @@ -0,0 +1,59 @@ +package migration + +import ( + "context" + + "github.com/influxdata/chronograf/bolt" +) + +// Migration defines a database state/schema transition +// ID: After the migration is run, this id is stored in the database. +// We don't want to run a state transition twice +// Up: The forward-transition function. After a version upgrade, a number +// of these will run on database startup in order to bring a user's +// schema in line with struct definitions in the new version. +// Down: The backward-transition function. We don't expect these to be +// run on a user's database -- if the user needs to rollback +// to a previous version, it will be easier for them to replace +// their current database with one of their backups. The primary +// purpose of a Down() function is to help contributors move across +// development branches that have different schema definitions. +type Migration struct { + ID string + Up func(ctx context.Context, client bolt.Client) error + Down func(ctx context.Context, client bolt.Client) error +} + +// Migrate runs one migration's Up() function, if it has not already been run +func (m Migration) Migrate(ctx context.Context, client bolt.Client) error { + complete, err := client.BuildStore.IsMigrationComplete(m.ID) + if err != nil { + return err + } + if complete { + return nil + } + + // client.logger.Info("Running migration (", m.ID, ")") + + if err = m.Up(ctx, client); err != nil { + return err + } + + return client.BuildStore.MarkMigrationAsComplete(m.ID) +} + +// MigrateAll iterates through all known migrations and runs them in order +func MigrateAll(ctx context.Context, client bolt.Client) error { + for _, m := range migrations { + if err := m.Migrate(ctx, client); err != nil { + return err + } + } + + return nil +} + +var migrations = []Migration{ + changeIntervalToDuration, +} diff --git a/bolt/migrations/change_interval_to_duration.go b/bolt/migrations/change_interval_to_duration.go new file mode 100644 index 0000000000..1877f0902a --- /dev/null +++ b/bolt/migrations/change_interval_to_duration.go @@ -0,0 +1,44 @@ +package migration + +import ( + "context" + "strings" + + "github.com/influxdata/chronograf/bolt" +) + +// 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, +} + +var up = func(ctx context.Context, client bolt.Client) error { + boards, err := client.DashboardsStore.All(ctx) + if err != nil { + return err + } + + for _, board := range boards { + for i, cell := range board.Cells { + for i, query := range cell.Queries { + query.Command = strings.Replace(query.Command, ":interval:", "time(:interval:)", -1) + cell.Queries[i] = query + } + + board.Cells[i] = cell + } + + client.DashboardsStore.Update(ctx, board) + } + + return nil +} + +var down = func(ctx context.Context, client bolt.Client) error { + return nil +}