mirror of
https://github.com/harness/drone.git
synced 2025-05-07 21:21:51 +08:00
108 lines
2.5 KiB
Go
108 lines
2.5 KiB
Go
// Copyright 2022 Harness Inc. All rights reserved.
|
|
// Use of this source code is governed by the Polyform Free Trial License
|
|
// that can be found in the LICENSE.md file for this repository.
|
|
|
|
package migrate
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"embed"
|
|
"fmt"
|
|
"io/fs"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
"github.com/maragudk/migrate"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
//go:embed postgres/*.sql
|
|
var postgres embed.FS
|
|
|
|
//go:embed sqlite/*.sql
|
|
var sqlite embed.FS
|
|
|
|
const tableName = "migrations"
|
|
|
|
// Migrate performs the database migration.
|
|
func Migrate(ctx context.Context, db *sqlx.DB) error {
|
|
opts := getMigrator(db)
|
|
return migrate.New(opts).MigrateUp(ctx)
|
|
}
|
|
|
|
// To performs the database migration to the specific version.
|
|
func To(ctx context.Context, db *sqlx.DB, version string) error {
|
|
opts := getMigrator(db)
|
|
return migrate.New(opts).MigrateTo(ctx, version)
|
|
}
|
|
|
|
// Current returns the current version ID (the latest migration applied) of the database.
|
|
func Current(ctx context.Context, db *sqlx.DB) (string, error) {
|
|
var (
|
|
query string
|
|
migrationTableCount int
|
|
)
|
|
|
|
switch db.DriverName() {
|
|
case "sqlite3":
|
|
query = `
|
|
SELECT count(*)
|
|
FROM sqlite_master
|
|
WHERE name = ? and type = 'table'`
|
|
default:
|
|
query = `
|
|
SELECT count(*)
|
|
FROM information_schema.tables
|
|
WHERE table_name = ? and table_schema = 'public'`
|
|
}
|
|
|
|
if err := db.QueryRowContext(ctx, query, tableName).Scan(&migrationTableCount); err != nil {
|
|
return "", fmt.Errorf("failed to check migration table existence: %w", err)
|
|
}
|
|
|
|
if migrationTableCount == 0 {
|
|
return "", nil
|
|
}
|
|
|
|
var version string
|
|
|
|
query = "select version from " + tableName + " limit 1"
|
|
if err := db.QueryRowContext(ctx, query).Scan(&version); err != nil {
|
|
return "", fmt.Errorf("failed to read current DB version from migration table: %w", err)
|
|
}
|
|
|
|
return version, nil
|
|
}
|
|
|
|
func getMigrator(db *sqlx.DB) migrate.Options {
|
|
before := func(_ context.Context, _ *sql.Tx, version string) error {
|
|
log.Trace().Str("version", version).Msg("migration started")
|
|
return nil
|
|
}
|
|
|
|
after := func(_ context.Context, _ *sql.Tx, version string) error {
|
|
log.Trace().Str("version", version).Msg("migration complete")
|
|
return nil
|
|
}
|
|
|
|
opts := migrate.Options{
|
|
After: after,
|
|
Before: before,
|
|
DB: db.DB,
|
|
FS: sqlite,
|
|
Table: tableName,
|
|
}
|
|
|
|
switch db.DriverName() {
|
|
case "postgres":
|
|
folder, _ := fs.Sub(postgres, "postgres")
|
|
opts.FS = folder
|
|
|
|
default:
|
|
folder, _ := fs.Sub(sqlite, "sqlite")
|
|
opts.FS = folder
|
|
}
|
|
|
|
return opts
|
|
}
|