psql

package
v0.10.3 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2020 License: GPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package psql is the Postgresql storage layer of Qvain.

Index

Constants

View Source
const (
	CompareEq = iota // ==
	CompareLe = iota // <=
	CompareGe = iota // >=
	CompareLt = iota // <
	CompareGt = iota // >
)

Constants for comparison types.

View Source
const DefaultPoolAcquireTimeout = 10 * time.Second

DefaultPoolAcquireTimeout is the duration pgx waits for a connection to become available from the pool.

Variables

View Source
var (
	ErrExists         = NewError("exists")
	ErrNotFound       = NewError("not found")
	ErrNotOwner       = NewError("not owner")
	ErrInvalidJson    = NewError("invalid json")
	ErrNotImplemented = NewError("not implemented")
)

Errors exported by the database layer.

View Source
var (
	ErrTemporary  = NewError("temporary database error")
	ErrTimeout    = NewError("database timeout")
	ErrConnection = NewError("database connection error")
)

Errors from the underlying database connection.

View Source
var ComparisonSuffixes = map[string]int{
	"":    CompareEq,
	"_eq": CompareEq,
	"_le": CompareLe,
	"_ge": CompareGe,
	"_lt": CompareLt,
	"_gt": CompareGt,
}

ComparisonSuffixes are used to determine the type of comparison used in a query parameter.

View Source
var DatasetFilterGroupByPaths = map[string]string{
	"schema":       `schema`,
	"organization": `blob->>'metadata_provider_org' as organization`,
	"access_type":  `blob#>>'{"research_dataset","access_rights","access_type","identifier"}' as access_type`,
	"date_created": `date_trunc('day', created$tz) as created`,
}

DatasetFilterGroupByPaths provides paths/values for grouping datasets. Keys contained in this map are the only valid options for group_by.

View Source
var TimeZoneRegex = regexp.MustCompile(`(Z|([\+-]\d\d:\d\d))$`)

TimeZoneRegex is used to determine if a date string ends with a timezone offset.

Functions

func NewError

func NewError(text string) error

New returns an error that formats as the given text.

Types

type BatchManager

type BatchManager struct {
	// contains filtered or unexported fields
}

func (*BatchManager) Commit

func (b *BatchManager) Commit() error

func (*BatchManager) Create

func (b *BatchManager) Create(dataset *models.Dataset) error

func (*BatchManager) CreateWithMetadata

func (b *BatchManager) CreateWithMetadata(dataset *models.Dataset) error

func (*BatchManager) Delete

func (b *BatchManager) Delete(id uuid.UUID) error

func (*BatchManager) Rollback

func (b *BatchManager) Rollback()

func (*BatchManager) Update

func (b *BatchManager) Update(id uuid.UUID, blob []byte) error

func (*BatchManager) UpdateSynced

func (b *BatchManager) UpdateSynced(id uuid.UUID) error

func (*BatchManager) Upsert

func (b *BatchManager) Upsert(data *models.Dataset) error

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB holds the database methods and configuration.

func NewPoolService

func NewPoolService(connString string) (db *DB, err error)

NewPoolService creates a psql service from a connection string and initialises the connection pool.

func NewPoolServiceFromEnv

func NewPoolServiceFromEnv() (db *DB, err error)

NewPoolService creates a psql service using environment variables and initialises the connection pool.

func NewService

func NewService(connString string) (db *DB, err error)

NewService returns a database handle configured with the given connection string. It does not try to connect.

func (*DB) BatchStore

func (db *DB) BatchStore(datasets []*models.Dataset) error

BatchStore takes a list of datasets and stores them as new datasets.

func (*DB) Begin

func (psql *DB) Begin() (*Tx, error)

func (*DB) ChangeOwnerTo

func (db *DB) ChangeOwnerTo(id uuid.UUID, uid uuid.UUID) error

ChangeOwnerTo updates a dataset's owner.

func (*DB) Check

