github.com/fr-nvriep/migrate/v4@v4.3.2/internal/cli/commands.go (about) 1 package cli 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/fr-nvriep/migrate/v4" 7 _ "github.com/fr-nvriep/migrate/v4/database/stub" // TODO remove again 8 _ "github.com/fr-nvriep/migrate/v4/source/file" 9 "os" 10 "path/filepath" 11 "strconv" 12 "strings" 13 "time" 14 ) 15 16 func nextSeq(matches []string, dir string, seqDigits int) (string, error) { 17 if seqDigits <= 0 { 18 return "", errors.New("Digits must be positive") 19 } 20 21 nextSeq := 1 22 if len(matches) > 0 { 23 filename := matches[len(matches)-1] 24 matchSeqStr := strings.TrimPrefix(filename, dir) 25 idx := strings.Index(matchSeqStr, "_") 26 if idx < 1 { // Using 1 instead of 0 since there should be at least 1 digit 27 return "", errors.New("Malformed migration filename: " + filename) 28 } 29 matchSeqStr = matchSeqStr[0:idx] 30 var err error 31 nextSeq, err = strconv.Atoi(matchSeqStr) 32 if err != nil { 33 return "", err 34 } 35 nextSeq++ 36 } 37 if nextSeq <= 0 { 38 return "", errors.New("Next sequence number must be positive") 39 } 40 41 nextSeqStr := strconv.Itoa(nextSeq) 42 if len(nextSeqStr) > seqDigits { 43 return "", fmt.Errorf("Next sequence number %s too large. At most %d digits are allowed", nextSeqStr, seqDigits) 44 } 45 padding := seqDigits - len(nextSeqStr) 46 if padding > 0 { 47 nextSeqStr = strings.Repeat("0", padding) + nextSeqStr 48 } 49 return nextSeqStr, nil 50 } 51 52 func createCmd(dir string, startTime time.Time, format string, name string, ext string, seq bool, seqDigits int) { 53 var base string 54 if seq && format != defaultTimeFormat { 55 log.fatalErr(errors.New("The seq and format options are mutually exclusive")) 56 } 57 if seq { 58 if seqDigits <= 0 { 59 log.fatalErr(errors.New("Digits must be positive")) 60 } 61 matches, err := filepath.Glob(dir + "*" + ext) 62 if err != nil { 63 log.fatalErr(err) 64 } 65 nextSeqStr, err := nextSeq(matches, dir, seqDigits) 66 if err != nil { 67 log.fatalErr(err) 68 } 69 base = fmt.Sprintf("%v%v_%v.", dir, nextSeqStr, name) 70 } else { 71 switch format { 72 case "": 73 log.fatal("Time format may not be empty") 74 case "unix": 75 base = fmt.Sprintf("%v%v_%v.", dir, startTime.Unix(), name) 76 case "unixNano": 77 base = fmt.Sprintf("%v%v_%v.", dir, startTime.UnixNano(), name) 78 default: 79 base = fmt.Sprintf("%v%v_%v.", dir, startTime.Format(format), name) 80 } 81 } 82 83 if err := os.MkdirAll(dir, os.ModePerm); err != nil { 84 log.fatalErr(err) 85 } 86 87 createFile(base + "up" + ext) 88 createFile(base + "down" + ext) 89 } 90 91 func createFile(fname string) { 92 if _, err := os.Create(fname); err != nil { 93 log.fatalErr(err) 94 } 95 } 96 97 func gotoCmd(m *migrate.Migrate, v uint) { 98 if err := m.Migrate(v); err != nil { 99 if err != migrate.ErrNoChange { 100 log.fatalErr(err) 101 } else { 102 log.Println(err) 103 } 104 } 105 } 106 107 func upCmd(m *migrate.Migrate, limit int) { 108 if limit >= 0 { 109 if err := m.Steps(limit); err != nil { 110 if err != migrate.ErrNoChange { 111 log.fatalErr(err) 112 } else { 113 log.Println(err) 114 } 115 } 116 } else { 117 if err := m.Up(); err != nil { 118 if err != migrate.ErrNoChange { 119 log.fatalErr(err) 120 } else { 121 log.Println(err) 122 } 123 } 124 } 125 } 126 127 func downCmd(m *migrate.Migrate, limit int) { 128 if limit >= 0 { 129 if err := m.Steps(-limit); err != nil { 130 if err != migrate.ErrNoChange { 131 log.fatalErr(err) 132 } else { 133 log.Println(err) 134 } 135 } 136 } else { 137 if err := m.Down(); err != nil { 138 if err != migrate.ErrNoChange { 139 log.fatalErr(err) 140 } else { 141 log.Println(err) 142 } 143 } 144 } 145 } 146 147 func dropCmd(m *migrate.Migrate) { 148 if err := m.Drop(); err != nil { 149 log.fatalErr(err) 150 } 151 } 152 153 func forceCmd(m *migrate.Migrate, v int) { 154 if err := m.Force(v); err != nil { 155 log.fatalErr(err) 156 } 157 } 158 159 func versionCmd(m *migrate.Migrate) { 160 v, dirty, err := m.Version() 161 if err != nil { 162 log.fatalErr(err) 163 } 164 if dirty { 165 log.Printf("%v (dirty)\n", v) 166 } else { 167 log.Println(v) 168 } 169 }