tableaccess

package
v11.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package tableaccess is the MySQL database.Manager: the administrative surface that creates users and databases and grants table privileges, as distinct from the query path a database.Client serves.

It is provisioning code. The calls here are the ones a service makes when it stands up a tenant's database or hands a new user the privileges it needs, not ones a request handler makes.

Why there is one of these per dialect

None of this is portable SQL. CREATE USER, GRANT, and the catalog queries that answer "does this user exist" differ per engine, and — the part that decides the shape of the code — user names and identifiers cannot travel as bind parameters at all, because these are utility statements. Every dialect therefore has to solve credential handling its own way, and its own way is what each of these packages is.

Here that means the credential never appears in statement text. CREATE USER binds the name and password into session variables, assembles the statement server-side with MySQL's own QUOTE, and runs it as a prepared statement, so every string that goes over the wire is a constant. The point is otelsql: it copies statement text onto a span attribute when query logging is on, and a directly interpolated password would ride out to whatever consumes those spans.

MySQL has no transactional DDL to lean on the way the Postgres sibling does, and session variables outlive the statement that set them, so the whole sequence pins one connection and clears the variables before returning it to the pool. Literal quoting done in Go doubles backslashes as well as quotes, which MySQL needs and standard SQL does not; it assumes the default SQL mode, with NO_BACKSLASH_ESCAPES off.

A name already taken comes back wrapping database.ErrUserAlreadyExists, but only after a read confirms it. MySQL spends one error number on every CREATE USER it declines to elaborate on, so the number alone is grounds to check rather than a diagnosis — and a check that itself fails leaves the original error intact rather than reporting a collision nobody established.

Nothing on a span or in a log here carries a password.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Manager

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

Manager is the MySQL database.Manager implementation. It is exported, and returned by NewManager, so a caller who has chosen MySQL can depend on that choice rather than on the interface every dialect's manager shares.

func NewManager

func NewManager(db *sql.DB, opts ...Option) *Manager

func (*Manager) CreateDatabase

func (m *Manager) CreateDatabase(ctx context.Context, dbName, owner string) error

func (*Manager) CreateUser

func (m *Manager) CreateUser(ctx context.Context, username, password string) (err error)

CreateUser creates a user with the given password.

The password never appears in statement text. CREATE USER accepts no bind parameters, so the direct spelling has to interpolate the credential into the SQL — and otelsql copies statement text onto the db.statement span attribute whenever LOG_QUERIES is on, which puts a live credential on a span that may well be exported to a third party. Binding the arguments into session variables and assembling the statement server-side means every statement that goes over the wire is a constant.

Session variables outlive a statement, which is why this pins one connection for the whole sequence and clears them before handing it back to the pool. MySQL has no transactional DDL to lean on the way the Postgres twin does.

A username already in use comes back wrapping database.ErrUserAlreadyExists, which errors/http and errors/grpc map to a conflict rather than a 500. The driver's own error is preserved underneath it.

func (*Manager) DatabaseExists

func (m *Manager) DatabaseExists(ctx context.Context, dbName string) (bool, error)

func (*Manager) DeleteDatabase

func (m *Manager) DeleteDatabase(ctx context.Context, dbName string) error

func (*Manager) DeleteUser

func (m *Manager) DeleteUser(ctx context.Context, username string) error

func (*Manager) GrantUserAccessToTable

func (m *Manager) GrantUserAccessToTable(ctx context.Context, username, schema, table, privilege string) error

GrantUserAccessToTable grants a specific privilege on a table to a user.

func (*Manager) UserCanAccessDatabase

func (m *Manager) UserCanAccessDatabase(ctx context.Context, username, dbName string) (bool, error)

func (*Manager) UserExists

func (m *Manager) UserExists(ctx context.Context, username string) (bool, error)

type Option

type Option func(*options)

Option configures the Manager this package constructs. The zero configuration works: an absent logger logs nowhere and an absent tracer provider traces nowhere.

There is no metrics provider. Everything here is an administrative act — a role created, a database dropped, a grant issued — performed a handful of times over a deployment's life by something that already reports what it did. A counter over those is a number nobody has a question for; the span and the log line, which say which role and which database, are what somebody auditing the change actually wants.

func WithLogger

func WithLogger(logger logging.Logger) Option

WithLogger attaches a logger.

func WithPillars

func WithPillars(pillars *observability.Pillars) Option

WithPillars supplies logger and tracer provider at once. Options apply in order, so a WithPillars followed by a narrower option wins for that component. The pillars' metrics provider is ignored — see Option.

func WithTracerProvider

func WithTracerProvider(tracerProvider tracing.Provider) Option

WithTracerProvider attaches a tracer provider, enabling spans on every operation.

type Privilege

type Privilege string
const (
	PrivilegeSelect     Privilege = "SELECT"
	PrivilegeInsert     Privilege = "INSERT"
	PrivilegeUpdate     Privilege = "UPDATE"
	PrivilegeDelete     Privilege = "DELETE"
	PrivilegeReferences Privilege = "REFERENCES"
	PrivilegeTrigger    Privilege = "TRIGGER"
	PrivilegeConnect    Privilege = "CONNECT"
)

Jump to

Keyboard shortcuts

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