github.com/status-im/status-go@v1.1.0/protocol/sqlite/ad_hoc_migration.go (about)

     1  package sqlite
     2  
     3  import (
     4  	"database/sql"
     5  
     6  	_ "github.com/mutecomm/go-sqlcipher/v4" // We require go sqlcipher that overrides default implementation
     7  	"github.com/pkg/errors"
     8  	"github.com/status-im/migrate/v4"
     9  )
    10  
    11  const communitiesMigrationVersion uint = 1605075346
    12  
    13  // FixCommunitiesMigration fixes an issue with a released migration
    14  // In some instances if it was interrupted the migration would be skipped
    15  // but marked as completed.
    16  // What we do here is that we check whether we are at that migration, if
    17  // so we check that the communities table is present, if not we re-run that
    18  // migration.
    19  func FixCommunitiesMigration(version uint, dirty bool, m *migrate.Migrate, db *sql.DB) error {
    20  	// If the version is not the same, ignore
    21  	if version != communitiesMigrationVersion {
    22  		return nil
    23  	}
    24  
    25  	// If it's dirty, it will be replayed anyway
    26  	if dirty {
    27  		return nil
    28  	}
    29  
    30  	// Otherwise we check whether it actually succeeded by checking for the
    31  	// presence of the communities_communities table
    32  
    33  	var name string
    34  
    35  	err := db.QueryRow(`SELECT name FROM sqlite_master WHERE type='table' AND name='communities_communities'`).Scan(&name)
    36  
    37  	// If the err is nil, it means the migration went through fine
    38  	if err == nil {
    39  		return nil
    40  	}
    41  
    42  	// If any other other, we return the error as that's unexpected
    43  	if err != sql.ErrNoRows {
    44  		return errors.Wrap(err, "failed to find the communities table")
    45  	}
    46  
    47  	// We replay the migration then
    48  	return ReplayLastMigration(version, m)
    49  }
    50  
    51  func ReplayLastMigration(version uint, m *migrate.Migrate) error {
    52  	// Force version if dirty so it's not dirty anymore
    53  	if err := m.Force(int(version)); err != nil {
    54  		return errors.Wrap(err, "failed to force migration")
    55  	}
    56  
    57  	// Step down 1 and we retry
    58  	if err := m.Steps(-1); err != nil {
    59  		return errors.Wrap(err, "failed to step down")
    60  	}
    61  
    62  	return nil
    63  }
    64  
    65  func ApplyAdHocMigrations(version uint, dirty bool, m *migrate.Migrate, db *sql.DB) error {
    66  	return FixCommunitiesMigration(version, dirty, m, db)
    67  }