Documentation
¶
Index ¶
- Constants
- Variables
- func BuildTitleZapScript(systemID, name string, tags []TagInfo) string
- func CheckSchemaVersion(db *sql.DB, migrationFiles embed.FS, migrationDir string) error
- func GroupTagFiltersByOperator(filters []zapscript.TagFilter) (and, not, or []zapscript.TagFilter)
- func MediaKey(systemID, path string) string
- func MigrateUp(db *sql.DB, migrationFiles embed.FS, migrationDir, dbPath, sidecarPath string) error
- func TagKey(tagType, tagValue string) string
- func TitleKey(systemID, slug string) string
- type BrowseCursor
- type BrowseDirectoriesOptions
- type BrowseDirectoryResult
- type BrowseFileCountOptions
- type BrowseFilesOptions
- type BrowseRouteCount
- type BrowseRouteCountsOptions
- type BrowseSystemRootCandidates
- type BrowseSystemRootCandidatesOptions
- type BrowseVirtualScheme
- type BrowseVirtualSchemesOptions
- type Client
- type Database
- type FileInfo
- type GenericDBI
- type HistoryEntry
- type InboxMessage
- type JournalMode
- type Mapping
- type Media
- type MediaBlob
- type MediaDBI
- type MediaFullRow
- type MediaHistoryEntry
- type MediaHistoryTopEntry
- type MediaProperty
- type MediaQuery
- type MediaTag
- type MediaTagLink
- type MediaTitle
- type MediaWithFullPath
- type ScanState
- type ScrapeResultBatchApplier
- type ScrapeWrite
- type ScrapeWriteTarget
- type ScrapingOperation
- type SearchFilters
- type SearchResult
- type SearchResultWithCursor
- type System
- type Tag
- type TagInfo
- type TagType
- type TitleWithSystem
- type UserDBI
Constants ¶
const MaxMediaPropertyBinaryBytes = 16 * 1024 * 1024
MaxMediaPropertyBinaryBytes caps decoded binary property payloads hydrated into memory. Larger blobs remain addressable via BlobDBID/BlobSize but Binary is left nil so API handlers can return a controlled error instead of OOMing.
Variables ¶
var ErrMediaBlobTooLarge = errors.New("media blob too large")
ErrMediaBlobTooLarge indicates a blob exists but exceeds a caller-provided read cap.
var ErrSchemaAhead = errors.New("database schema is newer than this binary supports")
ErrSchemaAhead is returned when the database schema version is newer than the binary supports. This happens when switching from a newer binary (e.g. beta) to an older one (e.g. stable).
var ZapScriptTagTypes = []string{"year", "players", "rev", "developer", "publisher", "credit", "edition", "release"}
ZapScriptTagTypes defines which tag types are eligible for inclusion in ZapScript title commands. Only these types are considered when checking for disambiguation.
Functions ¶
func BuildTitleZapScript ¶ added in v2.10.0
BuildTitleZapScript builds a ZapScript title command string from a system ID, media name, and disambiguating tags. Format: @SystemID/Name (year:YYYY) (type:value) Only includes tags that are present in the provided slice.
func CheckSchemaVersion ¶ added in v2.11.0
CheckSchemaVersion compares the database's migration version against the latest migration embedded in the current binary. Returns ErrSchemaAhead if the database is ahead, preventing the older binary from running against an incompatible schema.
func GroupTagFiltersByOperator ¶ added in v2.7.0
GroupTagFiltersByOperator groups tag filters by operator type for consistent processing. Returns (andFilters, notFilters, orFilters) to enable both SQL generation and in-memory filtering to use the same grouping logic.
func MediaKey ¶ added in v2.9.1
MediaKey builds a composite key for media deduplication: "systemID:path"
func MigrateUp ¶ added in v2.7.0
func MigrateUp( db *sql.DB, migrationFiles embed.FS, migrationDir, dbPath, sidecarPath string, ) error
MigrateUp provides thread-safe database migration using goose. It locks access to goose's global state to prevent race conditions between multiple databases setting their migration filesystems.
dbPath and sidecarPath enable a fast path that skips goose's metadata queries (which on a cold SQLite file can cost hundreds of milliseconds) when a previously-written sidecar reports the live DB file is already at the latest embedded migration version. Pass both as empty strings to disable the sidecar fast path (e.g. in tests against in-memory DBs).
Types ¶
type BrowseCursor ¶ added in v2.10.0
BrowseCursor holds the keyset pagination state for browse queries. SortValue is the value of the sort column (Name or Path) from the last result, LastID is the DBID tiebreaker, and TotalFiles carries the first-page count so cursor pages do not need to rerun the same count query.
type BrowseDirectoriesOptions ¶ added in v2.12.0
type BrowseDirectoriesOptions struct {
PathPrefix string
Systems []systemdefs.System
}
BrowseDirectoriesOptions contains parameters for the BrowseDirectories query.
type BrowseDirectoryResult ¶ added in v2.10.0
BrowseDirectoryResult represents a subdirectory found during browse navigation.
type BrowseFileCountOptions ¶ added in v2.12.0
type BrowseFileCountOptions struct {
Letter *string
PathPrefix string
Systems []systemdefs.System
}
BrowseFileCountOptions contains parameters for the BrowseFileCount query.
type BrowseFilesOptions ¶ added in v2.10.0
type BrowseFilesOptions struct {
Cursor *BrowseCursor
Letter *string
PathPrefix string
Sort string
Systems []systemdefs.System
Limit int
}
BrowseFilesOptions contains parameters for the BrowseFiles query.
type BrowseRouteCount ¶ added in v2.12.0
BrowseRouteCount represents a populated browse route and its media count.
type BrowseRouteCountsOptions ¶ added in v2.12.0
type BrowseRouteCountsOptions struct {
Systems []systemdefs.System
Routes []string
}
BrowseRouteCountsOptions contains candidate route paths to resolve against indexed media for system-scoped browse root discovery.
type BrowseSystemRootCandidates ¶ added in v2.12.0
BrowseSystemRootCandidates is the cache-backed result of resolving a list of filesystem roots against system-scoped browse data. Children holds the immediate subdirectory names of each root that contain media for the requested systems; HasMedia is true when a root has any media in its subtree (even purely via descendants).
type BrowseSystemRootCandidatesOptions ¶ added in v2.12.0
type BrowseSystemRootCandidatesOptions struct {
Roots []string
Systems []systemdefs.System
}
BrowseSystemRootCandidatesOptions parameterises the batched lookup used to build `media.browse({systems:[...], path:""})` candidates in two queries against the BrowseDirCounts cache.
type BrowseVirtualScheme ¶ added in v2.10.0
BrowseVirtualScheme represents a virtual URI scheme with indexed content.
type BrowseVirtualSchemesOptions ¶ added in v2.12.0
type BrowseVirtualSchemesOptions struct {
Systems []systemdefs.System
}
BrowseVirtualSchemesOptions contains parameters for BrowseVirtualSchemes.
type Client ¶ added in v2.11.0
type Client struct {
ClientID string `json:"clientId"`
ClientName string `json:"clientName"`
AuthToken string `json:"-"`
PairingKey []byte `json:"-"`
DBID int64 `json:"-"`
CreatedAt int64 `json:"createdAt"`
LastSeenAt int64 `json:"lastSeenAt"`
}
Client represents a paired API client. AuthToken and PairingKey are hidden from JSON (API uses models.PairedClient instead).
type GenericDBI ¶
type HistoryEntry ¶
type HistoryEntry struct {
Time time.Time `json:"time"`
CreatedAt time.Time `json:"createdAt,omitempty"`
SyncedAt *time.Time `json:"syncedAt,omitempty"`
DeviceID *string `json:"deviceId,omitempty"`
BootUUID string `json:"bootUuid,omitempty"`
ID string `json:"uuid,omitempty"`
TokenData string `json:"tokenData"`
TokenValue string `json:"tokenValue"`
TokenID string `json:"tokenId"`
Type string `json:"type"`
DBID int64 `db:"DBID" json:"id"`
MonotonicStart int64 `json:"monotonicStart,omitempty"`
Success bool `json:"success"`
ClockReliable bool `json:"clockReliable"`
IsDeleted bool `json:"isDeleted,omitempty"`
}
type InboxMessage ¶ added in v2.8.0
type JournalMode ¶ added in v2.7.0
type JournalMode string
JournalMode represents SQLite journal mode
const ( JournalModeWAL JournalMode = "WAL" JournalModeDELETE JournalMode = "DELETE" )
Journal mode constants
type MediaBlob ¶ added in v2.12.0
MediaBlob is a row from the MediaBlobs content-addressed store. Data is identified by the hex-encoded SHA-256 of its framed content type and bytes.
type MediaDBI ¶
type MediaDBI interface {
GenericDBI
BeginTransaction(batchEnabled bool) error
CommitTransaction() error
RollbackTransaction() error
Exists() bool
UpdateLastGenerated() error
GetLastGenerated() (time.Time, error)
SetOptimizationStatus(status string) error
GetOptimizationStatus() (string, error)
SetOptimizationStep(step string) error
GetOptimizationStep() (string, error)
RunBackgroundOptimization(statusCallback func(optimizing bool), pauser *syncutil.Pauser)
WaitForBackgroundOperations()
TrackBackgroundOperation()
BackgroundOperationDone()
InvalidateCountCache() error
RebuildSlugSearchCache() error
RebuildTagCache() error
// On-disk persistence for the rebuilt caches. Persist* writes the
// current in-memory cache atomically; LoadCached* reads it back at
// startup and returns (false, nil) on missing/stale/version-mismatch
// so the caller can fall through to a SQL rebuild.
PersistTagCache() error
LoadCachedTagCache() (bool, error)
PersistSlugSearchCache() error
LoadCachedSlugSearchCache() (bool, error)
// IndexGeneration is bumped at the end of every successful indexing
// run. Persisted cache files embed the value they were built against
// so a stale cache from a previous run is rejected on next load.
IndexGeneration() (int64, error)
BumpIndexGeneration() (int64, error)
// Slug resolution cache methods
GetCachedSlugResolution(
ctx context.Context, systemID, slug string, tagFilters []zapscript.TagFilter,
) (int64, string, bool)
SetCachedSlugResolution(
ctx context.Context, systemID, slug string, tagFilters []zapscript.TagFilter, mediaDBID int64, strategy string,
) error
InvalidateSlugCache(ctx context.Context) error
InvalidateSlugCacheForSystems(ctx context.Context, systemIDs []string) error
GetMediaByDBID(ctx context.Context, mediaDBID int64) (SearchResultWithCursor, error)
GetZapScriptTagsBySystemAndPath(ctx context.Context, systemID, path string) ([]TagInfo, error)
SetIndexingCacheSize(enable bool)
DropSecondaryIndexes() error
CreateSecondaryIndexes() error
SetIndexingStatus(status string) error
GetIndexingStatus() (string, error)
SetScrapingStatus(status string) error
GetScrapingStatus() (string, error)
SetScrapingOperation(operation ScrapingOperation) error
GetScrapingOperation() (ScrapingOperation, bool, error)
ClearScrapingOperation() error
SetLastIndexedSystem(systemID string) error
GetLastIndexedSystem() (string, error)
SetIndexingSystems(systemIDs []string) error
GetIndexingSystems() ([]string, error)
TruncateSystems(systemIDs []string) error
SearchMediaPathExact(ctx context.Context, systems []systemdefs.System, query string) ([]SearchResult, error)
SearchMediaWithFilters(ctx context.Context, filters *SearchFilters) ([]SearchResultWithCursor, error)
SearchMediaBySlug(
ctx context.Context, systemID string, slug string, tags []zapscript.TagFilter,
) ([]SearchResultWithCursor, error)
SearchMediaBySecondarySlug(
ctx context.Context, systemID string, secondarySlug string, tags []zapscript.TagFilter,
) ([]SearchResultWithCursor, error)
SearchMediaBySlugPrefix(
ctx context.Context, systemID string, slugPrefix string, tags []zapscript.TagFilter,
) ([]SearchResultWithCursor, error)
SearchMediaBySlugIn(
ctx context.Context, systemID string, slugs []string, tags []zapscript.TagFilter,
) ([]SearchResultWithCursor, error)
GetTitlesWithPreFilter(
ctx context.Context, systemID string, minLength, maxLength, minWordCount, maxWordCount int,
) ([]MediaTitle, error)
GetLaunchCommandForMedia(ctx context.Context, systemID, path string) (string, error)
GetTags(ctx context.Context, systems []systemdefs.System) ([]TagInfo, error)
GetAllUsedTags(ctx context.Context) ([]TagInfo, error)
PopulateSystemTagsCache(ctx context.Context) error
PopulateSystemTagsCacheForSystems(ctx context.Context, systems []systemdefs.System) error
RefreshSlugSearchCacheForSystems(ctx context.Context, systemIDs []string) error
GetSystemTagsCached(ctx context.Context, systems []systemdefs.System) ([]TagInfo, error)
InvalidateSystemTagsCache(ctx context.Context, systems []systemdefs.System) error
SearchMediaPathGlob(systems []systemdefs.System, query string) ([]SearchResult, error)
// Browse methods for directory-style navigation of indexed content
BrowseDirectories(ctx context.Context, opts BrowseDirectoriesOptions) ([]BrowseDirectoryResult, error)
BrowseFiles(ctx context.Context, opts *BrowseFilesOptions) ([]SearchResultWithCursor, error)
BrowseFileCount(ctx context.Context, opts BrowseFileCountOptions) (int, error)
BrowseVirtualSchemes(ctx context.Context, opts BrowseVirtualSchemesOptions) ([]BrowseVirtualScheme, error)
BrowseRootCounts(ctx context.Context, rootDirs []string) (map[string]*int, error)
BrowseRouteCounts(ctx context.Context, opts BrowseRouteCountsOptions) (map[string]BrowseRouteCount, error)
BrowseSystemRootCandidates(
ctx context.Context, opts BrowseSystemRootCandidatesOptions,
) (result BrowseSystemRootCandidates, cacheReady bool, err error)
PopulateBrowseCache(ctx context.Context) error
IndexedSystems() ([]string, error)
SystemIndexed(system *systemdefs.System) bool
RandomGame(ctx context.Context, systems []systemdefs.System) (SearchResult, error)
RandomGameWithQuery(ctx context.Context, query *MediaQuery) (SearchResult, error)
GetTotalMediaCount() (int, error)
GetScrapedMediaCount(ctx context.Context, scraperID string) (int, error)
GetTotalScrapedMediaCount(ctx context.Context) (int, error)
FindSystem(row System) (System, error)
FindSystemBySystemID(systemID string) (System, error)
InsertSystem(row System) (System, error)
FindOrInsertSystem(row System) (System, error)
FindMediaTitle(row *MediaTitle) (MediaTitle, error)
InsertMediaTitle(row *MediaTitle) (MediaTitle, error)
FindOrInsertMediaTitle(row *MediaTitle) (MediaTitle, error)
FindMedia(row Media) (Media, error)
InsertMedia(row Media) (Media, error)
FindOrInsertMedia(row Media) (Media, error)
UpdateMediaTitle(mediaDBID, mediaTitleDBID int64) error
UpdateMediaParentDir(mediaDBID int64, parentDir string) error
DeleteMediaTags(mediaDBID int64) error
DeleteMediaTag(mediaDBID, tagDBID int64) error
DeleteMediaTagsByTagIDs(mediaDBID int64, tagDBIDs []int) error
TemporaryRepairJobsPending(ctx context.Context) (bool, error)
FindTagType(row TagType) (TagType, error)
InsertTagType(row TagType) (TagType, error)
FindOrInsertTagType(row TagType) (TagType, error)
FindTag(row Tag) (Tag, error)
InsertTag(row Tag) (Tag, error)
FindOrInsertTag(row Tag) (Tag, error)
FindMediaTag(row MediaTag) (MediaTag, error)
InsertMediaTag(row MediaTag) (MediaTag, error)
FindOrInsertMediaTag(row MediaTag) (MediaTag, error)
// Missing media methods for persistent indexing
BulkSetMediaMissing(dbids map[int]struct{}) error
ResetMissingFlags(systemDBIDs []int) error
// CleanMediaOrphans removes Media rows where IsMissing=1 together with
// their associated MediaTags and MediaProperties. MediaTitles that are
// no longer referenced by any Media row are also removed (including their
// MediaTitleTags and MediaTitleProperties). Tags unreferenced by any join
// table are pruned. A VACUUM is issued on success.
//
// Returns the count of Media rows deleted, or one of ErrIndexingInProgress,
// ErrOptimizationInProgress, or ErrTransactionActive when the operation
// cannot safely run.
CleanMediaOrphans(ctx context.Context) (int64, error)
// GetMax*ID methods for resume functionality
GetMaxSystemID() (int64, error)
GetMaxTitleID() (int64, error)
GetMaxMediaID() (int64, error)
GetMaxTagTypeID() (int64, error)
GetMaxTagID() (int64, error)
GetMaxMediaTagID() (int64, error)
// GetAll* methods for populating scan state maps
GetAllSystems() ([]System, error)
GetAllMediaTitles() ([]MediaTitle, error)
GetAllMedia() ([]Media, error)
GetAllTags() ([]Tag, error)
GetAllTagTypes() ([]TagType, error)
// Optimized JOIN query methods for populating scan state
GetTitlesWithSystems() ([]TitleWithSystem, error)
GetMediaWithFullPath() ([]MediaWithFullPath, error)
// Optimized JOIN query methods for selective indexing (excluding specified systems)
GetSystemsExcluding(excludeSystemIDs []string) ([]System, error)
GetTitlesWithSystemsExcluding(excludeSystemIDs []string) ([]TitleWithSystem, error)
GetMediaWithFullPathExcluding(excludeSystemIDs []string) ([]MediaWithFullPath, error)
// Per-system query methods for lazy loading during resume
GetTitlesBySystemID(systemID string) ([]TitleWithSystem, error)
GetMediaBySystemID(systemID string) ([]MediaWithFullPath, error)
GetMediaTagsBySystemID(systemID string) ([]MediaTagLink, error)
GetScannerMediaTagsBySystemID(systemID string) ([]MediaTagLink, error)
// FindMediaBySystemAndPath returns the Media row matching systemDBID and path,
// or nil, nil when no row is found.
FindMediaBySystemAndPath(ctx context.Context, systemDBID int64, path string) (*Media, error)
FindMediaBySystemAndPaths(ctx context.Context, systemDBID int64, paths []string) (map[string]Media, error)
// FindSingleDescendantMedia returns the only non-missing Media row below dirPath
// for systemDBID, or nil, nil when dirPath has zero or multiple descendants.
FindSingleDescendantMedia(ctx context.Context, systemDBID int64, dirPath string) (*Media, error)
// FindMediaBySystemAndPathFold returns the Media row matching systemDBID and
// path using a case-insensitive path comparison, or nil, nil when no row is
// found. Intended for scrapers where the incoming path casing may differ from
// what the indexer recorded (e.g. Windows filesystem with mixed-case system
// directory names).
FindMediaBySystemAndPathFold(ctx context.Context, systemDBID int64, path string) (*Media, error)
// FindMediaBySystemAndPathSuffix returns all Media rows for the given system
// whose Path ends with "/" + filename. Used when companion XML child paths are
// root-relative (./file.rom) and the indexed path may be in any subdirectory.
FindMediaBySystemAndPathSuffix(ctx context.Context, systemDBID int64, filename string) ([]Media, error)
// MediaHasTag returns true when the Media row has a tag whose full string
// (type:value) equals tagValue.
MediaHasTag(ctx context.Context, mediaDBID int64, tagValue string) (bool, error)
// GetScrapedMediaIDs returns media DBIDs in a system already marked as scraped
// by scraperID.
GetScrapedMediaIDs(ctx context.Context, scraperID string, systemDBID int64) (map[int64]struct{}, error)
// UpsertMediaTags writes tags to MediaTags for a specific Media row.
// Exclusive types (TagTypes.IsExclusive=1) delete existing tags of that type
// for the entity before inserting; additive types use INSERT OR IGNORE.
UpsertMediaTags(ctx context.Context, mediaDBID int64, tags []TagInfo) error
// UpsertMediaTitleTags writes tags to MediaTitleTags for a specific MediaTitle row.
// Exclusive/additive behaviour is identical to UpsertMediaTags.
UpsertMediaTitleTags(ctx context.Context, mediaTitleDBID int64, tags []TagInfo) error
// UpsertMediaTitleProperties upserts properties into MediaTitleProperties.
// Conflicts on (MediaTitleDBID, TypeTagDBID) update data columns; DBID is preserved.
UpsertMediaTitleProperties(ctx context.Context, mediaTitleDBID int64, props []MediaProperty) error
// UpsertMediaProperties upserts properties into MediaProperties.
// Conflicts on (MediaDBID, TypeTagDBID) update data columns; DBID is preserved.
UpsertMediaProperties(ctx context.Context, mediaDBID int64, props []MediaProperty) error
// ApplyScrapeResult atomically writes all scraper metadata for a Media row and
// writes the sentinel tag last.
ApplyScrapeResult(ctx context.Context, mediaDBID, mediaTitleDBID int64, write *ScrapeWrite) error
// FindMediaTitlesWithoutSentinel returns MediaTitle rows for the given system
// that have no Media row with the given sentinel tag value.
FindMediaTitlesWithoutSentinel(ctx context.Context, systemDBID int64, sentinelTag string) ([]MediaTitle, error)
// FindMediaTitleByDBID returns the MediaTitle with the given DBID,
// or nil, nil when no row is found.
FindMediaTitleByDBID(ctx context.Context, dbid int64) (*MediaTitle, error)
// FindMediaTitleBySystemAndSlug returns the MediaTitle matching systemDBID and
// slug, or nil, nil when no row is found.
FindMediaTitleBySystemAndSlug(ctx context.Context, systemDBID int64, slug string) (*MediaTitle, error)
// GetMediaTitleProperties returns all properties for a MediaTitle row,
// with TypeTagDBID resolved to the tag value string. Binary blobs are capped
// at MaxMediaPropertyBinaryBytes; larger blobs populate BlobSize but not Binary.
GetMediaTitleProperties(ctx context.Context, mediaTitleDBID int64) ([]MediaProperty, error)
GetMediaTitlePropertiesByMediaTitleDBIDs(
ctx context.Context, mediaTitleDBIDs []int64,
) (map[int64][]MediaProperty, error)
GetMediaTitlePropertyMetadata(ctx context.Context, mediaTitleDBID int64) ([]MediaProperty, error)
GetMediaTitlePropertyMetadataByMediaTitleDBIDs(
ctx context.Context, mediaTitleDBIDs []int64,
) (map[int64][]MediaProperty, error)
// GetMediaProperties returns all properties for a Media row,
// with TypeTagDBID resolved to the tag value string. Binary blobs are capped
// at MaxMediaPropertyBinaryBytes; larger blobs populate BlobSize but not Binary.
GetMediaProperties(ctx context.Context, mediaDBID int64) ([]MediaProperty, error)
GetMediaPropertiesByMediaDBIDs(ctx context.Context, mediaDBIDs []int64) (map[int64][]MediaProperty, error)
GetMediaPropertyMetadata(ctx context.Context, mediaDBID int64) ([]MediaProperty, error)
GetMediaPropertyMetadataByMediaDBIDs(ctx context.Context, mediaDBIDs []int64) (map[int64][]MediaProperty, error)
// DeleteMediaTitleProperty removes a single property row from MediaTitleProperties
// identified by (mediaTitleDBID, typeTagDBID). A no-op if the row does not exist.
DeleteMediaTitleProperty(ctx context.Context, mediaTitleDBID int64, typeTagDBID int64) error
// DeleteMediaProperty removes a single property row from MediaProperties
// identified by (mediaDBID, typeTagDBID). A no-op if the row does not exist.
DeleteMediaProperty(ctx context.Context, mediaDBID int64, typeTagDBID int64) error
// GetMediaWithTitleAndSystem fetches a Media record together with its parent
// MediaTitle and System via a single JOIN query. Returns nil, nil when no
// Media row with the given DBID exists. IsMissing is NOT filtered — metadata
// remains accessible for missing files.
GetMediaWithTitleAndSystem(ctx context.Context, mediaDBID int64) (*MediaFullRow, error)
GetMediaWithTitleAndSystemByIDs(ctx context.Context, mediaDBIDs []int64) (map[int64]MediaFullRow, error)
// GetMediaTagsByMediaDBID returns the file-level tags (MediaTags) for a
// single Media row. Does not include title-level tags.
GetMediaTagsByMediaDBID(ctx context.Context, mediaDBID int64) ([]TagInfo, error)
GetMediaTagsByMediaDBIDs(ctx context.Context, mediaDBIDs []int64) (map[int64][]TagInfo, error)
// GetMediaTitleTagsByMediaTitleDBID returns the title-level tags
// (MediaTitleTags) for a single MediaTitle row.
GetMediaTitleTagsByMediaTitleDBID(ctx context.Context, mediaTitleDBID int64) ([]TagInfo, error)
GetMediaTitleTagsByMediaTitleDBIDs(ctx context.Context, mediaTitleDBIDs []int64) (map[int64][]TagInfo, error)
// UpsertMediaBlob inserts a blob into MediaBlobs when no row with the same
// SHA-256 hash of framed content type and bytes already exists, then returns its DBID.
// Hash computation is performed internally; callers supply only contentType and raw data.
UpsertMediaBlob(ctx context.Context, contentType string, data []byte) (int64, error)
// GetMediaBlob returns the MediaBlob row for the given DBID,
// or nil, nil when not found.
GetMediaBlob(ctx context.Context, blobDBID int64) (*MediaBlob, error)
GetMediaBlobDataCapped(ctx context.Context, blobDBID int64, maxBytes int64) ([]byte, string, error)
// PruneOrphanedBlobs deletes MediaBlobs rows that are not referenced by
// any MediaTitleProperties or MediaProperties row. Returns the count of
// rows deleted. Safe to call from CleanMediaOrphans.
PruneOrphanedBlobs(ctx context.Context) (int64, error)
}
type MediaFullRow ¶ added in v2.12.0
type MediaFullRow struct {
System System
Media
Title MediaTitle
}
MediaFullRow is the result of a joined query fetching a Media record together with its parent MediaTitle and System in a single round-trip.
type MediaHistoryEntry ¶ added in v2.7.0
type MediaHistoryEntry struct {
StartTime time.Time `json:"startTime"`
UpdatedAt time.Time `json:"updatedAt,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
EndTime *time.Time `json:"endTime,omitempty"`
SyncedAt *time.Time `json:"syncedAt,omitempty"`
DeviceID *string `json:"deviceId,omitempty"`
BootUUID string `json:"bootUuid,omitempty"`
ClockSource string `json:"clockSource,omitempty"`
SystemID string `json:"systemId"`
ID string `json:"uuid,omitempty"`
LauncherID string `json:"launcherId"`
SystemName string `json:"systemName"`
MediaPath string `json:"mediaPath"`
MediaName string `json:"mediaName"`
DBID int64 `db:"DBID" json:"id"`
WallDuration int `json:"wallDuration"`
DurationSec int `json:"durationSec"`
MonotonicStart int64 `json:"monotonicStart,omitempty"`
PlayTime int `json:"playTime"`
TimeSkewFlag bool `json:"timeSkewFlag"`
ClockReliable bool `json:"clockReliable"`
IsDeleted bool `json:"isDeleted,omitempty"`
}
type MediaHistoryTopEntry ¶ added in v2.10.0
type MediaProperty ¶ added in v2.12.0
type MediaProperty struct {
BlobDBID *int64
TypeTag string
Text string
ContentType string
Binary []byte
TypeTagDBID int64
BlobSize int64
}
MediaProperty is a static content property attached to a MediaTitle or Media record. Properties are fetched for display, not filtered by value.
For writes: set TypeTag to the full "type:value" string (e.g. "property:description"). The database layer resolves the TypeTagDBID from TypeTag automatically. To associate binary data with a property, call UpsertMediaBlob first to obtain a BlobDBID, then set that field before upserting the property. For reads: TypeTag is populated from the joined Tags row; TypeTagDBID is also set. ContentType, BlobSize, and Binary are hydrated from the MediaBlobs JOIN and are read-only — do not set them for writes.
type MediaQuery ¶ added in v2.7.0
type MediaQuery struct {
PathGlob string `json:"pathGlob,omitempty"`
PathPrefix string `json:"pathPrefix,omitempty"`
Systems []string `json:"systems,omitempty"`
Tags []zapscript.TagFilter `json:"tags,omitempty"`
}
MediaQuery represents parameters for querying media counts used in random selection
type MediaTagLink ¶ added in v2.11.0
type MediaTitle ¶
type MediaWithFullPath ¶ added in v2.7.0
type MediaWithFullPath struct {
Path string
ParentDir string
TitleSlug string
SystemID string
DBID int64
MediaTitleDBID int64
}
MediaWithFullPath represents a Media item with its associated title and system information
type ScanState ¶
type ScanState struct {
SystemIDs map[string]int
TitleIDs map[string]int
MediaIDs map[string]int
MediaTitleIDs map[int]int // Existing media DBID -> MediaTitleDBID for persistent reconciliation
MediaParentDirs map[int]string
MediaTagIDs map[int]map[int]struct{}
TagTypeIDs map[string]int
TagIDs map[string]int
UserOwnedTagIDs map[int]bool
MissingMedia map[int]struct{} // DBIDs of media not yet re-found during scan
SystemsIndex int
TitlesIndex int
MediaIndex int
TagTypesIndex int
TagsIndex int
}
type ScrapeResultBatchApplier ¶ added in v2.14.0
type ScrapeResultBatchApplier interface {
ApplyScrapeResults(ctx context.Context, targets []ScrapeWriteTarget) error
}
ScrapeResultBatchApplier optionally batches scrape writes for DB implementations that can keep multiple targets in one transaction.
type ScrapeWrite ¶ added in v2.12.0
type ScrapeWrite struct {
Sentinel TagInfo
MediaTags []TagInfo
TitleTags []TagInfo
TitleProps []MediaProperty
MediaProps []MediaProperty
}
ScrapeWrite is the database-level write payload produced by a scraper for a matched Media row. Sentinel is written after all metadata so interrupted runs can safely retry the record.
type ScrapeWriteTarget ¶ added in v2.14.0
type ScrapeWriteTarget struct {
Write *ScrapeWrite
MediaDBID int64
MediaTitleDBID int64
}
ScrapeWriteTarget pairs a scraper write payload with the existing Media and MediaTitle rows it should enrich.
type ScrapingOperation ¶ added in v2.14.0
type SearchFilters ¶ added in v2.7.0
type SearchFilters struct {
Cursor *int64 `json:"cursor,omitempty"`
Letter *string `json:"letter,omitempty"`
Query string `json:"query"`
Systems []systemdefs.System `json:"systems,omitempty"`
Tags []zapscript.TagFilter `json:"tags,omitempty"`
Limit int `json:"limit"`
}
SearchFilters represents parameters for filtered media search
type SearchResult ¶
type SearchResultWithCursor ¶ added in v2.7.0
type SearchResultWithCursor struct {
SystemID string
Name string
Path string
SortValue string
SortMode string
Tags []TagInfo
ZapScriptTags []TagInfo // Disambiguating tags only (tags that differ across sibling variants)
MediaID int64
MediaTitleID int64 `json:"-"`
}
func (*SearchResultWithCursor) ZapScript ¶ added in v2.10.0
func (r *SearchResultWithCursor) ZapScript() string
ZapScript returns the ZapScript title command string for this search result. Uses ZapScriptTags (disambiguating tags only). If ZapScriptTags has not been computed (nil), no tags are emitted — callers that need disambiguation must ensure ZapScriptTags is populated via computeZapScriptTags or equivalent.
type TitleWithSystem ¶ added in v2.7.0
TitleWithSystem represents a MediaTitle with its associated System information
type UserDBI ¶
type UserDBI interface {
GenericDBI
AddHistory(entry *HistoryEntry) error
GetHistory(lastID int64) ([]HistoryEntry, error)
CleanupHistory(retentionDays int) (int64, error)
AddMediaHistory(entry *MediaHistoryEntry) (int64, error)
UpdateMediaHistoryTime(dbid int64, playTime int) error
CloseMediaHistory(dbid int64, endTime time.Time, playTime int) error
GetMediaHistory(systemIDs []string, lastID int64, limit int) ([]MediaHistoryEntry, error)
GetLatestMediaHistory() (MediaHistoryEntry, bool, error)
GetMediaHistoryTop(systemIDs []string, since *time.Time, limit int) ([]MediaHistoryTopEntry, error)
CloseHangingMediaHistory() error
CleanupMediaHistory(retentionDays int) (int64, error)
HealTimestamps(bootUUID string, trueBootTime time.Time) (int64, error)
AddMapping(m *Mapping) error
GetMapping(id int64) (Mapping, error)
DeleteMapping(id int64) error
UpdateMapping(id int64, m *Mapping) error
GetAllMappings() ([]Mapping, error)
GetEnabledMappings() ([]Mapping, error)
UpdateZapLinkHost(host string, zapscript int) error
GetZapLinkHost(host string) (bool, bool, error)
GetSupportedZapLinkHosts() ([]string, error)
PruneExpiredZapLinkHosts(olderThan time.Duration) (int64, error)
UpdateZapLinkCache(url string, zapscript string) error
GetZapLinkCache(url string) (string, error)
AddInboxMessage(msg *InboxMessage) (*InboxMessage, error)
GetInboxMessages() ([]InboxMessage, error)
DeleteInboxMessage(id int64) error
DeleteAllInboxMessages() (int64, error)
CreateClient(c *Client) error
GetClientByToken(authToken string) (*Client, error)
ListClients() ([]Client, error)
DeleteClient(clientID string) error
UpdateClientLastSeen(authToken string, lastSeenAt int64) error
CountClients() (int, error)
}
Directories
¶
| Path | Synopsis |
|---|---|
|
Package scraper defines the metadata scraper types and generic run loop.
|
Package scraper defines the metadata scraper types and generic run loop. |
|
gamelistxml
Package gamelistxml implements a scraper that reads EmulationStation gamelist.xml files to enrich the Zaparoo MediaDB with developer, publisher, genre, rating, year, artwork paths, and descriptions.
|
Package gamelistxml implements a scraper that reads EmulationStation gamelist.xml files to enrich the Zaparoo MediaDB with developer, publisher, genre, rating, year, artwork paths, and descriptions. |