database

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2023 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanStressTest

func CleanStressTest()

func ContextWithDbConn

func ContextWithDbConn(parent context.Context, db *Database, conn *DbConn) context.Context

func DeletePolicy

func DeletePolicy(ctx context.Context, table string, name string) error

func DeletePrivilege

func DeletePrivilege(ctx context.Context, privilege *Privilege) error

func DeleteRole

func DeleteRole(ctx context.Context, name string) error

func DeleteSchema

func DeleteSchema(ctx context.Context, name string, cascade bool) error

func DeleteUser

func DeleteUser(ctx context.Context, name string) error

func FillContext

func FillContext(ctx context.Context, r *http.Request, db *Database, conn *DbConn, role string) context.Context

func HasTX

func HasTX(c *DbPoolConn) bool

func PrepareConnection

func PrepareConnection(ctx context.Context, conn *DbPoolConn, role string, claims string, newAcquire bool) error

PrepareConnection starts a transaction if the configuration requires it, i.e. if TransactionEnd is not equal to 'none'. If the role parameter is not empty, it binds the role to the connection.

func PrepareStressTest

func PrepareStressTest(conn *pgxpool.Conn)

func ReleaseConn

func ReleaseConn(ctx context.Context, conn *DbPoolConn) error

ReleaseConn releases a connection to the proper pool. It is a simplified version of ReleaseConnection

func ReleaseConnection

func ReleaseConnection(ctx context.Context, conn *DbPoolConn, err bool, resetRole bool) error

ReleaseConnection releases a connection to the proper pool. It resets its role if requested and closes the transaction, based on the configuration.

func SetQueryBuilder

func SetQueryBuilder(ctx context.Context, qb QueryBuilder)

func SetRequestParser

func SetRequestParser(ctx context.Context, rp RequestParser)

func StressTest

func StressTest()

Types

type Argument

type Argument struct {
	Name string
	Type string
	Mode byte // i IN, o OUT, b INOUT, v VARIADIC, t TABLE

}

type BuildError

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

func (*BuildError) Error

func (e *BuildError) Error() string

type BuildStack

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

BuildStack represents the context when navigating the AST produced by the parser

type Column

type Column struct {
	Name        string   `json:"name"`
	Type        string   `json:"type"`
	NotNull     bool     `json:"notnull"`
	Default     *string  `json:"default"`
	Constraints []string `json:"constraints"`
	Table       string   `json:"table,omitempty"`
}

type ColumnType

type ColumnType struct {
	Table       string `json:"table"`
	Name        string `json:"name"`
	Type        string `json:"type"`
	DataType    string `json:"datatype"`
	IsArray     bool   `json:"isarray"`
	IsComposite bool   `json:"iscomposite"`
}

type ColumnUpdate

type ColumnUpdate struct {
	Name    string  `json:"name"`
	NewName *string `json:"newname"`
	Type    *string `json:"type"`
	NotNull *bool   `json:"notnull"`
	Default *string `json:"default"`
	Table   string  `json:"-"`
}

type CommonBuilder

type CommonBuilder struct{}

func (CommonBuilder) BuildDelete

func (CommonBuilder) BuildDelete(table string, parts *QueryParts, options QueryOptions, info *SchemaInfo) (
	delete string, valueList []any, err error)

func (CommonBuilder) BuildExecute

