github.com/paweljw/pop/v5@v5.4.6/file_migrator.go (about)

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