focalboard/server/services/store/sqlstore/data_migrations.go
Miguel de la Cruz e7c38c8822
Adds data migrations and the unique IDs migration (#1776)
* Adds data migrations and the unique IDs migration

* Adds GetSystemSetting tests

* Add log statements to data migrations

* Move migrations to the store and ensure they follow an order mixing database and data migrations

* Fix system settings

* Add tests for unique id migration

* Small comment change

* Make a couple of methods private and wrap the migration in a transaction

* Update public methods

* Add database mutex to data migrations

* Create server params and pass a mutex factory to the store

* Fix plugin linter

* Make isPlugin private

* Fix comment typo

Co-authored-by: Doug Lauder <wiggin77@warpmail.net>

Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
2021-11-11 17:01:43 +01:00

78 lines
2.3 KiB
Go

package sqlstore
import (
"context"
"fmt"
"strconv"
"github.com/mattermost/focalboard/server/model"
"github.com/mattermost/focalboard/server/utils"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
)
const (
UniqueIDsMigrationKey = "UniqueIDsMigrationComplete"
)
func (s *SQLStore) runUniqueIDsMigration() error {
setting, err := s.GetSystemSetting(UniqueIDsMigrationKey)
if err != nil {
return fmt.Errorf("cannot get migration state: %w", err)
}
// If the migration is already completed, do not run it again.
if hasAlreadyRun, _ := strconv.ParseBool(setting); hasAlreadyRun {
return nil
}
s.logger.Debug("Running Unique IDs migration")
tx, txErr := s.db.BeginTx(context.Background(), nil)
if txErr != nil {
return txErr
}
blocks, err := s.getBlocksWithSameID(tx)
if err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
s.logger.Error("unique IDs transaction rollback error", mlog.Err(rollbackErr), mlog.String("methodName", "getBlocksWithSameID"))
}
return fmt.Errorf("cannot get blocks with same ID: %w", err)
}
blocksByID := map[string][]model.Block{}
for _, block := range blocks {
blocksByID[block.ID] = append(blocksByID[block.ID], block)
}
for _, blocks := range blocksByID {
for i, block := range blocks {
if i == 0 {
// do nothing for the first ID, only updating the others
continue
}
newID := utils.NewID(model.BlockType2IDType(block.Type))
if err := s.replaceBlockID(tx, block.ID, newID, block.WorkspaceID); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
s.logger.Error("unique IDs transaction rollback error", mlog.Err(rollbackErr), mlog.String("methodName", "replaceBlockID"))
}
return fmt.Errorf("cannot replace blockID %s: %w", block.ID, err)
}
}
}
if err := s.setSystemSetting(tx, UniqueIDsMigrationKey, strconv.FormatBool(true)); err != nil {
if rollbackErr := tx.Rollback(); rollbackErr != nil {
s.logger.Error("unique IDs transaction rollback error", mlog.Err(rollbackErr), mlog.String("methodName", "setSystemSetting"))
}
return fmt.Errorf("cannot mark migration as completed: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("cannot commit unique IDs transaction: %w", err)
}
s.logger.Debug("Unique IDs migration finished successfully")
return nil
}