status-go/protocol/sqlite/db.go

89 lines
2.4 KiB
Go
Raw Normal View History

2019-07-17 22:25:42 +00:00
package sqlite
import (
"database/sql"
2019-07-30 06:14:13 +00:00
"github.com/pkg/errors"
_ "github.com/mutecomm/go-sqlcipher/v4" // We require go sqlcipher that overrides default implementation
2019-07-17 22:25:42 +00:00
"github.com/status-im/migrate/v4"
"github.com/status-im/migrate/v4/database/sqlcipher"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
mvdsmigrations "github.com/status-im/mvds/persistenceutil"
2019-07-17 22:25:42 +00:00
)
var migrationsTable = "status_protocol_go_" + sqlcipher.DefaultMigrationsTable
// applyMigrations allows to apply bindata migrations on the current *sql.DB.
2019-07-17 22:25:42 +00:00
// `assetNames` is a list of assets with migrations and `assetGetter` is responsible
// for returning the content of the asset with a given name.
func applyMigrations(db *sql.DB, assetNames []string, assetGetter func(name string) ([]byte, error)) error {
2019-07-17 22:25:42 +00:00
resources := bindata.Resource(
assetNames,
assetGetter,
)
source, err := bindata.WithInstance(resources)
if err != nil {
2019-07-30 06:14:13 +00:00
return errors.Wrap(err, "failed to create migration source")
2019-07-17 22:25:42 +00:00
}
driver, err := sqlcipher.WithInstance(db, &sqlcipher.Config{
MigrationsTable: migrationsTable,
})
2019-07-17 22:25:42 +00:00
if err != nil {
2019-07-30 06:14:13 +00:00
return errors.Wrap(err, "failed to create driver")
2019-07-17 22:25:42 +00:00
}
m, err := migrate.NewWithInstance(
"go-bindata",
source,
"sqlcipher",
2019-07-30 06:14:13 +00:00
driver,
)
2019-07-17 22:25:42 +00:00
if err != nil {
2019-07-30 06:14:13 +00:00
return errors.Wrap(err, "failed to create migration instance")
2019-07-17 22:25:42 +00:00
}
2020-10-01 08:31:23 +00:00
version, dirty, err := m.Version()
if err != nil && err != migrate.ErrNilVersion {
return errors.Wrap(err, "could not get version")
}
err = ApplyAdHocMigrations(version, dirty, m, db)
if err != nil {
return errors.Wrap(err, "failed to apply ad-hoc migrations")
}
2020-10-01 08:31:23 +00:00
if dirty {
err = ReplayLastMigration(version, m)
if err != nil {
return errors.Wrap(err, "failed to replay last migration")
2020-10-01 08:31:23 +00:00
}
}
2019-07-17 22:25:42 +00:00
if err = m.Up(); err != migrate.ErrNoChange {
2019-07-30 06:14:13 +00:00
return errors.Wrap(err, "failed to migrate")
2019-07-17 22:25:42 +00:00
}
return nil
}
func Migrate(database *sql.DB) error {
// Apply migrations for all components.
err := mvdsmigrations.Migrate(database)
if err != nil {
return errors.Wrap(err, "failed to apply mvds migrations")
}
migrationNames, migrationGetter, err := prepareMigrations(defaultMigrations)
if err != nil {
return errors.Wrap(err, "failed to prepare status-go/protocol migrations")
}
err = applyMigrations(database, migrationNames, migrationGetter)
if err != nil {
return errors.Wrap(err, "failed to apply status-go/protocol migrations")
}
return nil
}