batch

package
v0.73.0 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package batch is the one op-list machinery behind Koha's batch record modification, MARC modification templates, and advanced-editor macros (tasks/047): a Selection names a set of Works, an editor.Op list names the edit, and the executor applies it per grain with per-record results -- dry-run first, exact quad deltas, everything audited. Saved queries and macros live in the datastore; a shared macro run over a selection is the modification-template shape.

Index

Constants

View Source
const (
	KindIDs         = "ids"
	KindSearch      = "search"
	KindSavedQuery  = "savedQuery"
	KindAll         = "all"
	KindImportBatch = "importBatch"
)

Selection kinds. importBatch is reserved for copy cataloging (tasks/050) and rejected until an import surface exists.

Variables

View Source
var ErrForbidden = errors.New("batch: not the owner")

ErrForbidden reports an edit to somebody else's macro.

View Source
var ErrNotFound = errors.New("batch: not found")

ErrNotFound reports a missing macro or saved query.

View Source
var ErrValidation = errors.New("batch: invalid request")

ErrValidation reports a request the executor refuses to run.

Functions

func ApplyParams

func ApplyParams(m Macro, values map[string]string) ([]editor.Op, error)

ApplyParams substitutes ${name} references in the macro's op values from the caller's values (falling back to declared defaults) and returns the concrete op list. An unresolved reference fails closed -- a template never silently writes its placeholder text into a record.

Types

type IndexUpdater added in v0.48.0

type IndexUpdater interface {
	Apply(grainPath, etag string, grain []byte)
	AppendFeed(ctx context.Context, paths ...string) error
}

IndexUpdater is the workindex.Index surface batch writes keep exact: Apply folds one written grain in, AppendFeed publishes the changed paths so other containers read-their-writes without a corpus List.

type ItemResult

type ItemResult struct {
	WorkID string       `json:"workId"`
	ETag   string       `json:"etag,omitempty"`
	Error  string       `json:"error,omitempty"`
	Diff   *editor.Diff `json:"diff,omitempty"`
}

ItemResult is one Work's outcome in a run.

type ItemTemplate

type ItemTemplate struct {
	OwnedMeta
	CallNumber string `json:"callNumber,omitempty"`
	Location   string `json:"location,omitempty"`
	Note       string `json:"note,omitempty"`
	// BarcodePrefix seeds bulk add ("B-" -> B-0001, B-0002, ...).
	BarcodePrefix string `json:"barcodePrefix,omitempty"`
	// BarcodeWidth is the zero-padded counter width (default 4).
	BarcodeWidth int `json:"barcodeWidth,omitempty"`
}

ItemTemplate is a saved item field set (tasks/069): applied it pre-fills the item form; its barcode prefix seeds bulk add's auto-incrementing pattern. Personal or library-shared on the macros sharing model.

type Macro

type Macro struct {
	OwnedMeta
	Keys   string      `json:"keys,omitempty"`
	Ops    []editor.Op `json:"ops"`
	Params []Param     `json:"params,omitempty"`
}

Macro is a replayable op list (tasks/047): recorded in the editor, replayed against another record, or -- when shared -- run over a batch selection, which is the MARC-modification-template shape. Keys optionally names a single-character editor shortcut.

type OwnedMeta

type OwnedMeta struct {
	ID        string    `json:"id"`
	Label     string    `json:"label"`
	Shared    bool      `json:"shared"`
	Owner     string    `json:"owner"`
	CreatedAt time.Time `json:"createdAt"`
	UpdatedAt time.Time `json:"updatedAt"`
}

OwnedMeta is the shared identity/sharing surface of the owned-or-shared record shapes (macros, item templates): one record per item, living in the owner's partition or the library-shared one, owner-gated for writes.

type Param

type Param struct {
	Name    string `json:"name"`
	Label   string `json:"label,omitempty"`
	Default string `json:"default,omitempty"`
}

Param declares one macro parameter, referenced in op values as ${name}.

type RunResult

type RunResult struct {
	DryRun         bool         `json:"dryRun"`
	Matched        int          `json:"matched"`
	Applied        int          `json:"applied"`
	Failed         int          `json:"failed"`
	Added          int          `json:"added"`
	Removed        int          `json:"removed"`
	Results        []ItemResult `json:"results"`
	DiffsTruncated bool         `json:"diffsTruncated,omitempty"`
}

RunResult summarizes a batch run. Added/Removed aggregate the quad deltas across every work (dry-run and execute alike).

type SavedQuery

type SavedQuery struct {
	ID        string    `json:"id"`
	Label     string    `json:"label"`
	Query     string    `json:"query"`
	Owner     string    `json:"owner"`
	CreatedAt time.Time `json:"createdAt"`
}

SavedQuery is a named works search, the reusable half of a Selection.

type Selection

type Selection struct {
	Kind         string   `json:"kind"`
	IDs          []string `json:"ids,omitempty"`          // kind=ids
	Query        string   `json:"query,omitempty"`        // kind=search
	SavedQueryID string   `json:"savedQueryId,omitempty"` // kind=savedQuery
}

Selection names a set of Works to operate on.

type Service

