Documentation
¶
Index ¶
- Constants
- Variables
- func CheckDatabase(dbConfig *Config) (bool, error)
- func CleanStressTest()
- func ContextWithDbConn(parent context.Context, db *Database, conn *DbConn) context.Context
- func CreateRecords(ctx context.Context, table string, records []Record, filters Filters) ([]byte, int64, error)
- func CreateRecordsFromJSON(ctx context.Context, table string, records []Record, body []byte, ...) ([]byte, int64, error)
- func Delete(ctx context.Context, table string, filters Filters) ([]byte, int64, error)
- func DeleteColumn(ctx context.Context, tablename string, name string, cascade bool) error
- func DeleteConstraint(ctx context.Context, tablename string, name string) error
- func DeleteFunction(ctx context.Context, name string) error
- func DeletePolicy(ctx context.Context, table string, name string) error
- func DeletePrivilege(ctx context.Context, privilege *Privilege) error
- func DeleteRecords(ctx context.Context, table string, filters Filters) ([]byte, int64, error)
- func DeleteRole(ctx context.Context, name string) error
- func DeleteSchema(ctx context.Context, name string, cascade bool) error
- func DeleteTable(ctx context.Context, name string, ifExists bool) error
- func DeleteUser(ctx context.Context, name string) error
- func DeleteView(ctx context.Context, name string) error
- func ExecFunction(ctx context.Context, fname string, record Record, filters Filters, ...) ([]byte, int64, error)
- func Execute(ctx context.Context, function string, record Record, filters Filters, ...) ([]byte, int64, error)
- func FillContext(ctx context.Context, r *http.Request, db *Database, conn *DbConn, role string) context.Context
- func GetDbRole(ctx context.Context) string
- func GetDynStructures(ctx context.Context, query string) ([]any, error)
- func GetMaps(ctx context.Context, query string) ([]map[string]any, error)
- func GetRecords(ctx context.Context, table string, filters Filters) ([]byte, int64, error)
- func GetServerVersion(ctx context.Context) (int, error)
- func Insert(ctx context.Context, table string, records []Record, filters Filters) ([]byte, int64, error)
- func InsertJSON(ctx context.Context, table string, records []Record, body []byte, ...) ([]byte, int64, error)
- func IsExist(err error) bool
- func JQTransformResponse(ctx context.Context, data []byte) ([]byte, error)
- func PrepareConnection(ctx context.Context, conn *DbPoolConn, role string, claims string, ...) error
- func PrepareDatabase(adminURL string, dbConfig *Config) error
- func PrepareNow(ctx context.Context) error
- func PrepareRequest(ctx context.Context, role, claims string, readOnly bool, deferred bool) error
- func PrepareStressTest(conn *pgxpool.Conn)
- func QueryExec(ctx context.Context, query string, values ...any) error
- func QueryStructure[T any](ctx context.Context, query string, values ...any) (*T, error)
- func QueryStructures[T any](ctx context.Context, query string, values ...any) ([]T, error)
- func ReleaseConn(ctx context.Context, conn *DbPoolConn) error
- func ReleaseConnection(ctx context.Context, conn *DbPoolConn, httpErr bool, resetRole bool) error
- func Select(ctx context.Context, table string, filters Filters) ([]byte, int64, error)
- func SetQueryBuilder(ctx context.Context, qb QueryBuilder)
- func SetReadOnly(ctx context.Context) error
- func SetRequestParser(ctx context.Context, rp RequestParser)
- func StressTest()
- func Update(ctx context.Context, table string, record Record, filters Filters) ([]byte, int64, error)
- func UpdateColumn(ctx context.Context, tablename string, name string, column *ColumnUpdate) error
- func UpdateRecords(ctx context.Context, table string, record Record, filters Filters) ([]byte, int64, error)
- func UpdateRecordsWithJQ(ctx context.Context, table string, filters Filters) ([]byte, int64, error)
- func UpdateRole(ctx context.Context, name string, role *RoleUpdate) error
- func UpdateSchema(ctx context.Context, name string, schema *SchemaUpdate) error
- func UpdateTable(ctx context.Context, name string, table *TableUpdate) error
- func VerifyAuthN(ctx context.Context, user, password string) error
- type AmbiguousFunctionError
- type Argument
- type BinarySerializer
- type BuildError
- type BuildStack
- type CSVSerializer
- type Column
- type ColumnType
- type ColumnUpdate
- type CommonBuilder
- func (CommonBuilder) BuildDelete(table string, parts *QueryParts, options *QueryOptions, info *SchemaInfo) (delete string, valueList []any, err error)
- func (CommonBuilder) BuildExecute(name string, f *Function, record Record, parts *QueryParts, ...) (query string, valueList []any, err error)
- func (CommonBuilder) BuildInsert(table string, records []Record, body []byte, parts *QueryParts, ...) (insert string, valueList []any, err error)
- func (CommonBuilder) BuildUpdate(table string, record Record, parts *QueryParts, options *QueryOptions, ...) (update string, valueList []any, err error)
- type Config
- type Constraint
- type ContentTypeError
- type CustomRows
- func (cr *CustomRows) Close()
- func (cr *CustomRows) CommandTag() pgconn.CommandTag
- func (cr *CustomRows) Conn() *pgx.Conn
- func (cr *CustomRows) Err() error
- func (cr *CustomRows) FieldDescriptions() []pgconn.FieldDescription
- func (cr *CustomRows) Next() bool
- func (cr *CustomRows) RawValues() [][]byte
- func (cr *CustomRows) Scan(dest ...any) error
- func (cr *CustomRows) TypeMap() *pgtype.Map
- func (cr *CustomRows) Values() ([]any, error)
- type Database
- type DatabaseInfo
- type DatabaseUpdate
- type DbConn
- type DbEngine
- func (dbe *DbEngine) AcquireConnection(ctx context.Context) (*pgxpool.Conn, error)
- func (dbe *DbEngine) CloneDatabase(ctx context.Context, name string, source string, force bool) (*DatabaseInfo, error)
- func (dbe *DbEngine) Close()
- func (dbe *DbEngine) CreateActiveDatabase(ctx context.Context, name string, owner string) (*Database, error)
- func (dbe *DbEngine) CreateDatabase(ctx context.Context, name string, owner string, getIfExists bool) (*DatabaseInfo, error)
- func (dbe *DbEngine) DeleteDatabase(ctx context.Context, name string) error
- func (dbe *DbEngine) GetActiveDatabase(ctx context.Context, name string) (db *Database, err error)
- func (dbe *DbEngine) GetDatabase(ctx context.Context, name string) (*DatabaseInfo, error)
- func (dbe *DbEngine) GetDatabases(ctx context.Context) ([]DatabaseInfo, error)
- func (dbe *DbEngine) GetMainDatabase(ctx context.Context) (*Database, error)
- func (dbe *DbEngine) GetOrCreateActiveDatabase(ctx context.Context, name string) (*Database, error)
- func (dbe *DbEngine) IsDatabaseAllowed(name string) bool
- func (dbe *DbEngine) ReloadAllSchemas(ctx context.Context) error
- func (dbe *DbEngine) ReloadDatabaseSchema(ctx context.Context, dbName string) error
- func (dbe *DbEngine) ReloadRoleSettings(ctx context.Context) error
- func (dbe *DbEngine) UpdateDatabase(ctx context.Context, name string, update *DatabaseUpdate) error
- type DbLogger
- type DbPoolConn
- type DirectQueryBuilder
- type Field
- type Filters
- type ForeignKey
- type Function
- type JSONSerializer
- type Join
- type ListenerConfig
- type NotificationHandler
- type NotificationListener
- type OrderField
- type ParseError
- type Policy
- type PostgRestParser
- type PostgresConfig
- type Privilege
- type QueryBuilder
- type QueryOptions
- type QueryParts
- type RangeError
- type Record
- type RecursiveInfo
- type RelType
- type Relationship
- type Request
- type RequestParser
- type Role
- type RoleUpdate
- type Schema
- type SchemaError
- type SchemaInfo
- func (si *SchemaInfo) FindFunction(name string, keys []string) (*Function, error)
- func (si *SchemaInfo) FindRelationshipByCol(ftable, col string) *Relationship
- func (si *SchemaInfo) FindRelationshipByFK(ftable, fk string) *Relationship
- func (si *SchemaInfo) FindRelationshipsByHintCol(ftable, relatedTable, col string) []Relationship
- func (si *SchemaInfo) GetColumnType(ftable string, column string) *ColumnType
- func (si *SchemaInfo) GetForeignKeys(ftable string) []ForeignKey
- func (si *SchemaInfo) GetPrimaryKey(ftable string) *Constraint
- func (si *SchemaInfo) GetRelationships(ftable string) []Relationship
- func (si *SchemaInfo) GetTable(ftable string) *Table
- func (si *SchemaInfo) GetTypeById(id uint32) *Type
- func (si *SchemaInfo) ServerAtLeast(major int) bool
- type SchemaUpdate
- type SelectField
- type SelectRelation
- type SerializeError
- type SmoothContext
- type Table
- type TableUpdate
- type TextBuilder
- type TextSerializer
- type Type
- type User
- type View
- type ViewColDep
- type WhereConditionNode
Constants ¶
const DEFAULT_ANON = "anon"
const MinServerVersion = 140000
MinServerVersion is the oldest PostgreSQL the server agrees to run on, as a server_version_num. It is PostgREST's minimumPgVersion (14.0): smoothdb's behaviour is specified as PostgREST's, which is only verified from 14 on, and every release below it has reached end of life. InitDbEngine refuses to start on an older server with an error naming both versions.
const (
SMOOTHDB = "smoothdb"
)
Variables ¶
var ErrAcquisitionTimeout = errors.New("Timed out acquiring connection from connection pool.")
ErrAcquisitionTimeout is the error of an acquire that ran out of PoolAcquisitionTimeout, with PostgREST's message (PGRST003).
Functions ¶
func CheckDatabase ¶ added in v0.2.3
func CleanStressTest ¶
func CleanStressTest()
func ContextWithDbConn ¶
ContextWithDb creates a context using a specific connection
func CreateRecords ¶ added in v0.2.0
func CreateRecordsFromJSON ¶ added in v0.10.0
func CreateRecordsFromJSON(ctx context.Context, table string, records []Record, body []byte, filters Filters) ([]byte, int64, error)
CreateRecordsFromJSON inserts the records decoded from body, a JSON object or array of objects, sending body itself as the rows, as PostgREST does.
func DeleteColumn ¶ added in v0.1.2
func DeleteConstraint ¶ added in v0.1.2
func DeleteRecords ¶ added in v0.2.0
func DeleteTable ¶ added in v0.1.2
func ExecFunction ¶ added in v0.2.0
func FillContext ¶
func FillContext(ctx context.Context, r *http.Request, db *Database, conn *DbConn, role string) context.Context
FillContext compiles and inserts the information related to the database, cresting a new derived context
func GetDynStructures ¶ added in v0.2.4
func GetRecords ¶ added in v0.2.0
func GetServerVersion ¶ added in v0.9.0
GetServerVersion reads the PostgreSQL version of the connection in the context, as a server_version_num.
func InsertJSON ¶ added in v0.10.0
func InsertJSON(ctx context.Context, table string, records []Record, body []byte, filters Filters) ([]byte, int64, error)
InsertJSON is Insert for records decoded from body, a JSON object or array of objects: body itself is sent as the rows (see BuildInsert).
func JQTransformResponse ¶ added in v0.8.0
JQTransformResponse applies the jq program carried by the jq= query parameter (see QueryOptions) to a fully buffered JSON response body, binding jq_args as variables. It returns the body unchanged when no program is present. Only JSON content types can be transformed.
func PrepareConnection ¶
func PrepareConnection(ctx context.Context, conn *DbPoolConn, role string, claims string, newAcquire bool, readOnly bool) error
PrepareConnection starts a transaction if the configuration requires it, i.e. if TransactionMode is not equal to 'none'. If the role parameter is not empty, it binds the role to the connection. A read-only request (GET, HEAD) runs READ ONLY as in PostgREST, so that whatever it reaches cannot write: the transaction is begun READ ONLY, or, with TransactionMode "none", the session is set read-only for it and back for the next write on the same connection.
The role's own settings (ALTER ROLE ... SET) apply to the request, as in PostgREST, in the statement that switches the role: no extra round trip. In a transaction they are transaction-local, so they end with it whatever becomes of the connection, and the transaction takes the role's isolation. With autocommit there is no transaction to hold them: they are session settings, which ReleaseConnection resets before the pool hands the connection to anyone else.
func PrepareDatabase ¶ added in v0.2.3
PrepareDatabase prepares the database for SmoothDb
func PrepareNow ¶ added in v0.11.0
PrepareNow applies the deferred variables of the request in ctx, for a handler that is about to use the connection outside the query executor.
func PrepareRequest ¶ added in v0.11.0
PrepareRequest gets the connection of the request in ctx (FillContext) ready for role and claims, and for a read-only request if readOnly. With deferred the variables wait for the first statement of the request (see requestVars), otherwise they are applied now, as PrepareConnection does.
func PrepareStressTest ¶
func QueryStructure ¶ added in v0.2.4
func QueryStructures ¶ added in v0.2.4
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 ¶
ReleaseConnection releases a connection to the proper pool. It closes the transaction, based on the configuration, and then, if requested, resets the session-level role and claims a request left on it: after, so that a ROLLBACK cannot undo the reset.
func SetQueryBuilder ¶
func SetQueryBuilder(ctx context.Context, qb QueryBuilder)
SetQueryBuilder allows changing the query builder in the current context
func SetReadOnly ¶ added in v0.9.0
SetReadOnly makes the rest of the request run READ ONLY: the open transaction when there is one, the session's implicit transactions otherwise. It is for a request prepared as a write that turns out to be a read (a POST calling a STABLE or IMMUTABLE function); the next request on the connection sets the mode it needs again through PrepareConnection.
func SetRequestParser ¶
func SetRequestParser(ctx context.Context, rp RequestParser)
SetRequestParser allows changing the request parser in the current context
func StressTest ¶
func StressTest()
func UpdateColumn ¶ added in v0.1.2
func UpdateRecords ¶ added in v0.2.0
func UpdateRecordsWithJQ ¶ added in v0.8.0
UpdateRecordsWithJQ performs a jq-update: an atomic read-modify-write of the rows matched by the filters, driven by the jq program in the jq= query parameter (carried on QueryOptions).
Inside the request transaction (one is started if not already open):
- The matched rows are selected FOR UPDATE, in the order= order, capped at MaxUpdateRows+1 (exceeding the cap is an error).
- Each row, as a JSON object with the columns visible to the role, is fed to the program. The output must be a JSON object whose keys are columns of the table: it becomes that row's UPDATE ... SET. An empty object leaves the row untouched.
- Any parse/eval error, non-object output or unknown column aborts the whole request: all rows or none.
RLS and triggers apply unchanged. With Prefer: return=representation it returns the resulting rows in that order (all visible columns; select= is not applied).
func UpdateRole ¶ added in v0.2.7
func UpdateRole(ctx context.Context, name string, role *RoleUpdate) error
func UpdateSchema ¶ added in v0.2.7
func UpdateSchema(ctx context.Context, name string, schema *SchemaUpdate) error
func UpdateTable ¶ added in v0.1.2
func UpdateTable(ctx context.Context, name string, table *TableUpdate) error
Types ¶
type AmbiguousFunctionError ¶ added in v0.10.0
type AmbiguousFunctionError struct {
Hint string
// contains filtered or unexported fields
}
AmbiguousFunctionError: more than one overload of a function accepts the argument names of a call (300, PostgREST PGRST203)
func (AmbiguousFunctionError) Error ¶ added in v0.10.0
func (e AmbiguousFunctionError) Error() string
type BinarySerializer ¶ added in v0.2.6
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 CSVSerializer ¶ added in v0.2.5
type CSVSerializer struct {
TextBuilder
}
type Column ¶
type Column struct {
Name string `json:"name"`
Type string `json:"type"`
NotNull bool `json:"notnull"`
Default *string `json:"default"`
Generated string `json:"generated,omitempty"` // "stored" or "virtual" (PostgreSQL 18) for a GENERATED ALWAYS AS column
ReadOnly bool `json:"readonly"` // a generated column has no default and cannot be written
Comment *string `json:"comment"`
Constraints []string `json:"constraints"`
Table string `json:"table,omitempty"`
Schema string `json:"schema,omitempty"`
}
func CreateColumn ¶ added in v0.1.2
type ColumnType ¶
type ColumnType struct {
Table string `json:"table"`
Schema string `json:"schema"`
Name string `json:"name"`
Type string `json:"type"`
DataType string `json:"datatype"`
IsArray bool `json:"isarray"`
IsComposite bool `json:"iscomposite"`
Builtin bool `json:"builtin"` // the type (a domain's base type) is pg_catalog's
}
func GetColumnTypes ¶ added in v0.1.2
func GetColumnTypes(ctx context.Context) (types []ColumnType, err error)
GetColumnTypes reads the columns with an empty search path, as PostgREST loads its schema cache (SchemaCache.hs empties it for its introspection): format_type then qualifies every type outside pg_catalog with its schema, so DataType names the type whatever the search path of the connection that uses it later, in an insert's column definition list. The SET LOCAL lives in a transaction of its own, or, when the caller already has one open, in a savepoint: rolled back once the rows are read, either undoes the setting and nothing else, and the caller's transaction is neither committed nor changed. The rollback runs even when ctx has been cancelled meanwhile, which pgx would otherwise refuse before sending it.
type ColumnUpdate ¶
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, f *Function, record Record, parts *QueryParts, options *QueryOptions, info *SchemaInfo) ( query string, valueList []any, err error)
func (CommonBuilder) BuildInsert ¶
func (CommonBuilder) BuildInsert(table string, records []Record, body []byte, parts *QueryParts, options *QueryOptions, info *SchemaInfo) ( insert string, valueList []any, err error)
BuildInsert inserts the rows as PostgREST does (SqlFragment.hs, fromJsonBodyF): the rows travel as the statement's only parameter, a json array read with json_to_recordset, so no bulk insert runs into the 65 535 parameters of the extended protocol, and the database's input functions convert the values (an array, a composite, a json column keeping its text). body is the request's JSON, sent as it is: the JSON the records were decoded from, or the JSON a CSV or form body converts to, as in PostgREST. Without one (the Go API) the records are Go values, encoded with the meaning pgx gave them (see insertRows).
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"`
MinPoolConnections int32 `comment:"Miminum connections per pool (default: 10)"`
MaxPoolConnections int32 `comment:"Maximum connections per pool (default: 100)"`
AnonRole string `comment:"Anonymous role (default: '' for no anon)"`
AllowedDatabases []string `comment:"Allowed databases (default: [] for all)"`
SchemaSearchPath []string `comment:"Schema search path (default: [] for Postgres search path)"`
ExposedSchemas []string `` /* 143-byte string literal not displayed */
TransactionMode string `` /* 137-byte string literal not displayed */
AggregatesEnabled bool `comment:"Enable aggregate functions (default: true)"`
MaxRecursiveDepth int `comment:"Maximum recursive query depth; 0 disables recursive queries (default: 100)"`
PoolAcquisitionTimeout int `comment:"Seconds a request waits for a pool connection before answering 504, 0 to wait without a bound (default: 10)"`
MaxRows int64 `` /* 127-byte string literal not displayed */
}
func DefaultConfig ¶
func DefaultConfig() *Config
type Constraint ¶
type Constraint struct {
Name string `json:"name"`
Type string `json:"type"` // check, unique, primary, foreign
Table string `json:"table"`
Schema string `json:"schema"`
Columns []string `json:"columns"`
RelatedTable *string `json:"reltable"`
RelatedSchema *string `json:"relschema"`
RelatedColumns []string `json:"relcolumns"`
Definition string `json:"definition"`
}
func CreateConstraint ¶ added in v0.1.2
func CreateConstraint(ctx context.Context, constraint *Constraint) (*Constraint, error)
func GetConstraints ¶ added in v0.1.2
func GetConstraints(ctx context.Context, tablename string) ([]Constraint, error)
type ContentTypeError ¶ added in v0.2.5
type ContentTypeError struct {
// contains filtered or unexported fields
}
func (ContentTypeError) Error ¶ added in v0.2.5
func (e ContentTypeError) Error() string
type CustomRows ¶ added in v0.2.0
type CustomRows struct {
FieldDescriptions_ []pgconn.FieldDescription
RawValues_ [][][]byte
CurrentRow int
TypeMap_ *pgtype.Map
}
CustomRows is used for testing, to be able to do more iterations on a single query result. This is not permitted by pgx.Rows.
func (*CustomRows) Close ¶ added in v0.2.0
func (cr *CustomRows) Close()
func (*CustomRows) CommandTag ¶ added in v0.2.0
func (cr *CustomRows) CommandTag() pgconn.CommandTag
func (*CustomRows) Conn ¶ added in v0.2.0
func (cr *CustomRows) Conn() *pgx.Conn
func (*CustomRows) Err ¶ added in v0.2.0
func (cr *CustomRows) Err() error
func (*CustomRows) FieldDescriptions ¶ added in v0.2.0
func (cr *CustomRows) FieldDescriptions() []pgconn.FieldDescription
func (*CustomRows) Next ¶ added in v0.2.0
func (cr *CustomRows) Next() bool
func (*CustomRows) RawValues ¶ added in v0.2.0
func (cr *CustomRows) RawValues() [][]byte
func (*CustomRows) Scan ¶ added in v0.2.0
func (cr *CustomRows) Scan(dest ...any) error
func (*CustomRows) TypeMap ¶ added in v0.9.0
func (cr *CustomRows) TypeMap() *pgtype.Map
TypeMap is the map of the copied rows; nil for rows built by hand in tests.
func (*CustomRows) Values ¶ added in v0.2.0
func (cr *CustomRows) Values() ([]any, error)
type Database ¶
type Database struct {
DatabaseInfo
// contains filtered or unexported fields
}
func (*Database) AcquireConnection ¶
AcquireConnection takes a connection from the pool. Unless the acquire is a request's (see the package's AcquireConnection), a connection used since its last cleanup is cleaned first: a function may have left its role or claims on the session, and an internal user (the schema reload, the activation of a database, a library caller) would run as them. Every lease counts as a use, a library caller's too: it may prepare the connection for a role and call such a function as well.
type DatabaseInfo ¶
type DatabaseUpdate ¶ added in v0.2.7
type DbConn ¶
func GetConn ¶
GetConn gets the database connection from the current context, with the request's role and claims in force (see PrepareRequest). If they cannot be applied, the connection is closed: no statement may run on it without them, and the pool discards it. Code on the path of a request uses conn(ctx), which returns that error.
type DbEngine ¶
type DbEngine struct {
// contains filtered or unexported fields
}
DbEngine represents the database engine (the PostgreSQL instance or "cluster")
func InitDbEngine ¶
InitDbEngine creates a connection pool, connects to the engine and initializes it
func (*DbEngine) AcquireConnection ¶
AcquireConnection acquires a connection in the database engine
func (*DbEngine) CloneDatabase ¶ added in v0.2.3
func (dbe *DbEngine) CloneDatabase(ctx context.Context, name string, source string, force bool) (*DatabaseInfo, error)
CloneDatabase creates a new database cloning a source db. The force parameter can be used to stop all the connections to the source db, which is a prerequisite.
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, owner string) (*Database, error)
CreateActiveDatabase allows to create a database and ensures it is activated
func (*DbEngine) CreateDatabase ¶
func (dbe *DbEngine) CreateDatabase(ctx context.Context, name string, owner string, getIfExists bool) (*DatabaseInfo, error)
CreateDatabase creates a new database Use CreateActiveDatabase to create an active instance of a database
func (*DbEngine) DeleteDatabase ¶
DeleteDatabase deletes a database. It blocks until all connections are returned to pool.
func (*DbEngine) GetActiveDatabase ¶
GetActiveDatabase allows to get a database and ensures it is activated (eg it has a connection pool and its cached information)
func (*DbEngine) GetDatabase ¶
GetDatabase gets information about a database. Use GetActiveDatabase to get an active instance of a database. The first request to a database activates it through here, so the wait for the main pool is bounded like the request's own (ErrAcquisitionTimeout).
func (*DbEngine) GetDatabases ¶
func (dbe *DbEngine) GetDatabases(ctx context.Context) ([]DatabaseInfo, error)
GetDatabases lists the available databases, filtering the not-managed ones
func (*DbEngine) GetMainDatabase ¶ added in v0.2.4
GetMainDatabase is used to get the main db
func (*DbEngine) GetOrCreateActiveDatabase ¶ added in v0.2.3
GetOrCreateActiveDatabase allows to get or create a database and ensures it is activated
func (*DbEngine) IsDatabaseAllowed ¶
IsDatabaseAllowed checks if a database can be managed by smoothdb
func (*DbEngine) ReloadAllSchemas ¶ added in v0.3.0
ReloadAllSchemas reloads the schema cache for all active databases
func (*DbEngine) ReloadDatabaseSchema ¶ added in v0.3.0
ReloadDatabaseSchema reloads the schema cache for a specific database
func (*DbEngine) ReloadRoleSettings ¶ added in v0.11.0
ReloadRoleSettings reads the role settings again, with a connection of the main pool.
func (*DbEngine) UpdateDatabase ¶ added in v0.2.7
UpdateDatabase updates a database.
type DbLogger ¶
type DbLogger struct {
// contains filtered or unexported fields
}
func NewDbLogger ¶
NewDbLogger accepts a zerolog.Logger as input and returns a new custom pgx logging facade as output.
type DbPoolConn ¶
func AcquireConnection ¶
func AcquireConnection(ctx context.Context, db *Database) (conn *DbPoolConn, err error)
AcquireConnection takes a connection from a database pool, clean of anything a request left on its session (see Database.AcquireConnection). If the db parameter is nil, it uses the main db pool. The wait is bounded by PoolAcquisitionTimeout (see acquireBounded).
func AcquireRequestConnection ¶ added in v0.11.0
func AcquireRequestConnection(ctx context.Context, db *Database) (conn *DbPoolConn, err error)
AcquireRequestConnection is AcquireConnection for a request, which applies its own role and claims (PrepareRequest) over whatever the session of the connection carries: it skips the cleanup.
func ContextWithDb ¶
func ContextWithDb(parent context.Context, db *Database, role string) (context.Context, *DbPoolConn, error)
ContextWithDb creates a context and gets a connection to the requested database, with a specific role. The db parameter can be nil, to indicate the main database. It is used to start a communication with a database, both internally and from code using smoothdb as a library.
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 ForeignKey ¶
type Function ¶
type Function struct {
Name string `json:"name"`
Schema string `json:"schema"`
Arguments []Argument `json:"arguments"`
ArgDefaults int `json:"argdefaults"` // pronargdefaults: how many of the last input arguments have a default
Returns string `json:"returns"`
Language string `json:"language"`
Definition string `json:"definition"`
ReturnTypeId uint32 `json:"rettypeid"`
ReturnIsSet bool `json:"retisset"`
ReturnRows float32 `json:"retrows"` // prorows: estimated number of result rows
HasUnnamed bool `json:"hasunnamed"` // has unnamed parameters
HasOut bool `json:"hasout"` // has OUT, INOUT, TABLE parameters
IsVariadic bool `json:"isvariadic"`
Volatility string `json:"volatility"` // provolatile: i IMMUTABLE, s STABLE, v VOLATILE
}
func CreateFunction ¶ added in v0.2.0
type JSONSerializer ¶ added in v0.2.5
type JSONSerializer struct {
TextBuilder
}
JSONSerializer writes the rows as a JSON array of objects, decoding the raw wire values itself.
The wire-format rule. pgx asks the server for each result column in the format its type map prefers: binary for the types it has a binary codec for, text for everything else (enums, custom and extension types, and the types re-registered as text-only in textFormatOnlyTypes). FieldDescription.Format says which one arrived, and the serializers dispatch on it, never assuming:
- Binary (appendType): the OID switch decodes the builtin scalars, and the schema cache classifies arrays, composites and enums, whose elements are decoded recursively, in binary too. A binary value of any other type is a SerializeError naming the type: it is never copied through as if it were text. The fix for such a type is a decoder in the switch or an entry in textFormatOnlyTypes.
- Text (appendText): PostgreSQL's own output for the value, converted by the shape of its type the way to_json converts the value: json and jsonb verbatim, bool t/f as true/false, int2/int4/int8/float4/float8/ numeric bare (NaN and the infinities quoted), an array literal parsed into a JSON array and a record literal into a JSON object with the elements converted by the same rule, and any other type a JSON string (a range or a multirange is one: range_out's text, its quotes escaped). Every other type serializes correctly in text format with no code of its own; the one difference from to_json is that a timestamp keeps PostgreSQL's space between date and time, which only shows inside a composite that arrives in text.
The CSV serializer shares the binary decoders and writes a text-format value as the text it is, which for an array or a composite is the literal PostgREST's CSV carries too.
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 ListenerConfig ¶ added in v0.3.0
ListenerConfig holds configuration for the notification listener
func DefaultListenerConfig ¶ added in v0.3.0
func DefaultListenerConfig() *ListenerConfig
DefaultListenerConfig returns the default configuration
type NotificationHandler ¶ added in v0.3.0
NotificationHandler defines the interface for handling notifications
func CreateSchemaReloadHandler ¶ added in v0.3.0
func CreateSchemaReloadHandler(dbe *DbEngine) NotificationHandler
CreateSchemaReloadHandler creates a handler for schema reload notifications
type NotificationListener ¶ added in v0.3.0
type NotificationListener struct {
// contains filtered or unexported fields
}
NotificationListener implements the PostgreSQL LISTEN/NOTIFY functionality
func NewNotificationListener ¶ added in v0.3.0
func NewNotificationListener(connString string, config *ListenerConfig, logger *logging.Logger) *NotificationListener
NewNotificationListener creates a new notification listener
func (*NotificationListener) RegisterHandler ¶ added in v0.3.0
func (l *NotificationListener) RegisterHandler(command string, handler NotificationHandler)
RegisterHandler registers a handler for a specific notification command
func (*NotificationListener) Start ¶ added in v0.3.0
func (l *NotificationListener) Start(ctx context.Context) error
Start begins listening for notifications
func (*NotificationListener) Stop ¶ added in v0.3.0
func (l *NotificationListener) Stop()
Stop stops the listener, interrupting a pending WaitForNotification, and waits for the loop to exit, so its dedicated connection is closed when Stop returns — also when racing another Stop. It must not be called from a notification handler, which runs on the loop it would wait for.
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 PostgRestParser ¶
type PostgRestParser struct {
// contains filtered or unexported fields
}
type PostgresConfig ¶ added in v0.2.3
type PostgresConfig struct {
Host string // host (e.g. localhost) or absolute path to unix domain socket directory (e.g. /private/tmp)
Port uint16
Database string
User string
Password string
}
func ParsePostgresURL ¶ added in v0.2.3
func ParsePostgresURL(url string) (*PostgresConfig, error)
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 GetDatabasePrivileges ¶
type QueryBuilder ¶
type QueryBuilder interface {
BuildSelect(table string, parts *QueryParts, options *QueryOptions, info *SchemaInfo) (string, []any, error)
BuildInsert(table string, records []Record, body []byte, 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 calls the function name, whose overload f (nil when unknown)
// is the one SchemaInfo.FindFunction resolves for the record's keys
BuildExecute(name string, f *Function, record Record, parts *QueryParts, options *QueryOptions, info *SchemaInfo) (string, []any, error)
// contains filtered or unexported methods
}
type QueryOptions ¶
type QueryOptions struct {
Schema string
ContentType string // json, csv
ReturnRepresentation bool
MergeDuplicates bool
IgnoreDuplicates bool
ParamsAsSingleObject bool
TxCommit bool
TxRollback bool
Singular bool
HasRange bool
RangeMin int64
RangeMax int64
Count string // exact, planned, estimated
JQ string // jq program from the jq= query parameter
JQArgs string // raw JSON object from the jq_args= query parameter
// Total is the total of a counted read (Count set), written by the
// executor: the rows that the request selects, whatever its range
Total int64
// contains filtered or unexported fields
}
func GetQueryOptions ¶ added in v0.2.7
func GetQueryOptions(ctx context.Context) *QueryOptions
GetQueryOptions gets the query options from the current context
type QueryParts ¶
type QueryParts struct {
// contains filtered or unexported fields
}
QueryParts is the root of the AST produced by the request parser
type RangeError ¶ added in v0.2.4
type RangeError struct {
// contains filtered or unexported fields
}
func (RangeError) Error ¶ added in v0.2.4
func (e RangeError) Error() string
type RecursiveInfo ¶ added in v0.5.0
type RecursiveInfo struct {
StartField string // column for base case (e.g. "id")
StartValue string // seed value (e.g. "5")
RecurseField string // FK column to follow (e.g. "manager_id")
MaxDepth int // max depth; -1 = unlimited (capped by server max)
ExcludeStart bool // true when "after" operator is used instead of "start"
RecurseUp bool // true for recurse!up — follow the FK toward ancestors (single-table only)
ViaTable string // edge table for multi-table recursion (empty = single-table)
ViaFromCol string // edge table column matching the start value (e.g. "src_id")
ViaToCol string // edge table column linking to main table's start field (e.g. "dst_id")
ViaConditions *WhereConditionNode // parsed filter tree for the edge table
ViaBidirectional bool // true for via!both(...) — follow edges in either direction
WalkConditions *WhereConditionNode // filters that prune the walk (walk.* prefix); plain filters are result filters
}
RecursiveInfo holds the parameters for a recursive CTE query. StartField/StartValue define the base case; RecurseField defines the FK to follow.
type Relationship ¶
type Relationship struct {
Type RelType
Table string
Columns []string
RelatedTable string
RelatedColumns []string
JunctionTable string
JColumns []string
JRelatedColumns []string
ForeignKey string
// Computed relationship fields
FunctionName string // function name (e.g., "read_principals")
FunctionSchema string // function schema (e.g., "public")
ReturnIsSet bool // whether the function returns SETOF
}
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 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
}
type RoleUpdate ¶ added in v0.2.7
type RoleUpdate 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"`
}
type SchemaError ¶ added in v0.9.0
type SchemaError struct {
Hint string
// contains filtered or unexported fields
}
SchemaError: the Accept-Profile or Content-Profile header names a schema that is not exposed (406, PostgREST PGRST106)
func (SchemaError) Error ¶ added in v0.9.0
func (e SchemaError) Error() string
type SchemaInfo ¶
type SchemaInfo struct {
// ServerVersion is the PostgreSQL version as server_version_num (160015 is
// 16.15), read with the rest of the cache and so refreshed on every schema
// reload. Gate a feature on it with ServerAtLeast, see its convention.
ServerVersion int
// contains filtered or unexported fields
}
func NewSchemaInfo ¶
func NewSchemaInfo(ctx context.Context, db *Database) (*SchemaInfo, error)
func (*SchemaInfo) FindFunction ¶ added in v0.10.0
func (si *SchemaInfo) FindFunction(name string, keys []string) (*Function, error)
FindFunction returns the overload of the function name (schema.name, as _s builds it) that a call with the argument names keys invokes, chosen as PostgREST chooses it (Plan.hs findProc): by the names alone, an overload matching when each key names one of its input arguments and each input argument without a default has a key. The overload decides the shape of the response and whether a POST runs READ ONLY.
With no match it returns nil, and the call is left to PostgreSQL: it fails there, or reaches a function the cache does not hold, one with an unnamed argument. With more than one it returns an AmbiguousFunctionError naming them, where PostgreSQL would pick one by its type rules or fail.
func (*SchemaInfo) FindRelationshipByCol ¶
func (si *SchemaInfo) FindRelationshipByCol(ftable, col string) *Relationship
func (*SchemaInfo) FindRelationshipByFK ¶ added in v0.3.0
func (si *SchemaInfo) FindRelationshipByFK(ftable, fk string) *Relationship
func (*SchemaInfo) FindRelationshipsByHintCol ¶ added in v0.10.2
func (si *SchemaInfo) FindRelationshipsByHintCol(ftable, relatedTable, col string) []Relationship
FindRelationshipsByHintCol returns the relationships of ftable to relatedTable that a column hint selects, relatedTable!col(...), as PostgREST matches them (Plan.hs findRel): a one-to-many, many-to-one or one-to-one relationship whose single foreign key column, on either side, is col. In a self-relationship only the one-to-many side matches, by the referencing column (/organizations?select=auditees:organizations!auditor(*)). Relationships to other relations than relatedTable never match, even when they carry the same column (card 34668 column-hint-embed).
func (*SchemaInfo) GetColumnType ¶
func (si *SchemaInfo) GetColumnType(ftable string, column string) *ColumnType
func (*SchemaInfo) GetForeignKeys ¶
func (si *SchemaInfo) GetForeignKeys(ftable string) []ForeignKey
func (*SchemaInfo) GetPrimaryKey ¶
func (si *SchemaInfo) GetPrimaryKey(ftable string) *Constraint
func (*SchemaInfo) GetRelationships ¶
func (si *SchemaInfo) GetRelationships(ftable string) []Relationship
func (*SchemaInfo) GetTable ¶
func (si *SchemaInfo) GetTable(ftable string) *Table
func (*SchemaInfo) GetTypeById ¶
func (si *SchemaInfo) GetTypeById(id uint32) *Type
func (*SchemaInfo) ServerAtLeast ¶ added in v0.9.0
func (si *SchemaInfo) ServerAtLeast(major int) bool
ServerAtLeast reports whether the server runs PostgreSQL major or later (ServerAtLeast(17) is true on 17.0 and on 17.4, false on 16.15).
Convention for version-gated features: a code path that needs SQL introduced in PostgreSQL N checks info.ServerAtLeast(N) and either falls back to the pre-N SQL (preferred, whenever one exists, as PostgREST does for pg_basetype in its schema cache) or refuses the request with a BuildError (a 400) whose message names the required version. It never lets PostgreSQL raise a syntax error at execution: that comes back as a 500 that says nothing about the cause. A gate on a minor version (a fix that shipped in 16.3) compares ServerVersion >= 160003 directly. A hand-built SchemaInfo has ServerVersion 0, so it takes the fallback branch of every gate.
type SchemaUpdate ¶ added in v0.2.7
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:
- a SelectField with field.name = "id"
- a SelectField with field.name = "name"
- 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 is the request's connection. With deferred variables (see
// PrepareRequest) the role is not on it yet: take it with GetConn, which
// applies them, unless the statement goes through the query executor.
Conn *DbConn
Role string
RequestParser RequestParser
QueryBuilder QueryBuilder
QueryOptions QueryOptions
// contains filtered or unexported fields
}
SmoothContext contains all the information needed to perform database commands as well as configured parser and query builder
func GetSmoothContext ¶
func GetSmoothContext(ctx context.Context) *SmoothContext
GetSmoothContext gets SmoothContext from the standard context
type Table ¶
type Table struct {
Name string `json:"name"`
Schema string `json:"schema"`
Owner string `json:"owner"`
Comment *string `json:"comment"`
RowSecurity bool `json:"rowsecurity"`
Columns []Column `json:"columns,omitempty"`
Constraints []string `json:"constraints"`
Inherits string `json:"inherit,omitempty"`
IfNotExists bool `json:"ifnotexists,omitempty"`
HasIndexes bool `json:"hasindexes"`
HasTriggers bool `json:"hastriggers"`
IsPartition bool `json:"ispartition"`
}
func CreateTable ¶ added in v0.1.2
type TableUpdate ¶
type TextBuilder ¶ added in v0.2.5
type TextSerializer ¶ added in v0.2.5
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"`
IsMultirange bool `json:"ismultirange"`
IsComposite bool `json:"iscomposite"`
IsTable bool `json:"istable"`
IsEnum bool `json:"isenum"`
IsDomain bool `json:"isdomain"`
ArraySubType uint32 `json:"arraysubtype"`
RangeSubType *uint32 `json:"rangesubtype"`
DomainSubType string `json:"domainsubtype"`
DomainBaseId uint32 `json:"domainbaseid"` // typbasetype, the type a domain is over (0 otherwise)
SubTypeIds []uint32 `json:"subtypeids"`
SubTypeNames []string `json:"subtypenames"`
}
type User ¶
type View ¶
type ViewColDep ¶ added in v0.5.0
type ViewColDep struct {
ViewSchema string
ViewName string
ViewColumn string
BaseSchema string
BaseTable string
BaseColumn string
}
ViewColDep maps a view column back to its originating base table column, extracted from the view's internal query tree (pg_rewrite ev_action).
func GetViewColDeps ¶ added in v0.5.0
func GetViewColDeps(ctx context.Context) ([]ViewColDep, error)
type WhereConditionNode ¶
type WhereConditionNode struct {
// contains filtered or unexported fields
}
Source Files
¶
- columns.go
- config.go
- conn.go
- constraints.go
- content_type.go
- context.go
- database.go
- db_log.go
- db_types.go
- dbengine.go
- errors.go
- functions.go
- grants.go
- init_config.go
- jqupdate.go
- mapserializer.go
- notification_listener.go
- policies.go
- querybuilder.go
- queryexecutor.go
- records.go
- requestparser.go
- requestvars.go
- roles.go
- rolesettings.go
- schemainfo.go
- schemas.go
- serverversion.go
- stress.go
- structserializer.go
- tables.go
- textformat.go
- textserializer.go
- types.go
- users.go
- utils.go
- views.go