database

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Sep 23, 2024 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package database provides the Driver interface. All database drivers must implement this interface, register themselves, optionally provide a `WithInstance` function and pass the tests in package database/testing.

Index

Examples

Constants

View Source
const NilVersion int = -1

Variables

View Source
var (
	ErrLocked    = fmt.Errorf("can't acquire lock")
	ErrNotLocked = fmt.Errorf("can't unlock, as not currently locked")

	ErrNotImplemented = fmt.Errorf("not implemented")
)

Functions

func CasRestoreOnErr

func CasRestoreOnErr(lock *atomic.Bool, o, n bool, casErr error, f func() error) error

CasRestoreOnErr CAS wrapper to automatically restore the lock state on error

func GenerateAdvisoryLockId

func GenerateAdvisoryLockId(databaseName string, additionalNames ...string) (string, error)

GenerateAdvisoryLockId inspired by rails migrations, see https://goo.gl/8o9bCT

func List

func List() []string

List lists the registered drivers

func Register

func Register(name string, driver Driver)

Register globally registers a driver.

Types

type Driver

type Driver interface {
	// Open returns a new driver instance configured with parameters
	// coming from the URL string. Migrate will call this function
	// only once per instance.
	Open(url string) (Driver, error)

	SetSourceDriver(sourceDrv source.Driver) error

	// Close closes the underlying database instance managed by the driver.
	// Migrate will call this function only once per instance.
	Close() error

	// Lock should acquire a database lock so that only one migration process
	// can run at a time. Migrate will call this function before Run is called.
	// If the implementation can't provide this functionality, return nil.
	// Return database.ErrLocked if database is already locked.
	Lock() error

	// Unlock should release the lock. Migrate will call this function after
	// all migrations have been run.
	Unlock() error

	// Run applies a migration to the database. migration is guaranteed to be not nil.
	Run(migration io.Reader) error

	// SetVersion saves version and dirty state.
	// Migrate will call this function before and after each call to Run.
	// version must be >= -1. -1 means NilVersion.
	//
	//   forced
	// forced flag indicates that this is a forced migration.
	//
	//   knownDirection
	// If knownDirection is not provided, direction will be estimated
	// based on comparing the given version with the last applied version.
	SetVersion(version int, dirty bool, forced bool, knownDirection *source.Direction) (*source.Direction, error)

	// Version returns the currently active version and if the database is dirty.
	// When no migration has been applied, it must return version -1.
	// Dirty means, a previous migration failed and user interaction is required.
	Version() (version int, dirty bool, err error)

	// ListAppliedVersions returns a list of all versions that are known
	// to be applied to the database.  This will not include versions that
	// were applied before history tracking was enabled.
	// Versions that were applied but "reverted" by down migrations will
	// not be included until up migrations are re-run to restore them.
	ListAppliedVersions() ([]int, error)

	// Drop deletes everything in the database.
	// Note that this is a breaking action, a new call to Open() is necessary to
	// ensure subsequent calls work as expected.
	Drop() error
}

Driver is the interface every database driver must implement.

How to implement a database driver?

  1. Implement this interface.
  2. Optionally, add a function named `WithInstance`. This function should accept an existing DB instance and a Config{} struct and return a driver instance.
  3. Add a test that calls database/testing.go:Test()
  4. Add own tests for Open(), WithInstance() (when provided) and Close(). All other functions are tested by tests in database/testing. Saves you some time and makes sure all database drivers behave the same way.
  5. Call Register in init().
  6. Create a internal/cli/build_<driver-name>.go file
  7. Add driver name in 'DATABASE' variable in Makefile

Guidelines:

  • Don't try to correct user input. Don't assume things. When in doubt, return an error and explain the situation to the user.
  • All configuration input must come from the URL string in func Open() or the Config{} struct in WithInstance. Don't os.Getenv().
Example
// see database/stub for an example

// database/stub/stub.go has the driver implementation
// database/stub/stub_test.go runs database/testing/test.go:Test
Output:

func Open

func Open(url string) (Driver, error)

Open returns a new driver instance.

type Error

type Error struct {
	// Optional: the line number
	Line uint

	// Query is a query excerpt
	Query []byte

	// Err is a useful/helping error message for humans
	Err string

	// OrigErr is the underlying error
	OrigErr error
}

Error should be used for errors involving queries ran against the database

func (Error) Error

func (e Error) Error() string

Directories

Path Synopsis
Package multistmt provides methods for parsing multi-statement database migrations
Package multistmt provides methods for parsing multi-statement database migrations
pgx
v5
Package testing has the database tests.
Package testing has the database tests.

Jump to

Keyboard shortcuts

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