github.com/pjdufour-truss/pop@v4.11.2-0.20190705085848-4c90b0ff4d5a+incompatible/file_migrator.go (about)

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