mirror of
https://github.com/go-shiori/shiori.git
synced 2025-10-03 18:26:00 +08:00
fix: postgresql migration not working with other languages (#1013)
* fix: word check on migration error * refactor: Improve PostgreSQL migration error handling using error codes * refactor: Improve PostgreSQL migration error handling and transaction management * refactor: Remove unused compareWordsInString function and its tests * style: Clean up migrations.go imports and comments * style: Fix gofmt formatting in migrations.go * chore: remove migrations_test file * ci: address golangci-lint warning * test: stop tests if creating database fails * fix: ensure migration transaction is commited or rolled back
This commit is contained in:
parent
7b6fad897b
commit
4aa0f51f10
4 changed files with 32 additions and 20 deletions
|
@ -20,12 +20,12 @@ linters-settings:
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
|
- copyloopvar
|
||||||
- gofmt
|
- gofmt
|
||||||
- gosimple
|
- gosimple
|
||||||
# - govet # Re-enable when all shadow declarations are fixed
|
# - govet # Re-enable when all shadow declarations are fixed
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- predeclared
|
- predeclared
|
||||||
- exportloopref
|
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- unconvert
|
- unconvert
|
||||||
- unused
|
- unused
|
||||||
|
|
|
@ -45,7 +45,7 @@ func testDatabase(t *testing.T, dbFactory testDatabaseFactory) {
|
||||||
t.Run(testName, func(tInner *testing.T) {
|
t.Run(testName, func(tInner *testing.T) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
db, err := dbFactory(t, ctx)
|
db, err := dbFactory(t, ctx)
|
||||||
assert.NoError(tInner, err, "Error recreating database")
|
require.NoError(tInner, err, "Error recreating database")
|
||||||
testCase(tInner, db)
|
testCase(tInner, db)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package database implements database operations and migrations
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -13,13 +14,14 @@ import (
|
||||||
//go:embed migrations/*
|
//go:embed migrations/*
|
||||||
var migrationFiles embed.FS
|
var migrationFiles embed.FS
|
||||||
|
|
||||||
|
// migration represents a database schema migration
|
||||||
type migration struct {
|
type migration struct {
|
||||||
fromVersion semver.Version
|
fromVersion semver.Version
|
||||||
toVersion semver.Version
|
toVersion semver.Version
|
||||||
migrationFunc func(db *sql.DB) error
|
migrationFunc func(db *sql.DB) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// txFunc is a function that runs in a transaction.
|
// txFn is a function that runs in a transaction.
|
||||||
type txFn func(tx *sql.Tx) error
|
type txFn func(tx *sql.Tx) error
|
||||||
|
|
||||||
// runInTransaction runs the given function in a transaction.
|
// runInTransaction runs the given function in a transaction.
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
_ "github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
var postgresMigrations = []migration{
|
var postgresMigrations = []migration{
|
||||||
|
@ -25,16 +25,21 @@ var postgresMigrations = []migration{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to start transaction: %w", err)
|
return fmt.Errorf("failed to start transaction: %w", err)
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
_, err = tx.Exec(`ALTER TABLE bookmark ADD COLUMN has_content BOOLEAN DEFAULT FALSE NOT NULL`)
|
_, err = tx.Exec(`ALTER TABLE bookmark ADD COLUMN has_content BOOLEAN DEFAULT FALSE NOT NULL`)
|
||||||
if err != nil && strings.Contains(err.Error(), `column "has_content" of relation "bookmark" already exists`) {
|
if err != nil {
|
||||||
tx.Rollback()
|
// Check if this is a "column already exists" error (PostgreSQL error code 42701)
|
||||||
} else if err != nil {
|
// If it's not, return error.
|
||||||
return fmt.Errorf("failed to add has_content column to bookmark table: %w", err)
|
// This is needed for users upgrading from >1.5.4 directly into this version.
|
||||||
} else if err == nil {
|
pqErr, ok := err.(*pq.Error)
|
||||||
if errCommit := tx.Commit(); errCommit != nil {
|
if ok && pqErr.Code == "42701" {
|
||||||
return fmt.Errorf("failed to commit transaction: %w", errCommit)
|
tx.Rollback()
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("failed to add has_content column to bookmark table: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,16 +47,21 @@ var postgresMigrations = []migration{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to start transaction: %w", err)
|
return fmt.Errorf("failed to start transaction: %w", err)
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
_, err = tx.Exec(`ALTER TABLE account ADD COLUMN config JSONB NOT NULL DEFAULT '{}'`)
|
_, err = tx.Exec(`ALTER TABLE account ADD COLUMN config JSONB NOT NULL DEFAULT '{}'`)
|
||||||
if err != nil && strings.Contains(err.Error(), `column "config" of relation "account" already exists`) {
|
if err != nil {
|
||||||
tx.Rollback()
|
// Check if this is a "column already exists" error (PostgreSQL error code 42701)
|
||||||
} else if err != nil {
|
// If it's not, return error
|
||||||
return fmt.Errorf("failed to add config column to account table: %w", err)
|
// This is needed for users upgrading from >1.5.4 directly into this version.
|
||||||
} else if err == nil {
|
pqErr, ok := err.(*pq.Error)
|
||||||
if errCommit := tx.Commit(); errCommit != nil {
|
if ok && pqErr.Code == "42701" {
|
||||||
return fmt.Errorf("failed to commit transaction: %w", errCommit)
|
tx.Rollback()
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("failed to add config column to account table: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue