Started adding migrations
continuous-integration/drone/push Build is failing Details

This commit is contained in:
konrad 2019-03-24 21:45:18 +01:00
parent 5e16a77b7b
commit 94eea2f32f
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
4 changed files with 240 additions and 0 deletions

View File

@ -0,0 +1,17 @@
// Vikunja is a todo-list application to facilitate your life.
// Copyright 2019 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package migration

View File

@ -16,6 +16,14 @@
package migration
import "src.techknowlogick.com/xormigrate"
// You can get the id string for new migrations by running `date +%Y%m%d%H%M%S` on a unix system.
var migrations []*xormigrate.Migration
func Migrate() {
// Because init() does not guarantee the order in which these are added to the slice,
// we need to sort them to ensure that they are in order
}

214
vendor/github.com/go-xorm/xorm/migrate/migrate.go generated vendored Normal file
View File

@ -0,0 +1,214 @@
package migrate
import (
"errors"
"fmt"
"github.com/go-xorm/xorm"
)
// MigrateFunc is the func signature for migrating.
type MigrateFunc func(*xorm.Engine) error
// RollbackFunc is the func signature for rollbacking.
type RollbackFunc func(*xorm.Engine) error
// InitSchemaFunc is the func signature for initializing the schema.
type InitSchemaFunc func(*xorm.Engine) error
// Options define options for all migrations.
type Options struct {
// TableName is the migration table.
TableName string
// IDColumnName is the name of column where the migration id will be stored.
IDColumnName string
}
// Migration represents a database migration (a modification to be made on the database).
type Migration struct {
// ID is the migration identifier. Usually a timestamp like "201601021504".
ID string
// Migrate is a function that will br executed while running this migration.
Migrate MigrateFunc
// Rollback will be executed on rollback. Can be nil.
Rollback RollbackFunc
}
// Migrate represents a collection of all migrations of a database schema.
type Migrate struct {
db *xorm.Engine
options *Options
migrations []*Migration
initSchema InitSchemaFunc
}
var (
// DefaultOptions can be used if you don't want to think about options.
DefaultOptions = &Options{
TableName: "migrations",
IDColumnName: "id",
}
// ErrRollbackImpossible is returned when trying to rollback a migration
// that has no rollback function.
ErrRollbackImpossible = errors.New("It's impossible to rollback this migration")
// ErrNoMigrationDefined is returned when no migration is defined.
ErrNoMigrationDefined = errors.New("No migration defined")
// ErrMissingID is returned when the ID od migration is equal to ""
ErrMissingID = errors.New("Missing ID in migration")
// ErrNoRunnedMigration is returned when any runned migration was found while
// running RollbackLast
ErrNoRunnedMigration = errors.New("Could not find last runned migration")
)
// New returns a new Gormigrate.
func New(db *xorm.Engine, options *Options, migrations []*Migration) *Migrate {
return &Migrate{
db: db,
options: options,
migrations: migrations,
}
}
// InitSchema sets a function that is run if no migration is found.
// The idea is preventing to run all migrations when a new clean database
// is being migrating. In this function you should create all tables and
// foreign key necessary to your application.
func (m *Migrate) InitSchema(initSchema InitSchemaFunc) {
m.initSchema = initSchema
}
// Migrate executes all migrations that did not run yet.
func (m *Migrate) Migrate() error {
if err := m.createMigrationTableIfNotExists(); err != nil {
return err
}
if m.initSchema != nil && m.isFirstRun() {
if err := m.runInitSchema(); err != nil {
return err
}
return nil
}
for _, migration := range m.migrations {
if err := m.runMigration(migration); err != nil {
return err
}
}
return nil
}
// RollbackLast undo the last migration
func (m *Migrate) RollbackLast() error {
if len(m.migrations) == 0 {
return ErrNoMigrationDefined
}
lastRunnedMigration, err := m.getLastRunnedMigration()
if err != nil {
return err
}
if err := m.RollbackMigration(lastRunnedMigration); err != nil {
return err
}
return nil
}
func (m *Migrate) getLastRunnedMigration() (*Migration, error) {
for i := len(m.migrations) - 1; i >= 0; i-- {
migration := m.migrations[i]
if m.migrationDidRun(migration) {
return migration, nil
}
}
return nil, ErrNoRunnedMigration
}
// RollbackMigration undo a migration.
func (m *Migrate) RollbackMigration(mig *Migration) error {
if mig.Rollback == nil {
return ErrRollbackImpossible
}
if err := mig.Rollback(m.db); err != nil {
return err
}
sql := fmt.Sprintf("DELETE FROM %s WHERE %s = ?", m.options.TableName, m.options.IDColumnName)
if _, err := m.db.Exec(sql, mig.ID); err != nil {
return err
}
return nil
}
func (m *Migrate) runInitSchema() error {
if err := m.initSchema(m.db); err != nil {
return err
}
for _, migration := range m.migrations {
if err := m.insertMigration(migration.ID); err != nil {
return err
}
}
return nil
}
func (m *Migrate) runMigration(migration *Migration) error {
if len(migration.ID) == 0 {
return ErrMissingID
}
if !m.migrationDidRun(migration) {
if err := migration.Migrate(m.db); err != nil {
return err
}
if err := m.insertMigration(migration.ID); err != nil {
return err
}
}
return nil
}
func (m *Migrate) createMigrationTableIfNotExists() error {
exists, err := m.db.IsTableExist(m.options.TableName)
if err != nil {
return err
}
if exists {
return nil
}
sql := fmt.Sprintf("CREATE TABLE %s (%s VARCHAR(255) PRIMARY KEY)", m.options.TableName, m.options.IDColumnName)
if _, err := m.db.Exec(sql); err != nil {
return err
}
return nil
}
func (m *Migrate) migrationDidRun(mig *Migration) bool {
row := m.db.DB().QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM %s WHERE %s = ?", m.options.TableName, m.options.IDColumnName), mig.ID)
var count int
row.Scan(&count)
return count > 0
}
func (m *Migrate) isFirstRun() bool {
row := m.db.DB().QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM %s", m.options.TableName))
var count int
row.Scan(&count)
return count == 0
}
func (m *Migrate) insertMigration(id string) error {
sql := fmt.Sprintf("INSERT INTO %s (%s) VALUES (?)", m.options.TableName, m.options.IDColumnName)
_, err := m.db.Exec(sql, id)
return err
}

1
vendor/modules.txt vendored
View File

@ -54,6 +54,7 @@ github.com/go-xorm/builder
# github.com/go-xorm/core v0.5.8
github.com/go-xorm/core
# github.com/go-xorm/xorm v0.0.0-20170930012613-29d4a0330a00
github.com/go-xorm/xorm/migrate
github.com/go-xorm/xorm
# github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
github.com/go-xorm/xorm-redis-cache