github.com/tufanbarisyildirim/pop@v4.13.1+incompatible/file_migrator.go (about)

     1  package pop
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // FileMigrator is a migrator for SQL and Fizz
    11  // files on disk at a specified path.
    12  type FileMigrator struct {
    13  	Migrator
    14  	Path string
    15  }
    16  
    17  // NewFileMigrator for a path and a Connection
    18  func NewFileMigrator(path string, c *Connection) (FileMigrator, error) {
    19  	fm := FileMigrator{
    20  		Migrator: NewMigrator(c),
    21  		Path:     path,
    22  	}
    23  	fm.SchemaPath = path
    24  
    25  	runner := func(mf Migration, tx *Connection) error {
    26  		f, err := os.Open(mf.Path)
    27  		if err != nil {
    28  			return err
    29  		}
    30  		defer f.Close()
    31  		content, err := MigrationContent(mf, tx, f, true)
    32  		if err != nil {
    33  			return errors.Wrapf(err, "error processing %s", mf.Path)
    34  		}
    35  		if content == "" {
    36  			return nil
    37  		}
    38  		err = tx.RawQuery(content).Exec()
    39  		if err != nil {
    40  			return errors.Wrapf(err, "error executing %s, sql: %s", mf.Path, content)
    41  		}
    42  		return nil
    43  	}
    44  
    45  	err := fm.findMigrations(runner)
    46  	if err != nil {
    47  		return fm, err
    48  	}
    49  
    50  	return fm, nil
    51  }
    52  
    53  func (fm *FileMigrator) findMigrations(runner func(mf Migration, tx *Connection) error) error {
    54  	dir := fm.Path
    55  	if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
    56  		// directory doesn't exist
    57  		return nil
    58  	}
    59  	return filepath.Walk(dir, func(p string, info os.FileInfo, err error) error {
    60  		if !info.IsDir() {
    61  			match, err := ParseMigrationFilename(info.Name())
    62  			if err != nil {
    63  				return err
    64  			}
    65  			if match == nil {
    66  				return nil
    67  			}
    68  			mf := Migration{
    69  				Path:      p,
    70  				Version:   match.Version,
    71  				Name:      match.Name,
    72  				DBType:    match.DBType,
    73  				Direction: match.Direction,
    74  				Type:      match.Type,
    75  				Runner:    runner,
    76  			}
    77  			fm.Migrations[mf.Direction] = append(fm.Migrations[mf.Direction], mf)
    78  		}
    79  		return nil
    80  	})
    81  }