Documentation ¶
Index ¶
- Constants
- Variables
- func AsString(node *pg_query.Node) string
- func CheckPackageName(name string) error
- func Exit(err error)
- func LogLouder()
- func LogQuieter()
- func ParseArgs(prefix string) error
- func PrintError(err error)
- func QualifiedName(nodes []*pg_query.Node) string
- func Remote()
- func Sanitize(pattern *regexp.Regexp, v string) string
- func SanitizeSlice(pattern *regexp.Regexp, values []string) []string
- func WriteProject(z *zip.Writer, p *Project) error
- type Bundle
- type Cache
- type DirSource
- type FSSource
- type InfoWriter
- type MOB
- type ManagedObject
- type PKGError
- type PKGErrorContext
- type PKGObject
- type Package
- type PkgTx
- type Project
- func (p *Project) AddEmbeddedFS(f fs.FS, path string) (*Package, error)
- func (p *Project) AddPackage(source Source, isDependency bool) (*Package, error)
- func (p *Project) AddSource(src Source) (*Package, error)
- func (p *Project) Init(tx *PkgTx) error
- func (p *Project) Migrate(dsn string) error
- func (p *Project) Open(dsn string) (*sql.DB, error)
- func (p *Project) Parse() error
- func (p *Project) PrintInfo(w InfoWriter)
- type ReadCache
- type Schema
- type Source
- type Statement
- type Tests
- type Unit
- type WriteCache
- type ZipByteSource
Constants ¶
const PGKSchemaName = "pgpkg"
PGKSchemaName is the name of the pgpkg schema itself.
Variables ¶
var CachePkgNotFound = errors.New("package not found in cache")
var ErrUserRequest = errors.New("terminating due to user request")
Used when a --option requires the caller to quit, but there wasn't an error. e.g., --dry-run
var Options struct { Verbose bool // print lots of stuff Summary bool // print a summary of the installation DryRun bool // rollback after installation (default) ShowTests bool // Show the result of each SQL test that was run. ShowSkipped bool // Show skipped tests SkipTests bool // Don't run the tests. Useful when fixing them! IncludePattern *regexp.Regexp // Pattern to use for running tests ExcludePattern *regexp.Regexp // Pattern to use for running tests }
var Verbose = Stdout
Functions ¶
func CheckPackageName ¶
CheckPackageName checks if the given string is a valid pgpkg package name and returns an error if not.
func Exit ¶
func Exit(err error)
Exit usually prints the error message (with context, if available), and then exits immediately with status 1. However, err == ErrUserRequest then no message is printed and we exit with status 0. project.Open() will return ErrUserRequest if the command-line options indicate a dry run or other condition that should not result in a program printing an error.
Applications should call pgpkg.Exit(err) after calling project.Open() if err is not nil.
func LogQuieter ¶
func LogQuieter()
func ParseArgs ¶
ParseArgs parses the os.Args for a standard set of OS arguments. ParseArgs deletes matching arguments from os.Args so that the caller doesn't need to worry about them.
When embedding pgpkg into your own programs, set prefix to "pgpkg" to differentiate pgpkg arguments from your own. Doing this will make it possible to set pgpkg options from your code are runtime with prefixed options such as "--dry-run". If "prefix" is empty ("") then options will not be prefixed; ie, "--dry-run".
You should call ParseArgs before calling flag.Parse() if you are using the standard flag library.
func PrintError ¶
func PrintError(err error)
func QualifiedName ¶
Types ¶
type Bundle ¶
type Bundle struct { Package *Package // canonical name of the package. Path string // Path of this bundle, relative to the Package Index map[string]*Unit // Index of location of each unit. Units []*Unit // Ordered list of build units within the bundle }
func (*Bundle) PrintInfo ¶
func (b *Bundle) PrintInfo(w InfoWriter)
type Cache ¶
Cache represents a dependency cache which contains the source of any dependencies listed in the "Uses" section of pgpkg.toml.
Users can manually import project dependencies into the project cache with `pgpkg import`.
type DirSource ¶
type DirSource struct {
// contains filtered or unexported fields
}
func NewDirSource ¶
type InfoWriter ¶
type InfoWriter struct {
// contains filtered or unexported fields
}
func NewInfoWriter ¶
func NewInfoWriter(w io.Writer) InfoWriter
func (InfoWriter) Print ¶
func (i InfoWriter) Print(name string, value any)
func (InfoWriter) Printf ¶
func (i InfoWriter) Printf(format string, args ...any)
func (InfoWriter) Println ¶
func (i InfoWriter) Println(args ...any)
type MOB ¶
type MOB struct { *Bundle // contains filtered or unexported fields }
func (*MOB) Apply ¶
Apply performs the SQL required to create the objects listed in the MOB object, to register them in the pgpkg.object table. Since objects in an MOB may depend on one another, this function starts with a list of the statements to be executed, and attempts to execute them one at a time.
Each statement is executed in a savepoint. If a statement fails, we skip over it and keep trying.
The apply function will keep running until it's unable to create any statement, after which it will terminate.
func (*MOB) DefaultContext ¶
func (m *MOB) DefaultContext() *PKGErrorContext
func (*MOB) PrintInfo ¶
func (m *MOB) PrintInfo(w InfoWriter)
type ManagedObject ¶
type ManagedObject struct { ObjectSchema string ObjectType string ObjectName string ObjectArgs []string }
ManagedObject refers to a managed database object, with a schema name, object name and object type.
type PKGError ¶
type PKGError struct { Message string Object PKGObject Context *PKGErrorContext Err error // In the case of applying a migration, there may be multiple errors, // e.g. if a MOB can't be processed (typically because of dependencies). Errors []*PKGError }
PKGError is the error type used internally by pgpkg.
func (*PKGError) GetContext ¶
func (e *PKGError) GetContext() *PKGErrorContext
func (*PKGError) PrintRootContext ¶
Print prints useful information about this error.
type PKGErrorContext ¶
type PKGErrorContext struct { Source string LineNumber int Location string Next *PKGErrorContext // Indicates addtional stack traces. }
func (*PKGErrorContext) Print ¶
func (c *PKGErrorContext) Print(contextLines int)
type PKGObject ¶
type PKGObject interface { Location() string DefaultContext() *PKGErrorContext }
PKGObject is any object (statement, unit, package) that can tell us where a problem happened.
type Package ¶
type Package struct { Project *Project Name string // canonical, unique name of the pgpkg package Location string // Location of this package Source Source // Source of the package (dir, zip, embedded, ...) SchemaNames []string // Packages participate in one or more schemas RoleName string // Associated role name StatFuncCount int // Stat showing the number of functions in the package StatViewCount int // Stat showing the number of views in the package StatTriggerCount int // Stat showing the number of triggers in the package StatMigrationCount int // Stat showing how many migration scripts were run StatTestCount int // Stat showing how many tests there are. Schema *Schema MOB *MOB Tests *Tests IsDependency bool // This package was loaded from .pgpkg cache // contains filtered or unexported fields }
func (*Package) AddUses ¶
AddUses adds the given package name to the Uses clause of the package. Returns false if the package already exists in the Uses clause. Note that this does not update the config file; to do this, see WriteConfig.
func (*Package) PrintInfo ¶
func (p *Package) PrintInfo(w InfoWriter)
func (*Package) WriteConfig ¶
type Project ¶
type Project struct { Root *Package // the root (main package) of this project Sources []Source // All package sources, in no particular order. Cache *WriteCache // primary cache for this project Search []Cache // other caches to search for dependencies. // contains filtered or unexported fields }
Project represents a collection of individual packages that are to be installed into a single database. This struct is responsible for tracking the package sources that make up a project, including dependencies and caches, and arranging for them to be installed in the correct order.
You work with a project by adding the "sources" you need - which might be directories, ZIP files, embedded filesystems, or embedded ZIP binaries. If a project- or search-cache is defined, then this will be used to find dependencies.
Once you've added all the sources for your project, p.Open() or p.Migrate() performs the migration.
The `pgpkg` package is always installed automatically, and is never exported.
func NewProject ¶
func NewProject() *Project
NewProject creates a new project. It adds the "pgpkg" package to the project, which is required to track the objects we create and remove.
func NewProjectFrom ¶
NewProjectFrom creates a new project and adds the package found at path. It also configures (and possibly creates) a project cache, also rooted at the given path. If searchCaches is not nil, these will be searched in order when resolving dependencies. Search caches take precedence over the project cache.
func (*Project) AddEmbeddedFS ¶
func (*Project) AddPackage ¶
AddPackage adds an individual package to the project.
func (*Project) Init ¶
Init initialises the pgpkg schema itself. It effectively uses pgpkg's migration tools to bookstrap itself.
func (*Project) Open ¶
Open opens the given database, installs the packages from the project, and returns the database connection.
Open is the main entry point for pgpkg.
Packages are installed within a single transaction. Migrations and tests are applied automatically. Package installation is atomic; it either fully succeeds or fails without changing the database.
If this method returns an error, you should call pgpkg.Exit(err) to exit. This call checks that the error was significant and will adjust the OS exit status accordingly. See pgpkg.Exit() for more details.
If dsn is an empty string, pgpkg will attempt to use the PGPKG_DSN environment variable. If PGPKG_DSN is not set, pgpkg will use the usual libpq PG environment variables.
func (*Project) Parse ¶
Parse prepares a project for migrating or other processing by resolving any dependencies and parsing the schemas.
func (*Project) PrintInfo ¶
func (p *Project) PrintInfo(w InfoWriter)
type ReadCache ¶
type ReadCache struct {
// contains filtered or unexported fields
}
func NewReadCache ¶
type Schema ¶
type Schema struct { *Bundle // contains filtered or unexported fields }
func (*Schema) PrintInfo ¶
func (s *Schema) PrintInfo(w InfoWriter)
type Source ¶
type Source interface { // FS is implemented by every Source. fs.FS // Sub returns a source representing a subdirectory within the source. Sub(dir string) (Source, error) // Location should return the actual path for a source, taking account // any subpaths that have been extracted from it. This is going to require a different // format and handling for directories, embeds, ZIPs, and other objects. Location() string // Cache returns the cache for this source, if one exists. You should return // a WriteCache from this function if your source supports writing. FIXME. Cache() (Cache, error) }
Source represents the tree of files in a package; it's basically a wrapper around fs.FS, but adds context. Source lets us access filesystems in any format, which currently includes filesystems (eg, for use with go:embed), ZIP files (for packaging), and local directories.
Sources may include a cache, which could be either a read or write cache, depending on the type of source.
type Statement ¶
type Statement struct { Unit *Unit // Unit this statement appears in LineNumber int // Line number within the Unit Source string // The actual SQL Tree *pg_query.RawStmt // Parsed SQL statement. Error error // The most recent result from processing the statement. // contains filtered or unexported fields }
Statement is a parsed SQL statement within a unit.
func (*Statement) DefaultContext ¶
func (s *Statement) DefaultContext() *PKGErrorContext
func (*Statement) GetManagedObject ¶
func (s *Statement) GetManagedObject() (*ManagedObject, error)
GetManagedObject returns identifying information about an object from a CREATE statement, such as function, view or trigger. NOTE: This functon might not support all object types, but you can add more as needed.
The result is cached since it's used repeatedly during MOB processing.
func (*Statement) Headline ¶
Headline returns the first line of the statement, eg, to provide context during debugging and logging.
func (*Statement) LocationOffset ¶
func (*Statement) Try ¶
Try executes a statement in a savepoint. This allows us to find context if statement execution fails.
Returns true if the statement succeeded, or true-with-error if it failed but could be retried (this depends on where the error occurred). Returns false if an error occurred that was not related to statement execution.
If an error occurs while executing the statement, the statement's Error field is also set.
type Tests ¶
type Tests struct { *Bundle NamedTests map[string]*Statement // contains filtered or unexported fields }
func (*Tests) PrintInfo ¶
func (t *Tests) PrintInfo(w InfoWriter)
type Unit ¶
type Unit struct { // The Bundle that this unit belongs to. Bundle *Bundle // Path is the filename within the Bundle FS that this Unit // should read from when it's parsed. Path string // The contents (SQL statements) declared in the unit. Source string // The list of parsed statements in this unit. Statements []*Statement }
Unit (ie, build unit) represents potentially parsable tree of SQL source code taken from a single file. Units are lazily loaded, and don't parse their contents until requested, with the Statements() function. Once the unit is compiled, individual statements contain line number and other debugging information.
func (*Unit) DefaultContext ¶
func (u *Unit) DefaultContext() *PKGErrorContext
type WriteCache ¶
type WriteCache struct { ReadCache // contains filtered or unexported fields }
func NewWriteCache ¶
func NewWriteCache(dir string) *WriteCache
func (*WriteCache) ImportProject ¶
func (c *WriteCache) ImportProject(srcProject *Project) error
ImportProject imports the given project into the cache. If the project has dependencies, these are imported from the child project's cache, unless they are already present in the target cache.
func (*WriteCache) RemovePackage ¶
func (c *WriteCache) RemovePackage(pkgName string) error
RemovePackage removes (deletes) a package from the cache.
type ZipByteSource ¶
type ZipByteSource struct {
// contains filtered or unexported fields
}
func NewZipByteSource ¶
func NewZipByteSource(zipBytes []byte) (*ZipByteSource, error)
NewZipByteSource creates a new ZIP source from a byte slice.
func NewZipPathSource ¶
func NewZipPathSource(path string) (*ZipByteSource, error)
NewZipPathSource creates a new ZIP source from a filesystem path. This reads the whole ZIP file into memory and returns a ZipByteSource.
func (*ZipByteSource) Cache ¶
func (zs *ZipByteSource) Cache() (Cache, error)
func (*ZipByteSource) Location ¶
func (zs *ZipByteSource) Location() string
func (*ZipByteSource) String ¶
func (zs *ZipByteSource) String() string