pgmig

package module
v0.35.1 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2023 License: Apache-2.0 Imports: 17 Imported by: 0

README

pgmig

postgresql migration library & tool

GoDoc codecov drone.io build status codebeat badge GoCard GitHub Release GitHub license

This is an alpha state project. See docs.

Notes

why pgx

In this lib, test results are received via RAISE NOTICE which is supported in pgx, but don't in sqlx, see details

why go-imbed

Because I didn't find another lib which supports UnionFS, ie checks OS filesystem before embedded. If you know better, drop me a line please.

TODO

  • TODOs in code
  • overwiew
  • tests
  • docs

License

Apache License 2.0, see LICENSE.

Copyright (c) 2019-2021 Aleksey Kovrizhkin lekovr+pgmig@gmail.com

Documentation

Index

Examples

Constants

View Source
const (
	// CmdCheck holds name of check command
	CmdCheck = "check"
	// CmdInit holds name of init command
	CmdInit = "init"
	// CmdTest holds name of test command
	CmdTest = "test"
	// CmdDrop  holds name of drop command
	CmdDrop = "drop"
	// CmdErase holds name of erase command
	CmdErase = "erase"
	// CmdReInit holds name of reinit (drop+init) command
	CmdReInit = "reinit"

	// CorePackage is the name of pgmig core package
	CorePackage = "pgmig"
	// CoreTable is the name of table inside core package(scheme) which must exist if pgmig is installed already
	CoreTable = "pkg"
	// CorePrefix is the name of var which holds PG variable names prefix
	CorePrefix = "pgmig.prefix"

	// SQLPgMigExists is a query to check pgmig.pkg table presence
	SQLPgMigExists = "SELECT true FROM information_schema.tables WHERE table_schema = $1 AND table_name = $2"
	// SQLPgMigVar gets Pg config var
	SQLPgMigVar = "SELECT current_setting($1, true)"
	// SQLSetVar sets Pg config var
	SQLSetVar = "SELECT set_config($1 || $2, $3, true)"
	// SQLPkgVersion is a query for installed package version
	SQLPkgVersion = "SELECT %s.%s($1)"
	// SQLPkgOp called before and after running an op
	SQLPkgOp = "SELECT %s.%s(a_op => $1, a_code => $2, a_version => $3, a_repo => $4)"
	// SQLScriptProtected checks if file registered in db
	SQLScriptProtected = "SELECT %s.%s(a_pkg => $1, a_file => $2)"
	// SQLScriptProtect registers file in db
	SQLScriptProtect = "SELECT %s.%s(a_pkg => $1, a_file => $2, a_md5 => $3)"
)

Variables

This section is empty.

Functions

func SliceReverse

func SliceReverse(pkgs []string)

SliceReverse replace the contents of a slice with the same elements but in reverse order See https://github.com/golang/go/wiki/SliceTricks#reversing

Types

type Config

type Config struct {
	Vars       map[string]string `long:"var" description:"Transaction variable(s)"`
	VarsPrefix string            `long:"var_prefix" default:"pgmig.var." description:"Transaction variable(s) prefix"`
	//Command string default check
	NoCommit bool `long:"nocommit" description:"Do not commit work"`
	ListOnly bool `long:"listonly" description:"Show file list and exit"` // TODO: --dry-run
	Debug    bool `long:"debug" description:"Print debug info"`           // TODO: process
	Quiet    bool `short:"q" long:"quiet" description:"Do not show messages from DB"`

	// TODO: Force    bool   `long:"force" description:"Allow erase command"`
	NoHooks    bool   `long:"nohooks" description:"Do not call before/after hooks"`
	HookBefore string `long:"hook_before" default:"pkg_op_before" description:"Func called before command for every pkg"`
	HookAfter  string `long:"hook_after" default:"pkg_op_after" description:"Func called after command for every pkg"`

	PkgVersion string `long:"pkg_version" default:"pkg_version" description:"Func for fetching installed package version"`

	ScriptProtected string `long:"script_protected" default:"script_protected" description:"Func for fetchng md5 of protected script"`
	ScriptProtect   string `long:"script_protect" default:"script_protect" description:"Func for saving md5 of protected script"`

	InitIncludes []string `long:"init" default:"*.sql" description:"File masks for init command"`
	TestIncludes []string `long:"test" default:"*.test.sql" description:"File masks for test command"`
	NewIncludes  []string `long:"new" default:"*.new.sql" description:"File masks loaded on init if package is new"`
	OnceIncludes []string `long:"once" default:"*.once.sql" description:"File masks loaded once on init"`

	GitInfo gitinfo.Config `group:"GitInfo Options" namespace:"gi"`
}

