db

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 17 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

func New(ctx context.Context, driver, dsn string) (*DB, error)

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

func (d *DB) AddPredefinedLabel(ctx context.Context, name string) error

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

func (d *DB) AddPredefinedPriority(ctx context.Context, name string) error

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) Close

func (d *DB) Close() error

Close releases the database handle.

func (*DB) Create

func (d *DB) Create(ctx context.Context, in models.CreateTodo) (models.Todo, error)

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

func (d *DB) CreateBoard(ctx context.Context, in models.CreateBoard) (models.Board, error)

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) Delete

func (d *DB) Delete(ctx context.Context, id int64) error

Delete removes a todo; ON DELETE CASCADE clears children and label links.

func (*DB) DeleteBoard

func (d *DB) DeleteBoard(ctx context.Context, id int64) error

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

func (d *DB) DeleteLabel(ctx context.Context, name string) error

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

func (d *DB) DeleteSavedSearch(ctx context.Context, id int64) error

DeleteSavedSearch removes a saved search by id.

func (*DB) Get

func (d *DB) Get(ctx context.Context, id int64) (models.Todo, error)

Get returns a single todo with labels.

func (*DB) GetBoard

func (d *DB) GetBoard(ctx context.Context, id int64) (models.Board, error)

GetBoard returns a single board by id.

func (*DB) ListAll

func (d *DB) ListAll(ctx context.Context, boardID int64) ([]models.Todo, error)

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

func (d *DB) ListBoards(ctx context.Context) ([]models.Board, error)

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

func (d *DB) ListLabels(ctx context.Context) ([]models.Label, error)

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

func (d *DB) ListPriorities(ctx context.Context) ([]models.Priority, error)

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

func (d *DB) ListSavedSearches(ctx context.Context) ([]models.SavedSearch, error)

ListSavedSearches returns every saved search in creation order.

func (*DB) Move

func (d *DB) Move(ctx context.Context, id int64, in models.MoveTodo) (models.Todo, error)

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

func (d *DB) RemovePredefinedLabel(ctx context.Context, name string) error

RemovePredefinedLabel removes a label from the predefined set. Ad-hoc usages on todos are unaffected. Matching is case-insensitive.

func (*DB) RemovePredefinedPriority

func (d *DB) RemovePredefinedPriority(ctx context.Context, name string) error

RemovePredefinedPriority removes a priority from the predefined set. Todos already using it are unaffected (they keep the priority until cleared).

func (*DB) ReorderPriorities

func (d *DB) ReorderPriorities(ctx context.Context, names []string) error

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

func (d *DB) SetCompleted(ctx context.Context, id int64, completed bool) (models.Todo, error)

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

func (d *DB) SetLabelColor(ctx context.Context, name string, color string) error

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

func (d *DB) SetPriorityColor(ctx context.Context, name string, color string) error

SetPriorityColor sets the user-defined colour for a priority. An empty colour clears it so the priority reverts to the auto-assigned palette colour.

func (*DB) Update

func (d *DB) Update(ctx context.Context, id int64, in models.UpdateTodo) (models.Todo, error)

Update applies a partial update to a todo. Position/ParentID changes route through Move for correct sibling reordering.

func (*DB) UpdateBoard

func (d *DB) UpdateBoard(ctx context.Context, id int64, in models.UpdateBoard) (models.Board, error)

UpdateBoard applies a partial update to a board. Position changes shift siblings to keep ordering gapless.

Jump to

Keyboard shortcuts

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