pattern.go
package cmd
import (
"context"
"flag"
"fmt"
"strconv"
"skraak/tools"
)
// RunPatternCreate creates a new cyclic recording pattern.
//
// JSON output schema:
//
// {
// "pattern": {
// "id": string, // Pattern ID (12 characters)
// "record_s": int, // Record duration in seconds
// "sleep_s": int, // Sleep duration in seconds
// "created_at": string, // Creation timestamp (RFC3339)
// "last_modified": string, // Last modification timestamp (RFC3339)
// "active": bool // Whether the pattern is active
// },
// "message": string // Success message
// }
func RunPatternCreate(args []string) error {
fs := flag.NewFlagSet("pattern create", flag.ExitOnError)
dbPath := fs.String("db", "", "Path to DuckDB database (required)")
record := fs.Int("record", 0, "Record duration in seconds (required, must be positive)")
sleep := fs.Int("sleep", 0, "Sleep duration in seconds (required, must be positive)")
fs.Usage = usagePrinter(fs,
"skraak pattern create [options]",
"Create a new cyclic recording pattern.",
"skraak pattern create --db ./db/skraak.duckdb --record 60 --sleep 1740",
"# Creates 60s record / 1740s sleep = 30 min cycle",
)
if err := fs.Parse(args); err != nil {
return fmt.Errorf("parsing flags: %w", err)
}
if err := requireFlags(fs, map[string]any{
"--db": *dbPath,
"--record": *record,
"--sleep": *sleep,
}); err != nil {
return err
}
defer initEventLog(*dbPath)()
input := tools.PatternInput{
DBPath: *dbPath,
RecordSeconds: record,
SleepSeconds: sleep,
}
output, err := tools.CreateOrUpdatePattern(context.Background(), input)
if err != nil {
return fmt.Errorf("creating pattern: %w", err)
}
return printJSON(output)
}
// RunPatternUpdate updates an existing recording pattern.
//
// JSON output schema: same as RunPatternCreate
func RunPatternUpdate(args []string) error {
fs := flag.NewFlagSet("pattern update", flag.ExitOnError)
dbPath := fs.String("db", "", "Path to DuckDB database (required)")
id := fs.String("id", "", "Pattern ID (required)")
recordStr := fs.String("record", "", "New record duration in seconds (optional)")
sleepStr := fs.String("sleep", "", "New sleep duration in seconds (optional)")
fs.Usage = usagePrinter(fs,
"skraak pattern update [options]",
"Update an existing recording pattern. Only provided fields are updated.",
"skraak pattern update --db ./db/skraak.duckdb --id pattern123 --record 30",
)
if err := fs.Parse(args); err != nil {
return fmt.Errorf("parsing flags: %w", err)
}
if err := requireFlags(fs, map[string]any{"--db": *dbPath, "--id": *id}); err != nil {
return err
}
var record, sleep *int
if *recordStr != "" {
r, err := strconv.Atoi(*recordStr)
if err != nil {
return fmt.Errorf("invalid record value: %w", err)
}
record = &r
}
if *sleepStr != "" {
s, err := strconv.Atoi(*sleepStr)
if err != nil {
return fmt.Errorf("invalid sleep value: %w", err)
}
sleep = &s
}
defer initEventLog(*dbPath)()
input := tools.PatternInput{
DBPath: *dbPath,
ID: id,
}
if record != nil {
input.RecordSeconds = record
}
if sleep != nil {
input.SleepSeconds = sleep
}
output, err := tools.CreateOrUpdatePattern(context.Background(), input)
if err != nil {
return fmt.Errorf("updating pattern: %w", err)
}
return printJSON(output)
}