logsql

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 2, 2025 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package logsql provides wrapper for database/sql with Logger interface. To create new logged *sql.DB use either NewConnectorFromDriver or NewConnectorFromConnector to retrieve driver.Connector and pass it to sql.OpenDB.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNilLogHandler       = errors.New("log handler is nil")
	ErrUnsupportedByDriver = errors.New("unsupported by underlying driver")
)

Functions

func NewConnectorFromConnector

func NewConnectorFromConnector(connector driver.Connector, cfg Config) driver.Connector

NewConnectorFromConnector returns new driver.Connector based on existing connector. Panics if Config.Validate returns non nil error

func NewConnectorFromDriver

func NewConnectorFromDriver(d driver.Driver, dsn string, cfg Config) driver.Connector

NewConnectorFromDriver returns new driver.Connector based on an existing driver and DSN. Panics if Config.Validate returns non-nil error

func NoOpQueryErrReplacer

func NoOpQueryErrReplacer(_ error) error

NoOpQueryErrReplacer will not replace anything

Types

type Config

type Config struct {
	Qer        QueryErrReplacer
	LogHandler Logger
}

Config must contain Logger for logging sql.DB events. If Qer is nil, NoOpQueryErrReplacer will be used

func (Config) Validate

func (c Config) Validate() error

Validate returns error if config is not ready to use

type Logger

type Logger interface {
	Connect(ctx context.Context, err error, dt time.Duration)
	ConnClose(ctx context.Context, err error, dt time.Duration)

	TxBegin(ctx context.Context, err error, dt time.Duration)
	TxCommit(ctx context.Context, err error, dt time.Duration)
	TxRollback(ctx context.Context, err error, dt time.Duration)

	Exec(ctx context.Context, query string, args []driver.NamedValue, replacedErr error, err error, dt time.Duration)
	Query(ctx context.Context, query string, args []driver.NamedValue, replacedErr error, err error, dt time.Duration)

	Ping(ctx context.Context, err error, dt time.Duration)

	RowsClose(ctx context.Context, err error, dt time.Duration)
	// RowsNext can receive [io.EOF] as err in the end of scanning
	RowsNext(ctx context.Context, dest []driver.Value, err error, dt time.Duration)

	PrepareStatement(ctx context.Context, query string, err error, dt time.Duration)
	ClosePreparedStatement(ctx context.Context, query string, err error, dt time.Duration)
	ExecPreparedStatement(ctx context.Context, query string, args []driver.NamedValue, replacedErr error, err error, dt time.Duration)
	QueryPreparedStatement(ctx context.Context, query string, args []driver.NamedValue, replacedErr error, err error, dt time.Duration)
}

Logger is used to log specific cases internally in [sql.DB]

type QueryErrReplacer

type QueryErrReplacer func(err error) error

QueryErrReplacer can be used for replacing actual errors from a driver ("Query", "QueryContext", "Exec", "ExecContext"). QueryErrReplacer must return non-nil error if new error should substitute the original one, nil otherwise. Such substitution is useful in case of checking raw SQL errors.

Example of handling SQL specific 42P07 error:

  1. SQL driver query error which underlying driver usually returns type SqlError struct { Code string } func (e SqlError) Error() string { return e.Code }
  1. Your own specific error var errDuplicateTable = errors.New("duplicate table")

3. QueryErrReplacer function. If err is not a SqlError, don't substitute anything. If it is expected error 42P07 return your own errDuplicateTable

 func myErrReplacer(err error) error {
	    var pgErr SqlError
	    if !errors.As(err, &pgErr) {
         return nil
	    }

	    switch pgErr.Code {
     case "42P07":
         return errDuplicateTable
     default:
         return nil
     }
 }

4. Handling. Thus, your own error can be handled in a specific way. Moreover, if Logger is properly configured, no ERROR entry will appear in logs because this error was expected

 err := db.ExecContext(ctx, query)
 if err != nil {
	    if errors.Is(err, errDuplicateTable) {
         // ...
	    }
	    return err
 }

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL