db

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2026 License: GPL-3.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoBackup = errors.New("no backup metadata found")

ErrNoBackup is returned when no backup metadata file is found.

Functions

func IsUniqueConstraintError added in v0.0.2

func IsUniqueConstraintError(err error) bool

IsUniqueConstraintError reports whether err is a unique constraint violation, regardless of dialect.

Types

type AccessGrantWithName added in v0.0.3

type AccessGrantWithName struct {
	AppAccessRow
	DisplayName string `db:"display_name" json:"display_name"`
}

AccessGrantWithName extends AppAccessRow with the user's display name.

type AppAccessRow added in v0.0.2

type AppAccessRow struct {
	AppID     string `db:"app_id"`
	Principal string `db:"principal"`
	Kind      string `db:"kind"`
	Role      string `db:"role"`
	GrantedBy string `db:"granted_by"`
	GrantedAt string `db:"granted_at"`
}

AppAccessRow represents a row from the app_access table.

type AppRow

type AppRow struct {
	ID                   string   `db:"id" json:"id"`
	Name                 string   `db:"name" json:"name"`
	Owner                string   `db:"owner" json:"owner"`
	AccessType           string   `db:"access_type" json:"access_type"`
	ActiveBundle         *string  `db:"active_bundle" json:"active_bundle"`
	MaxWorkersPerApp     *int     `db:"max_workers_per_app" json:"max_workers_per_app"`
	MaxSessionsPerWorker int      `db:"max_sessions_per_worker" json:"max_sessions_per_worker"`
	MemoryLimit          *string  `db:"memory_limit" json:"memory_limit"`
	CPULimit             *float64 `db:"cpu_limit" json:"cpu_limit"`
	Title                *string  `db:"title" json:"title"`
	Description          *string  `db:"description" json:"description"`
	CreatedAt            string   `db:"created_at" json:"created_at"`
	UpdatedAt            string   `db:"updated_at" json:"updated_at"`
	DeletedAt            *string  `db:"deleted_at" json:"deleted_at,omitempty"`
	PreWarmedSessions    int      `db:"pre_warmed_sessions" json:"pre_warmed_sessions"`
	RefreshSchedule      string   `db:"refresh_schedule" json:"refresh_schedule"`
	LastRefreshAt        *string  `db:"last_refresh_at" json:"last_refresh_at,omitempty"`
	Enabled              bool     `db:"enabled" json:"enabled"`
	Image                string   `db:"image" json:"image"`
	Runtime              string   `db:"runtime" json:"runtime"`
}

type AppUpdate

type AppUpdate struct {
	Name                 *string
	MaxWorkersPerApp     *int
	MaxSessionsPerWorker *int
	MemoryLimit          *string
	CPULimit             *float64
	AccessType           *string
	Title                *string
	Description          *string
	PreWarmedSessions    *int
	RefreshSchedule      *string
	Image                *string
	Runtime              *string
}

AppUpdate holds optional fields for updating an app's configuration.

type BackupMeta added in v0.0.3

type BackupMeta struct {
	BackupPath       string `json:"backup_path"`
	ImageTag         string `json:"image_tag"`
	MigrationVersion uint   `json:"migration_version"`
	CreatedAt        string `json:"created_at"`
}

BackupMeta records the state at the time of backup so rollback knows what to restore.

func LatestBackupMeta added in v0.0.3

func LatestBackupMeta(dbPath string) (*BackupMeta, error)

LatestBackupMeta finds the most recent backup metadata file in the database directory. Returns ErrNoBackup if none exists.

type BundleRow

type BundleRow struct {
	ID         string  `db:"id" json:"id"`
	AppID      string  `db:"app_id" json:"app_id"`
	Status     string  `db:"status" json:"status"`
	UploadedAt string  `db:"uploaded_at" json:"uploaded_at"`
	DeployedBy *string `db:"deployed_by" json:"deployed_by"`
	DeployedAt *string `db:"deployed_at" json:"deployed_at"`
	Pinned     bool    `db:"pinned" json:"pinned"`
}

type CatalogParams added in v0.0.2

