Documentation
¶
Index ¶
- Constants
- type AutomaticHealthCheckRecord
- type BackfillRecord
- type BackfillUpdate
- type BulkOperationResult
- type Config
- type DB
- type DBQuerier
- type DBSymlinkLookup
- type Dialect
- type FileHealth
- type HealthCheckUpsert
- type HealthErrorDetails
- type HealthPriority
- type HealthRepository
- func (r *HealthRepository) AddFileToHealthCheck(ctx context.Context, filePath string, libraryPath *string, maxRetries int, ...) error
- func (r *HealthRepository) AddFileToHealthCheckWithMetadata(ctx context.Context, filePath string, libraryPath *string, maxRetries int, ...) error
- func (r *HealthRepository) AddHealthCheck(ctx context.Context, filePath string, releaseDate time.Time, ...) error
- func (r *HealthRepository) BackfillReleaseDates(ctx context.Context, updates []BackfillUpdate) error
- func (r *HealthRepository) BatchAddAutomaticHealthChecks(ctx context.Context, records []AutomaticHealthCheckRecord) error
- func (r *HealthRepository) BatchAddFileToHealthCheck(ctx context.Context, records []HealthCheckUpsert) error
- func (r *HealthRepository) CountHealthItems(ctx context.Context, statusFilter *HealthStatus, sinceFilter *time.Time, ...) (int, error)
- func (r *HealthRepository) DeleteHealthRecord(ctx context.Context, filePath string) error
- func (r *HealthRepository) DeleteHealthRecordByID(ctx context.Context, id int64) error
- func (r *HealthRepository) DeleteHealthRecordByLibraryPath(ctx context.Context, libraryPath string) (string, error)
- func (r *HealthRepository) DeleteHealthRecordsBulk(ctx context.Context, filePaths []string) (int64, error)
- func (r *HealthRepository) DeleteHealthRecordsByDate(ctx context.Context, olderThan time.Time, statusFilter *HealthStatus) (int, error)
- func (r *HealthRepository) DeleteHealthRecordsByLibraryPathPrefix(ctx context.Context, libraryPathPrefix string) ([]string, int64, error)
- func (r *HealthRepository) DeleteHealthRecordsByPrefix(ctx context.Context, prefix string) (int64, error)
- func (r *HealthRepository) DeleteUnvalidatedHealthRecordsByPrefix(ctx context.Context, prefix string) (int64, error)
- func (r *HealthRepository) GetAllHealthCheckPaths(ctx context.Context) ([]string, error)
- func (r *HealthRepository) GetAllHealthCheckRecords(ctx context.Context) ([]AutomaticHealthCheckRecord, error)
- func (r *HealthRepository) GetFileHealth(ctx context.Context, filePath string) (*FileHealth, error)
- func (r *HealthRepository) GetFileHealthByID(ctx context.Context, id int64) (*FileHealth, error)
- func (r *HealthRepository) GetFileHealthByLibraryPath(ctx context.Context, libraryPath string) (*FileHealth, error)
- func (r *HealthRepository) GetFilesByPaths(ctx context.Context, filePaths []string) ([]*FileHealth, error)
- func (r *HealthRepository) GetFilesForLibrarySync(ctx context.Context) ([]*FileHealth, error)
- func (r *HealthRepository) GetFilesForRepairNotification(ctx context.Context, limit int) ([]*FileHealth, error)
- func (r *HealthRepository) GetFilesMissingReleaseDate(ctx context.Context, limit int) ([]BackfillRecord, error)
- func (r *HealthRepository) GetHealthStats(ctx context.Context) (map[HealthStatus]int, error)
- func (r *HealthRepository) GetSystemState(ctx context.Context, key string) (string, error)
- func (r *HealthRepository) GetUnhealthyFiles(ctx context.Context, limit int, strategy string, libraryDir string, ...) ([]*FileHealth, error)
- func (r *HealthRepository) HasImportHistoryForPath(ctx context.Context, virtualPath string) (bool, error)
- func (r *HealthRepository) IncrementRetryCount(ctx context.Context, filePath string, errorMessage *string, ...) error
- func (r *HealthRepository) IncrementStreamingFailureCount(ctx context.Context, filePath string, threshold int) (bool, bool, error)
- func (r *HealthRepository) ListHealthItems(ctx context.Context, statusFilter *HealthStatus, limit, offset int, ...) ([]*FileHealth, error)
- func (r *HealthRepository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, ...) error
- func (r *HealthRepository) MarkAsHealthy(ctx context.Context, filePath string, nextCheckTime time.Time) error
- func (r *HealthRepository) RegisterCorruptedFile(ctx context.Context, filePath string, libraryPath *string, errorMessage string) error
- func (r *HealthRepository) RelinkFileByFilename(ctx context.Context, filename, filePath, libraryPath string, ...) (bool, error)
- func (r *HealthRepository) RelinkFileByMetadata(ctx context.Context, webMeta *model.WebhookMetadata, ...) (bool, error)
- func (r *HealthRepository) RenameHealthRecord(ctx context.Context, oldPath, newPath string) error
- func (r *HealthRepository) ResetAllHealthChecks(ctx context.Context) (int, error)
- func (r *HealthRepository) ResetFileAllChecking(ctx context.Context) error
- func (r *HealthRepository) ResetHealthChecksBulk(ctx context.Context, filePaths []string) (int, error)
- func (r *HealthRepository) ResetStalePendingFiles(ctx context.Context) error
- func (r *HealthRepository) ResolvePendingRepairsInDirectory(ctx context.Context, dirPath string) (int64, error)
- func (r *HealthRepository) SetFileChecking(ctx context.Context, filePath string) error
- func (r *HealthRepository) SetFileCheckingByID(ctx context.Context, id int64) error
- func (r *HealthRepository) SetFilesCheckingBulk(ctx context.Context, filePaths []string) error
- func (r *HealthRepository) SetPriority(ctx context.Context, id int64, priority HealthPriority) error
- func (r *HealthRepository) SetRepairTriggered(ctx context.Context, filePath string, errorMessage *string, ...) error
- func (r *HealthRepository) SetRepairTriggeredByID(ctx context.Context, id int64, errorMessage *string, errorDetails *string) error
- func (r *HealthRepository) UnmaskFile(ctx context.Context, filePath string) error
- func (r *HealthRepository) UpdateFileHealth(ctx context.Context, filePath string, status HealthStatus, ...) error
- func (r *HealthRepository) UpdateFileHealthScheduled(ctx context.Context, filePath string, status HealthStatus, ...) error
- func (r *HealthRepository) UpdateFileMetadata(ctx context.Context, id int64, metadata []byte) error
- func (r *HealthRepository) UpdateHealthStatusBulk(ctx context.Context, updates []HealthStatusUpdate) error
- func (r *HealthRepository) UpdateLibraryPath(ctx context.Context, filePath string, libraryPath string) error
- func (r *HealthRepository) UpdateScheduledCheckTime(ctx context.Context, filePath string, nextCheckTime time.Time) error
- func (r *HealthRepository) UpdateSystemState(ctx context.Context, key string, value string) error
- type HealthStatus
- type HealthStatusUpdate
- type ImportDailyStat
- type ImportHistory
- type ImportHourlyStat
- type ImportMigration
- type ImportMigrationRepository
- func (r *ImportMigrationRepository) BackfillFromImportQueue(ctx context.Context) (int, error)
- func (r *ImportMigrationRepository) DeleteAllBySource(ctx context.Context, source string) (int64, error)
- func (r *ImportMigrationRepository) DeletePendingBySource(ctx context.Context, source string) (int64, error)
- func (r *ImportMigrationRepository) ExistsForSource(ctx context.Context, source string) (bool, error)
- func (r *ImportMigrationRepository) LinkQueueItemID(ctx context.Context, source string, externalIDs []string, queueItemID int64) error
- func (r *ImportMigrationRepository) ListByStatus(ctx context.Context, source string, status ImportMigrationStatus, ...) ([]*ImportMigration, error)
- func (r *ImportMigrationRepository) LookupByExternalID(ctx context.Context, source, externalID string) (*ImportMigration, error)
- func (r *ImportMigrationRepository) MarkFailed(ctx context.Context, queueItemID int64, errMsg string) error
- func (r *ImportMigrationRepository) MarkImported(ctx context.Context, queueItemID int64, finalPath string) error
- func (r *ImportMigrationRepository) MarkSymlinksMigrated(ctx context.Context, ids []int64) error
- func (r *ImportMigrationRepository) Stats(ctx context.Context, source string) (*ImportMigrationStats, error)
- func (r *ImportMigrationRepository) Upsert(ctx context.Context, row *ImportMigration) (int64, error)
- type ImportMigrationStats
- type ImportMigrationStatus
- type ImportQueueItem
- type IndexerAggregatedHealth
- type ProviderHistoricalStat
- type ProviderSpeedTestStat
- type QueuePriority
- type QueueRepository
- func (r *QueueRepository) AddBatchToQueue(ctx context.Context, items []*ImportQueueItem) error
- func (r *QueueRepository) AddImportHistory(ctx context.Context, history *ImportHistory) error
- func (r *QueueRepository) AddStoragePath(ctx context.Context, itemID int64, storagePath string) error
- func (r *QueueRepository) AddToQueue(ctx context.Context, item *ImportQueueItem) error
- func (r *QueueRepository) ClaimNextQueueItem(ctx context.Context) (*ImportQueueItem, error)
- func (r *QueueRepository) ClearDailyStats(ctx context.Context) error
- func (r *QueueRepository) ClearHourlyStats(ctx context.Context) error
- func (r *QueueRepository) ClearImportHistory(ctx context.Context) error
- func (r *QueueRepository) ClearImportHistorySince(ctx context.Context, since time.Time) error
- func (r *QueueRepository) ClearProviderHourlyStats(ctx context.Context) error
- func (r *QueueRepository) DeleteFailedItemsOlderThan(ctx context.Context, olderThan time.Time) ([]*ImportQueueItem, error)
- func (r *QueueRepository) DeleteImportHistoryOlderThan(ctx context.Context, olderThan time.Time) error
- func (r *QueueRepository) DeleteIndexerStats(ctx context.Context, indexer string) (int64, error)
- func (r *QueueRepository) GetImportDailyStats(ctx context.Context, days int) ([]*ImportDailyStat, error)
- func (r *QueueRepository) GetImportHistory(ctx context.Context, days int) ([]*ImportDailyStat, error)
- func (r *QueueRepository) GetImportHourlyStats(ctx context.Context, hours int) ([]*ImportHourlyStat, error)
- func (r *QueueRepository) GetIndexerHealthStats(ctx context.Context) ([]*IndexerAggregatedHealth, error)
- func (r *QueueRepository) GetPendingQueueItemsByPathPrefix(ctx context.Context, prefix string) ([]*ImportQueueItem, error)
- func (r *QueueRepository) GetQueueItem(ctx context.Context, id int64) (*ImportQueueItem, error)
- func (r *QueueRepository) GetQueueItemByDownloadID(ctx context.Context, downloadID string) (*ImportQueueItem, error)
- func (r *QueueRepository) GetQueueItemByNzbPath(ctx context.Context, nzbPath string) (*ImportQueueItem, error)
- func (r *QueueRepository) GetQueueStats(ctx context.Context) (*QueueStats, error)
- func (r *QueueRepository) GetUnknownIndexerStatsDownloadIDs(ctx context.Context) ([]string, error)
- func (r *QueueRepository) IncrementDailyStat(ctx context.Context, statType string) error
- func (r *QueueRepository) IncrementHourlyStat(ctx context.Context, statType string) error
- func (r *QueueRepository) IncrementRetryCountAndResetStatus(ctx context.Context, id int64, errorMessage *string) (bool, error)
- func (r *QueueRepository) IsFileInQueue(ctx context.Context, filePath string) (bool, error)
- func (r *QueueRepository) ListImportHistory(ctx context.Context, limit int) ([]*ImportHistory, error)
- func (r *QueueRepository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, ...) error
- func (r *QueueRepository) PruneIndexerStats(ctx context.Context, hours int) (int64, error)
- func (r *QueueRepository) RemoveFromQueue(ctx context.Context, id int64) error
- func (r *QueueRepository) RemoveFromQueueBulk(ctx context.Context, ids []int64) (*BulkOperationResult, error)
- func (r *QueueRepository) ResetStaleItems(ctx context.Context) error
- func (r *QueueRepository) RestartQueueItemsBulk(ctx context.Context, ids []int64) error
- func (r *QueueRepository) UpdateImportHistoryIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *QueueRepository) UpdateIndexerStatsByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *QueueRepository) UpdateQueueItemCategory(ctx context.Context, id int64, category *string, priority QueuePriority) error
- func (r *QueueRepository) UpdateQueueItemIndexer(ctx context.Context, id int64, indexer string) error
- func (r *QueueRepository) UpdateQueueItemIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *QueueRepository) UpdateQueueItemNzbPath(ctx context.Context, id int64, nzbPath string) error
- func (r *QueueRepository) UpdateQueueItemPriority(ctx context.Context, id int64, priority QueuePriority) error
- func (r *QueueRepository) UpdateQueueItemStatus(ctx context.Context, id int64, status QueueStatus, errorMessage *string) error
- type QueueStats
- type QueueStatus
- type Repository
- func (r *Repository) AddBatchToQueue(ctx context.Context, items []*ImportQueueItem) error
- func (r *Repository) AddBytesDownloadedToDailyStat(ctx context.Context, bytes int64) error
- func (r *Repository) AddBytesDownloadedToHourlyStat(ctx context.Context, bytes int64) error
- func (r *Repository) AddImportHistory(ctx context.Context, history *ImportHistory) error
- func (r *Repository) AddProviderBytesToHourlyStat(ctx context.Context, providerID string, bytes int64) error
- func (r *Repository) AddToQueue(ctx context.Context, item *ImportQueueItem) error
- func (r *Repository) BatchUpdateSystemStats(ctx context.Context, stats map[string]int64) error
- func (r *Repository) ClaimNextQueueItem(ctx context.Context) (*ImportQueueItem, error)
- func (r *Repository) ClearCompletedQueueItems(ctx context.Context) ([]string, int, error)
- func (r *Repository) ClearDailyStats(ctx context.Context) error
- func (r *Repository) ClearDailyStatsSince(ctx context.Context, since time.Time) error
- func (r *Repository) ClearFailedQueueItems(ctx context.Context) ([]string, int, error)
- func (r *Repository) ClearHourlyStats(ctx context.Context) error
- func (r *Repository) ClearHourlyStatsSince(ctx context.Context, since time.Time) error
- func (r *Repository) ClearImportHistory(ctx context.Context) error
- func (r *Repository) ClearImportHistorySince(ctx context.Context, since time.Time) error
- func (r *Repository) ClearPendingQueueItems(ctx context.Context) ([]string, int, error)
- func (r *Repository) ClearProviderHourlyStats(ctx context.Context) error
- func (r *Repository) CountActiveQueueItems(ctx context.Context, search string, category string) (int, error)
- func (r *Repository) CountQueueItems(ctx context.Context, status *QueueStatus, search string, category string) (int, error)
- func (r *Repository) DeleteIndexerStats(ctx context.Context, indexer string) (int64, error)
- func (r *Repository) DeleteQueueItemsByPath(ctx context.Context, path string) error
- func (r *Repository) GetExpiredStremioQueueItems(ctx context.Context, ttlHours int) ([]*ImportQueueItem, error)
- func (r *Repository) GetImportDailyStats(ctx context.Context, days int) ([]*ImportDailyStat, error)
- func (r *Repository) GetImportHistory(ctx context.Context, days int) ([]*ImportDailyStat, error)
- func (r *Repository) GetImportHistoryByDownloadID(ctx context.Context, downloadID string) (*ImportHistory, error)
- func (r *Repository) GetImportHistoryByNzbID(ctx context.Context, nzbID int64) (*ImportHistory, error)
- func (r *Repository) GetImportHistoryByPath(ctx context.Context, virtualPath string) (*ImportHistory, error)
- func (r *Repository) GetImportHistoryItem(ctx context.Context, id int64) (*ImportHistory, error)
- func (r *Repository) GetImportHourlyStats(ctx context.Context, hours int) ([]*ImportHourlyStat, error)
- func (r *Repository) GetIndexerHealthStats(ctx context.Context) ([]*IndexerAggregatedHealth, error)
- func (r *Repository) GetOldestProviderStatDates(ctx context.Context) (map[string]time.Time, error)
- func (r *Repository) GetOldestStatDate(ctx context.Context) (time.Time, error)
- func (r *Repository) GetProviderHistoricalStats(ctx context.Context, days int, interval string) ([]*ProviderHistoricalStat, error)
- func (r *Repository) GetProviderHourlyStats(ctx context.Context, hours int) (map[string]int64, error)
- func (r *Repository) GetProviderSpeedTestHistory(ctx context.Context, days int) ([]*ProviderSpeedTestStat, error)
- func (r *Repository) GetQueueItem(ctx context.Context, id int64) (*ImportQueueItem, error)
- func (r *Repository) GetQueueItemByDownloadID(ctx context.Context, downloadID string) (*ImportQueueItem, error)
- func (r *Repository) GetQueueStats(ctx context.Context) (*QueueStats, error)
- func (r *Repository) GetSystemState(ctx context.Context, key string) (string, error)
- func (r *Repository) GetSystemStats(ctx context.Context) (map[string]int64, error)
- func (r *Repository) GetUnknownIndexerStatsDownloadIDs(ctx context.Context) ([]string, error)
- func (r *Repository) HasActiveOrRecentQueueItemForStoragePath(ctx context.Context, relPath string, completedGrace time.Duration) (bool, error)
- func (r *Repository) IncrementDailyStat(ctx context.Context, statType string) error
- func (r *Repository) IncrementHourlyStat(ctx context.Context, statType string) error
- func (r *Repository) IsFileInQueue(ctx context.Context, filePath string) (bool, error)
- func (r *Repository) ListActiveQueueItems(ctx context.Context, search string, category string, limit, offset int, ...) ([]*ImportQueueItem, error)
- func (r *Repository) ListImportHistory(ctx context.Context, limit, offset int, search string, category string) ([]*ImportHistory, error)
- func (r *Repository) ListQueueItems(ctx context.Context, status *QueueStatus, search string, category string, ...) ([]*ImportQueueItem, error)
- func (r *Repository) ListRecentImportHistory(ctx context.Context, minutes int, category string) ([]*ImportHistory, error)
- func (r *Repository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, ...) error
- func (r *Repository) PruneIndexerStats(ctx context.Context, hours int) (int64, error)
- func (r *Repository) RecordProviderSpeedTest(ctx context.Context, providerID string, speedMbps float64) error
- func (r *Repository) RemoveFromHistory(ctx context.Context, id int64) (int64, error)
- func (r *Repository) RemoveFromHistoryByDownloadID(ctx context.Context, downloadID string) (int64, error)
- func (r *Repository) RemoveFromHistoryByNzbID(ctx context.Context, nzbID int64) (int64, error)
- func (r *Repository) RemoveFromQueue(ctx context.Context, id int64) error
- func (r *Repository) RemoveFromQueueBulk(ctx context.Context, ids []int64) (*BulkOperationResult, error)
- func (r *Repository) RemoveFromQueueByDownloadID(ctx context.Context, downloadID string) error
- func (r *Repository) RestartQueueItemsBulk(ctx context.Context, ids []int64) error
- func (r *Repository) UpdateImportHistoryIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *Repository) UpdateIndexerStatsByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *Repository) UpdateQueueItemIndexer(ctx context.Context, id int64, indexer string) error
- func (r *Repository) UpdateQueueItemIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
- func (r *Repository) UpdateQueueItemPriority(ctx context.Context, id int64, priority QueuePriority) error
- func (r *Repository) UpdateQueueItemStatus(ctx context.Context, id int64, status QueueStatus, errorMessage *string) error
- func (r *Repository) UpdateQueueItemsPriorityBulk(ctx context.Context, ids []int64, priority QueuePriority) (updated int, skipped int, err error)
- func (r *Repository) UpdateQueueStats(ctx context.Context) error
- func (r *Repository) UpdateSystemStat(ctx context.Context, key string, value int64) error
- func (r *Repository) UpdateSystemState(ctx context.Context, key string, value string) error
- func (r *Repository) WithImmediateTransaction(ctx context.Context, fn func(*Repository) error) error
- func (r *Repository) WithTransaction(ctx context.Context, fn func(*Repository) error) error
- type StoreRefRepository
- type UpdateType
- type User
- type UserRepository
- func (r *UserRepository) CreateUser(ctx context.Context, user *User) error
- func (r *UserRepository) GetAllUsers(ctx context.Context) ([]*User, error)
- func (r *UserRepository) GetUserByAPIKey(ctx context.Context, apiKey string) (*User, error)
- func (r *UserRepository) GetUserByEmail(ctx context.Context, email string) (*User, error)
- func (r *UserRepository) GetUserByID(ctx context.Context, userID string) (*User, error)
- func (r *UserRepository) GetUserByProvider(ctx context.Context, provider, providerID string) (*User, error)
- func (r *UserRepository) GetUserByUsername(ctx context.Context, username string) (*User, error)
- func (r *UserRepository) GetUserCount(ctx context.Context) (int, error)
- func (r *UserRepository) RegenerateAPIKey(ctx context.Context, userID string) (string, error)
- func (r *UserRepository) UpdateLastLogin(ctx context.Context, userID string) error
- func (r *UserRepository) UpdatePassword(ctx context.Context, userID string, passwordHash string) error
Constants ¶
const IndexerUnknown = "Unknown"
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AutomaticHealthCheckRecord ¶
type AutomaticHealthCheckRecord struct {
FilePath string
LibraryPath *string
ReleaseDate *time.Time
ScheduledCheckAt *time.Time
SourceNzbPath *string
Status HealthStatus
MaxRetries int
MaxRepairRetries int
}
AutomaticHealthCheckRecord represents a batch insert record
type BackfillRecord ¶
BackfillRecord represents a record used for metadata backfilling
type BackfillUpdate ¶
BackfillUpdate represents an update for release date backfilling
type BulkOperationResult ¶
type BulkOperationResult struct {
DeletedCount int
ProcessingCount int
FailedIDs []int64
// DeletedPaths holds the nzb_path values for rows that were actually removed,
// so callers can clean up the corresponding files on disk.
DeletedPaths []string
}
BulkOperationResult represents the result of a bulk queue operation
type Config ¶
type Config struct {
// Type selects the backend: "sqlite" (default) or "postgres".
Type string
DatabasePath string // SQLite only
DSN string // PostgreSQL only
}
Config holds database configuration.
type DB ¶
type DB struct {
// Repository is kept for backwards-compat; prefer using Connection() directly.
Repository *QueueRepository
MigrationRepo *ImportMigrationRepository
StoreRefRepo *StoreRefRepository
// contains filtered or unexported fields
}
DB wraps the database connection and provides access to operations.
func (*DB) Connection ¶
Connection returns the underlying database connection.
func (*DB) StartCheckpointLoop ¶ added in v0.3.0
StartCheckpointLoop starts a background goroutine that periodically forces a WAL checkpoint (SQLite only). Call once after opening the DB; stops when ctx is cancelled.
func (*DB) UpdateConnectionPool ¶
UpdateConnectionPool adjusts the database connection pool settings based on worker count.
type DBQuerier ¶
type DBQuerier interface {
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}
DBQuerier defines the interface for database query operations Both *sql.DB and *sql.Tx implement this interface
type DBSymlinkLookup ¶ added in v0.3.0
type DBSymlinkLookup struct {
// contains filtered or unexported fields
}
DBSymlinkLookup adapts ImportMigrationRepository to migration.SymlinkLookup.
func NewDBSymlinkLookup ¶ added in v0.3.0
func NewDBSymlinkLookup(repo *ImportMigrationRepository) *DBSymlinkLookup
NewDBSymlinkLookup creates a new DBSymlinkLookup wrapping the given repository.
func (*DBSymlinkLookup) LookupFinalPath ¶ added in v0.3.0
func (l *DBSymlinkLookup) LookupFinalPath(ctx context.Context, source, externalID string) (string, bool, error)
LookupFinalPath returns the final AltMount path for the given source and externalID. Returns ("", false, nil) when no matching row exists or the row has no final_path.
Season-pack episode rows use a "file:<episodeFilename>" relative_path to signal that final_path stores the season directory and the episode path must be computed by joining them. This keeps MarkImported simple (always stores the directory) while allowing per-episode resolution here.
func (*DBSymlinkLookup) MarkSymlinksMigrated ¶ added in v0.3.0
func (l *DBSymlinkLookup) MarkSymlinksMigrated(ctx context.Context, ids []int64) error
MarkSymlinksMigrated sets status=symlinks_migrated for the given row IDs.
type FileHealth ¶
type FileHealth struct {
ID int64 `db:"id"`
FilePath string `db:"file_path"`
LibraryPath *string `db:"library_path"` // Path to file in library directory (symlink or .strm file)
Status HealthStatus `db:"status"`
LastChecked *time.Time `db:"last_checked"`
LastError *string `db:"last_error"`
RetryCount int `db:"retry_count"` // Health check retry count
MaxRetries int `db:"max_retries"` // Max health check retries
RepairRetryCount int `db:"repair_retry_count"` // Repair retry count
MaxRepairRetries int `db:"max_repair_retries"` // Max repair retries
SourceNzbPath *string `db:"source_nzb_path"`
ErrorDetails *string `db:"error_details"` // JSON error details
Metadata *string `db:"metadata"` // JSON metadata
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
// Health check scheduling fields
ReleaseDate *time.Time `db:"release_date"` // Cached from metadata for scheduling
ScheduledCheckAt *time.Time `db:"scheduled_check_at"` // Next check time
Priority HealthPriority `db:"priority"` // Priority level for health checks
// Failure masking fields
StreamingFailureCount int `db:"streaming_failure_count"`
IsMasked bool `db:"is_masked"`
Indexer *string `db:"indexer"`
DownloadID *string `db:"download_id"`
}
FileHealth represents the health tracking of files in the filesystem
func (*FileHealth) EffectiveLibraryPath ¶ added in v0.3.0
func (f *FileHealth) EffectiveLibraryPath() (string, bool)
EffectiveLibraryPath returns the real library path and true when the record has been relinked by an ARR; otherwise ("", false).
func (*FileHealth) IsImported ¶ added in v0.3.0
func (f *FileHealth) IsImported() bool
IsImported reports whether library_path points to a real, ARR-relinked library location rather than the import-time placeholder. The placeholder is stored equal to file_path (optionally with a leading slash from path normalization); a real filesystem path can never equal file_path or "/"+file_path, so this is unambiguous on every platform.
type HealthCheckUpsert ¶ added in v0.3.0
type HealthCheckUpsert struct {
FilePath string
LibraryPath *string
SourceNzbPath *string
Indexer *string
Priority HealthPriority
MaxRetries int
MaxRepairRetries int
ReleaseDate *time.Time
Metadata *string
DownloadID *string
}
HealthCheckUpsert is one record for BatchAddFileToHealthCheck.
type HealthErrorDetails ¶ added in v0.3.0
type HealthErrorDetails struct {
ErrorType string `json:"error_type"`
Message string `json:"message,omitempty"`
MissingArticles int `json:"missing_articles,omitempty"`
TotalArticles int `json:"total_articles,omitempty"`
Sampled int `json:"sampled,omitempty"`
PlaybackImpact *holes.Impact `json:"playback_impact,omitempty"`
}
HealthErrorDetails is the structured JSON stored in file_health.error_details. Both the health checker and the streaming failure path marshal this envelope; the frontend parses it to render playback-impact information. Legacy rows may contain other ad-hoc JSON shapes or plain strings — parsers must tolerate that.
func (*HealthErrorDetails) Marshal ¶ added in v0.3.0
func (d *HealthErrorDetails) Marshal() *string
Marshal renders the envelope for storage, returning nil on the (practically impossible) marshal error so callers can assign it directly to *string fields.
type HealthPriority ¶
type HealthPriority int
HealthPriority represents the priority level of a health check
const ( HealthPriorityNormal HealthPriority = 0 HealthPriorityHigh HealthPriority = 1 HealthPriorityNext HealthPriority = 2 )
type HealthRepository ¶
type HealthRepository struct {
// contains filtered or unexported fields
}
HealthRepository handles file health database operations
func NewHealthRepository ¶
func NewHealthRepository(db *sql.DB, d Dialect) *HealthRepository
NewHealthRepository creates a new health repository
func (*HealthRepository) AddFileToHealthCheck ¶
func (r *HealthRepository) AddFileToHealthCheck(ctx context.Context, filePath string, libraryPath *string, maxRetries int, maxRepairRetries int, sourceNzbPath *string, priority HealthPriority) error
AddFileToHealthCheck adds a file to the health database for checking
func (*HealthRepository) AddFileToHealthCheckWithMetadata ¶
func (r *HealthRepository) AddFileToHealthCheckWithMetadata(ctx context.Context, filePath string, libraryPath *string, maxRetries int, maxRepairRetries int, sourceNzbPath *string, priority HealthPriority, releaseDate *time.Time, metadata *string, indexer *string, downloadID *string) error
AddFileToHealthCheckWithMetadata adds a file to the health database for checking with metadata. On conflict (re-import over an existing record) the record is reset to pending for re-validation, but repair_retry_count is intentionally preserved: it is the per-title repair budget, so a re-download of a broken release cannot reset its own escalation counter. A successful health check resets it to 0.
func (*HealthRepository) AddHealthCheck ¶
func (r *HealthRepository) AddHealthCheck( ctx context.Context, filePath string, releaseDate time.Time, scheduledCheckAt time.Time, sourceNzbPath *string, ) error
AddHealthCheck adds or updates a health check record
func (*HealthRepository) BackfillReleaseDates ¶
func (r *HealthRepository) BackfillReleaseDates(ctx context.Context, updates []BackfillUpdate) error
BackfillReleaseDates updates multiple health records with their release dates and next check times
func (*HealthRepository) BatchAddAutomaticHealthChecks ¶
func (r *HealthRepository) BatchAddAutomaticHealthChecks(ctx context.Context, records []AutomaticHealthCheckRecord) error
BatchAddAutomaticHealthChecks inserts multiple automatic health checks efficiently
func (*HealthRepository) BatchAddFileToHealthCheck ¶ added in v0.3.0
func (r *HealthRepository) BatchAddFileToHealthCheck(ctx context.Context, records []HealthCheckUpsert) error
BatchAddFileToHealthCheck upserts many health records in a few multi-row statements instead of one transaction per file. It has the SAME conflict semantics as AddFileToHealthCheckWithMetadata (reset to pending for re-validation, repair_retry_count preserved as the per-title budget). Used by the import post-processor, where a single archive/season-pack import can expand to hundreds of per-file checks.
func (*HealthRepository) CountHealthItems ¶
func (r *HealthRepository) CountHealthItems(ctx context.Context, statusFilter *HealthStatus, sinceFilter *time.Time, search string) (int, error)
CountHealthItems returns the total count of health records with optional filtering
func (*HealthRepository) DeleteHealthRecord ¶
func (r *HealthRepository) DeleteHealthRecord(ctx context.Context, filePath string) error
DeleteHealthRecord removes a specific health record from the database
func (*HealthRepository) DeleteHealthRecordByID ¶
func (r *HealthRepository) DeleteHealthRecordByID(ctx context.Context, id int64) error
DeleteHealthRecordByID removes a specific health record from the database by ID
func (*HealthRepository) DeleteHealthRecordByLibraryPath ¶
func (r *HealthRepository) DeleteHealthRecordByLibraryPath(ctx context.Context, libraryPath string) (string, error)
DeleteHealthRecordByLibraryPath deletes the health record matching the given absolute library path. Returns the file_path of the deleted record so the caller can use it for metadata cleanup.
func (*HealthRepository) DeleteHealthRecordsBulk ¶
func (r *HealthRepository) DeleteHealthRecordsBulk(ctx context.Context, filePaths []string) (int64, error)
DeleteHealthRecordsBulk removes multiple health records from the database
func (*HealthRepository) DeleteHealthRecordsByDate ¶
func (r *HealthRepository) DeleteHealthRecordsByDate(ctx context.Context, olderThan time.Time, statusFilter *HealthStatus) (int, error)
DeleteHealthRecordsByDate deletes health records older than the specified date with optional status filter
func (*HealthRepository) DeleteHealthRecordsByLibraryPathPrefix ¶
func (r *HealthRepository) DeleteHealthRecordsByLibraryPathPrefix(ctx context.Context, libraryPathPrefix string) ([]string, int64, error)
DeleteHealthRecordsByLibraryPathPrefix deletes health records where library_path matches the given prefix. Returns the file_paths of deleted records for metadata cleanup, plus the count.
func (*HealthRepository) DeleteHealthRecordsByPrefix ¶
func (r *HealthRepository) DeleteHealthRecordsByPrefix(ctx context.Context, prefix string) (int64, error)
DeleteHealthRecordsByPrefix removes ALL health records at or under the given virtual path prefix. Used by the webhook directory-delete handler, where the whole subtree is genuinely gone and every record (including healthy/relinked ones) must be removed. For failed-import rollback use DeleteUnvalidatedHealthRecordsByPrefix instead.
func (*HealthRepository) DeleteUnvalidatedHealthRecordsByPrefix ¶ added in v0.3.0
func (r *HealthRepository) DeleteUnvalidatedHealthRecordsByPrefix(ctx context.Context, prefix string) (int64, error)
DeleteUnvalidatedHealthRecordsByPrefix removes only the still-unvalidated placeholder records at or under the prefix — those an ARR webhook has not yet relinked to a real library path (library_path NULL or still equal to the virtual file_path) and that are not in a terminal/repair state. This is the failed-import rollback path: the nzbFolder is deterministic per release (not unique per queue item), so a failed re-import of a release that previously imported successfully shares the subtree. Scoping to unvalidated records protects the prior successful import's healthy/relinked/repair_triggered/corrupted records (and the repair budget they carry) from being wiped by an unrelated failed attempt.
func (*HealthRepository) GetAllHealthCheckPaths ¶
func (r *HealthRepository) GetAllHealthCheckPaths(ctx context.Context) ([]string, error)
GetAllHealthCheckPaths returns all health check file paths (memory optimized)
func (*HealthRepository) GetAllHealthCheckRecords ¶
func (r *HealthRepository) GetAllHealthCheckRecords(ctx context.Context) ([]AutomaticHealthCheckRecord, error)
GetAllHealthCheckRecords returns all health check records tracked in health system
func (*HealthRepository) GetFileHealth ¶
func (r *HealthRepository) GetFileHealth(ctx context.Context, filePath string) (*FileHealth, error)
GetFileHealth retrieves health record for a specific file
func (*HealthRepository) GetFileHealthByID ¶
func (r *HealthRepository) GetFileHealthByID(ctx context.Context, id int64) (*FileHealth, error)
func (*HealthRepository) GetFileHealthByLibraryPath ¶ added in v0.3.0
func (r *HealthRepository) GetFileHealthByLibraryPath(ctx context.Context, libraryPath string) (*FileHealth, error)
GetFileHealthByLibraryPath retrieves health record for a specific file by its library path
func (*HealthRepository) GetFilesByPaths ¶
func (r *HealthRepository) GetFilesByPaths(ctx context.Context, filePaths []string) ([]*FileHealth, error)
GetFilesByPaths returns health records for the specified file paths
func (*HealthRepository) GetFilesForLibrarySync ¶
func (r *HealthRepository) GetFilesForLibrarySync(ctx context.Context) ([]*FileHealth, error)
GetFilesForLibrarySync returns all health records to verify their physical presence in the library
func (*HealthRepository) GetFilesForRepairNotification ¶
func (r *HealthRepository) GetFilesForRepairNotification(ctx context.Context, limit int) ([]*FileHealth, error)
GetFilesForRepairNotification returns files that need repair notification (repair_triggered status). Records whose repair_retry_count has reached max_repair_retries are returned too: the worker finalizes them as corrupted (prepareRepairNotificationUpdate). Filtering them out here would leave them permanently stuck in repair_triggered — no other query ever selects that status.
func (*HealthRepository) GetFilesMissingReleaseDate ¶
func (r *HealthRepository) GetFilesMissingReleaseDate(ctx context.Context, limit int) ([]BackfillRecord, error)
GetFilesMissingReleaseDate returns a list of files that don't have a release date cached
func (*HealthRepository) GetHealthStats ¶
func (r *HealthRepository) GetHealthStats(ctx context.Context) (map[HealthStatus]int, error)
GetHealthStats returns statistics about file health
func (*HealthRepository) GetSystemState ¶
GetSystemState retrieves a persistent state value
func (*HealthRepository) GetUnhealthyFiles ¶
func (r *HealthRepository) GetUnhealthyFiles(ctx context.Context, limit int, strategy string, libraryDir string, maxRetries int) ([]*FileHealth, error)
GetUnhealthyFiles returns files that need health checks
func (*HealthRepository) HasImportHistoryForPath ¶
func (r *HealthRepository) HasImportHistoryForPath(ctx context.Context, virtualPath string) (bool, error)
HasImportHistoryForPath checks if any import history record exists for the given virtual path. Used to protect symlinks from deletion when an import has been recorded by AltMount, regardless of current metadata state.
func (*HealthRepository) IncrementRetryCount ¶
func (r *HealthRepository) IncrementRetryCount(ctx context.Context, filePath string, errorMessage *string, errorDetails *string, nextCheck time.Time) error
IncrementRetryCount increments the retry count and schedules next check
func (*HealthRepository) IncrementStreamingFailureCount ¶
func (r *HealthRepository) IncrementStreamingFailureCount(ctx context.Context, filePath string, threshold int) (bool, bool, error)
IncrementStreamingFailureCount increments the streaming failure count and returns whether masking/repair threshold was reached
func (*HealthRepository) ListHealthItems ¶
func (r *HealthRepository) ListHealthItems(ctx context.Context, statusFilter *HealthStatus, limit, offset int, sinceFilter *time.Time, search string, sortBy string, sortOrder string) ([]*FileHealth, error)
ListHealthItems returns all health records with optional filtering, sorting and pagination
func (*HealthRepository) LogIndexerImport ¶ added in v0.3.0
func (r *HealthRepository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, downloadID string) error
LogIndexerImport records a success or failure for an indexer persistently.
func (*HealthRepository) MarkAsHealthy ¶
func (r *HealthRepository) MarkAsHealthy(ctx context.Context, filePath string, nextCheckTime time.Time) error
MarkAsHealthy marks a file as healthy and clears all retry/error state
func (*HealthRepository) RegisterCorruptedFile ¶
func (r *HealthRepository) RegisterCorruptedFile(ctx context.Context, filePath string, libraryPath *string, errorMessage string) error
RegisterCorruptedFile adds or updates a file as corrupted and schedules it for immediate check/repair
func (*HealthRepository) RelinkFileByFilename ¶
func (r *HealthRepository) RelinkFileByFilename(ctx context.Context, filename, filePath, libraryPath string, metadataStr *string, revalidate bool) (bool, error)
RelinkFileByFilename updates the file_path and library_path for a record that matches by filename. This is typically called by webhooks during renames or downloads to provide a definitive library path.
revalidate controls what happens to records in repair_triggered/corrupted state:
- true (Download events — a re-downloaded copy was just imported): reset the record to pending with an immediate check so the fresh copy is validated instead of being destroyed by the next repair re-trigger. retry_count restarts for the new copy, but repair_retry_count is preserved as the per-title repair budget so repeatedly broken re-downloads still escalate to corrupted instead of looping forever.
- false (Rename events — no new content): preserve repair/corrupted state so a library reorganization cannot wipe repair progress.
func (*HealthRepository) RelinkFileByMetadata ¶ added in v0.3.0
func (r *HealthRepository) RelinkFileByMetadata(ctx context.Context, webMeta *model.WebhookMetadata, filePath, libraryPath string, metadataStr *string, revalidate bool) (bool, error)
RelinkFileByMetadata matches repair_triggered or corrupted records by metadata and updates them to pending.
revalidate controls what happens to records in repair_triggered/corrupted state:
- true (Download events — a re-downloaded copy was just imported): reset the record to pending with an immediate check so the fresh copy is validated instead of being destroyed by the next repair re-trigger. retry_count restarts for the new copy, but repair_retry_count is preserved as the per-title repair budget so repeatedly broken re-downloads still escalate to corrupted instead of looping forever.
- false (Rename events — no new content): preserve repair/corrupted state so a library reorganization cannot wipe repair progress.
func (*HealthRepository) RenameHealthRecord ¶
func (r *HealthRepository) RenameHealthRecord(ctx context.Context, oldPath, newPath string) error
RenameHealthRecord updates the file_path of a health record or records under a directory after a MOVE operation
func (*HealthRepository) ResetAllHealthChecks ¶
func (r *HealthRepository) ResetAllHealthChecks(ctx context.Context) (int, error)
ResetAllHealthChecks resets all health records to pending status
func (*HealthRepository) ResetFileAllChecking ¶
func (r *HealthRepository) ResetFileAllChecking(ctx context.Context) error
func (*HealthRepository) ResetHealthChecksBulk ¶
func (r *HealthRepository) ResetHealthChecksBulk(ctx context.Context, filePaths []string) (int, error)
ResetHealthChecksBulk resets multiple health records to pending status
func (*HealthRepository) ResetStalePendingFiles ¶
func (r *HealthRepository) ResetStalePendingFiles(ctx context.Context) error
ResetStalePendingFiles resets pending files that have exhausted retries back to retry_count=0 so they can be re-checked in the next health cycle. Called during worker startup.
func (*HealthRepository) ResolvePendingRepairsInDirectory ¶
func (r *HealthRepository) ResolvePendingRepairsInDirectory(ctx context.Context, dirPath string) (int64, error)
ResolvePendingRepairsInDirectory removes health records with repair_triggered or corrupted status that exist in the specified directory. This is used when a new file is imported into a directory, implying it is a replacement for the broken file.
func (*HealthRepository) SetFileChecking ¶
func (r *HealthRepository) SetFileChecking(ctx context.Context, filePath string) error
SetFileChecking sets a file's status to 'checking'
func (*HealthRepository) SetFileCheckingByID ¶
func (r *HealthRepository) SetFileCheckingByID(ctx context.Context, id int64) error
SetFileCheckingByID sets a file's status to 'checking' by ID
func (*HealthRepository) SetFilesCheckingBulk ¶ added in v0.3.0
func (r *HealthRepository) SetFilesCheckingBulk(ctx context.Context, filePaths []string) error
SetFilesCheckingBulk marks many files 'checking' in as few writes as possible. The health cycle calls this once for the whole batch instead of issuing one UPDATE per file, which under SQLite's single writer would serialize N transactions against each other and the final bulk status write. Crash recovery is unchanged: ResetFileAllChecking at worker startup re-arms any record stranded in 'checking'.
func (*HealthRepository) SetPriority ¶
func (r *HealthRepository) SetPriority(ctx context.Context, id int64, priority HealthPriority) error
SetPriority sets the priority for a file health record
func (*HealthRepository) SetRepairTriggered ¶
func (r *HealthRepository) SetRepairTriggered(ctx context.Context, filePath string, errorMessage *string, errorDetails *string) error
SetRepairTriggered sets a file's status to repair_triggered
func (*HealthRepository) SetRepairTriggeredByID ¶
func (r *HealthRepository) SetRepairTriggeredByID(ctx context.Context, id int64, errorMessage *string, errorDetails *string) error
SetRepairTriggeredByID sets a file's status to repair_triggered by ID
func (*HealthRepository) UnmaskFile ¶
func (r *HealthRepository) UnmaskFile(ctx context.Context, filePath string) error
UnmaskFile removes the mask from a file and resets the failure count
func (*HealthRepository) UpdateFileHealth ¶
func (r *HealthRepository) UpdateFileHealth(ctx context.Context, filePath string, status HealthStatus, errorMessage *string, sourceNzbPath *string, errorDetails *string, noRetry bool) error
UpdateFileHealth updates or inserts a file health record
func (*HealthRepository) UpdateFileHealthScheduled ¶
func (r *HealthRepository) UpdateFileHealthScheduled(ctx context.Context, filePath string, status HealthStatus, errorMessage *string, sourceNzbPath *string, errorDetails *string, noRetry bool, scheduledAt time.Time) error
UpdateFileHealthScheduled is like UpdateFileHealth but uses an explicit scheduledAt time instead of datetime('now') for the scheduled_check_at column.
func (*HealthRepository) UpdateFileMetadata ¶ added in v0.3.0
UpdateFileMetadata updates the metadata column for a health record
func (*HealthRepository) UpdateHealthStatusBulk ¶
func (r *HealthRepository) UpdateHealthStatusBulk(ctx context.Context, updates []HealthStatusUpdate) error
UpdateHealthStatusBulk updates multiple health records in a single transaction
func (*HealthRepository) UpdateLibraryPath ¶
func (r *HealthRepository) UpdateLibraryPath(ctx context.Context, filePath string, libraryPath string) error
UpdateLibraryPath updates the library_path for a specific file
func (*HealthRepository) UpdateScheduledCheckTime ¶
func (r *HealthRepository) UpdateScheduledCheckTime(ctx context.Context, filePath string, nextCheckTime time.Time) error
UpdateScheduledCheckTime updates the scheduled check time for a file
func (*HealthRepository) UpdateSystemState ¶
UpdateSystemState updates or inserts a persistent state value
type HealthStatus ¶
type HealthStatus string
HealthStatus represents the health status of a file
const ( HealthStatusPending HealthStatus = "pending" // File has not been checked yet HealthStatusChecking HealthStatus = "checking" // File is currently being checked HealthStatusHealthy HealthStatus = "healthy" // File passed health check HealthStatusRepairTriggered HealthStatus = "repair_triggered" // File repair has been triggered in Arrs HealthStatusCorrupted HealthStatus = "corrupted" // File has missing segments or is corrupted HealthStatusDegraded HealthStatus = "degraded" // Missing segments only hit media payload: still playable, no repair )
type HealthStatusUpdate ¶
type HealthStatusUpdate struct {
Type UpdateType
FilePath string
Status HealthStatus
ErrorMessage *string
ErrorDetails *string
ScheduledCheckAt time.Time
Skip bool // if true, skip this record in the bulk update (e.g. record already deleted)
// ExpectedStatus, when non-nil, makes the write conditional on the record still being
// in that status (the status the worker based its decision on). It closes the TOCTOU
// window where a concurrent webhook relink, re-import upsert or manual recheck lands
// between the cycle's read and its write: if the status changed underneath us the
// guarded UPDATE matches no rows and the concurrent actor's decision wins instead of
// being silently clobbered (last-writer-wins re-entering the repair loop).
ExpectedStatus *HealthStatus
}
HealthStatusUpdate represents a single update request for batch processing
type ImportDailyStat ¶
type ImportDailyStat struct {
Day time.Time `db:"day"`
CompletedCount int `db:"completed_count"`
FailedCount int `db:"failed_count"`
BytesDownloaded int64 `db:"bytes_downloaded"`
UpdatedAt time.Time `db:"updated_at"`
}
ImportDailyStat represents historical import statistics for a specific day
type ImportHistory ¶
type ImportHistory struct {
ID int64 `db:"id"`
DownloadID *string `db:"download_id"`
NzbID *int64 `db:"nzb_id"` // Nullable if queue item deleted
NzbName string `db:"nzb_name"`
FileName string `db:"file_name"`
FileSize int64 `db:"file_size"`
VirtualPath string `db:"virtual_path"`
LibraryPath *string `db:"library_path"` // Added to show final location from file_health
Category *string `db:"category"`
Metadata *string `db:"metadata"`
Indexer *string `db:"indexer"`
CompletedAt time.Time `db:"completed_at"`
}
ImportHistory represents a persistent record of a single imported file
type ImportHourlyStat ¶
type ImportHourlyStat struct {
Hour time.Time `db:"hour"`
CompletedCount int `db:"completed_count"`
FailedCount int `db:"failed_count"`
BytesDownloaded int64 `db:"bytes_downloaded"`
UpdatedAt time.Time `db:"updated_at"`
}
ImportHourlyStat represents historical import statistics for a specific hour
type ImportMigration ¶ added in v0.3.0
type ImportMigration struct {
ID int64 `db:"id"`
Source string `db:"source"` // e.g. "nzbdav"
ExternalID string `db:"external_id"` // source-specific ID (nzbdav GUID)
QueueItemID *int64 `db:"queue_item_id"` // FK → import_queue.id (nullable)
RelativePath string `db:"relative_path"` // virtual path when enqueued
FinalPath *string `db:"final_path"` // storage_path after import
Status ImportMigrationStatus `db:"status"`
Error *string `db:"error"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
ImportMigration tracks progress of two-phase migrations (e.g. nzbdav → altmount)
type ImportMigrationRepository ¶ added in v0.3.0
type ImportMigrationRepository struct {
// contains filtered or unexported fields
}
ImportMigrationRepository handles database operations for import_migrations.
func NewImportMigrationRepository ¶ added in v0.3.0
func NewImportMigrationRepository(db *sql.DB, d Dialect) *ImportMigrationRepository
NewImportMigrationRepository creates a new ImportMigrationRepository.
func (*ImportMigrationRepository) BackfillFromImportQueue ¶ added in v0.3.0
func (r *ImportMigrationRepository) BackfillFromImportQueue(ctx context.Context) (int, error)
BackfillFromImportQueue reads completed import_queue rows that contain a nzbdav_id in their metadata JSON and inserts them as status=imported rows into import_migrations (idempotent via ON CONFLICT IGNORE / INSERT OR IGNORE). Returns the number of rows inserted.
func (*ImportMigrationRepository) DeleteAllBySource ¶ added in v0.3.0
func (r *ImportMigrationRepository) DeleteAllBySource(ctx context.Context, source string) (int64, error)
DeleteAllBySource removes every migration row for a source regardless of status. Returns the number of rows deleted. Use to force a full re-import after the imported files have been deleted from AltMount.
func (*ImportMigrationRepository) DeletePendingBySource ¶ added in v0.3.0
func (r *ImportMigrationRepository) DeletePendingBySource(ctx context.Context, source string) (int64, error)
DeletePendingBySource removes all migration rows for a source that have status='pending'. Returns the number of rows deleted. Use this to clear orphaned rows from a previous import attempt so a fresh import starts clean (imported/symlinks_migrated rows are preserved).
func (*ImportMigrationRepository) ExistsForSource ¶ added in v0.3.0
func (r *ImportMigrationRepository) ExistsForSource(ctx context.Context, source string) (bool, error)
ExistsForSource returns true if any rows exist for the given source.
func (*ImportMigrationRepository) LinkQueueItemID ¶ added in v0.3.0
func (r *ImportMigrationRepository) LinkQueueItemID(ctx context.Context, source string, externalIDs []string, queueItemID int64) error
LinkQueueItemID sets queue_item_id for all migration rows matching (source, externalIDs). Unconditionally overwrites any existing queue_item_id so that re-imports after a cancelled/failed first attempt can re-link to the new queue item. This is safe because IsMigrationCompleted already short-circuits rows with status=imported before we get here.
func (*ImportMigrationRepository) ListByStatus ¶ added in v0.3.0
func (r *ImportMigrationRepository) ListByStatus(ctx context.Context, source string, status ImportMigrationStatus, limit, offset int) ([]*ImportMigration, error)
ListByStatus returns paginated rows for source with the given status.
func (*ImportMigrationRepository) LookupByExternalID ¶ added in v0.3.0
func (r *ImportMigrationRepository) LookupByExternalID(ctx context.Context, source, externalID string) (*ImportMigration, error)
LookupByExternalID returns the migration row for (source, external_id), or nil if not found.
func (*ImportMigrationRepository) MarkFailed ¶ added in v0.3.0
func (r *ImportMigrationRepository) MarkFailed(ctx context.Context, queueItemID int64, errMsg string) error
MarkFailed sets status=failed and error for all rows matching queue_item_id.
func (*ImportMigrationRepository) MarkImported ¶ added in v0.3.0
func (r *ImportMigrationRepository) MarkImported(ctx context.Context, queueItemID int64, finalPath string) error
MarkImported sets status=imported and final_path for all rows matching queue_item_id.
func (*ImportMigrationRepository) MarkSymlinksMigrated ¶ added in v0.3.0
func (r *ImportMigrationRepository) MarkSymlinksMigrated(ctx context.Context, ids []int64) error
MarkSymlinksMigrated sets status=symlinks_migrated for the given row IDs.
func (*ImportMigrationRepository) Stats ¶ added in v0.3.0
func (r *ImportMigrationRepository) Stats(ctx context.Context, source string) (*ImportMigrationStats, error)
Stats returns aggregate counts for a source.
func (*ImportMigrationRepository) Upsert ¶ added in v0.3.0
func (r *ImportMigrationRepository) Upsert(ctx context.Context, row *ImportMigration) (int64, error)
Upsert inserts or updates a migration row keyed by (source, external_id). Returns the row ID.
type ImportMigrationStats ¶ added in v0.3.0
type ImportMigrationStats struct {
Pending int
Imported int
Failed int
SymlinksMigrated int
Total int
}
ImportMigrationStats holds aggregate counts for a source
type ImportMigrationStatus ¶ added in v0.3.0
type ImportMigrationStatus string
ImportMigrationStatus represents the status of a migration item
const ( ImportMigrationStatusPending ImportMigrationStatus = "pending" ImportMigrationStatusImported ImportMigrationStatus = "imported" ImportMigrationStatusFailed ImportMigrationStatus = "failed" ImportMigrationStatusSymlinksMigrated ImportMigrationStatus = "symlinks_migrated" )
type ImportQueueItem ¶
type ImportQueueItem struct {
ID int64 `db:"id"`
DownloadID *string `db:"download_id"` // GUID/String ID for external tracking (e.g. Sonarr/Radarr)
NzbPath string `db:"nzb_path"`
RelativePath *string `db:"relative_path"`
StoragePath *string `db:"storage_path"`
Category *string `db:"category"` // SABnzbd-compatible category
Priority QueuePriority `db:"priority"`
Status QueueStatus `db:"status"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
StartedAt *time.Time `db:"started_at"`
CompletedAt *time.Time `db:"completed_at"`
RetryCount int `db:"retry_count"`
MaxRetries int `db:"max_retries"`
ErrorMessage *string `db:"error_message"`
BatchID *string `db:"batch_id"`
Metadata *string `db:"metadata"` // JSON metadata
FileSize *int64 `db:"file_size"` // Total size in bytes calculated from segments
TargetPath *string `db:"target_path"` // Optional forced symlink destination path
SkipArrNotification bool `db:"skip_arr_notification"`
SkipPostImportLinks bool `db:"skip_post_import_links"`
Indexer *string `db:"indexer"`
}
ImportQueueItem represents a queued NZB file waiting for import
type IndexerAggregatedHealth ¶ added in v0.3.0
type IndexerAggregatedHealth struct {
Indexer string `json:"indexer"`
TotalImports int `json:"total_imports"`
SuccessCount int `json:"success_count"`
FailedCount int `json:"failed_count"`
Last24hCount int `json:"last_24h_count"`
SuccessRate float64 `json:"success_rate"`
LastSeenAt time.Time `json:"last_seen_at"`
}
type ProviderHistoricalStat ¶ added in v0.3.0
type ProviderHistoricalStat struct {
Timestamp time.Time `db:"timestamp"`
ProviderID string `db:"provider_id"`
BytesDownloaded int64 `db:"bytes_downloaded"`
}
ProviderHistoricalStat represents aggregated data usage for a provider over a time period
type ProviderSpeedTestStat ¶ added in v0.3.0
type ProviderSpeedTestStat struct {
ID int64 `db:"id"`
ProviderID string `db:"provider_id"`
SpeedMbps float64 `db:"speed_mbps"`
CreatedAt time.Time `db:"created_at"`
}
ProviderSpeedTestStat represents a historical speed test result for a provider
type QueuePriority ¶
type QueuePriority int
QueuePriority represents the priority level of a queued import
const ( QueuePriorityHigh QueuePriority = 1 QueuePriorityNormal QueuePriority = 2 QueuePriorityLow QueuePriority = 3 )
type QueueRepository ¶
type QueueRepository struct {
// contains filtered or unexported fields
}
QueueRepository handles queue-specific database operations
func NewQueueRepository ¶
func NewQueueRepository(db *sql.DB, d Dialect) *QueueRepository
NewQueueRepository creates a new queue repository
func (*QueueRepository) AddBatchToQueue ¶
func (r *QueueRepository) AddBatchToQueue(ctx context.Context, items []*ImportQueueItem) error
AddBatchToQueue adds multiple items to the queue in a single transaction
func (*QueueRepository) AddImportHistory ¶
func (r *QueueRepository) AddImportHistory(ctx context.Context, history *ImportHistory) error
AddImportHistory records a successful file import in the persistent history table
func (*QueueRepository) AddStoragePath ¶
func (*QueueRepository) AddToQueue ¶
func (r *QueueRepository) AddToQueue(ctx context.Context, item *ImportQueueItem) error
AddToQueue adds a new NZB file to the import queue
func (*QueueRepository) ClaimNextQueueItem ¶
func (r *QueueRepository) ClaimNextQueueItem(ctx context.Context) (*ImportQueueItem, error)
ClaimNextQueueItem atomically claims and returns the next available queue item
func (*QueueRepository) ClearDailyStats ¶
func (r *QueueRepository) ClearDailyStats(ctx context.Context) error
ClearDailyStats deletes all records from the import_daily_stats, import_hourly_stats, and provider_hourly_stats tables
func (*QueueRepository) ClearHourlyStats ¶
func (r *QueueRepository) ClearHourlyStats(ctx context.Context) error
ClearHourlyStats deletes all records from the import_hourly_stats table
func (*QueueRepository) ClearImportHistory ¶
func (r *QueueRepository) ClearImportHistory(ctx context.Context) error
ClearImportHistory deletes all records from the import_history and import_daily_stats tables
func (*QueueRepository) ClearImportHistorySince ¶
ClearImportHistorySince deletes records from the import_history and import_queue tables since the specified time, and adjusts the import_daily_stats and import_hourly_stats accordingly.
func (*QueueRepository) ClearProviderHourlyStats ¶ added in v0.2.0
func (r *QueueRepository) ClearProviderHourlyStats(ctx context.Context) error
ClearProviderHourlyStats deletes all records from the provider_hourly_stats table
func (*QueueRepository) DeleteFailedItemsOlderThan ¶
func (r *QueueRepository) DeleteFailedItemsOlderThan(ctx context.Context, olderThan time.Time) ([]*ImportQueueItem, error)
DeleteFailedItemsOlderThan deletes failed queue items older than the given time. Returns the deleted items so the caller can clean up associated NZB files.
func (*QueueRepository) DeleteImportHistoryOlderThan ¶ added in v0.3.0
func (r *QueueRepository) DeleteImportHistoryOlderThan(ctx context.Context, olderThan time.Time) error
DeleteImportHistoryOlderThan deletes import_history records completed before olderThan.
func (*QueueRepository) DeleteIndexerStats ¶ added in v0.3.0
DeleteIndexerStats deletes all records for a specific indexer and returns the number of rows affected.
func (*QueueRepository) GetImportDailyStats ¶
func (r *QueueRepository) GetImportDailyStats(ctx context.Context, days int) ([]*ImportDailyStat, error)
GetImportDailyStats retrieves historical import statistics for the last N days
func (*QueueRepository) GetImportHistory ¶
func (r *QueueRepository) GetImportHistory(ctx context.Context, days int) ([]*ImportDailyStat, error)
GetImportHistory retrieves historical import statistics for the last N days (Alias for GetImportDailyStats)
func (*QueueRepository) GetImportHourlyStats ¶
func (r *QueueRepository) GetImportHourlyStats(ctx context.Context, hours int) ([]*ImportHourlyStat, error)
GetImportHourlyStats retrieves import statistics for the specified number of hours
func (*QueueRepository) GetIndexerHealthStats ¶ added in v0.3.0
func (r *QueueRepository) GetIndexerHealthStats(ctx context.Context) ([]*IndexerAggregatedHealth, error)
GetIndexerHealthStats aggregates all historical records to calculate success/failure rates.
func (*QueueRepository) GetPendingQueueItemsByPathPrefix ¶ added in v0.3.0
func (r *QueueRepository) GetPendingQueueItemsByPathPrefix(ctx context.Context, prefix string) ([]*ImportQueueItem, error)
GetPendingQueueItemsByPathPrefix returns pending queue items whose nzb_path starts with prefix.
func (*QueueRepository) GetQueueItem ¶
func (r *QueueRepository) GetQueueItem(ctx context.Context, id int64) (*ImportQueueItem, error)
GetQueueItem retrieves a specific queue item by ID
func (*QueueRepository) GetQueueItemByDownloadID ¶ added in v0.3.0
func (r *QueueRepository) GetQueueItemByDownloadID(ctx context.Context, downloadID string) (*ImportQueueItem, error)
GetQueueItemByDownloadID retrieves a queue item by its DownloadID
func (*QueueRepository) GetQueueItemByNzbPath ¶ added in v0.3.0
func (r *QueueRepository) GetQueueItemByNzbPath(ctx context.Context, nzbPath string) (*ImportQueueItem, error)
GetQueueItemByNzbPath returns the queue item with the given NZB path, or nil if not found.
func (*QueueRepository) GetQueueStats ¶
func (r *QueueRepository) GetQueueStats(ctx context.Context) (*QueueStats, error)
GetQueueStats returns current queue statistics
func (*QueueRepository) GetUnknownIndexerStatsDownloadIDs ¶ added in v0.3.0
func (r *QueueRepository) GetUnknownIndexerStatsDownloadIDs(ctx context.Context) ([]string, error)
func (*QueueRepository) IncrementDailyStat ¶
func (r *QueueRepository) IncrementDailyStat(ctx context.Context, statType string) error
IncrementDailyStat increments the completed or failed count for the current day
func (*QueueRepository) IncrementHourlyStat ¶
func (r *QueueRepository) IncrementHourlyStat(ctx context.Context, statType string) error
IncrementHourlyStat increments the completed or failed count for the current hour
func (*QueueRepository) IncrementRetryCountAndResetStatus ¶
func (r *QueueRepository) IncrementRetryCountAndResetStatus(ctx context.Context, id int64, errorMessage *string) (bool, error)
IncrementRetryCountAndResetStatus increments the retry count and resets the status to pending
func (*QueueRepository) IsFileInQueue ¶
IsFileInQueue checks if a file is already in the queue (pending, processing, or paused). It matches by exact nzb_path first, and also by filename suffix to handle the case where ensurePersistentNzb has already moved the file and updated nzb_path from the temp path to the persistent storage path (e.g. /tmp/altmount-uploads/x.nzb → /.nzbs/stremio/42-x.nzb). The LIKE pattern uses "%-filename" (dash wildcard) rather than "%/filename" so it also matches the "<id>-<base>.nzb" naming that ensurePersistentNzb applies on collision.
func (*QueueRepository) ListImportHistory ¶
func (r *QueueRepository) ListImportHistory(ctx context.Context, limit int) ([]*ImportHistory, error)
ListImportHistory retrieves the last N successful imports from the persistent history
func (*QueueRepository) LogIndexerImport ¶ added in v0.3.0
func (r *QueueRepository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, downloadID string) error
LogIndexerImport records a success or failure for an indexer persistently.
func (*QueueRepository) PruneIndexerStats ¶ added in v0.3.0
PruneIndexerStats deletes records that were created within the last N hours.
func (*QueueRepository) RemoveFromQueue ¶
func (r *QueueRepository) RemoveFromQueue(ctx context.Context, id int64) error
RemoveFromQueue removes an item from the queue
func (*QueueRepository) RemoveFromQueueBulk ¶
func (r *QueueRepository) RemoveFromQueueBulk(ctx context.Context, ids []int64) (*BulkOperationResult, error)
RemoveFromQueueBulk removes multiple items from the queue in bulk
func (*QueueRepository) ResetStaleItems ¶
func (r *QueueRepository) ResetStaleItems(ctx context.Context) error
ResetStaleItems resets processing items back to pending on service startup
func (*QueueRepository) RestartQueueItemsBulk ¶
func (r *QueueRepository) RestartQueueItemsBulk(ctx context.Context, ids []int64) error
RestartQueueItemsBulk resets multiple queue items back to pending status
func (*QueueRepository) UpdateImportHistoryIndexerByDownloadID ¶ added in v0.3.0
func (*QueueRepository) UpdateIndexerStatsByDownloadID ¶ added in v0.3.0
func (*QueueRepository) UpdateQueueItemCategory ¶ added in v0.3.0
func (r *QueueRepository) UpdateQueueItemCategory(ctx context.Context, id int64, category *string, priority QueuePriority) error
UpdateQueueItemCategory updates the category and priority of a queue item.
func (*QueueRepository) UpdateQueueItemIndexer ¶ added in v0.3.0
func (r *QueueRepository) UpdateQueueItemIndexer(ctx context.Context, id int64, indexer string) error
UpdateQueueItemIndexer updates the indexer for a queue item by its ID
func (*QueueRepository) UpdateQueueItemIndexerByDownloadID ¶ added in v0.3.0
func (r *QueueRepository) UpdateQueueItemIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
UpdateQueueItemIndexerByDownloadID updates the indexer for a queue item by its DownloadID
func (*QueueRepository) UpdateQueueItemNzbPath ¶
func (r *QueueRepository) UpdateQueueItemNzbPath(ctx context.Context, id int64, nzbPath string) error
UpdateQueueItemNzbPath updates the NZB path of a queue item
func (*QueueRepository) UpdateQueueItemPriority ¶
func (r *QueueRepository) UpdateQueueItemPriority(ctx context.Context, id int64, priority QueuePriority) error
UpdateQueueItemPriority updates the priority of a queue item
func (*QueueRepository) UpdateQueueItemStatus ¶
func (r *QueueRepository) UpdateQueueItemStatus(ctx context.Context, id int64, status QueueStatus, errorMessage *string) error
UpdateQueueItemStatus updates the status of a queue item
type QueueStats ¶
type QueueStats struct {
ID int64 `db:"id"`
TotalQueued int `db:"total_queued"`
TotalProcessing int `db:"total_processing"`
TotalCompleted int `db:"total_completed"`
TotalFailed int `db:"total_failed"`
AvgProcessingTimeMs *int `db:"avg_processing_time_ms"`
LastUpdated time.Time `db:"last_updated"`
}
QueueStats represents statistics about the import queue
type QueueStatus ¶
type QueueStatus string
QueueStatus represents the status of a queued import
const ( QueueStatusPending QueueStatus = "pending" QueueStatusProcessing QueueStatus = "processing" QueueStatusCompleted QueueStatus = "completed" QueueStatusFailed QueueStatus = "failed" QueueStatusPaused QueueStatus = "paused" QueueStatusFallback QueueStatus = "fallback" // Sent to external SABnzbd as fallback )
type Repository ¶
type Repository struct {
// contains filtered or unexported fields
}
Repository provides database operations for NZB and file management
func NewRepository ¶
func NewRepository(db *sql.DB, d Dialect) *Repository
NewRepository creates a new repository instance
func (*Repository) AddBatchToQueue ¶
func (r *Repository) AddBatchToQueue(ctx context.Context, items []*ImportQueueItem) error
AddBatchToQueue adds multiple items to the queue in a single transaction for better performance
func (*Repository) AddBytesDownloadedToDailyStat ¶
func (r *Repository) AddBytesDownloadedToDailyStat(ctx context.Context, bytes int64) error
AddBytesDownloadedToDailyStat increments the bytes_downloaded counter for the current day
func (*Repository) AddBytesDownloadedToHourlyStat ¶
func (r *Repository) AddBytesDownloadedToHourlyStat(ctx context.Context, bytes int64) error
AddBytesDownloadedToHourlyStat increments the bytes_downloaded counter for the current hour
func (*Repository) AddImportHistory ¶
func (r *Repository) AddImportHistory(ctx context.Context, history *ImportHistory) error
AddImportHistory records a successful file import in the persistent history table
func (*Repository) AddProviderBytesToHourlyStat ¶ added in v0.2.0
func (r *Repository) AddProviderBytesToHourlyStat(ctx context.Context, providerID string, bytes int64) error
AddProviderBytesToHourlyStat adds bytes downloaded to the current hour's stat for a specific provider
func (*Repository) AddToQueue ¶
func (r *Repository) AddToQueue(ctx context.Context, item *ImportQueueItem) error
AddToQueue adds an NZB file to the import queue with optimized concurrency
func (*Repository) BatchUpdateSystemStats ¶
BatchUpdateSystemStats updates multiple system statistics in a single transaction
func (*Repository) ClaimNextQueueItem ¶
func (r *Repository) ClaimNextQueueItem(ctx context.Context) (*ImportQueueItem, error)
ClaimNextQueueItem atomically claims and returns the next available queue item This prevents multiple workers from processing the same item Uses a single atomic UPDATE...RETURNING query to eliminate race conditions
func (*Repository) ClearCompletedQueueItems ¶
ClearCompletedQueueItems removes completed items from the queue and returns the paths of deleted rows.
func (*Repository) ClearDailyStats ¶
func (r *Repository) ClearDailyStats(ctx context.Context) error
ClearDailyStats deletes all records from the import_daily_stats, import_hourly_stats, and provider_hourly_stats tables
func (*Repository) ClearDailyStatsSince ¶
ClearDailyStatsSince deletes records from the import_daily_stats table since the specified time
func (*Repository) ClearFailedQueueItems ¶
ClearFailedQueueItems removes failed items from the queue and returns the paths of deleted rows.
func (*Repository) ClearHourlyStats ¶
func (r *Repository) ClearHourlyStats(ctx context.Context) error
ClearHourlyStats deletes all records from the import_hourly_stats table
func (*Repository) ClearHourlyStatsSince ¶
ClearHourlyStatsSince deletes records from the import_hourly_stats table since the specified time
func (*Repository) ClearImportHistory ¶
func (r *Repository) ClearImportHistory(ctx context.Context) error
ClearImportHistory deletes all records from the import_history and import_daily_stats tables
func (*Repository) ClearImportHistorySince ¶
ClearImportHistorySince deletes records from the import_history and import_queue tables since the specified time, and adjusts the import_daily_stats accordingly.
func (*Repository) ClearPendingQueueItems ¶
ClearPendingQueueItems removes pending items from the queue and returns the paths of deleted rows.
func (*Repository) ClearProviderHourlyStats ¶ added in v0.2.0
func (r *Repository) ClearProviderHourlyStats(ctx context.Context) error
ClearProviderHourlyStats deletes all records from the provider_hourly_stats table
func (*Repository) CountActiveQueueItems ¶
func (r *Repository) CountActiveQueueItems(ctx context.Context, search string, category string) (int, error)
CountActiveQueueItems counts the total number of pending and processing queue items
func (*Repository) CountQueueItems ¶
func (r *Repository) CountQueueItems(ctx context.Context, status *QueueStatus, search string, category string) (int, error)
CountQueueItems counts the total number of queue items matching the given filters
func (*Repository) DeleteIndexerStats ¶ added in v0.3.0
DeleteIndexerStats deletes all records for a specific indexer and returns the number of rows affected.
func (*Repository) DeleteQueueItemsByPath ¶ added in v0.3.0
func (r *Repository) DeleteQueueItemsByPath(ctx context.Context, path string) error
DeleteQueueItemsByPath removes items from the queue matching the given path
func (*Repository) GetExpiredStremioQueueItems ¶
func (r *Repository) GetExpiredStremioQueueItems(ctx context.Context, ttlHours int) ([]*ImportQueueItem, error)
GetExpiredStremioQueueItems returns completed Stremio queue items whose completed_at is older than ttlHours. Items are identified as Stremio-originated by their download_id having the "stremio:" prefix set when the addon enqueues an import.
func (*Repository) GetImportDailyStats ¶
func (r *Repository) GetImportDailyStats(ctx context.Context, days int) ([]*ImportDailyStat, error)
GetImportDailyStats retrieves import statistics for the specified number of days
func (*Repository) GetImportHistory ¶
func (r *Repository) GetImportHistory(ctx context.Context, days int) ([]*ImportDailyStat, error)
GetImportHistory retrieves historical import statistics for the last N days (Alias for GetImportDailyStats)
func (*Repository) GetImportHistoryByDownloadID ¶ added in v0.2.0
func (r *Repository) GetImportHistoryByDownloadID(ctx context.Context, downloadID string) (*ImportHistory, error)
GetImportHistoryByDownloadID retrieves an import history item by its DownloadID
func (*Repository) GetImportHistoryByNzbID ¶ added in v0.3.0
func (r *Repository) GetImportHistoryByNzbID(ctx context.Context, nzbID int64) (*ImportHistory, error)
GetImportHistoryByNzbID retrieves an import history item by its original NZB ID (the integer ID of the queue row that produced this history entry). Returns (nil, nil) when no matching row exists.
func (*Repository) GetImportHistoryByPath ¶
func (r *Repository) GetImportHistoryByPath(ctx context.Context, virtualPath string) (*ImportHistory, error)
GetImportHistoryByPath retrieves an import history item by its virtual path
func (*Repository) GetImportHistoryItem ¶ added in v0.2.0
func (r *Repository) GetImportHistoryItem(ctx context.Context, id int64) (*ImportHistory, error)
GetImportHistoryItem retrieves a specific import history item by ID
func (*Repository) GetImportHourlyStats ¶
func (r *Repository) GetImportHourlyStats(ctx context.Context, hours int) ([]*ImportHourlyStat, error)
GetImportHourlyStats retrieves import statistics for the specified number of hours
func (*Repository) GetIndexerHealthStats ¶ added in v0.3.0
func (r *Repository) GetIndexerHealthStats(ctx context.Context) ([]*IndexerAggregatedHealth, error)
GetIndexerHealthStats aggregates all historical records to calculate success/failure rates.
func (*Repository) GetOldestProviderStatDates ¶ added in v0.3.0
GetOldestProviderStatDates returns the date of the oldest record per provider in provider_hourly_stats
func (*Repository) GetOldestStatDate ¶ added in v0.3.0
GetOldestStatDate returns the date of the oldest record in import_daily_stats or import_history
func (*Repository) GetProviderHistoricalStats ¶ added in v0.3.0
func (r *Repository) GetProviderHistoricalStats(ctx context.Context, days int, interval string) ([]*ProviderHistoricalStat, error)
GetProviderHistoricalStats retrieves aggregated data usage per provider over the given number of days. The data is grouped by the specified interval.
func (*Repository) GetProviderHourlyStats ¶ added in v0.2.0
func (r *Repository) GetProviderHourlyStats(ctx context.Context, hours int) (map[string]int64, error)
GetProviderHourlyStats retrieves provider download statistics for the last N hours
func (*Repository) GetProviderSpeedTestHistory ¶ added in v0.3.0
func (r *Repository) GetProviderSpeedTestHistory(ctx context.Context, days int) ([]*ProviderSpeedTestStat, error)
GetProviderSpeedTestHistory retrieves the speed test history over the given number of days
func (*Repository) GetQueueItem ¶
func (r *Repository) GetQueueItem(ctx context.Context, id int64) (*ImportQueueItem, error)
GetQueueItem retrieves a specific queue item by ID
func (*Repository) GetQueueItemByDownloadID ¶ added in v0.2.0
func (r *Repository) GetQueueItemByDownloadID(ctx context.Context, downloadID string) (*ImportQueueItem, error)
GetQueueItemByDownloadID retrieves a queue item by its DownloadID
func (*Repository) GetQueueStats ¶
func (r *Repository) GetQueueStats(ctx context.Context) (*QueueStats, error)
GetQueueStats retrieves current queue statistics
func (*Repository) GetSystemState ¶
GetSystemState retrieves a system state string by key
func (*Repository) GetSystemStats ¶
GetSystemStats retrieves all system statistics as a map
func (*Repository) GetUnknownIndexerStatsDownloadIDs ¶ added in v0.3.0
func (r *Repository) GetUnknownIndexerStatsDownloadIDs(ctx context.Context) ([]string, error)
GetUnknownIndexerStatsDownloadIDs gets all unique download_ids that have indexer = 'Unknown' in the stats table.
func (*Repository) HasActiveOrRecentQueueItemForStoragePath ¶ added in v0.3.0
func (r *Repository) HasActiveOrRecentQueueItemForStoragePath( ctx context.Context, relPath string, completedGrace time.Duration, ) (bool, error)
HasActiveOrRecentQueueItemForStoragePath reports whether any import_queue row references a storage_path equal to (or nested under) the given relative path and is either still active (pending/processing/paused/retrying) or was completed within the supplied grace window. It is used to guard against arr webhook directory deletions racing a sibling import that just wrote into the same release folder.
relPath is matched as a path prefix; both "<relPath>" and "/<relPath>" are considered (storage_path is typically absolute, e.g. "/moviesHQ/release/...", while webhook-normalized paths are relative).
func (*Repository) IncrementDailyStat ¶
func (r *Repository) IncrementDailyStat(ctx context.Context, statType string) error
IncrementDailyStat increments the completed or failed count for the current day
func (*Repository) IncrementHourlyStat ¶
func (r *Repository) IncrementHourlyStat(ctx context.Context, statType string) error
IncrementHourlyStat increments the completed or failed count for the current hour
func (*Repository) IsFileInQueue ¶
IsFileInQueue checks if a file is already in the queue (pending or processing)
func (*Repository) ListActiveQueueItems ¶
func (r *Repository) ListActiveQueueItems(ctx context.Context, search string, category string, limit, offset int, sortBy, sortOrder string) ([]*ImportQueueItem, error)
ListActiveQueueItems retrieves pending and processing queue items
func (*Repository) ListImportHistory ¶
func (r *Repository) ListImportHistory(ctx context.Context, limit, offset int, search string, category string) ([]*ImportHistory, error)
ListImportHistory retrieves import history items with optional filtering and pagination
func (*Repository) ListQueueItems ¶
func (r *Repository) ListQueueItems(ctx context.Context, status *QueueStatus, search string, category string, limit, offset int, sortBy, sortOrder string) ([]*ImportQueueItem, error)
ListQueueItems retrieves queue items with optional filtering
func (*Repository) ListRecentImportHistory ¶
func (r *Repository) ListRecentImportHistory(ctx context.Context, minutes int, category string) ([]*ImportHistory, error)
ListRecentImportHistory retrieves import history items completed within the last N minutes.
func (*Repository) LogIndexerImport ¶ added in v0.3.0
func (r *Repository) LogIndexerImport(ctx context.Context, indexer string, status string, errMsg string, downloadID string) error
LogIndexerImport records a success or failure for an indexer persistently.
func (*Repository) PruneIndexerStats ¶ added in v0.3.0
PruneIndexerStats deletes records that were created within the last N hours.
func (*Repository) RecordProviderSpeedTest ¶ added in v0.3.0
func (r *Repository) RecordProviderSpeedTest(ctx context.Context, providerID string, speedMbps float64) error
RecordProviderSpeedTest saves a speed test result for a provider
func (*Repository) RemoveFromHistory ¶
RemoveFromHistory removes a record from import_history by its own ID
func (*Repository) RemoveFromHistoryByDownloadID ¶ added in v0.2.0
func (r *Repository) RemoveFromHistoryByDownloadID(ctx context.Context, downloadID string) (int64, error)
RemoveFromHistoryByDownloadID removes a record from import_history by its DownloadID
func (*Repository) RemoveFromHistoryByNzbID ¶
RemoveFromHistoryByNzbID removes a record from import_history by its original NZB ID
func (*Repository) RemoveFromQueue ¶
func (r *Repository) RemoveFromQueue(ctx context.Context, id int64) error
RemoveFromQueue removes an item from the queue
func (*Repository) RemoveFromQueueBulk ¶
func (r *Repository) RemoveFromQueueBulk(ctx context.Context, ids []int64) (*BulkOperationResult, error)
RemoveFromQueueBulk removes multiple items from the queue, excluding those currently being processed
func (*Repository) RemoveFromQueueByDownloadID ¶ added in v0.2.0
func (r *Repository) RemoveFromQueueByDownloadID(ctx context.Context, downloadID string) error
RemoveFromQueueByDownloadID removes an item from the queue by its DownloadID
func (*Repository) RestartQueueItemsBulk ¶
func (r *Repository) RestartQueueItemsBulk(ctx context.Context, ids []int64) error
RestartQueueItemsBulk resets multiple queue items to pending status for reprocessing
func (*Repository) UpdateImportHistoryIndexerByDownloadID ¶ added in v0.3.0
func (r *Repository) UpdateImportHistoryIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
UpdateImportHistoryIndexerByDownloadID updates the indexer for an import history item by its DownloadID
func (*Repository) UpdateIndexerStatsByDownloadID ¶ added in v0.3.0
func (r *Repository) UpdateIndexerStatsByDownloadID(ctx context.Context, downloadID string, indexer string) error
UpdateIndexerStatsByDownloadID updates the indexer for a success or failure record in indexer_import_stats by its DownloadID
func (*Repository) UpdateQueueItemIndexer ¶ added in v0.3.0
UpdateQueueItemIndexer updates the indexer for a queue item by its ID
func (*Repository) UpdateQueueItemIndexerByDownloadID ¶ added in v0.3.0
func (r *Repository) UpdateQueueItemIndexerByDownloadID(ctx context.Context, downloadID string, indexer string) error
UpdateQueueItemIndexerByDownloadID updates the indexer for a queue item by its DownloadID
func (*Repository) UpdateQueueItemPriority ¶
func (r *Repository) UpdateQueueItemPriority(ctx context.Context, id int64, priority QueuePriority) error
UpdateQueueItemPriority updates the priority of a queue item
func (*Repository) UpdateQueueItemStatus ¶
func (r *Repository) UpdateQueueItemStatus(ctx context.Context, id int64, status QueueStatus, errorMessage *string) error
UpdateQueueItemStatus updates the status of a queue item
func (*Repository) UpdateQueueItemsPriorityBulk ¶ added in v0.3.0
func (r *Repository) UpdateQueueItemsPriorityBulk(ctx context.Context, ids []int64, priority QueuePriority) (updated int, skipped int, err error)
UpdateQueueItemsPriorityBulk updates the priority of multiple queue items, skipping any that are currently processing. Returns the number of items updated and the number skipped.
func (*Repository) UpdateQueueStats ¶
func (r *Repository) UpdateQueueStats(ctx context.Context) error
UpdateQueueStats updates queue statistics based on current queue state
func (*Repository) UpdateSystemStat ¶
UpdateSystemStat updates or inserts a single system statistic
func (*Repository) UpdateSystemState ¶
UpdateSystemState updates a system state string (JSON) by key
func (*Repository) WithImmediateTransaction ¶
func (r *Repository) WithImmediateTransaction(ctx context.Context, fn func(*Repository) error) error
WithImmediateTransaction executes a function within an immediate database transaction This reduces lock contention for queue operations by acquiring write locks immediately Uses SQLite's IMMEDIATE transaction mode via BeginTx with Serializable isolation
func (*Repository) WithTransaction ¶
func (r *Repository) WithTransaction(ctx context.Context, fn func(*Repository) error) error
WithTransaction executes a function within a database transaction
type StoreRefRepository ¶ added in v0.3.0
type StoreRefRepository struct {
// contains filtered or unexported fields
}
StoreRefRepository tracks reference counts on .nzbz store files. When all .meta files that reference a given store are deleted, the refcount hits 0 and the caller can delete the store file.
func NewStoreRefRepository ¶ added in v0.3.0
func NewStoreRefRepository(db *sql.DB, d Dialect) *StoreRefRepository
NewStoreRefRepository creates a new StoreRefRepository.
func (*StoreRefRepository) DecStoreRef ¶ added in v0.3.0
DecStoreRef decrements the ref_count for storePath by 1. If the resulting count is ≤ 0, the row is deleted and 0 is returned. Returns the new count (0 if the row was deleted or did not exist).
func (*StoreRefRepository) GetStoreRefCount ¶ added in v0.3.0
GetStoreRefCount returns the current ref_count for storePath. Returns 0 (and no error) if the row does not exist.
func (*StoreRefRepository) IncStoreRef ¶ added in v0.3.0
func (r *StoreRefRepository) IncStoreRef(ctx context.Context, storePath string) error
IncStoreRef increments the ref_count for storePath by 1. If no row exists yet, it inserts one with ref_count = 1.
type UpdateType ¶
type UpdateType int
UpdateType represents the type of health update
const ( UpdateTypeHealthy UpdateType = 1 UpdateTypeRetry UpdateType = 2 UpdateTypeRepairRetry UpdateType = 3 // re-check of an already-triggered repair; increments repair_retry_count UpdateTypeCorrupted UpdateType = 4 UpdateTypeRepairTrigger UpdateType = 5 // first-time trigger; does not increment repair_retry_count UpdateTypeDegraded UpdateType = 6 // playable with glitches; no repair, periodic re-check )
type User ¶
type User struct {
ID int64 `db:"id"`
UserID string `db:"user_id"` // Unique identifier from auth provider
Email *string `db:"email"` // User email address (nullable)
Name *string `db:"name"` // User display name (nullable)
AvatarURL *string `db:"avatar_url"` // User avatar image URL (nullable)
Provider string `db:"provider"` // Auth provider (direct, github, google, dev, etc.)
ProviderID *string `db:"provider_id"` // Provider-specific user ID (nullable)
PasswordHash *string `db:"password_hash"` // Bcrypt password hash for direct auth (nullable)
APIKey *string `db:"api_key"` // API key for user authentication (nullable)
IsAdmin bool `db:"is_admin"` // Admin privileges flag
CreatedAt time.Time `db:"created_at"` // Account creation timestamp
UpdatedAt time.Time `db:"updated_at"` // Last profile update timestamp
LastLogin *time.Time `db:"last_login"` // Last login timestamp (nullable)
}
User represents a user account in the system
type UserRepository ¶
type UserRepository struct {
// contains filtered or unexported fields
}
UserRepository handles user database operations
func NewUserRepository ¶
func NewUserRepository(db *sql.DB, d Dialect) *UserRepository
NewUserRepository creates a new user repository
func (*UserRepository) CreateUser ¶
func (r *UserRepository) CreateUser(ctx context.Context, user *User) error
CreateUser creates a new user account
func (*UserRepository) GetAllUsers ¶
func (r *UserRepository) GetAllUsers(ctx context.Context) ([]*User, error)
GetAllUsers retrieves all users with API keys for authentication purposes
func (*UserRepository) GetUserByAPIKey ¶
GetUserByAPIKey retrieves a user by their API key
func (*UserRepository) GetUserByEmail ¶
GetUserByEmail retrieves a user by their email address for direct authentication
func (*UserRepository) GetUserByID ¶
GetUserByID retrieves a user by their unique user ID
func (*UserRepository) GetUserByProvider ¶
func (r *UserRepository) GetUserByProvider(ctx context.Context, provider, providerID string) (*User, error)
GetUserByProvider retrieves a user by provider and provider ID
func (*UserRepository) GetUserByUsername ¶
GetUserByUsername retrieves a user by their username (user_id) for direct authentication
func (*UserRepository) GetUserCount ¶
func (r *UserRepository) GetUserCount(ctx context.Context) (int, error)
GetUserCount returns the total number of users
func (*UserRepository) RegenerateAPIKey ¶
RegenerateAPIKey generates and updates a new API key for the user
func (*UserRepository) UpdateLastLogin ¶
func (r *UserRepository) UpdateLastLogin(ctx context.Context, userID string) error
UpdateLastLogin updates the user's last login timestamp
func (*UserRepository) UpdatePassword ¶
func (r *UserRepository) UpdatePassword(ctx context.Context, userID string, passwordHash string) error
UpdatePassword updates a user's password hash