func (psql *DB) Check() error

func (*DB) CheckOwner

func (db *DB) CheckOwner(id uuid.UUID, owner uuid.UUID) (err error)

CheckOwner calls tx.CheckOwner to check if the record exists and is owner by the given user.

func (*DB) Clone

func (db *DB) Clone(id uuid.UUID, newid uuid.UUID, blob []byte) error

func (*DB) Connect

func (psql *DB) Connect() (*pgx.Conn, error)

Connect returns a single database conn or an error.

func (*DB) CountDatasets

func (db *DB) CountDatasets(filter *DatasetFilter) (json.RawMessage, error)

CountDatasets gives the number of datasets matching the DatasetFilter. Returns a json object containing the count. If grouping is enabled, returns a json array containing the grouped results.

func (*DB) Create

func (db *DB) Create(dataset *models.Dataset) error

Create creates a new dataset. It is a convenience wrapper for the Create method on transactions.

func (*DB) CreateWithMetadata

func (db *DB) CreateWithMetadata(dataset *models.Dataset) error

CreateWithMetadata creates a new dataset with extra metadata instead of default values.

func (*DB) Delete

func (db *DB) Delete(id uuid.UUID, owner *uuid.UUID) error

Delete removes one dataset from the database if the owner matches.

func (*DB) ExportAsJson

func (db *DB) ExportAsJson(id uuid.UUID) (json.RawMessage, error)

func (*DB) Get

func (db *DB) Get(id uuid.UUID) (*models.Dataset, error)

Get retrieves a dataset from the database.

func (*DB) GetAllForUid

func (db *DB) GetAllForUid(uid uuid.UUID) ([]*models.Dataset, error)

GetAllForUid returns all datasets for a given user.

func (*DB) GetIdentityForUid

func (db *DB) GetIdentityForUid(svc string, uid uuid.UUID) (id string, err error)

GetIdentityForUid gets the identity for a given uid and service.

func (*DB) GetLastSync

func (db *DB) GetLastSync(uid uuid.UUID) (time.Time, error)

func (*DB) GetUidForIdentity

func (db *DB) GetUidForIdentity(svc, id string) (uid uuid.UUID, err error)

GetUidForIdentity gets the application uid for a given external service and identity.

Note that identities need not be unique, though those used for login ought to be.

func (*DB) GetWithOwner

func (db *DB) GetWithOwner(id uuid.UUID, owner uuid.UUID) (*models.Dataset, error)

GetWithOwner retrieves a dataset from the database if the owner matches.

func (*DB) InitPool

func (psql *DB) InitPool() (err error)

InitPool initialises a pool with default settings on the database object.

func (*DB) ListAllForUid

func (db *DB) ListAllForUid(uid uuid.UUID) ([]*models.Dataset, error)

ListAllForUid returns the list of datasets for a given user.

func (*DB) Log

func (psql *DB) Log(plevel pgx.LogLevel, msg string, data map[string]interface{})

func (*DB) LookupByFairdataIdentifier

func (db *DB) LookupByFairdataIdentifier(fdid string) (uuid.UUID, error)

LookupByFairdataIdentifier returns the Qvain id for a given Fairdata identifier.

func (*DB) LookupByQvainId

func (db *DB) LookupByQvainId(id uuid.UUID) (bool, error)

func (*DB) MustConnect

func (psql *DB) MustConnect() *pgx.Conn

MustConnect returns a single database conn and panics on failure.

func (*DB) NewBatch

func (db *DB) NewBatch() (*BatchManager, error)

func (*DB) NewBatchForUser

func (db *DB) NewBatchForUser(uid uuid.UUID) (*BatchManager, error)

func (*DB) Patch

func (db *DB) Patch(id uuid.UUID, blob []byte) error

func (*DB) PatchWithOwner

func (db *DB) PatchWithOwner(id uuid.UUID, blob []byte, owner uuid.UUID) error