type CatalogParams struct {
	CallerSub  string
	CallerRole string   // "admin", "publisher", "viewer", or ""
	Tag        string   // deprecated: use Tags
	Tags       []string // multi-tag filter
	TagMode    string   // "and" (default) or "or"
	Search     string
	Sort       string // column key, e.g. "name", "status", "last_deployed"
	SortDir    string // "asc" or "desc"
	Page       int
	PerPage    int
}

CatalogParams holds query parameters for the catalog listing.

type CatalogRow added in v0.0.3

type CatalogRow struct {
	AppRow
	Relation string `db:"relation" json:"relation"`
	Tags     string `db:"tags" json:"tags"` // comma-separated tag names
}

CatalogRow extends AppRow with per-app relation and tags for list responses.

type DB

type DB struct {
	*sqlx.DB
	// contains filtered or unexported fields
}

DB wraps sqlx.DB with dialect awareness.

func Open

func Open(cfg config.DatabaseConfig) (*DB, error)

Open opens a database connection based on the config.

func (*DB) ActivateBundle added in v0.0.2

func (db *DB) ActivateBundle(appID, bundleID string) error

ActivateBundle marks a bundle as ready, sets deployed_at, and sets it as the app's active bundle in a single transaction.

func (*DB) AddAppTag added in v0.0.2

func (db *DB) AddAppTag(appID, tagID string) error

func (*DB) Backup added in v0.0.3

func (db *DB) Backup(ctx context.Context) (string, error)

Backup creates a point-in-time backup of the database.

SQLite: VACUUM INTO to {path}.backup.{timestamp} — an atomic, consistent snapshot safe for live databases under concurrent access. PostgreSQL: pg_dump --format=custom to {dbname}.backup.{timestamp}.

Returns the path to the backup file.

func (*DB) BackupWithMeta added in v0.0.3

func (db *DB) BackupWithMeta(ctx context.Context, imageTag string) (*BackupMeta, error)

BackupWithMeta creates a database backup and writes a metadata sidecar. Returns the metadata on success.

func (*DB) CheckDownMigrationSafety added in v0.0.3

func (db *DB) CheckDownMigrationSafety(toVersion, fromVersion uint) error

CheckDownMigrationSafety verifies that all down migrations between fromVersion and toVersion are reversible. Returns an error describing the first irreversible migration found.

func (*DB) CleanupExpiredRedirects added in v0.0.3

func (db *DB) CleanupExpiredRedirects() error

CleanupExpiredRedirects deletes redirect-phase rows past their expiry.

func (*DB) ClearActiveBundle

func (db *DB) ClearActiveBundle(appID string) error

ClearActiveBundle sets active_bundle to NULL for the given app.

func (*DB) Close added in v0.0.2

func (db *DB) Close() error

Close closes the database and removes any temp file created for :memory:.

func (*DB) CountRecentSessions added in v0.0.3

func (db *DB) CountRecentSessions(appID string, since time.Time) (int, error)

CountRecentSessions returns session count since the given time.

func (*DB) CountSessions added in v0.0.3

func (db *DB) CountSessions(appID string) (int, error)

CountSessions returns total session count for an app.

func (*DB) CountUniqueVisitors added in v0.0.3

func (db *DB) CountUniqueVisitors(appID string) (int, error)

CountUniqueVisitors returns distinct user_sub count for an app.

func (*DB) CrashWorkerSessions added in v0.0.3

func (db *DB) CrashWorkerSessions(workerID string) error

CrashWorkerSessions marks all active sessions for a worker as crashed.

func (*DB) CreateApp

func (db *DB) CreateApp(name, owner string) (*AppRow, error)

func (*DB) CreateBundle

func (db *DB) CreateBundle(id, appID, deployedBy string, pinned bool) (*BundleRow, error)

func (*DB) CreatePAT added in v0.0.2

func (db *DB) CreatePAT(id string, tokenHash []byte, userSub, name string, expiresAt *string) (*PATRow, error)

func (*DB) CreateSession added in v0.0.3

func (db *DB) CreateSession(id, appID, workerID, userSub string) error

CreateSession inserts a new session record.