Config holds all config vars

type File

type File interface {
	io.Closer
	io.Reader
	io.Seeker
	Readdir(count int) ([]os.FileInfo, error)
	Stat() (os.FileInfo, error)
}

File is an interface for os.File struct

type FileSystem

type FileSystem interface {
	Walk(root string, walkFn filepath.WalkFunc) error
	Open(name string) (File, error)
}

FileSystem holds all of used filesystem access methods

type Migrator

type Migrator struct {
	Config     *Config
	Root       string
	Log        logr.Logger
	FS         FileSystem
	IsTerminal bool

	MessageChan chan interface{}
	// contains filtered or unexported fields
}

Migrator holds service data

func New

func New(log logr.Logger, cfg Config, fs FileSystem, root string) *Migrator

New creates an Migrator object

func (*Migrator) Connect added in v0.35.0

func (mig *Migrator) Connect(ctx context.Context, dsn string) (*pgx.Conn, error)

Connect makes connect to DB and returns ins handle

func (*Migrator) PrintMessages added in v0.35.0

func (mig *Migrator) PrintMessages(wg *sync.WaitGroup)

PrintMessages prints messages from SQL functions

Example
sink := genericr.New(func(e genericr.Entry) {
	fmt.Fprintln(os.Stderr, e.String())
})
log := logr.New(sink)
mig := New(log, Config{}, nil, "")
mig.IsTerminal = false
mig.MessageChan = make(chan interface{}, 50)

wg := sync.WaitGroup{}
wg.Add(1)
go mig.PrintMessages(&wg)

tests := []interface{}{
	&Status{Exists: true},
	//		mig.MessageChan <- pgErr
	&Op{Pkg: "pkg.Name", Op: "pkg.Op"},
	&Version{Version: "installedVersion"},
	&NewVersion{Version: "info.Version", Repo: "info.Repository"},
	&RunFile{Name: "file.Name"},
	&TestCount{Count: 1},
	&TestOk{Current: 1, Message: "message"},
	&TestFail{Current: 1, Message: "message", Detail: "detail"},
	&pgconn.PgError{
		File:          "file",
		Line:          1,
		Severity:      "NOTICE",
		Code:          "0000",
		Message:       "msg",
		Detail:        "det",
		Hint:          "hint",
		Where:         "where",
		InternalQuery: "query",
	},
}
for _, tt := range tests {
	mig.MessageChan <- tt
}
close(mig.MessageChan)
wg.Wait()
Output:

PgMig exists: true
# pkg.Name.pkg.Op
Installed version: installedVersion
New version:       info.Version from info.Repository

# file.Name
1..1
ok 1 - message
not ok 1 - message
  ---
detail
  ---
#  file:1 NOTICE 0000 msg
#  Detail: det
#  Hint: hint
#  Where: where
#  Query: query

func (*Migrator) ProcessNotice

func (mig *Migrator) ProcessNotice(code, message, detail string)

ProcessNotice receives PG notices with test metadata and plain TODO: add multiprocess support?

func (*Migrator) Run

func (mig *Migrator) Run(tx pgx.Tx, command string, packages []string) (*bool, error)

Run does all work

type NewVersion added in v0.35.0

type NewVersion struct {
	Version string
	Repo    string
}

NewVersion holds new version message fields.

type Op added in v0.35.0

type Op struct {
	Pkg string
	Op  string
}

Op holds Op message fields.

type RunFile added in v0.35.0

type RunFile struct{ Name string }

RunFile holds run file message fields.

type Status added in v0.35.0

type Status struct {
	Exists bool
}

Status holds Status message fields.

type TestCount added in v0.35.0

type TestCount struct{ Count int }

TestCount holds test count message fields.

type TestFail added in v0.35.0

type TestFail struct {
	Current int
	Message string
	Detail  string
}

TestFail holds fields of unsuccessfull test fields.

type TestOk added in v0.35.0

type TestOk struct {
	Current int
	Message string
}

TestOk holds fields of successfull test results.

type Version added in v0.35.0

type Version struct{ Version string }

Version holds version message fields.

Directories

Path Synopsis
cmd
pgmig/internal/sql
Package sql holds binary resources embedded into Go executable
Package sql holds binary resources embedded into Go executable

Jump to

Keyboard shortcuts

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