- Add gocron/v2 v2.19.1 as direct dependency - Append subscribers and scheduled_jobs CREATE TABLE to schema.sql - Implement full subscriber CRUD (Add/Remove/List/IsSubscribed) - Implement full scheduled job CRUD (Save/List/Get/Delete/UpdateLastRun/SetEnabled)
112 lines
3.0 KiB
Go
112 lines
3.0 KiB
Go
package storage
|
|
|
|
import (
|
|
"database/sql"
|
|
"time"
|
|
)
|
|
|
|
// ScheduledJob represents a cron-based scheduled scan job.
|
|
type ScheduledJob struct {
|
|
ID int64
|
|
Name string
|
|
CronExpr string
|
|
ScanCommand string
|
|
NotifyTelegram bool
|
|
Enabled bool
|
|
LastRun *time.Time
|
|
NextRun *time.Time
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// SaveScheduledJob inserts a new scheduled job. Returns the new row ID.
|
|
func (db *DB) SaveScheduledJob(j ScheduledJob) (int64, error) {
|
|
res, err := db.sql.Exec(
|
|
`INSERT INTO scheduled_jobs (name, cron_expr, scan_command, notify_telegram, enabled)
|
|
VALUES (?, ?, ?, ?, ?)`,
|
|
j.Name, j.CronExpr, j.ScanCommand, j.NotifyTelegram, j.Enabled,
|
|
)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return res.LastInsertId()
|
|
}
|
|
|
|
// ListScheduledJobs returns all scheduled jobs.
|
|
func (db *DB) ListScheduledJobs() ([]ScheduledJob, error) {
|
|
rows, err := db.sql.Query(
|
|
`SELECT id, name, cron_expr, scan_command, notify_telegram, enabled, last_run, next_run, created_at
|
|
FROM scheduled_jobs ORDER BY id`,
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var jobs []ScheduledJob
|
|
for rows.Next() {
|
|
var j ScheduledJob
|
|
var lastRun, nextRun sql.NullTime
|
|
if err := rows.Scan(&j.ID, &j.Name, &j.CronExpr, &j.ScanCommand,
|
|
&j.NotifyTelegram, &j.Enabled, &lastRun, &nextRun, &j.CreatedAt); err != nil {
|
|
return nil, err
|
|
}
|
|
if lastRun.Valid {
|
|
j.LastRun = &lastRun.Time
|
|
}
|
|
if nextRun.Valid {
|
|
j.NextRun = &nextRun.Time
|
|
}
|
|
jobs = append(jobs, j)
|
|
}
|
|
return jobs, rows.Err()
|
|
}
|
|
|
|
// GetScheduledJob returns a single scheduled job by name.
|
|
func (db *DB) GetScheduledJob(name string) (*ScheduledJob, error) {
|
|
var j ScheduledJob
|
|
var lastRun, nextRun sql.NullTime
|
|
err := db.sql.QueryRow(
|
|
`SELECT id, name, cron_expr, scan_command, notify_telegram, enabled, last_run, next_run, created_at
|
|
FROM scheduled_jobs WHERE name = ?`, name,
|
|
).Scan(&j.ID, &j.Name, &j.CronExpr, &j.ScanCommand,
|
|
&j.NotifyTelegram, &j.Enabled, &lastRun, &nextRun, &j.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if lastRun.Valid {
|
|
j.LastRun = &lastRun.Time
|
|
}
|
|
if nextRun.Valid {
|
|
j.NextRun = &nextRun.Time
|
|
}
|
|
return &j, nil
|
|
}
|
|
|
|
// DeleteScheduledJob removes a scheduled job by name. Returns rows affected.
|
|
func (db *DB) DeleteScheduledJob(name string) (int64, error) {
|
|
res, err := db.sql.Exec(`DELETE FROM scheduled_jobs WHERE name = ?`, name)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return res.RowsAffected()
|
|
}
|
|
|
|
// UpdateJobLastRun updates the last_run and next_run timestamps for a job.
|
|
func (db *DB) UpdateJobLastRun(name string, lastRun time.Time, nextRun *time.Time) error {
|
|
var nr sql.NullTime
|
|
if nextRun != nil {
|
|
nr = sql.NullTime{Time: *nextRun, Valid: true}
|
|
}
|
|
_, err := db.sql.Exec(
|
|
`UPDATE scheduled_jobs SET last_run = ?, next_run = ? WHERE name = ?`,
|
|
lastRun, nr, name,
|
|
)
|
|
return err
|
|
}
|
|
|
|
// SetJobEnabled updates the enabled flag for a scheduled job.
|
|
func (db *DB) SetJobEnabled(name string, enabled bool) error {
|
|
_, err := db.sql.Exec(`UPDATE scheduled_jobs SET enabled = ? WHERE name = ?`, enabled, name)
|
|
return err
|
|
}
|