182 lines
4.8 KiB
Go
182 lines
4.8 KiB
Go
package main
|
||
|
||
// pack_store.go:打包任务与控制台日志的本地 SQLite 持久化(不同步云端)。
|
||
|
||
import (
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
packTaskKeepLimit = 100
|
||
packLogKeepLimit = 2000
|
||
)
|
||
|
||
func (s *Store) markInterruptedPackTasks() {
|
||
now := time.Now().Format(time.RFC3339)
|
||
rows, e := s.db.Query(`SELECT id FROM pack_tasks WHERE status='running'`)
|
||
if e != nil {
|
||
return
|
||
}
|
||
var ids []string
|
||
for rows.Next() {
|
||
var id string
|
||
if rows.Scan(&id) == nil && id != "" {
|
||
ids = append(ids, id)
|
||
}
|
||
}
|
||
_ = rows.Close()
|
||
if len(ids) == 0 {
|
||
return
|
||
}
|
||
_, _ = s.db.Exec(`UPDATE pack_tasks SET status='failed', error=?, ended_at=? WHERE status='running'`,
|
||
"应用退出,任务中断", now)
|
||
for _, id := range ids {
|
||
_, _ = s.db.Exec(`INSERT INTO pack_task_logs(task_id,line,created_at) VALUES(?,?,?)`,
|
||
id, "✗ 应用退出,任务中断", now)
|
||
}
|
||
}
|
||
|
||
func (s *Store) insertPackTask(t LocalPackTask) error {
|
||
_, e := s.db.Exec(
|
||
`INSERT INTO pack_tasks(id,title,cmd,dir,status,pid,started_at,ended_at,error) VALUES(?,?,?,?,?,?,?,?,?)`,
|
||
t.ID, t.Title, t.Cmd, t.Dir, t.Status, t.PID, t.StartedAt, t.EndedAt, t.Error,
|
||
)
|
||
return e
|
||
}
|
||
|
||
func (s *Store) updatePackTaskMeta(t LocalPackTask) {
|
||
_, _ = s.db.Exec(
|
||
`UPDATE pack_tasks SET title=?, cmd=?, dir=?, status=?, pid=?, started_at=?, ended_at=?, error=? WHERE id=?`,
|
||
t.Title, t.Cmd, t.Dir, t.Status, t.PID, t.StartedAt, t.EndedAt, t.Error, t.ID,
|
||
)
|
||
}
|
||
|
||
func (s *Store) appendPackTaskLog(taskID, line string) {
|
||
line = strings.TrimRight(line, "\r\n")
|
||
if strings.TrimSpace(line) == "" {
|
||
return
|
||
}
|
||
if len(line) > 8000 {
|
||
line = line[:8000] + "…"
|
||
}
|
||
_, _ = s.db.Exec(`INSERT INTO pack_task_logs(task_id,line,created_at) VALUES(?,?,?)`,
|
||
taskID, line, time.Now().Format(time.RFC3339))
|
||
_, _ = s.db.Exec(`DELETE FROM pack_task_logs WHERE task_id=? AND id NOT IN (
|
||
SELECT id FROM pack_task_logs WHERE task_id=? ORDER BY id DESC LIMIT ?)`,
|
||
taskID, taskID, packLogKeepLimit)
|
||
}
|
||
|
||
func (s *Store) listPackTasks(limit int) ([]LocalPackTask, error) {
|
||
if limit <= 0 || limit > packTaskKeepLimit {
|
||
limit = packTaskKeepLimit
|
||
}
|
||
rows, e := s.db.Query(
|
||
`SELECT id,title,cmd,dir,status,pid,started_at,ended_at,error FROM pack_tasks ORDER BY started_at DESC, id DESC LIMIT ?`,
|
||
limit,
|
||
)
|
||
if e != nil {
|
||
return nil, e
|
||
}
|
||
defer rows.Close()
|
||
out := []LocalPackTask{}
|
||
for rows.Next() {
|
||
var t LocalPackTask
|
||
if e = rows.Scan(&t.ID, &t.Title, &t.Cmd, &t.Dir, &t.Status, &t.PID, &t.StartedAt, &t.EndedAt, &t.Error); e != nil {
|
||
return nil, e
|
||
}
|
||
out = append(out, t)
|
||
}
|
||
return out, rows.Err()
|
||
}
|
||
|
||
func (s *Store) getPackTask(id string) (LocalPackTask, error) {
|
||
var t LocalPackTask
|
||
e := s.db.QueryRow(
|
||
`SELECT id,title,cmd,dir,status,pid,started_at,ended_at,error FROM pack_tasks WHERE id=?`, id,
|
||
).Scan(&t.ID, &t.Title, &t.Cmd, &t.Dir, &t.Status, &t.PID, &t.StartedAt, &t.EndedAt, &t.Error)
|
||
if e != nil {
|
||
return LocalPackTask{}, e
|
||
}
|
||
return t, nil
|
||
}
|
||
|
||
func (s *Store) listPackTaskLogs(taskID string) ([]string, error) {
|
||
rows, e := s.db.Query(
|
||
`SELECT line FROM pack_task_logs WHERE task_id=? ORDER BY id ASC`, taskID,
|
||
)
|
||
if e != nil {
|
||
return nil, e
|
||
}
|
||
defer rows.Close()
|
||
out := []string{}
|
||
for rows.Next() {
|
||
var line string
|
||
if e = rows.Scan(&line); e != nil {
|
||
return nil, e
|
||
}
|
||
out = append(out, line)
|
||
}
|
||
return out, rows.Err()
|
||
}
|
||
|
||
func (s *Store) listPackTaskLogTail(taskID string, n int) ([]string, error) {
|
||
if n <= 0 {
|
||
n = 3
|
||
}
|
||
rows, e := s.db.Query(
|
||
`SELECT line FROM pack_task_logs WHERE task_id=? ORDER BY id DESC LIMIT ?`, taskID, n,
|
||
)
|
||
if e != nil {
|
||
return nil, e
|
||
}
|
||
defer rows.Close()
|
||
rev := []string{}
|
||
for rows.Next() {
|
||
var line string
|
||
if e = rows.Scan(&line); e != nil {
|
||
return nil, e
|
||
}
|
||
rev = append(rev, line)
|
||
}
|
||
for i, j := 0, len(rev)-1; i < j; i, j = i+1, j-1 {
|
||
rev[i], rev[j] = rev[j], rev[i]
|
||
}
|
||
return rev, rows.Err()
|
||
}
|
||
|
||
func (s *Store) deleteFinishedPackTasks() error {
|
||
_, e := s.db.Exec(`DELETE FROM pack_task_logs WHERE task_id IN (SELECT id FROM pack_tasks WHERE status!='running')`)
|
||
if e != nil {
|
||
return e
|
||
}
|
||
_, e = s.db.Exec(`DELETE FROM pack_tasks WHERE status!='running'`)
|
||
return e
|
||
}
|
||
|
||
func (s *Store) deletePackTask(id string) error {
|
||
var status string
|
||
if e := s.db.QueryRow(`SELECT status FROM pack_tasks WHERE id=?`, id).Scan(&status); e != nil {
|
||
return e
|
||
}
|
||
if status == "running" {
|
||
return nil
|
||
}
|
||
_, _ = s.db.Exec(`DELETE FROM pack_task_logs WHERE task_id=?`, id)
|
||
_, e := s.db.Exec(`DELETE FROM pack_tasks WHERE id=?`, id)
|
||
return e
|
||
}
|
||
|
||
func (s *Store) pruneOldPackTasks() {
|
||
_, _ = s.db.Exec(`DELETE FROM pack_task_logs WHERE task_id IN (
|
||
SELECT id FROM pack_tasks WHERE id NOT IN (
|
||
SELECT id FROM pack_tasks ORDER BY started_at DESC, id DESC LIMIT ?
|
||
)
|
||
)`, packTaskKeepLimit)
|
||
_, _ = s.db.Exec(`DELETE FROM pack_tasks WHERE id NOT IN (
|
||
SELECT id FROM (
|
||
SELECT id FROM pack_tasks ORDER BY started_at DESC, id DESC LIMIT ?
|
||
)
|
||
)`, packTaskKeepLimit)
|
||
}
|