feat(17-02): add gocron dependency, subscribers and scheduled_jobs tables with CRUD
- 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)
This commit is contained in:
111
pkg/storage/scheduled_jobs.go
Normal file
111
pkg/storage/scheduled_jobs.go
Normal file
@@ -0,0 +1,111 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user