github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/migration/cli/command/command.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path"
     8  	"text/template"
     9  	"time"
    10  )
    11  
    12  var defaultMigrationDir = "migrations/"
    13  
    14  type MigrationType string
    15  
    16  const (
    17  	SQL MigrationType = "sql"
    18  	Go  MigrationType = "go"
    19  )
    20  
    21  type MigrationCommand struct {
    22  	GenerateCommand GenerateCommand `command:"generate"`
    23  }
    24  
    25  type GenerateCommand struct {
    26  	MigrationDirectory string        `short:"d" long:"directory" default:"migrations" description:"The directory to which the migration files should be written"`
    27  	MigrationName      string        `short:"n" long:"name" description:"The name of the migration"`
    28  	Type               MigrationType `short:"t" long:"type" description:"The file type of the migration"`
    29  }
    30  
    31  func NewGenerateCommand(migrationDir string, migrationName string, migrationType MigrationType) *GenerateCommand {
    32  	if migrationDir == "" {
    33  		migrationDir = defaultMigrationDir
    34  	}
    35  
    36  	return &GenerateCommand{
    37  		migrationDir,
    38  		migrationName,
    39  		migrationType,
    40  	}
    41  }
    42  
    43  func (c *GenerateCommand) Execute(args []string) error {
    44  	if c.Type == SQL {
    45  		return c.GenerateSQLMigration()
    46  	} else if c.Type == Go {
    47  		return c.GenerateGoMigration()
    48  	}
    49  	return fmt.Errorf("unsupported migration type %s. Supported types include %s and %s", c.Type, SQL, Go)
    50  }
    51  
    52  func (c *GenerateCommand) GenerateSQLMigration() error {
    53  	currentTime := time.Now().Unix()
    54  	fileNameFormat := "%d_%s.%s.sql"
    55  
    56  	upMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "up")
    57  	downMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "down")
    58  
    59  	contents := ""
    60  
    61  	err := ioutil.WriteFile(path.Join(c.MigrationDirectory, upMigrationFileName), []byte(contents), 0644)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	err = ioutil.WriteFile(path.Join(c.MigrationDirectory, downMigrationFileName), []byte(contents), 0644)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	return nil
    70  }
    71  
    72  type migrationInfo struct {
    73  	MigrationId int64
    74  	Direction   string
    75  }
    76  
    77  const goMigrationTemplate = `package migrations
    78  
    79  // implement the migration in this function
    80  func {{ .Direction }}_{{ .MigrationId }}() error {
    81  	return nil
    82  }`
    83  
    84  func renderGoMigrationToFile(filePath string, state migrationInfo) error {
    85  	migrationFile, err := os.Create(filePath)
    86  	if err != nil {
    87  		return err
    88  	}
    89  	defer migrationFile.Close()
    90  
    91  	tmpl, err := template.New("go-migration-template").Parse(goMigrationTemplate)
    92  	if err != nil {
    93  		return err
    94  	}
    95  
    96  	err = tmpl.Execute(migrationFile, state)
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	return nil
   102  }
   103  
   104  func (c *GenerateCommand) GenerateGoMigration() error {
   105  	currentTime := time.Now().Unix()
   106  	fileNameFormat := "%d_%s.%s.go"
   107  
   108  	upMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "up")
   109  	downMigrationFileName := fmt.Sprintf(fileNameFormat, currentTime, c.MigrationName, "down")
   110  
   111  	err := renderGoMigrationToFile(path.Join(c.MigrationDirectory, upMigrationFileName), migrationInfo{
   112  		MigrationId: currentTime,
   113  		Direction:   "Up",
   114  	})
   115  	if err != nil {
   116  		return err
   117  	}
   118  
   119  	err = renderGoMigrationToFile(path.Join(c.MigrationDirectory, downMigrationFileName), migrationInfo{
   120  		MigrationId: currentTime,
   121  		Direction:   "Down",
   122  	})
   123  	if err != nil {
   124  		return err
   125  	}
   126  
   127  	return nil
   128  }