Documentation
¶
Overview ¶
Package db provides the persistence layer for todos, backed by SQLite or Postgres. All data access goes through the bun query builder so the same code runs on either engine; the dialect (placeholder rebinding, identity columns, type mapping) is handled by bun.
Index ¶
- Variables
- type DB
- func (d *DB) AddPredefinedLabel(ctx context.Context, name string) error
- func (d *DB) AddPredefinedPriority(ctx context.Context, name string) error
- func (d *DB) Close() error
- func (d *DB) Create(ctx context.Context, in models.CreateTodo) (models.Todo, error)
- func (d *DB) CreateBoard(ctx context.Context, in models.CreateBoard) (models.Board, error)
- func (d *DB) CreateSavedSearch(ctx context.Context, in models.CreateSavedSearch) (models.SavedSearch, error)
- func (d *DB) Delete(ctx context.Context, id int64) error
- func (d *DB) DeleteBoard(ctx context.Context, id int64) error
- func (d *DB) DeleteLabel(ctx context.Context, name string) error
- func (d *DB) DeleteSavedSearch(ctx context.Context, id int64) error
- func (d *DB) Get(ctx context.Context, id int64) (models.Todo, error)
- func (d *DB) GetBoard(ctx context.Context, id int64) (models.Board, error)
- func (d *DB) ListAll(ctx context.Context, boardID int64) ([]models.Todo, error)
- func (d *DB) ListBoards(ctx context.Context) ([]models.Board, error)
- func (d *DB) ListFiltered(ctx context.Context, boardID int64, q filter.Query, today string) ([]models.Todo, error)
- func (d *DB) ListLabels(ctx context.Context) ([]models.Label, error)
- func (d *DB) ListPriorities(ctx context.Context) ([]models.Priority, error)
- func (d *DB) ListSavedSearches(ctx context.Context) ([]models.SavedSearch, error)
- func (d *DB) Move(ctx context.Context, id int64, in models.MoveTodo) (models.Todo, error)
- func (d *DB) RemovePredefinedLabel(ctx context.Context, name string) error
- func (d *DB) RemovePredefinedPriority(ctx context.Context, name string) error
- func (d *DB) ReorderPriorities(ctx context.Context, names []string) error
- func (d *DB) SetCompleted(ctx context.Context, id int64, completed bool) (models.Todo, error)
- func (d *DB) SetLabelColor(ctx context.Context, name string, color string) error
- func (d *DB) SetPriorityColor(ctx context.Context, name string, color string) error
- func (d *DB) Update(ctx context.Context, id int64, in models.UpdateTodo) (models.Todo, error)
- func (d *DB) UpdateBoard(ctx context.Context, id int64, in models.UpdateBoard) (models.Board, error)
Constants ¶
This section is empty.
Variables ¶
var ( ErrNotFound = errors.New("todo not found") ErrSelfParent = errors.New("todo cannot be its own parent") ErrCycle = errors.New("moving this todo under that parent would create a cycle") ErrNoBoard = errors.New("boardId is required for top-level todos") ErrBoardNotFound = errors.New("board not found") ErrLastBoard = errors.New("cannot delete the last remaining board") ErrInvalidInput = errors.New("invalid input") ErrSavedSearchNotFound = errors.New("saved search not found") )
Sentinel errors surfaced to the API layer.
Functions ¶
This section is empty.
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB is the todo persistence layer.
func New ¶
New opens (or creates) the database for driver and applies the schema. driver selects the backend: "sqlite" (default; also "sqlite3"/"") opens a local SQLite file at dsn with a 5s busy timeout and foreign keys on; "postgres" (also "pg"/"postgresql") opens dsn as a Postgres connection string. SQLite serializes writes so its pool is capped at one connection; Postgres is left at the driver default.
func (*DB) AddPredefinedLabel ¶
AddPredefinedLabel records a label as predefined so it always appears in the global label list even when no todo uses it. Idempotent on name (case-insensitive).
func (*DB) AddPredefinedPriority ¶
AddPredefinedPriority records a priority as predefined so it always appears in the global priority list even when no todo uses it. Idempotent on name. New priorities are appended at the end of the ordering (position = max + 1).
func (*DB) Create ¶
Create inserts a todo. If Position is nil the item is appended after the current max position within its sibling group. Siblings after the inserted position are shifted down to keep ordering gapless.
BoardID resolution: if ParentID is set the new todo inherits the parent's board (subtasks always live on their parent's board). Otherwise BoardID must be supplied; if neither is present the request is rejected.
func (*DB) CreateBoard ¶
CreateBoard inserts a board. If Position is nil it is appended after the current max position; later boards are shifted to keep ordering gapless.
func (*DB) CreateSavedSearch ¶ added in v0.3.0
func (d *DB) CreateSavedSearch(ctx context.Context, in models.CreateSavedSearch) (models.SavedSearch, error)
CreateSavedSearch stores a named filter query.
func (*DB) DeleteBoard ¶
DeleteBoard removes a board and (via ON DELETE CASCADE) all of its todos. The last remaining board cannot be deleted.
func (*DB) DeleteLabel ¶ added in v0.2.0
DeleteLabel removes a label everywhere: its todo attachments, its colour row, and its predefined entry. Matching is case-insensitive. Returns ErrNotFound when no label with that name exists in any of the three tables.
func (*DB) DeleteSavedSearch ¶ added in v0.3.0
DeleteSavedSearch removes a saved search by id.
func (*DB) ListAll ¶
ListAll returns every todo on the given board with its labels attached. boardID <= 0 returns todos across all boards (used by the legacy complete-cascade sync path which already re-scopes on the client).
func (*DB) ListBoards ¶
ListBoards returns every board ordered by position.
func (*DB) ListFiltered ¶
func (d *DB) ListFiltered(ctx context.Context, boardID int64, q filter.Query, today string) ([]models.Todo, error)
ListFiltered returns the todos on a board that satisfy q, plus the ancestors that keep the tree connected. It reuses DB.ListAll for the full board (labels attached) and applies the filter in Go. today is the reference ISO date (YYYY-MM-DD) used by the date presets. When q carries sort criteria, the visible items are reordered within each sibling group (positions reassigned) so the rendered tree reflects the requested order.
func (*DB) ListLabels ¶
ListLabels returns all known labels, combining ad-hoc labels (attached to todos) with any predefined labels. The two sets are fetched separately and merged in Go (bun parenthesizes compound selects per-branch, which SQLite rejects), then de-duplicated and sorted. Each label carries its colour (a hex string, empty when no user-defined colour is set).
func (*DB) ListPriorities ¶
ListPriorities returns all known priorities, combining predefined priorities with any priorities currently in use across todos. De-duplicated. Each priority carries its colour (a hex string, empty when unset) and its position from the predefined set (nil when the priority is only ad-hoc). Ordered by position (predefined first, ad-hoc last, alphabetical within each group).
func (*DB) ListSavedSearches ¶ added in v0.3.0
ListSavedSearches returns every saved search in creation order.
func (*DB) Move ¶
Move relocates a todo within the tree. It may change its parent, its position among its siblings, or both. Other siblings are shifted to keep positions gapless within both the old and new sibling groups.
func (*DB) RemovePredefinedLabel ¶
RemovePredefinedLabel removes a label from the predefined set. Ad-hoc usages on todos are unaffected. Matching is case-insensitive.
func (*DB) RemovePredefinedPriority ¶
RemovePredefinedPriority removes a priority from the predefined set. Todos already using it are unaffected (they keep the priority until cleared).
func (*DB) ReorderPriorities ¶
ReorderPriorities sets the position of each predefined priority to match the order of the supplied names slice. Names not already in the predefined set are ignored. Priorities missing from the slice retain their old positions.
func (*DB) SetCompleted ¶
SetCompleted sets the completed flag on a todo and, recursively, all of its descendants, stamping completed_at as it goes (kept on the first completion, cleared on un-completion). Descendants are walked in Go (parent_id by parent_id) and the whole subtree is updated in one statement, so the cascade is as atomic as a single UPDATE. Returns the updated root todo.
func (*DB) SetLabelColor ¶
SetLabelColor sets the user-defined colour for a label. An empty colour clears it so the label reverts to the auto-assigned palette colour. Matching is case-insensitive: if the label exists under different casing, that row is updated.
func (*DB) SetPriorityColor ¶
SetPriorityColor sets the user-defined colour for a priority. An empty colour clears it so the priority reverts to the auto-assigned palette colour.