PatchWithOwner patches a dataset JSON blob with ownership checks.

func (*DB) RegisterIdentity

func (db *DB) RegisterIdentity(svc, id string) (uid uuid.UUID, isNew bool, err error)

RegisterIdentity takes an external service and identity and gets the corresponding application uid, creating it if necessary. Returns either a UUID uid and a boolean indicating if the account has been newly created or an error.

Note that while external ids are not guaranteed to be unique and might refer to multiple application users, this function allows only unique registrations as it creates real (login) users mapped to external accounts.

func (*DB) SetLogger

func (psql *DB) SetLogger(logger zerolog.Logger)

SetLogger assigns a zerolog logger to the database service. It is not safe to call this function after initialisation.

func (*DB) SmartGetWithOwner

func (db *DB) SmartGetWithOwner(id uuid.UUID, owner uuid.UUID) (*models.Dataset, error)

func (*DB) SmartUpdateWithOwner

func (db *DB) SmartUpdateWithOwner(id uuid.UUID, blob []byte, owner uuid.UUID) error

func (*DB) StoreNewVersion

func (db *DB) StoreNewVersion(id uuid.UUID, basedOn uuid.UUID, created time.Time, blob []byte) error

StoreNewVersion wraps a StoreNewVersion transaction.

func (*DB) StorePublished

func (db *DB) StorePublished(id uuid.UUID, blob []byte, synced time.Time) error

StorePublished saves a published dataset to the database and marks it as published. TODO: handle empty blob

func (*DB) Update

func (db *DB) Update(id uuid.UUID, blob []byte) error

func (*DB) UpdateWithOwner

func (db *DB) UpdateWithOwner(id uuid.UUID, blob []byte, owner uuid.UUID) error

UpdateWithOwner updates a dataset with ownership checks.

func (*DB) Version

func (psql *DB) Version() (string, error)

func (*DB) ViewDatasetInfoByIdentifier added in v0.10.3

func (db *DB) ViewDatasetInfoByIdentifier(identifierType string, identifier string) (json.RawMessage, error)

ViewDatasetInfoByIdentifier gives basic information for a single dataset with a given identifier.

func (*DB) ViewDatasetWithOwner

func (db *DB) ViewDatasetWithOwner(id uuid.UUID, owner uuid.UUID, svc string) (json.RawMessage, error)

func (*DB) ViewDatasetsByOwner

func (db *DB) ViewDatasetsByOwner(owner uuid.UUID) (json.RawMessage, error)

ViewDatasetsByOwner builds a JSON array with the datasets for a given owner.

func (*DB) ViewVersions

func (db *DB) ViewVersions(owner uuid.UUID, dataset uuid.UUID) (json.RawMessage, error)

ViewVersions returns a (JSON) array with existing versions for a given dataset and owner.

func (*DB) WithTransaction

func (db *DB) WithTransaction(f func(tx *Tx) error) error

WithTransaction abstracts some of the database logic by wrapping Tx methods.

example:

db.WithTransaction(func(tx psql.Tx) error {
	return tx.StoreNewVersion(id, parent, created, blob)
})

type DatabaseError

type DatabaseError struct {
	// contains filtered or unexported fields
}

DatabaseError is a trivial implementation of error.

func (*DatabaseError) Error

func (e *DatabaseError) Error() string

Error satisfies Go's Error interface.

type DatasetFilter

type DatasetFilter struct {
	OnlyDrafts    bool         // only drafts are counted
	OnlyPublished bool         // only published are counted
	OnlyAtt       bool         // only datasets in ATT catalog are counted
	OnlyIda       bool         // only datasets in IDA catalog are counted
	DateCreated   []TimeFilter // filters by creation date
	User          string       // filter by user (metadata_provider_user)
	Organization  string       // filter by organization (metadata_provider_org)
	GroupBy       string       // group values, see DatasetFilterGroupByPaths for valid options

	// options for testing, not currently exposed in the stats API
	QvainOwner    string // qvain id of owner
	GroupTimeZone string // time zone used in grouping dates, supported values are "" (local) and "UTC"
}

