• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

golang-migrate / migrate / 17662383123

12 Sep 2025 02:06AM UTC coverage: 50.017% (-4.0%) from 54.037%
17662383123

Pull #1318

github

daniel-garcia
store db migrates in the database if it supports it
Pull Request #1318: WIP: Store migrates in db

163 of 653 new or added lines in 7 files covered. (24.96%)

180 existing lines in 3 files now uncovered.

4362 of 8721 relevant lines covered (50.02%)

44.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/database_source.go
1
package migrate
2

3
import (
4
        "fmt"
5
        "io"
6
        "os"
7
        "strings"
8

9
        "github.com/golang-migrate/migrate/v4/database"
10
        "github.com/golang-migrate/migrate/v4/source"
11
)
12

13
// DatabaseSource implements source.Driver by reading migrations from database storage
14
type DatabaseSource struct {
15
        storageDriver database.MigrationStorageDriver
16
        logger        Logger
17
        versions      []uint
18
}
19

20
var _ source.Driver = &DatabaseSource{}
21

22
// Open is not used for DatabaseSource as it's created directly
NEW
23
func (d *DatabaseSource) Open(url string) (source.Driver, error) {
×
NEW
24
        return d, nil
×
NEW
25
}
×
26

27
// Close closes the database source
NEW
28
func (d *DatabaseSource) Close() error {
×
NEW
29
        return nil
×
NEW
30
}
×
31

32
// First returns the first migration version available in the database
NEW
33
func (d *DatabaseSource) First() (version uint, err error) {
×
NEW
34
        if err := d.loadVersions(); err != nil {
×
NEW
35
                return 0, err
×
NEW
36
        }
×
37
        
NEW
38
        if len(d.versions) == 0 {
×
NEW
39
                return 0, os.ErrNotExist
×
NEW
40
        }
×
41
        
NEW
42
        return d.versions[0], nil
×
43
}
44

45
// Prev returns the previous migration version relative to the current version
NEW
46
func (d *DatabaseSource) Prev(version uint) (prevVersion uint, err error) {
×
NEW
47
        if err := d.loadVersions(); err != nil {
×
NEW
48
                return 0, err
×
NEW
49
        }
×
50
        
NEW
51
        for i, v := range d.versions {
×
NEW
52
                if v == version && i > 0 {
×
NEW
53
                        return d.versions[i-1], nil
×
NEW
54
                }
×
55
        }
56
        
NEW
57
        return 0, os.ErrNotExist
×
58
}
59

60
// Next returns the next migration version relative to the current version
NEW
61
func (d *DatabaseSource) Next(version uint) (nextVersion uint, err error) {
×
NEW
62
        if err := d.loadVersions(); err != nil {
×
NEW
63
                return 0, err
×
NEW
64
        }
×
65
        
NEW
66
        for i, v := range d.versions {
×
NEW
67
                if v == version && i < len(d.versions)-1 {
×
NEW
68
                        return d.versions[i+1], nil
×
NEW
69
                }
×
70
        }
71
        
NEW
72
        return 0, os.ErrNotExist
×
73
}
74

75
// ReadUp reads the up migration for the specified version from the database
NEW
76
func (d *DatabaseSource) ReadUp(version uint) (r io.ReadCloser, identifier string, err error) {
×
NEW
77
        upScript, _, err := d.storageDriver.GetMigration(version)
×
NEW
78
        if err != nil {
×
NEW
79
                return nil, "", err
×
NEW
80
        }
×
81
        
NEW
82
        if len(upScript) == 0 {
×
NEW
83
                return nil, "", os.ErrNotExist
×
NEW
84
        }
×
85
        
NEW
86
        reader := io.NopCloser(strings.NewReader(string(upScript)))
×
NEW
87
        identifier = fmt.Sprintf("%d.up", version)
×
NEW
88
        
×
NEW
89
        return reader, identifier, nil
×
90
}
91

92
// ReadDown reads the down migration for the specified version from the database
NEW
93
func (d *DatabaseSource) ReadDown(version uint) (r io.ReadCloser, identifier string, err error) {
×
NEW
94
        _, downScript, err := d.storageDriver.GetMigration(version)
×
NEW
95
        if err != nil {
×
NEW
96
                return nil, "", err
×
NEW
97
        }
×
98
        
NEW
99
        if len(downScript) == 0 {
×
NEW
100
                return nil, "", os.ErrNotExist
×
NEW
101
        }
×
102
        
NEW
103
        reader := io.NopCloser(strings.NewReader(string(downScript)))
×
NEW
104
        identifier = fmt.Sprintf("%d.down", version)
×
NEW
105
        
×
NEW
106
        return reader, identifier, nil
×
107
}
108

109
// loadVersions loads available migration versions from the database
NEW
110
func (d *DatabaseSource) loadVersions() error {
×
NEW
111
        if d.versions != nil {
×
NEW
112
                return nil // Already loaded
×
NEW
113
        }
×
114
        
NEW
115
        versions, err := d.storageDriver.GetStoredMigrations()
×
NEW
116
        if err != nil {
×
NEW
117
                return fmt.Errorf("failed to load migrations from database: %w", err)
×
NEW
118
        }
×
119
        
NEW
120
        d.versions = versions
×
NEW
121
        return nil
×
122
}
123

124
// logPrintf writes to the logger if available
NEW
125
func (d *DatabaseSource) logPrintf(format string, v ...interface{}) {
×
NEW
126
        if d.logger != nil {
×
NEW
127
                d.logger.Printf(format, v...)
×
NEW
128
        }
×
129
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc