mirror of
https://github.com/matrix-org/dendrite.git
synced 2024-11-22 14:21:55 -06:00
Check unique constraint errors when manually inserting migrations (#2712)
This should avoid unnecessary logging on startup if the migration (were we need `InsertMigration`) was already executed. This now checks for "unique constraint errors" for SQLite and Postgres and fails the startup process if the migration couldn't be manually inserted for some other reason.
This commit is contained in:
parent
62afb936a5
commit
100fa9b235
|
@ -155,5 +155,10 @@ func InsertMigration(ctx context.Context, db *sql.DB, migrationName string) erro
|
||||||
time.Now().Format(time.RFC3339),
|
time.Now().Format(time.RFC3339),
|
||||||
internal.VersionString(),
|
internal.VersionString(),
|
||||||
)
|
)
|
||||||
|
// If the migration was already executed, we'll get a unique constraint error,
|
||||||
|
// return nil instead, to avoid unnecessary logging.
|
||||||
|
if IsUniqueConstraintViolationErr(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,27 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build wasm
|
//go:build !wasm
|
||||||
// +build wasm
|
// +build !wasm
|
||||||
|
|
||||||
package sqlutil
|
package sqlutil
|
||||||
|
|
||||||
// IsUniqueConstraintViolationErr no-ops for this architecture
|
import (
|
||||||
|
"github.com/lib/pq"
|
||||||
|
"github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsUniqueConstraintViolationErr returns true if the error is an unique_violation error
|
||||||
func IsUniqueConstraintViolationErr(err error) bool {
|
func IsUniqueConstraintViolationErr(err error) bool {
|
||||||
|
switch e := err.(type) {
|
||||||
|
case *pq.Error:
|
||||||
|
return e.Code == "23505"
|
||||||
|
case pq.Error:
|
||||||
|
return e.Code == "23505"
|
||||||
|
case *sqlite3.Error:
|
||||||
|
return e.Code == sqlite3.ErrConstraint
|
||||||
|
case sqlite3.Error:
|
||||||
|
return e.Code == sqlite3.ErrConstraint
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
|
@ -12,15 +12,20 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
//go:build !wasm
|
//go:build wasm
|
||||||
// +build !wasm
|
// +build wasm
|
||||||
|
|
||||||
package sqlutil
|
package sqlutil
|
||||||
|
|
||||||
import "github.com/lib/pq"
|
import "github.com/mattn/go-sqlite3"
|
||||||
|
|
||||||
// IsUniqueConstraintViolationErr returns true if the error is a postgresql unique_violation error
|
// IsUniqueConstraintViolationErr returns true if the error is an unique_violation error
|
||||||
func IsUniqueConstraintViolationErr(err error) bool {
|
func IsUniqueConstraintViolationErr(err error) bool {
|
||||||
pqErr, ok := err.(*pq.Error)
|
switch e := err.(type) {
|
||||||
return ok && pqErr.Code == "23505"
|
case *sqlite3.Error:
|
||||||
|
return e.Code == sqlite3.ErrConstraint
|
||||||
|
case sqlite3.Error:
|
||||||
|
return e.Code == sqlite3.ErrConstraint
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
|
@ -18,8 +18,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal"
|
"github.com/matrix-org/dendrite/internal"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
|
@ -81,8 +80,7 @@ func executeMigration(ctx context.Context, db *sql.DB) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
||||||
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
||||||
// not a fatal error, log and continue
|
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
|
||||||
logrus.WithError(err).Warnf("unable to manually insert migration '%s'", migrationName)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal"
|
"github.com/matrix-org/dendrite/internal"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
|
@ -80,8 +79,7 @@ func executeMigration(ctx context.Context, db *sql.DB) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
||||||
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
||||||
// not a fatal error, log and continue
|
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
|
||||||
logrus.WithError(err).Warnf("unable to manually insert migration '%s'", migrationName)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
// Import the postgres database driver.
|
// Import the postgres database driver.
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
|
|
||||||
|
@ -79,8 +77,7 @@ func executeMigration(ctx context.Context, db *sql.DB) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
||||||
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
||||||
// not a fatal error, log and continue
|
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
|
||||||
logrus.WithError(err).Warnf("unable to manually insert migration '%s'", migrationName)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/caching"
|
"github.com/matrix-org/dendrite/internal/caching"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
|
@ -87,8 +86,7 @@ func executeMigration(ctx context.Context, db *sql.DB) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
if errors.Is(err, sql.ErrNoRows) { // migration was already executed, as the column was removed
|
||||||
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
if err = sqlutil.InsertMigration(ctx, db, migrationName); err != nil {
|
||||||
// not a fatal error, log and continue
|
return fmt.Errorf("unable to manually insert migration '%s': %w", migrationName, err)
|
||||||
logrus.WithError(err).Warnf("unable to manually insert migration '%s'", migrationName)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue