123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // Package database provides database functionality
- package database
- import (
- "errors"
- "fmt"
- )
- // Common database error types
- var (
- // ErrInvalidConfig indicates missing or invalid database configuration
- ErrInvalidConfig = errors.New("invalid database configuration")
- // ErrConnectionFailed indicates failure to connect to the database
- ErrConnectionFailed = errors.New("failed to connect to database")
- // ErrQueryFailed indicates a query execution failure
- ErrQueryFailed = errors.New("query execution failed")
- // ErrTransactionFailed indicates a transaction operation failure
- ErrTransactionFailed = errors.New("transaction operation failed")
- // ErrMigrationFailed indicates a database migration failure
- ErrMigrationFailed = errors.New("database migration failed")
- // ErrPragmaFailed indicates failure to set database pragma
- ErrPragmaFailed = errors.New("failed to set database pragma")
- // ErrInvalidPath indicates an invalid database file path
- ErrInvalidPath = errors.New("invalid database path")
- // ErrDatabaseLocked indicates the database is locked
- ErrDatabaseLocked = errors.New("database is locked")
- // ErrNoRows indicates no rows were found
- ErrNoRows = errors.New("no rows found")
- // ErrDuplicateKey indicates a unique constraint violation
- ErrDuplicateKey = errors.New("duplicate key violation")
- )
- // Error represents a database-specific error with detailed context
- type Error struct {
- // Op is the operation that failed (e.g., "connect", "query", "migrate")
- Op string
- // Query is the SQL query that failed (if applicable)
- Query string
- // Err is the underlying error
- Err error
- // Details contains additional error context
- Details string
- }
- // Error returns a string representation of the error
- func (e *Error) Error() string {
- msg := fmt.Sprintf("database %s failed", e.Op)
- if e.Query != "" {
- // Truncate long queries in the error message
- const maxQueryLen = 100
- query := e.Query
- if len(query) > maxQueryLen {
- query = query[:maxQueryLen] + "..."
- }
- msg = fmt.Sprintf("%s for query %q", msg, query)
- }
- if e.Details != "" {
- msg = fmt.Sprintf("%s: %s", msg, e.Details)
- }
- if e.Err != nil {
- msg = fmt.Sprintf("%s: %v", msg, e.Err)
- }
- return msg
- }
- // Unwrap returns the underlying error
- func (e *Error) Unwrap() error {
- return e.Err
- }
- // Is reports whether target matches this error
- func (e *Error) Is(target error) bool {
- return errors.Is(e.Err, target)
- }
- // NewError creates a new database error
- func NewError(op string, err error, details string) *Error {
- return &Error{
- Op: op,
- Err: err,
- Details: details,
- }
- }
- // NewQueryError creates a new database error with query context
- func NewQueryError(op string, query string, err error, details string) *Error {
- return &Error{
- Op: op,
- Query: query,
- Err: err,
- Details: details,
- }
- }
- // IsLockError returns true if the error indicates a database lock
- func IsLockError(err error) bool {
- var e *Error
- return errors.As(err, &e) && errors.Is(e.Err, ErrDatabaseLocked)
- }
- // IsNotFoundError returns true if the error indicates no rows were found
- func IsNotFoundError(err error) bool {
- var e *Error
- return errors.As(err, &e) && errors.Is(e.Err, ErrNoRows)
- }
- // IsDuplicateError returns true if the error indicates a duplicate key
- func IsDuplicateError(err error) bool {
- var e *Error
- return errors.As(err, &e) && errors.Is(e.Err, ErrDuplicateKey)
- }
|