func (*DB) CreateTag added in v0.0.2

func (db *DB) CreateTag(name string) (*TagRow, error)

func (*DB) DeleteBundle

func (db *DB) DeleteBundle(id string) (bool, error)

func (*DB) DeleteTag added in v0.0.2

func (db *DB) DeleteTag(id string) (bool, error)

func (*DB) EndAppSessions added in v0.0.3

func (db *DB) EndAppSessions(appID string) error

EndAppSessions marks all active sessions for an app as ended.

func (*DB) EndSession added in v0.0.3

func (db *DB) EndSession(id, status string) error

EndSession marks a session as ended with the given status.

func (*DB) EndWorkerSessions added in v0.0.3

func (db *DB) EndWorkerSessions(workerID string) error

EndWorkerSessions marks all active sessions for a worker as ended.

func (*DB) FailStaleBuilds

func (db *DB) FailStaleBuilds() (int64, error)

func (*DB) GetApp

func (db *DB) GetApp(id string) (*AppRow, error)

func (*DB) GetAppByAlias added in v0.0.3

func (db *DB) GetAppByAlias(name string) (*AppRow, string, error)

GetAppByAlias looks up an app via the alias table. Returns (app, phase, err). Phase is "alias" or "redirect".

func (*DB) GetAppByName

func (db *DB) GetAppByName(name string) (*AppRow, error)

func (*DB) GetAppByNameIncludeDeleted added in v0.0.3

func (db *DB) GetAppByNameIncludeDeleted(name string) (*AppRow, error)

GetAppByNameIncludeDeleted returns an app by name regardless of soft-delete status.

func (*DB) GetAppIncludeDeleted added in v0.0.3

func (db *DB) GetAppIncludeDeleted(id string) (*AppRow, error)

GetAppIncludeDeleted returns an app by ID regardless of soft-delete status. Used by the restore endpoint and the sweeper.

func (*DB) GetBundle

func (db *DB) GetBundle(id string) (*BundleRow, error)

func (*DB) GetBundleLog added in v0.0.3

func (db *DB) GetBundleLog(bundleID string) (string, error)

GetBundleLog returns the stored build log for a bundle.

func (*DB) GetSession added in v0.0.3

func (db *DB) GetSession(id string) (*SessionRow, error)

GetSession returns a single session by ID.

func (*DB) GetTag added in v0.0.2

func (db *DB) GetTag(id string) (*TagRow, error)

func (*DB) GetUser added in v0.0.2

func (db *DB) GetUser(sub string) (*UserRow, error)

func (*DB) GrantAppAccess added in v0.0.2

func (db *DB) GrantAppAccess(appID, principal, kind, role, grantedBy string) error

func (*DB) HardDeleteApp added in v0.0.3

func (db *DB) HardDeleteApp(id string) error

HardDeleteApp permanently removes an app row. Used by the sweeper after all associated resources (bundles, files) have been cleaned up.

func (*DB) InsertBundleLog added in v0.0.3

func (db *DB) InsertBundleLog(bundleID, output string) error

InsertBundleLog persists build output for a deployment.

func (*DB) ListAccessibleApps added in v0.0.2

func (db *DB) ListAccessibleApps(sub string) ([]AppRow, error)

ListAccessibleApps returns apps the caller can see: owned apps + apps with a user ACL grant + logged_in apps + public apps.

func (*DB) ListAppAccess added in v0.0.2

func (db *DB) ListAppAccess(appID string) ([]AppAccessRow, error)

func (*DB) ListAppAccessWithNames added in v0.0.3

func (db *DB) ListAppAccessWithNames(appID string) ([]AccessGrantWithName, error)

ListAppAccessWithNames returns access grants joined with user display names.

func (*DB) ListAppDataMounts added in v0.0.3

func (db *DB) ListAppDataMounts(appID string) ([]DataMountRow, error)

ListAppDataMounts returns all data mounts for an app.

func (*DB) ListAppTags added in v0.0.2

func (db *DB) ListAppTags(appID string) ([]TagRow, error)

func (*DB) ListApps

func (db *DB) ListApps() ([]AppRow, error)

