Documentation ¶
Overview ¶
Package schemarp provides a reification of the repo.Schema interface making it possible to create or drop different schema, foreign server, or manage database user roles.
Index ¶
- func ChangePasswords(ctx context.Context, tx *postgres.Tx, roleSuffix repo.Role, ...) error
- func CreateRoleIfNotExists[Q postgres.Queryer](ctx context.Context, q Q, roleSuffix repo.Role, role repo.Role) error
- func CreateSchema[Q postgres.Queryer](ctx context.Context, q Q, schema string) error
- func DropCascade[Q postgres.Queryer](ctx context.Context, q Q, schema string) error
- func DropIfExists[Q postgres.Queryer](ctx context.Context, q Q, schema string) error
- func DropServerIfExists(ctx context.Context, c *postgres.Conn, serverName string) error
- func GrantFDWUsage[Q postgres.Queryer](ctx context.Context, q Q, roleSuffix repo.Role, role repo.Role) error
- func GrantPrivileges[Q postgres.Queryer](ctx context.Context, q Q, roleSuffix repo.Role, schema string, role repo.Role) error
- func InstallFDWExtensionIfMissing(ctx context.Context, c *postgres.Conn) error
- func SetSearchPath[Q postgres.Queryer](ctx context.Context, q Q, roleSuffix repo.Role, schema string, role repo.Role) error
- type Repo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ChangePasswords ¶
func ChangePasswords( ctx context.Context, tx *postgres.Tx, roleSuffix repo.Role, hasher scram.Hasher, roles []repo.Role, passwords []string, ) error
ChangePasswords updates the passwords of the given roles in the current transaction. The roles and passwords slices must have the same number of entries, so they can be used in pair. These fields are not combined as a struct with two role and password fields because passing items separately ensures that all items are initialized explicitly in constrast to a struct which its fields can be zero-initialized and are more suitable to pass a set of optional fields.
The `roles` role names may be suffixed by `roleSuffix` if it is not empty. This is useful to have distinct role names if repo.Role predefined constants are not desirable. The `hasher` will be used for hashing of the `passwords` before sending them to the DBMS (so they may not leak in plaintext). This SCRAM hasher format must conform with the DBMS expected format.
func CreateRoleIfNotExists ¶
func CreateRoleIfNotExists[Q postgres.Queryer]( ctx context.Context, q Q, roleSuffix repo.Role, role repo.Role, ) error
CreateRoleIfNotExists creates the `role` role if it does not exist right now. Although the login option is enabled for the created role, but no specific password will be set for it. The ChangePasswords method may be used for setting a password if desired. Otherwise, that user may not login effectively (but using the trust or local identity methods).
The `role` role name may be suffixed by `roleSuffix` if it is not empty. This is useful to have distinct role names if repo.Role predefined constants are not desirable.
func CreateSchema ¶
CreateSchema tries to create the `schema` schema. There must be no other schema with the `schema` name, otherwise, this operation will fail.
Caller is responsible to pass a trusted schema name string.
func DropCascade ¶
DropCascade drops `schema` schema with cascading, dropping all dependent objects recursively. The `schema` must exist, otherwise, an error will be returned. This method is useful for dropping the intermediate schema which are created during a migration.
Caller is responsible to pass a trusted schema name string.
func DropIfExists ¶
DropIfExists drops the `schema` schema without cascading if it exists. That is, if `schema` does not exist, a nil error will be returned without any change. And if `schema` exists and is empty, it will be dropped. But if `schema` exists and is not empty, an error will be returned.
Caller is responsible to pass a trusted schema name string.
func DropServerIfExists ¶
DropServerIfExists drops the `serverName` foreign server, if it exists, with cascade. That is, dependent objects such as its user mapping will be dropped too.
Caller is responsible to pass a trusted serverName string.
func GrantFDWUsage ¶
func GrantFDWUsage[Q postgres.Queryer]( ctx context.Context, q Q, roleSuffix repo.Role, role repo.Role, ) error
GrantFDWUsage grants the USAGE privilege on the postgres_fdw extension to the `role` role. Thereafter, that `role` role can use the postgres_fdw extension in order to create a foreign server or create a user mapping for it.
The `role` role name may be suffixed by `roleSuffix` if it is not empty. This is useful to have distinct role names if repo.Role predefined constants are not desirable.
func GrantPrivileges ¶
func GrantPrivileges[Q postgres.Queryer]( ctx context.Context, q Q, roleSuffix repo.Role, schema string, role repo.Role, ) error
GrantPrivileges grants ALL privileges on the `schema` schema to the `role` role, so it may create or access tables in that schema and run relevant queries.
The `role` role name may be suffixed by `roleSuffix` if it is not empty. This is useful to have distinct role names if repo.Role predefined constants are not desirable.
func InstallFDWExtensionIfMissing ¶
InstallFDWExtensionIfMissing creates the postgres_fdw extension assuming that its relavant .so files are available in proper paths. If the extension is already created, calling this method causes no change.
Types ¶
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo represents a schema management repository.
func New ¶
New instantiates a schema management Repo struct. This method improves the caller code readability as schemarp.New makes this package to look alike a data type. The `roleSuffix` which may be empty specifies a suffix for role names. The CreateRoleIfNotExists, GrantPrivileges, SetSearchPath, GrantFDWUsage, and ChangePasswords will append it to their role arguments.
The `h` SCRAM hasher will be included in the returned *Repo instance so it may hash database role passwords properly. This hasher must conform with the configured format in the DBMS, otherwise, the passwords which are created may not be used for authentication.
func (*Repo) Conn ¶
func (schema *Repo) Conn(c repo.Conn) repo.SchemaConnQueryer
Conn unwraps the given repo.Conn instance, expecting to find an instance of *postgres.Conn as created by this adapter layer. Otherwise, it will panic. Unwrapped connection will be wrapped and returned as an instance of repo.SchemaConnQueryer interface, so it can be used in the use cases layer without requiring to type assert again and again. Returned querier instance can be used to run the connection-specific queries in addition to queries which support connections and transactions.
Currently, two operations mandate a connection. The InstallFDWExtensionIfMissing creates an extension which will be accessible by roles based on their granted privileges. That installation should be performed independent of a failed or successful migration and it is not required to uninstall it later too. Also, it requires the extension related files to be installed previously. So it is not possible to confine all of its steps in a transaction anyway. The DropServerIfExists drops a foreign server and its user mapping. Thereafter, it should be created with a distinct user role. And it should be attempted only after dropping the main and intermediate schema successfully. So, asking a connection helps to guarantee that other removals are completed (in their transaction or auto-commit transaction) beforehand. By the way, result of this operation can affect multiple user roles.
func (*Repo) Tx ¶
func (schema *Repo) Tx(tx repo.Tx) repo.SchemaTxQueryer
Tx unwraps the given repo.Tx instance, expecting to find an instance of *postgres.Tx as created by this adapter layer. Otherwise, it will panic. Unwrapped transaction will be wrapped and returned as an instance of repo.SchemaTxQueryer interface, so it can be used in the use cases layer without requiring to type assert again and again. Returned querier instance can be used to run the transaction-specific queries in addition to queries which support connections and transactions.
Currently, one operation mandate a transaction. ChangePasswords updates passwords of some roles. When creating roles for the first time, it is desired to change/set their passwords before making them visible by committing the transaction. Also, it may be desired to call this method multiple times if all roles and passwords may not be identified as the same time. So, a transaction is required since there are scenarios that other operation must be performed in the same transaction and caller must specify the proper point of commitment.