func (CommonBuilder) BuildExecute(name string, record Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (
	exec string, valueList []any, err error)

func (CommonBuilder) BuildInsert

func (CommonBuilder) BuildInsert(table string, records []Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (
	insert string, valueList []any, err error)

func (CommonBuilder) BuildUpdate

func (CommonBuilder) BuildUpdate(table string, record Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (
	update string, valueList []any, err error)

type Config

type Config struct {
	URL                string   `comment:"Database URL (default: postgres://localhost:5432)"`
	MinPoolConnections int32    `comment:"Miminum connections per pool (default: 10)"`
	MaxPoolConnections int32    `comment:"Maximum connections per pool (default: 100)"`
	AuthRole           string   `comment:"Authorization role (default: auth)"`
	AnonRole           string   `comment:"Anonymous role (default: anon)"`
	AllowedDatabases   []string `comment:"Allowed databases (default: [] for all)"`
	SchemaSearchPath   []string `comment:"Schema search path (default: [] for Postgres search path)"`
	TransactionEnd     string   `comment:"How to end a tx: none, commit, rollback (default: none)"`
}

func DefaultConfig

func DefaultConfig() *Config

type Constraint

type Constraint struct {
	Name           string   `json:"name"`
	Type           byte     `json:"type"` // c: check, u: unique, p: primary, f: foreign
	Table          string   `json:"table"`
	Columns        []string `json:"columns"`
	RelatedTable   *string  `json:"reltable"`
	RelatedColumns []string `json:"relcolumns"`
	Definition     string   `json:"definition"`
}

type Database

type Database struct {
	DatabaseInfo
	// contains filtered or unexported fields
}

func GetDb

func GetDb(ctx context.Context) *Database

func (*Database) AcquireConnection

func (db *Database) AcquireConnection(ctx context.Context) (*pgxpool.Conn, error)

func (*Database) Activate

func (db *Database) Activate(ctx context.Context) error

Activate initializes a database and starts its connection pool. It signals a db as activated even if there is an error, which is managed in DBE

func (*Database) Close

func (db *Database) Close()

func (*Database) CreateColumn

func (db *Database) CreateColumn(ctx context.Context, column *Column) (*Column, error)

func (*Database) CreateConstraint

func (db *Database) CreateConstraint(ctx context.Context, constraint *Constraint) (*Constraint, error)

func (*Database) CreateFunction

func (db *Database) CreateFunction(ctx context.Context, function *Function) (*Function, error)

func (*Database) CreateRecords

func (db *Database) CreateRecords(ctx context.Context, table string, records []Record, filters Filters) ([]byte, int64, error)

func (*Database) CreateTable

func (db *Database) CreateTable(ctx context.Context, table *Table) (*Table, error)

func (*Database) CreateView

func (db *Database) CreateView(ctx context.Context, view *View) (*View, error)

func (*Database) DeleteColumn

func (db *Database) DeleteColumn(ctx context.Context, table string, name string, cascade bool) error

func (*Database) DeleteConstraint

func (db *Database) DeleteConstraint(ctx context.Context, table string, name string) error

func (*Database) DeleteFunction

func (db *Database) DeleteFunction(ctx context.Context, name string) error

func (*Database) DeleteRecords

func (db *Database) DeleteRecords(ctx context.Context, table string, filters Filters) ([]byte, int64, error)

func (*Database) DeleteTable

func (db *Database) DeleteTable(ctx context.Context, name string) error

func (*Database) DeleteView

func (db *Database) DeleteView(ctx context.Context, name string) error

func (*Database) ExecFunction

func (db *Database) ExecFunction(ctx context.Context, name string, record Record, filters Filters) ([]byte, int64, error)

func (*Database) GetColumn

func (db *Database) GetColumn(ctx context.Context, ftablename string, name string) (*Column, error)

func (*Database) GetColumnTypes

func (db *Database) GetColumnTypes(ctx context.Context) ([]ColumnType, error)

func (*Database) GetColumns

func (db *Database) GetColumns(ctx context.Context, ftablename string) ([]Column, error)

func (*Database) GetConstraints

func (db *Database) GetConstraints(ctx context.Context, tablename string) ([]Constraint, error)

func (*Database) GetFunctions

func (db *Database) GetFunctions(ctx context.Context) ([]Function, error)

func (*Database) GetRecords

func (db *Database) GetRecords(ctx context.Context, table string, filters Filters) ([]byte, error)

func (*Database) GetStructures

func (db *Database) GetStructures(ctx context.Context, query string) ([]any, error)

/table?filter

func (*Database) GetTable

func (db *Database) GetTable(ctx context.Context, name string) (*Table, error)

func (*Database) GetTables

func (db *Database) GetTables(ctx context.Context) ([]Table, error)

func (*Database) GetView

func (db *Database) GetView(ctx context.Context, name string) (*View, error)

func (*Database) GetViews

func (db *Database) GetViews(ctx context.Context) ([]View, error)

func (*Database) UpdateColumn

func (db *Database) UpdateColumn(ctx context.Context, column *ColumnUpdate) (*Column, error)

func (*Database) UpdateRecords

func (db *Database) UpdateRecords(ctx context.Context, table string, record Record, filters Filters) ([]byte, int64, error)

func (*Database) UpdateTable

func (db *Database) UpdateTable(ctx context.Context, table *TableUpdate) (*Table, error)

type DatabaseInfo

type DatabaseInfo struct {
	Name  string `json:"name"`
	Owner string `json:"owner"`
}

type DatabaseJSONSerializer

type DatabaseJSONSerializer struct{}

func (DatabaseJSONSerializer) Serialize

func (DatabaseJSONSerializer) Serialize(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)

func (DatabaseJSONSerializer) SerializeSingle

func (DatabaseJSONSerializer) SerializeSingle(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)

type DbConn

type DbConn = pgx.Conn

func GetConn

func GetConn(ctx context.Context) *DbConn

type DbEngine

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

DbEngine represents the database engine (a "cluster")

var DBE *DbEngine

func InitDbEngine

func InitDbEngine(dbConfig *Config, logger *logging.Logger) (*DbEngine, error)

InitDbEngine creates a connection pool, connects to the engine and initializes it

func (*DbEngine) AcquireConnection

func (dbe *DbEngine) AcquireConnection(ctx context.Context) (*pgxpool.Conn, error)

AcquireConnection acquires a connection in the database engine

func (*DbEngine) Close

func (dbe *DbEngine) Close()

Close closes the database engine and all of its active databases

func (*DbEngine) CreateActiveDatabase

func (dbe *DbEngine) CreateActiveDatabase(ctx context.Context, name string) (*Database, error)

func (*DbEngine) CreateDatabase

func (dbe *DbEngine) CreateDatabase(ctx context.Context, name string) (*DatabaseInfo, error)

func (*DbEngine) DeleteDatabase

func (dbe *DbEngine) DeleteDatabase(ctx context.Context, name string) error

func (*DbEngine) GetActiveDatabase

func (dbe *DbEngine) GetActiveDatabase(ctx context.Context, name string) (*Database, error)

func (*DbEngine) GetDatabase

func (dbe *DbEngine) GetDatabase(ctx context.Context, name string) (*DatabaseInfo, error)

func (*DbEngine) GetDatabases

func (dbe *DbEngine) GetDatabases(ctx context.Context) ([]DatabaseInfo, error)

func (*DbEngine) IsDatabaseAllowed

func (dbe *DbEngine) IsDatabaseAllowed(name string) bool

IsDatabaseAllowed chacks if a database is usable

type DbLogger

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

func NewDbLogger

func NewDbLogger(logger *zerolog.Logger) *DbLogger

NewDbLogger accepts a zerolog.Logger as input and returns a new custom pgx logging facade as output.

func (*DbLogger) Log

func (pl *DbLogger) Log(ctx context.Context, level tracelog.LogLevel, msg string, data map[string]interface{})

type DbPoolConn

type DbPoolConn = pgxpool.Conn

func AcquireConnection

func AcquireConnection(ctx context.Context, db *Database) (conn *DbPoolConn, err error)

AcquireConnection takes a connection from a database pool. If the db parameter is nil, it uses the global engine pool.

func ContextWithDb

func ContextWithDb(parent context.Context, db *Database, role string) (context.Context, *DbPoolConn, error)

type DirectJSONSerializer

type DirectJSONSerializer struct {
	strings.Builder
	// contains filtered or unexported fields
}

func (*DirectJSONSerializer) Serialize

func (d *DirectJSONSerializer) Serialize(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)

func (*DirectJSONSerializer) SerializeSingle

func (d *DirectJSONSerializer) SerializeSingle(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)

type DirectQueryBuilder

type DirectQueryBuilder struct {
	CommonBuilder
}

func (DirectQueryBuilder) BuildSelect

func (DirectQueryBuilder) BuildSelect(table string, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)

type Field

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

Field represents a column and its attributes in the different parts of a query: select, where, order, etc clauses

type Filters

type Filters = url.Values

type ForeignKey

type ForeignKey struct {
	Name           string
	Table          string
	Columns        []string
	RelatedTable   string
	RelatedColumns []string
}

type Function

type Function struct {
	Name         string     `json:"name"`
	Arguments    []Argument `json:"arguments"`
	Returns      string     `json:"returns"`
	Language     string     `json:"language"`
	Definition   string     `json:"definition"`
	ReturnTypeId uint32     `json:"rettypeid"`
	ReturnIsSet  bool       `json:"retisset"`
	HasUnnamed   bool       `json:"hasunnamed"` // has unnamed parameters
	HasOut       bool       `json:"hasout"`     // has OUT, INOUT, TABLE parameters
}

type Join

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

Join containts information to create a join relationship. It is composed while building the select clause.

type OrderField

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

type ParseError

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

func (*ParseError) Error

func (e *ParseError) Error() string

type Policy

type Policy struct {
	Name       string   `json:"name"`
	Table      string   `json:"table"`
	Retrictive bool     `json:"deny"`
	Command    string   `json:"command"`
	Roles      []string `json:"roles"`
	Using      *string  `json:"using"`
	Check      *string  `json:"check"`
}

func CreatePolicy

func CreatePolicy(ctx context.Context, policy *Policy) (*Policy, error)

func GetPolicies

func GetPolicies(ctx context.Context, ftablename string) ([]Policy, error)

type PostgRestParser

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

type Privilege

type Privilege struct {
	TargetName   string   `json:"targetname"`
	TargetSchema string   `json:"targetschema,omitempty"`
	TargetType   string   `json:"targettype"`        // database, schema, table, column, function
	Columns      []string `json:"columns,omitempty"` // to insert column privileges
	Types        []string `json:"types"`
	Grantee      string   `json:"grantee"`
	Grantor      string   `json:"grantor"`
	ACL          string   `json:"acl"`
}

func CreatePrivilege

func CreatePrivilege(ctx context.Context, privilege *Privilege) (*Privilege, error)

func GetDatabasePrivileges

func GetDatabasePrivileges(ctx context.Context, dbname string) ([]Privilege, error)

func GetPrivileges

func GetPrivileges(ctx context.Context, targetType string, targetName string) ([]Privilege, error)

type QueryBuilder

type QueryBuilder interface {
	BuildSelect(table string, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)
	BuildInsert(table string, records []Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)
	BuildUpdate(table string, record Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)
	BuildDelete(table string, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)
	BuildExecute(table string, record Record, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)
	// contains filtered or unexported methods
}

type QueryExecutor

type QueryExecutor struct{}

func (QueryExecutor) Delete

func (QueryExecutor) Delete(ctx context.Context, table string, filters Filters) ([]byte, int64, error)

func (QueryExecutor) Execute

func (QueryExecutor) Execute(ctx context.Context, function string, record Record, filters Filters) ([]byte, int64, error)

func (QueryExecutor) Insert

func (QueryExecutor) Insert(ctx context.Context, table string, records []Record, filters Filters) ([]byte, int64, error)

func (QueryExecutor) Select

func (QueryExecutor) Select(ctx context.Context, table string, filters Filters) ([]byte, error)

func (QueryExecutor) Update

func (QueryExecutor) Update(ctx context.Context, table string, record Record, filters Filters) ([]byte, int64, error)

type QueryOptions

type QueryOptions struct {
	Schema               string
	ContentType          string // json, csv
	ReturnRepresentation bool
	MergeDuplicates      bool
	IgnoreDuplicates     bool
	TxCommit             bool
	TxRollback           bool
	Singular             bool
}

type QueryParts

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

QueryParts is the root of the AST produced by the request parser

type QueryWithJSON

type QueryWithJSON struct {
	CommonBuilder
}

func (QueryWithJSON) BuildSelect

func (QueryWithJSON) BuildSelect(table string, parts *QueryParts, options QueryOptions, info *SchemaInfo) (string, []any, error)

type Record

type Record = map[string]any

type ReflectSerializer

type ReflectSerializer struct{}

func (ReflectSerializer) Serialize

func (ReflectSerializer) Serialize(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)

type RelType

type RelType int
const (
	O2M RelType = iota
	M2O
	O2O
	M2M
)

type Relationship

type Relationship struct {
	Type            RelType
	Table           string
	Columns         []string
	RelatedTable    string
	RelatedColumns  []string
	JunctionTable   string
	JColumns        []string
	JRelatedColumns []string
}

type Request

type Request = http.Request

type RequestParser

type RequestParser interface {
	// contains filtered or unexported methods
}

RequestParser is the interface used to parse the query string in the request and extract the significant headers. Initially we will support PostgREST mode and later perhaps others (Django?).

type ResultSerializer

type ResultSerializer interface {
	Serialize(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)
	SerializeSingle(ctx context.Context, rows pgx.Rows, scalar bool, info *SchemaInfo) ([]byte, error)
}

type Role

type Role struct {
	Name                string   `json:"name"`
	IsSuperUser         bool     `json:"issuperuser"`
	CanLogin            bool     `json:"canlogin"`
	NoInheritPrivileges bool     `json:"noinherit"`
	CanCreateRoles      bool     `json:"cancreateroles"`
	CanCreateDatabases  bool     `json:"cancreatedatabases"`
	CanBypassRLS        bool     `json:"canbypassrls"`
	MemberOf            []string `json:"memberof"` // readonly for now
}

func CreateRole

func CreateRole(ctx context.Context, role *Role) (*Role, error)

func GetRole

func GetRole(ctx context.Context, name string) (*Role, error)

func GetRoles

func GetRoles(ctx context.Context) ([]Role, error)

type Schema

type Schema struct {
	Name  string `json:"name"`
	Owner string `json:"owner"`
}

func CreateSchema

func CreateSchema(ctx context.Context, name string) (*Schema, error)

func GetSchemas

func GetSchemas(ctx context.Context) ([]Schema, error)

type SchemaInfo

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

func NewSchemaInfo

func NewSchemaInfo(ctx context.Context, db *Database) (*SchemaInfo, error)

func (*SchemaInfo) FindRelationshipByCol

func (si *SchemaInfo) FindRelationshipByCol(table, col string) *Relationship

func (*SchemaInfo) GetColumnType

func (si *SchemaInfo) GetColumnType(table string, column string) *ColumnType

func (*SchemaInfo) GetForeignKeys

func (si *SchemaInfo) GetForeignKeys(table string) []ForeignKey

func (*SchemaInfo) GetFunction

func (si *SchemaInfo) GetFunction(name string) *Function

func (*SchemaInfo) GetPrimaryKey

func (si *SchemaInfo) GetPrimaryKey(table string) *Constraint

func (*SchemaInfo) GetRelationships

func (si *SchemaInfo) GetRelationships(table string) []Relationship

func (*SchemaInfo) GetTable

func (si *SchemaInfo) GetTable(table string) *Table

func (*SchemaInfo) GetTypeById

func (si *SchemaInfo) GetTypeById(id uint32) *Type

type SelectField

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

SelectField can contain a selected field or a relationship with another table. For example, select=id,name,other(name) will produce:

  1. a SelectField with field.name = "id"
  2. a SelectField with field.name = "name"
  3. a SelectField with an empty field and a SelectRelation with relation.name = "other", itself with a SelectField in relation.fields with field.name = "name".

label is used as an alias both for a field and a relation.

type SelectRelation

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

SelectRelation stores information about a relationship, expressed in the select clause like: /table?select=id,name,other1(name),...other2(id)

type SerializeError

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

func (*SerializeError) Error

func (e *SerializeError) Error() string

type SmoothContext

type SmoothContext struct {
	Db            *Database
	Conn          *DbConn
	Role          string
	RequestParser RequestParser
	QueryBuilder  QueryBuilder
	QueryOptions  QueryOptions
}

func GetSmoothContext

func GetSmoothContext(ctx context.Context) *SmoothContext

type Table

type Table struct {
	Name        string   `json:"name"`
	Owner       string   `json:"owner"`
	RowSecurity bool     `json:"rowsecurity"`
	HasIndexes  bool     `json:"hasindexes"`
	HasTriggers bool     `json:"hastriggers"`
	IsPartition bool     `json:"ispartition"`
	Constraints []string `json:"constraints"`
	Columns     []Column `json:"columns,omitempty"`
	Inherits    string   `json:"inherit,omitempty"`
	IfNotExists bool     `json:"ifnotexists,omitempty"`
}

type TableUpdate

type TableUpdate struct {
	Name        string  `json:"name"`
	NewName     *string `json:"newname"`
	NewSchema   *string `json:"newschema"`
	Owner       *string `json:"owner"`
	RowSecurity *bool   `json:"rowsecurity"`
}

type Type

type Type struct {
	Id           uint32   `json:"id"`
	Name         string   `json:"name"`
	Schema       string   `json:"schema"`
	IsArray      bool     `json:"isarray"`
	IsRange      bool     `json:"isrange"`
	IsComposite  bool     `json:"iscomposite"`
	IsTable      bool     `json:"istable"`
	IsEnum       bool     `json:"isenum"`
	ArraySubType uint32   `json:"arraysubtype"`
	RangeSubType *uint32  `json:"rangesubtype"`
	SubTypeIds   []uint32 `json:"subtypeids"`
	SubTypeNames []string `json:"subtypenames"`
}

func GetTypes

func GetTypes(ctx context.Context) ([]Type, error)

type User

type User struct {
	Name     string   `json:"name"`
	MemberOf []string `json:"memberof"`
}

func CreateUser

func CreateUser(ctx context.Context, role *User) (*User, error)

func GetUser

func GetUser(ctx context.Context, name string) (*User, error)

func GetUsers

func GetUsers(ctx context.Context) ([]User, error)

type View

type View struct {
	Name         string `json:"name"`
	Owner        string `json:"owner"`
	Definition   string `json:"definition"`
	Materialized bool   `json:"materialized"`
}

type WhereConditionNode

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

Jump to

Keyboard shortcuts

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