DatasetFilter is used to specify filtering options for datasets.

func (*DatasetFilter) GroupByPath

func (filter *DatasetFilter) GroupByPath() string

GroupByPath returns data path to use in GROUP BY statement.

func (*DatasetFilter) Where

func (filter *DatasetFilter) Where() (string, []interface{})

Where returns the WHERE statement for the filter.

type TimeFilter

type TimeFilter struct {
	Precision  time.Duration
	Time       time.Time
	Comparison int
}

TimeFilter contains data for time-based filtering. The timefilter represents a comparison performed on a time range defined by: start ≤ time < end

func ParseTimeFilter

func ParseTimeFilter(suffix string, timeString string) TimeFilter

ParseTimeFilter parses a time string for a given query suffix.

The suffix is used to determine the comparison used. For "param", the options are: - param equal - param_eq equal - param_le less than or equal - param_ge greater than or equal - param_lt less than - param_gt greater than

The function accepts RFC3339 dates. In addition, the date can be truncated to desired precision and timezone offset is optional. If timezone offset is not specified, the local timezone is assumed. - year: 2019 - month: 2019-08 - date: 2019-08-27 - hours: 2019-08-27T13 - minutes: 2019-08-27T13:30 - seconds: 2019-08-27T13:30:00 Comparisons will be made with the used precision, e.g. equality for a date without hours given will represent a 24 hour range starting from the date.

Timezone offset is either Z for UTC, or +/-hh:mm. Both escaped and unscaped query parameters should work, and space can be used instead of +.

func (*TimeFilter) End

func (t *TimeFilter) End() time.Time

End is the end of time range.

func (*TimeFilter) IsZero

func (t *TimeFilter) IsZero() bool

IsZero tells if the time contained has the zero time value.

func (*TimeFilter) Start

func (t *TimeFilter) Start() time.Time

Start is the start of the time range.

type Tx

type Tx struct {
	*pgx.Tx
}

func (*Tx) CheckOwner

func (tx *Tx) CheckOwner(id uuid.UUID, owner uuid.UUID) error

CheckOwner returns an error if the record is not owned by the given user.

func (*Tx) Create

func (tx *Tx) Create(dataset *models.Dataset) error

Create inserts a new dataset into the database using default values for date and boolean fields. Use this for new datasets created in this application.

func (*Tx) StoreNewVersion

func (tx *Tx) StoreNewVersion(basedOn uuid.UUID, id uuid.UUID, created time.Time, blob []byte) error

StoreNewVersion inserts a new version of an existing dataset, copying most fields.

type WhereBuilder

type WhereBuilder struct {
	// contains filtered or unexported fields
}

WhereBuilder is a helper object for creating SQL WHERE statements.

func NewWhereBuilder

func NewWhereBuilder() *WhereBuilder

NewWhereBuilder creates a WhereBuilder.

func (*WhereBuilder) MaybeAdd

func (w *WhereBuilder) MaybeAdd(enabled bool, query string)

MaybeAdd adds query to conditions if enabled is true.

func (*WhereBuilder) MaybeAddString

func (w *WhereBuilder) MaybeAddString(s string, query string)

MaybeAddString adds query to conditions if s is non-empty. The s argument is added as a query parameter and $ in the query string is replaced with its position.

func (*WhereBuilder) MaybeAddTimeFilter

func (w *WhereBuilder) MaybeAddTimeFilter(filter TimeFilter, query string)

MaybeAddTimeFilter adds a time condition if !TimeFilter.IsZero(). Time comparisons are performed against the query argument.

func (*WhereBuilder) Where

func (w *WhereBuilder) Where() (string, []interface{})

Where returns the WHERE statement.

Jump to

Keyboard shortcuts

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