func (*DB) ListAppsWithRefreshSchedule added in v0.0.3

func (db *DB) ListAppsWithRefreshSchedule() ([]AppRow, error)

ListAppsWithRefreshSchedule returns non-deleted apps that have a non-empty refresh_schedule. Used by the refresh scheduler.

func (*DB) ListBundlesByApp

func (db *DB) ListBundlesByApp(appID string) ([]BundleRow, error)

func (*DB) ListCatalog added in v0.0.2

func (db *DB) ListCatalog(params CatalogParams) ([]AppRow, int, error)

ListCatalog returns apps visible to the caller with access control, tag filtering, search, and pagination.

func (*DB) ListCatalogWithRelation added in v0.0.3

func (db *DB) ListCatalogWithRelation(params CatalogParams) ([]CatalogRow, int, error)

ListCatalogWithRelation returns apps visible to the caller with per-app relation and tags computed in the query. Replaces N+1 ListAppTags calls.

func (*DB) ListDeletedApps added in v0.0.3

func (db *DB) ListDeletedApps() ([]AppRow, error)

ListDeletedApps returns all soft-deleted apps, newest deletion first.

func (*DB) ListDeployments added in v0.0.3

func (db *DB) ListDeployments(opts DeploymentListOpts) ([]DeploymentRow, int, error)

ListDeployments returns a cross-app deployment listing with pagination. Results are filtered to apps where the caller has collaborator+ access.

func (*DB) ListExpiredDeletedApps added in v0.0.3

func (db *DB) ListExpiredDeletedApps(cutoff string) ([]AppRow, error)

ListExpiredDeletedApps returns soft-deleted apps whose deleted_at is older than the given cutoff time. Used by the sweeper.

func (*DB) ListPATsByUser added in v0.0.2

func (db *DB) ListPATsByUser(userSub string) ([]PATRow, error)

func (*DB) ListPreWarmedApps added in v0.0.3

func (db *DB) ListPreWarmedApps() ([]AppRow, error)

ListPreWarmedApps returns all non-deleted apps with pre_warmed_sessions > 0.

func (*DB) ListSessions added in v0.0.3

func (db *DB) ListSessions(appID string, opts SessionListOpts) ([]SessionRow, error)

ListSessions returns sessions for an app, most recent first.

func (*DB) ListTags added in v0.0.2

func (db *DB) ListTags() ([]TagRow, error)

func (*DB) ListTagsWithCounts added in v0.0.3

func (db *DB) ListTagsWithCounts() ([]TagWithCount, error)

ListTagsWithCounts returns all tags with the number of non-deleted apps using each.

func (*DB) ListUsers added in v0.0.2

func (db *DB) ListUsers(opts ListUsersOpts) ([]UserRow, int, error)

func (*DB) LookupPATByHash added in v0.0.2

func (db *DB) LookupPATByHash(tokenHash []byte) (*PATLookupResult, error)

LookupPATByHash looks up a PAT by its SHA-256 hash, joined with the owning user. Returns nil if not found.

func (*DB) MigrateDown added in v0.0.3

func (db *DB) MigrateDown(targetVersion uint) error

MigrateDown runs down migrations to the target version.

func (*DB) MigrationVersion added in v0.0.3

func (db *DB) MigrationVersion() (uint, bool, error)

MigrationVersion returns the current migration version and dirty flag.

func (*DB) PATHashExists added in v0.0.3

func (db *DB) PATHashExists(tokenHash []byte) bool

PATHashExists returns true if a PAT with the given hash exists (any state).

func (*DB) Ping added in v0.0.2

func (db *DB) Ping(ctx context.Context) error

Ping verifies the database connection is alive.

func (*DB) PurgeApp added in v0.0.3

func (db *DB) PurgeApp(appID string) error

PurgeApp permanently removes an app and all associated data in a single transaction. The caller must verify the app is soft-deleted.

func (*DB) RemoveAppTag added in v0.0.2

func (db *DB) RemoveAppTag(appID, tagID string) (bool, error)

func (*DB) RenameApp added in v0.0.3

func (db *DB) RenameApp(id, oldName, newName string) error

