mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-29 22:53:03 +02:00
kvdb/sqlbase: use positive+negative build tags for new sql error parsing
In this commit, we use exhaustive build tags to ensure that we can always build the `sqlbase` package, independent of the set build tags. To do this, we move the type declarations _into_ the parsing functions. This then allows us to create two versions for each db: with the db, and without it. To avoid a module tag round trip to get this working, we use a local replace for now. Once this is merged in, we can do the tag (along side rc3), then remove the replace.
This commit is contained in:
2
go.mod
2
go.mod
@@ -208,6 +208,8 @@ replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
|
|||||||
// allows us to specify that as an option.
|
// allows us to specify that as an option.
|
||||||
replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display
|
replace google.golang.org/protobuf => github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display
|
||||||
|
|
||||||
|
replace github.com/lightningnetwork/lnd/kvdb => ./kvdb
|
||||||
|
|
||||||
// If you change this please also update .github/pull_request_template.md and
|
// If you change this please also update .github/pull_request_template.md and
|
||||||
// docs/INSTALL.md.
|
// docs/INSTALL.md.
|
||||||
go 1.19
|
go 1.19
|
||||||
|
2
go.sum
2
go.sum
@@ -450,8 +450,6 @@ github.com/lightningnetwork/lnd/clock v1.1.0 h1:/yfVAwtPmdx45aQBoXQImeY7sOIEr7IX
|
|||||||
github.com/lightningnetwork/lnd/clock v1.1.0/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg=
|
github.com/lightningnetwork/lnd/clock v1.1.0/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg=
|
||||||
github.com/lightningnetwork/lnd/healthcheck v1.2.2 h1:im+qcpgSuteqRCGeorT9yqVXuLrS6A7/acYzGgarMS4=
|
github.com/lightningnetwork/lnd/healthcheck v1.2.2 h1:im+qcpgSuteqRCGeorT9yqVXuLrS6A7/acYzGgarMS4=
|
||||||
github.com/lightningnetwork/lnd/healthcheck v1.2.2/go.mod h1:IWY0GChlarRbXFkFDdE4WY5POYJabe/7/H1iCZt4ZKs=
|
github.com/lightningnetwork/lnd/healthcheck v1.2.2/go.mod h1:IWY0GChlarRbXFkFDdE4WY5POYJabe/7/H1iCZt4ZKs=
|
||||||
github.com/lightningnetwork/lnd/kvdb v1.4.3 h1:IqtByi6fJfQXMZMdS8iY1+D5wpKcuH0Mfx2pjJ6oJ48=
|
|
||||||
github.com/lightningnetwork/lnd/kvdb v1.4.3/go.mod h1:9SuaIqMA9ugrVkdvgQkYXa8CAKYNYd4vsEYORP4V698=
|
|
||||||
github.com/lightningnetwork/lnd/queue v1.1.0 h1:YpCJjlIvVxN/R7ww2aNiY8ex7U2fucZDLJ67tI3HFx8=
|
github.com/lightningnetwork/lnd/queue v1.1.0 h1:YpCJjlIvVxN/R7ww2aNiY8ex7U2fucZDLJ67tI3HFx8=
|
||||||
github.com/lightningnetwork/lnd/queue v1.1.0/go.mod h1:YTkTVZCxz8tAYreH27EO3s8572ODumWrNdYW2E/YKxg=
|
github.com/lightningnetwork/lnd/queue v1.1.0/go.mod h1:YTkTVZCxz8tAYreH27EO3s8572ODumWrNdYW2E/YKxg=
|
||||||
github.com/lightningnetwork/lnd/ticker v1.0.0/go.mod h1:iaLXJiVgI1sPANIF2qYYUJXjoksPNvGNYowB8aRbpX0=
|
github.com/lightningnetwork/lnd/ticker v1.0.0/go.mod h1:iaLXJiVgI1sPANIF2qYYUJXjoksPNvGNYowB8aRbpX0=
|
||||||
|
@@ -1,15 +1,8 @@
|
|||||||
//go:build kvdb_postgres || (kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64)))
|
|
||||||
|
|
||||||
package sqlbase
|
package sqlbase
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jackc/pgconn"
|
|
||||||
"github.com/jackc/pgerrcode"
|
|
||||||
"modernc.org/sqlite"
|
|
||||||
sqlite3 "modernc.org/sqlite/lib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -22,15 +15,13 @@ var (
|
|||||||
// error.
|
// error.
|
||||||
func MapSQLError(err error) error {
|
func MapSQLError(err error) error {
|
||||||
// Attempt to interpret the error as a sqlite error.
|
// Attempt to interpret the error as a sqlite error.
|
||||||
var sqliteErr *sqlite.Error
|
if sqliteErr := parseSqliteError(err); sqliteErr != nil {
|
||||||
if errors.As(err, &sqliteErr) {
|
return sqliteErr
|
||||||
return parseSqliteError(sqliteErr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to interpret the error as a postgres error.
|
// Attempt to interpret the error as a postgres error.
|
||||||
var pqErr *pgconn.PgError
|
if postgresErr := parsePostgresError(err); postgresErr != nil {
|
||||||
if errors.As(err, &pqErr) {
|
return postgresErr
|
||||||
return parsePostgresError(pqErr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return original error if it could not be classified as a database
|
// Return original error if it could not be classified as a database
|
||||||
@@ -38,48 +29,6 @@ func MapSQLError(err error) error {
|
|||||||
return err
|
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Database is currently busy, so we'll need to try again.
|
|
||||||
case sqlite3.SQLITE_BUSY:
|
|
||||||
return &ErrSerializationError{
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unable to serialize the transaction, so we'll need to try again.
|
|
||||||
case pgerrcode.SerializationFailure:
|
|
||||||
return &ErrSerializationError{
|
|
||||||
DBError: pqErr,
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown postgres error: %w", pqErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrSQLUniqueConstraintViolation is an error type which represents a database
|
// ErrSQLUniqueConstraintViolation is an error type which represents a database
|
||||||
// agnostic SQL unique constraint violation.
|
// agnostic SQL unique constraint violation.
|
||||||
type ErrSQLUniqueConstraintViolation struct {
|
type ErrSQLUniqueConstraintViolation struct {
|
||||||
|
9
kvdb/sqlbase/sqlerrors_no_postgres.go
Normal file
9
kvdb/sqlbase/sqlerrors_no_postgres.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build !kvdb_postgres
|
||||||
|
|
||||||
|
package sqlbase
|
||||||
|
|
||||||
|
// parsePostgresError attempts to parse a postgres error as a database agnostic
|
||||||
|
// SQL error.
|
||||||
|
func parsePostgresError(err error) error {
|
||||||
|
return nil
|
||||||
|
}
|
9
kvdb/sqlbase/sqlerrors_no_sqlite.go
Normal file
9
kvdb/sqlbase/sqlerrors_no_sqlite.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
//go:build !kvdb_sqlite || (windows && (arm || 386)) || (linux && (ppc64 || mips || mipsle || mips64))
|
||||||
|
|
||||||
|
package sqlbase
|
||||||
|
|
||||||
|
// parseSqliteError attempts to parse a sqlite error as a database agnostic
|
||||||
|
// SQL error.
|
||||||
|
func parseSqliteError(err error) error {
|
||||||
|
return nil
|
||||||
|
}
|
37
kvdb/sqlbase/sqlerrors_postgres.go
Normal file
37
kvdb/sqlbase/sqlerrors_postgres.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//go:build kvdb_postgres
|
||||||
|
|
||||||
|
package sqlbase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/jackc/pgconn"
|
||||||
|
"github.com/jackc/pgerrcode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// parsePostgresError attempts to parse a postgres error as a database agnostic
|
||||||
|
// SQL error.
|
||||||
|
func parsePostgresError(err error) error {
|
||||||
|
var pqErr *pgconn.PgError
|
||||||
|
if !errors.As(err, &pqErr) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pqErr.Code {
|
||||||
|
// Handle unique constraint violation error.
|
||||||
|
case pgerrcode.UniqueViolation:
|
||||||
|
return &ErrSQLUniqueConstraintViolation{
|
||||||
|
DBError: pqErr,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to serialize the transaction, so we'll need to try again.
|
||||||
|
case pgerrcode.SerializationFailure:
|
||||||
|
return &ErrSerializationError{
|
||||||
|
DBError: pqErr,
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown postgres error: %w", pqErr)
|
||||||
|
}
|
||||||
|
}
|
37
kvdb/sqlbase/sqlerrors_sqlite.go
Normal file
37
kvdb/sqlbase/sqlerrors_sqlite.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//go:build kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64))
|
||||||
|
|
||||||
|
package sqlbase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"modernc.org/sqlite"
|
||||||
|
sqlite3 "modernc.org/sqlite/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
// parseSqliteError attempts to parse a sqlite error as a database agnostic
|
||||||
|
// SQL error.
|
||||||
|
func parseSqliteError(err error) error {
|
||||||
|
var sqliteErr *sqlite.Error
|
||||||
|
if !errors.As(err, &sqliteErr) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch sqliteErr.Code() {
|
||||||
|
// Handle unique constraint violation error.
|
||||||
|
case sqlite3.SQLITE_CONSTRAINT_UNIQUE:
|
||||||
|
return &ErrSQLUniqueConstraintViolation{
|
||||||
|
DBError: sqliteErr,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Database is currently busy, so we'll need to try again.
|
||||||
|
case sqlite3.SQLITE_BUSY:
|
||||||
|
return &ErrSerializationError{
|
||||||
|
DBError: sqliteErr,
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown sqlite error: %w", sqliteErr)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user