From bb67131ce5641dc42b550eebf70d89c7736fd339 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 5 Sep 2023 18:20:04 -0700 Subject: [PATCH] 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. --- go.mod | 2 + go.sum | 2 - kvdb/sqlbase/sqlerrors.go | 59 ++------------------------- kvdb/sqlbase/sqlerrors_no_postgres.go | 9 ++++ kvdb/sqlbase/sqlerrors_no_sqlite.go | 9 ++++ kvdb/sqlbase/sqlerrors_postgres.go | 37 +++++++++++++++++ kvdb/sqlbase/sqlerrors_sqlite.go | 37 +++++++++++++++++ 7 files changed, 98 insertions(+), 57 deletions(-) create mode 100644 kvdb/sqlbase/sqlerrors_no_postgres.go create mode 100644 kvdb/sqlbase/sqlerrors_no_sqlite.go create mode 100644 kvdb/sqlbase/sqlerrors_postgres.go create mode 100644 kvdb/sqlbase/sqlerrors_sqlite.go diff --git a/go.mod b/go.mod index f735d538e..ccbbccf71 100644 --- a/go.mod +++ b/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. 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 // docs/INSTALL.md. go 1.19 diff --git a/go.sum b/go.sum index 0318d40e8..c8f70db33 100644 --- a/go.sum +++ b/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/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/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/go.mod h1:YTkTVZCxz8tAYreH27EO3s8572ODumWrNdYW2E/YKxg= github.com/lightningnetwork/lnd/ticker v1.0.0/go.mod h1:iaLXJiVgI1sPANIF2qYYUJXjoksPNvGNYowB8aRbpX0= diff --git a/kvdb/sqlbase/sqlerrors.go b/kvdb/sqlbase/sqlerrors.go index ccbb9c610..5e8afdb41 100644 --- a/kvdb/sqlbase/sqlerrors.go +++ b/kvdb/sqlbase/sqlerrors.go @@ -1,15 +1,8 @@ -//go:build kvdb_postgres || (kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64))) - package sqlbase import ( "errors" "fmt" - - "github.com/jackc/pgconn" - "github.com/jackc/pgerrcode" - "modernc.org/sqlite" - sqlite3 "modernc.org/sqlite/lib" ) var ( @@ -22,15 +15,13 @@ var ( // 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) + if sqliteErr := parseSqliteError(err); sqliteErr != nil { + return sqliteErr } // Attempt to interpret the error as a postgres error. - var pqErr *pgconn.PgError - if errors.As(err, &pqErr) { - return parsePostgresError(pqErr) + if postgresErr := parsePostgresError(err); postgresErr != nil { + return postgresErr } // Return original error if it could not be classified as a database @@ -38,48 +29,6 @@ func MapSQLError(err error) 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, - } - - // 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 // agnostic SQL unique constraint violation. type ErrSQLUniqueConstraintViolation struct { diff --git a/kvdb/sqlbase/sqlerrors_no_postgres.go b/kvdb/sqlbase/sqlerrors_no_postgres.go new file mode 100644 index 000000000..94f08b66a --- /dev/null +++ b/kvdb/sqlbase/sqlerrors_no_postgres.go @@ -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 +} diff --git a/kvdb/sqlbase/sqlerrors_no_sqlite.go b/kvdb/sqlbase/sqlerrors_no_sqlite.go new file mode 100644 index 000000000..9f475a14c --- /dev/null +++ b/kvdb/sqlbase/sqlerrors_no_sqlite.go @@ -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 +} diff --git a/kvdb/sqlbase/sqlerrors_postgres.go b/kvdb/sqlbase/sqlerrors_postgres.go new file mode 100644 index 000000000..3915a34f4 --- /dev/null +++ b/kvdb/sqlbase/sqlerrors_postgres.go @@ -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) + } +} diff --git a/kvdb/sqlbase/sqlerrors_sqlite.go b/kvdb/sqlbase/sqlerrors_sqlite.go new file mode 100644 index 000000000..c29146610 --- /dev/null +++ b/kvdb/sqlbase/sqlerrors_sqlite.go @@ -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) + } +}