RenameApp renames an app within a single transaction. It validates the new name, inserts the old name as an alias (2h TTL), and updates apps.name.

func (*DB) RenameTag added in v0.0.3

func (db *DB) RenameTag(id, newName string) error

RenameTag updates a tag's name. Returns an error on conflict.

func (*DB) RestoreApp added in v0.0.3

func (db *DB) RestoreApp(id string) error

RestoreApp clears deleted_at on a soft-deleted app.

func (*DB) RevokeAllPATs added in v0.0.2

func (db *DB) RevokeAllPATs(userSub string) (int64, error)

func (*DB) RevokeAppAccess added in v0.0.2

func (db *DB) RevokeAppAccess(appID, principal, kind string) (bool, error)

func (*DB) RevokePAT added in v0.0.2

func (db *DB) RevokePAT(id, userSub string) (bool, error)

func (*DB) SearchUsers added in v0.0.3

func (db *DB) SearchUsers(query string, limit int) ([]UserRow, error)

SearchUsers performs a case-insensitive substring match on name and email for active users. Returns at most limit rows ordered by name.

func (*DB) SetActiveBundle

func (db *DB) SetActiveBundle(appID, bundleID string) error

func (*DB) SetAppDataMounts added in v0.0.3

func (db *DB) SetAppDataMounts(appID string, mounts []DataMountRow) error

SetAppDataMounts replaces all data mounts for an app.

func (*DB) SetAppEnabled added in v0.0.3

func (db *DB) SetAppEnabled(appID string, enabled bool) error

SetAppEnabled sets the enabled flag on an app.

func (*DB) SetBundleDeployed added in v0.0.3

func (db *DB) SetBundleDeployed(bundleID, deployedBy string) error

SetBundleDeployed updates the deployed_by and deployed_at fields on a bundle. Used during rollbacks to record who triggered the rollback and when.

func (*DB) SoftDeleteApp added in v0.0.3

func (db *DB) SoftDeleteApp(id string) error

SoftDeleteApp sets deleted_at on an app.

func (*DB) TransitionExpiredAliases added in v0.0.3

func (db *DB) TransitionExpiredAliases() error

TransitionExpiredAliases moves alias-phase rows to redirect-phase (7d TTL).

func (*DB) UpdateApp

func (db *DB) UpdateApp(id string, u AppUpdate) (*AppRow, error)

UpdateApp applies partial updates to an app's configuration. Uses fetch-modify-write since updates are rare admin operations.

func (*DB) UpdateBundleStatus

func (db *DB) UpdateBundleStatus(id, status string) error

func (*DB) UpdateLastRefresh added in v0.0.3

func (db *DB) UpdateLastRefresh(appID string, t time.Time) error

UpdateLastRefresh records the timestamp of the last refresh for an app.

func (*DB) UpdatePATLastUsed added in v0.0.2

func (db *DB) UpdatePATLastUsed(ctx context.Context, id string)

func (*DB) UpdateUser added in v0.0.2

func (db *DB) UpdateUser(sub string, u UserUpdate) (*UserRow, error)

func (*DB) UpsertUser added in v0.0.2

func (db *DB) UpsertUser(sub, email, name string) (*UserRow, error)

UpsertUser creates or updates a user record on OIDC login. On conflict (existing user), updates email, name, and last_login but preserves role and active status set by admins.

func (*DB) UpsertUserWithRole added in v0.0.2

func (db *DB) UpsertUserWithRole(sub, email, name, role string) (*UserRow, error)

UpsertUserWithRole creates a user with a specific role (used for initial_admin). If the user already exists, only updates email, name, and last_login.

type DataMountRow added in v0.0.3

type DataMountRow struct {
	AppID    string `db:"app_id" json:"app_id"`
	Source   string `db:"source" json:"source"`
	Target   string `db:"target" json:"target"`
	ReadOnly bool   `db:"readonly" json:"readonly"`
}

DataMountRow represents a row from the app_data_mounts table.

type DeploymentListOpts added in v0.0.3

