-
Notifications
You must be signed in to change notification settings - Fork 542
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Expand Store interface; add GetLatestVersion method in Provider #675
Conversation
@@ -35,6 +35,10 @@ type Store interface { | |||
// version is not found, this method must return [ErrVersionNotFound]. | |||
GetMigration(ctx context.Context, db DBTxConn, version int64) (*GetMigrationResult, error) | |||
|
|||
// GetLatestVersion retrieves a latest version. If the query succeeds, but the | |||
// version is not found, this method must return [ErrVersionNotFound]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this comment is true, nothing returns ErrVersionNotFound
from our underlying implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really, I'd forgotten about that
3867034
@@ -135,3 +135,13 @@ func (s *store) ListMigrations( | |||
} | |||
return migrations, nil | |||
} | |||
|
|||
func (s *store) GetLatestVersion(ctx context.Context, db DBTxConn) (int64, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max
functions usually return NULL
when nothing is found, which is something we should guard against. I think you'll want something like this.
func (s *store) GetLatestVersion(ctx context.Context, db DBTxConn) (int64, error) {
q := s.querier.GetLatestVersion(s.tablename)
var maxVersion sql.NullInt64
err := db.QueryRowContext(ctx, q).Scan(&maxVersion)
if err != nil {
return 0, fmt.Errorf("failed to get last version: %w", err)
}
if maxVersion.Valid {
return maxVersion.Int64, nil
}
return -1, ErrVersionNotFound
}
A test like this should help cover most of the edge cases across postgres / sqlite, and we'll need to make sure it works like that across the rest of the databases.
t.Run("GetLatestVersion", func(t *testing.T) {
dir := t.TempDir()
db, err := sql.Open("sqlite", filepath.Join(dir, "sql_embed.db"))
check.NoError(t, err)
store, err := database.NewStore(database.DialectSQLite3, "foo")
check.NoError(t, err)
err = store.CreateVersionTable(context.Background(), db)
check.NoError(t, err)
v, err := store.GetLatestVersion(context.Background(), db)
check.HasError(t, err)
check.IsError(t, err, database.ErrVersionNotFound)
check.Number(t, v, -1)
err = store.Insert(context.Background(), db, database.InsertRequest{Version: 0})
check.NoError(t, err)
err = store.Insert(context.Background(), db, database.InsertRequest{Version: 1})
check.NoError(t, err)
v, err = store.GetLatestVersion(context.Background(), db)
check.NoError(t, err)
check.Number(t, v, 1)
})
go test -count=1 -race -cover ./database -json | tparse
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ STATUS │ ELAPSED │ PACKAGE │ COVER │ PASS │ FAIL │ SKIP │
│─────────┼─────────┼──────────────────────────────────────┼───────┼──────┼──────┼───────│
│ PASS │ 4.34s │ github.com/pressly/goose/v3/database │ 84.3% │ 6 │ 0 │ 0 │
└────────────────────────────────────────────────────────────────────────────────────────┘
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added tests for different databases
cb36bc6
@mfridman Is it still actual? |
Sorry for the delay, I'll take another pass to see if we still want to do this. One thing I wanted to avoid was adding additional database tests to this package, and only sticking to sqlite. It tests the Store interface and the underlying implementation, but not the dialects themselves. I think those kinds of tests should go in |
Appreciate you taking the time to put together a PR. My main issue with this PR was pulling in more database-specific tests into the store package, I really want to keep that running quickly. The rest of the dialect-specific bits should be handled in the ./internal/testing/integration tests. Going to close this in favor of #758. Thanks again though 💯 |
First pass at #673
expand
Store
interface with methodGetLatestVersion(ctx context.Context, db DBTxConn) (int64, error)
use it in
Provider
instead of an inefficient old one