mirror of
https://github.com/lightninglabs/loop
synced 2024-11-09 19:10:47 +00:00
72 lines
1.8 KiB
Go
72 lines
1.8 KiB
Go
|
package loopdb
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/jackc/pgconn"
|
||
|
"github.com/jackc/pgerrcode"
|
||
|
"modernc.org/sqlite"
|
||
|
sqlite3 "modernc.org/sqlite/lib"
|
||
|
)
|
||
|
|
||
|
// MapSQLError attempts to interpret a given error as a database agnostic SQL
|
||
|
// error.
|
||
|
func MapSQLError(err error) error {
|
||
|
// Attempt to interpret the error as a sqlite error.
|
||
|
var sqliteErr *sqlite.Error
|
||
|
if errors.As(err, &sqliteErr) {
|
||
|
return parseSqliteError(sqliteErr)
|
||
|
}
|
||
|
|
||
|
// Attempt to interpret the error as a postgres error.
|
||
|
var pqErr *pgconn.PgError
|
||
|
if errors.As(err, &pqErr) {
|
||
|
return parsePostgresError(pqErr)
|
||
|
}
|
||
|
|
||
|
// Return original error if it could not be classified as a database
|
||
|
// specific error.
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// parsePostgresError attempts to parse a sqlite error as a database agnostic
|
||
|
// SQL error.
|
||
|
func parseSqliteError(sqliteErr *sqlite.Error) error {
|
||
|
switch sqliteErr.Code() {
|
||
|
// Handle unique constraint violation error.
|
||
|
case sqlite3.SQLITE_CONSTRAINT_UNIQUE:
|
||
|
return &ErrSqlUniqueConstraintViolation{
|
||
|
DbError: sqliteErr,
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return fmt.Errorf("unknown sqlite error: %w", sqliteErr)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// parsePostgresError attempts to parse a postgres error as a database agnostic
|
||
|
// SQL error.
|
||
|
func parsePostgresError(pqErr *pgconn.PgError) error {
|
||
|
switch pqErr.Code {
|
||
|
// Handle unique constraint violation error.
|
||
|
case pgerrcode.UniqueViolation:
|
||
|
return &ErrSqlUniqueConstraintViolation{
|
||
|
DbError: pqErr,
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return fmt.Errorf("unknown postgres error: %w", pqErr)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ErrSqlUniqueConstraintViolation is an error type which represents a database
|
||
|
// agnostic SQL unique constraint violation.
|
||
|
type ErrSqlUniqueConstraintViolation struct {
|
||
|
DbError error
|
||
|
}
|
||
|
|
||
|
func (e ErrSqlUniqueConstraintViolation) Error() string {
|
||
|
return fmt.Sprintf("sql unique constraint violation: %v", e.DbError)
|
||
|
}
|