type DeploymentListOpts struct {
	CallerSub  string
	CallerRole string
	Search     string
	Status     string
	Sort       string // column key, e.g. "app_name", "deployed_by", "date", "status"
	SortDir    string // "asc" or "desc"
	Page       int
	PerPage    int
}

DeploymentListOpts holds query parameters for listing deployments.

type DeploymentRow added in v0.0.3

type DeploymentRow struct {
	AppID          string  `db:"app_id" json:"app_id"`
	AppName        string  `db:"app_name" json:"app_name"`
	BundleID       string  `db:"bundle_id" json:"bundle_id"`
	DeployedBy     *string `db:"deployed_by" json:"deployed_by"`
	DeployedByName *string `db:"deployed_by_name" json:"deployed_by_name"`
	DeployedAt     *string `db:"deployed_at" json:"deployed_at"`
	Status         string  `db:"status" json:"status"`
}

DeploymentRow represents a bundle deployment joined with app and user info.

type Dialect added in v0.0.3

type Dialect int

Dialect identifies the SQL dialect in use.

const (
	DialectSQLite Dialect = iota
	DialectPostgres
)

type ListUsersOpts added in v0.0.3

type ListUsersOpts struct {
	Search       string // case-insensitive substring match on name, email, sub
	Role         string // "admin", "publisher", "viewer", or "" for any
	ActiveFilter string // "active", "inactive", or "" for any
	Sort         string // "last_login", "name", "email", "role"
	SortDir      string // "asc" or "desc"
	Page         int    // 1-based; ignored if PerPage <= 0
	PerPage      int    // 0 means no limit
}

ListUsersOpts holds filter and pagination options for ListUsers. Zero value returns all users, newest login first.

type PATLookupResult added in v0.0.2

type PATLookupResult struct {
	PAT  PATRow
	User UserRow
}

PATLookupResult is the result of looking up a PAT by hash, joined with the owning user.

type PATRow added in v0.0.2

type PATRow struct {
	ID         string  `db:"id" json:"id"`
	UserSub    string  `db:"user_sub" json:"user_sub,omitempty"`
	Name       string  `db:"name" json:"name"`
	CreatedAt  string  `db:"created_at" json:"created_at"`
	ExpiresAt  *string `db:"expires_at" json:"expires_at"`
	LastUsedAt *string `db:"last_used_at" json:"last_used_at"`
	Revoked    bool    `db:"revoked" json:"revoked"`
}

PATRow represents a row from the personal_access_tokens table.

type SessionListOpts added in v0.0.3

type SessionListOpts struct {
	UserSub string
	Status  string
	Limit   int
}

SessionListOpts holds query parameters for listing sessions.

type SessionRow added in v0.0.3

type SessionRow struct {
	ID        string  `db:"id" json:"id"`
	AppID     string  `db:"app_id" json:"app_id"`
	WorkerID  string  `db:"worker_id" json:"worker_id"`
	UserSub   *string `db:"user_sub" json:"user_sub"`
	StartedAt string  `db:"started_at" json:"started_at"`
	EndedAt   *string `db:"ended_at" json:"ended_at"`
	Status    string  `db:"status" json:"status"`
}

SessionRow represents a row from the sessions table.

type TagRow added in v0.0.2

type TagRow struct {
	ID        string `db:"id"`
	Name      string `db:"name"`
	CreatedAt string `db:"created_at"`
}

TagRow represents a row from the tags table.

type TagWithCount added in v0.0.3

type TagWithCount struct {
	TagRow
	AppCount int `db:"app_count"`
}

TagWithCount extends TagRow with an app count.

type UserRow added in v0.0.2

type UserRow struct {
	Sub       string `db:"sub" json:"sub"`
	Email     string `db:"email" json:"email"`
	Name      string `db:"name" json:"name"`
	Role      string `db:"role" json:"role"`
	Active    bool   `db:"active" json:"active"`
	LastLogin string `db:"last_login" json:"last_login"`
}

UserRow represents a row from the users table.

type UserUpdate added in v0.0.2

type UserUpdate struct {
	Role   *string
	Active *bool
}

UserUpdate holds optional fields for updating a user.

Jump to

Keyboard shortcuts

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