type Service struct {
	Blob blob.Store
	DB   store.Store
	// Mapper is the static op mapper. MapperFn, when set, supersedes it so
	// runtime profile edits are picked up per run; leave Mapper for the
	// fixed-profile case (tests).
	Mapper   *editor.Mapper
	MapperFn func() *editor.Mapper
	// Queue, when set, receives one audit entry per execute run.
	Queue *suggest.Service
	// Trigger, when set, gets one grains-changed event per execute run.
	Trigger trigger.Notifier
	// Prefix is the grain tree root ("" = repo layout).
	Prefix string
	// MaxWorks bounds a run's selection (0 = defaultMaxWorks).
	MaxWorks int
	// Summaries, when set, is the shared maintained summary source
	// (workindex, tasks/109) search selections resolve against instead of a
	// per-run corpus walk; nil falls back to ScanSummaries.
	Summaries ingest.SummarySource
	// Labels, when set, writes vocabulary label companions next to term
	// IRIs a batch edit asserts (editor.ApplyOps, tasks/145).
	Labels editor.LabelResolver
	// Index, when set, is kept exact for this run's own writes -- the same
	// read-your-writes contract the single-record path holds (tasks/195).
	// Without it, batch edits wait out the workindex refresh TTL: invisible
	// to work search for up to 30s, and a chained batch selection resolves
	// against the stale index.
	Index IndexUpdater
}

Service resolves selections and executes op batches over the grain tree.

func (*Service) CreateItemTemplate

func (s *Service) CreateItemTemplate(ctx context.Context, t ItemTemplate, owner string) (ItemTemplate, error)

CreateItemTemplate validates and stores a template for owner (in the shared partition when t.Shared). The id is minted server-side.

func (*Service) CreateMacro

func (s *Service) CreateMacro(ctx context.Context, m Macro, owner string) (Macro, error)

CreateMacro validates and stores a macro for owner (in the shared partition when m.Shared). The id is minted server-side.

func (*Service) CreateQuery

func (s *Service) CreateQuery(ctx context.Context, label, query, owner string) (SavedQuery, error)

CreateQuery stores a named search for owner. Label and query validate after normalization: a whitespace-only query would persist a selection that forever resolves to the entire catalog (tasks/205).

func (*Service) DeleteItemTemplate

func (s *Service) DeleteItemTemplate(ctx context.Context, owner, id string) error

DeleteItemTemplate removes an owned template (shared or personal).

func (*Service) DeleteMacro

func (s *Service) DeleteMacro(ctx context.Context, owner, id string) error

DeleteMacro removes an owned macro (shared or personal).

func (*Service) DeleteQuery

func (s *Service) DeleteQuery(ctx context.Context, owner, id string) error

DeleteQuery removes one of the owner's saved queries.

func (*Service) GetItemTemplate

func (s *Service) GetItemTemplate(ctx context.Context, owner, id string) (ItemTemplate, error)

GetItemTemplate resolves a template the caller can use: their own, or a shared one.

func (*Service) GetMacro

func (s *Service) GetMacro(ctx context.Context, owner, id string) (Macro, error)

GetMacro resolves a macro the caller can run: their own, or a shared one.

func (*Service) GetQuery

func (s *Service) GetQuery(ctx context.Context, owner, id string) (SavedQuery, error)

GetQuery reads one of the owner's saved queries.

func (*Service) ListItemTemplates

func (s *Service) ListItemTemplates(ctx context.Context, owner string) ([]ItemTemplate, error)

ListItemTemplates returns the caller's templates plus every shared one, sorted by label.

func (*Service) ListMacros

func (s *Service) ListMacros(ctx context.Context, owner string) ([]Macro, error)

ListMacros returns the caller's macros plus every shared macro, sorted by label.

func (*Service) ListQueries

func (s *Service) ListQueries(ctx context.Context, owner string) ([]SavedQuery, error)

ListQueries returns the owner's saved queries in creation order.

func (*Service) Resolve

func (s *Service) Resolve(ctx context.Context, sel Selection, owner string) ([]Target, error)

Resolve expands a selection to its targets, owner-scoped for saved queries. Ids resolve without titles (no corpus scan); search kinds carry the summary title for preview listings.

func (*Service) Run

func (s *Service) Run(ctx context.Context, sel Selection, ops []editor.Op, dryRun bool, actor string) (RunResult, error)

Run applies ops to every work in the selection. Ops must target the work resource -- instance ids are per-record and meaningless across a selection. DryRun reads and diffs without writing; execute CAS-writes each grain and reports per-record success or failure, then audits and notifies once.

func (*Service) UpdateItemTemplate

func (s *Service) UpdateItemTemplate(ctx context.Context, id string, t ItemTemplate, owner string) (ItemTemplate, error)

UpdateItemTemplate replaces a template's definition. Only the owner may update; flipping Shared moves the record between partitions.

func (*Service) UpdateMacro

func (s *Service) UpdateMacro(ctx context.Context, id string, m Macro, owner string) (Macro, error)

UpdateMacro replaces a macro's definition. Only the owner may update, and flipping Shared moves the record between partitions.

type Target

type Target struct {
	WorkID string `json:"workId"`
	Title  string `json:"title,omitempty"`
	// contains filtered or unexported fields
}

Target is one resolved Work.

Jump to

Keyboard shortcuts

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