filestash/server/workflow/model/workflow.go

150 lines
4 KiB
Go

package model
import (
"database/sql"
"encoding/json"
. "github.com/mickael-kerjean/filestash/server/common"
)
type Workflow struct {
ID string `json:"id"`
Name string `json:"name"`
Published bool `json:"published"`
Trigger Step `json:"trigger"`
Actions []Step `json:"actions"`
UpdatedAt string `json:"updated_at"`
CreatedAt string `json:"created_at"`
History []any `json:"history"`
}
type Step struct {
Name string `json:"name"`
Params map[string]string `json:"params",omitzero`
Done bool `json:"done,omitempty"`
}
func FindWorkflows(triggerName string) ([]Workflow, error) {
rows, err := db.Query(`
SELECT w.id, w.name, w.published, w.trigger, w.actions, w.created_at, w.updated_at
FROM workflows w
WHERE json_extract(w.trigger, '$.name') = ?
ORDER BY w.created_at DESC
`, triggerName)
if err != nil {
return nil, err
}
defer rows.Close()
var workflows = []Workflow{}
for rows.Next() {
var w Workflow
var triggerJSON, actionsJSON string
if err := rows.Scan(&w.ID, &w.Name, &w.Published, &triggerJSON, &actionsJSON, &w.CreatedAt, &w.UpdatedAt); err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(triggerJSON), &w.Trigger); err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(actionsJSON), &w.Actions); err != nil {
return nil, err
}
workflows = append(workflows, w)
}
return workflows, rows.Err()
}
func AllWorkflows() ([]Workflow, error) {
rows, err := db.Query(`
SELECT id, name, published, trigger, actions, created_at, updated_at
FROM workflows
ORDER BY created_at DESC
`)
if err != nil {
return nil, err
}
defer rows.Close()
var workflows = []Workflow{}
for rows.Next() {
var w Workflow
var triggerJSON, actionsJSON string
err := rows.Scan(&w.ID, &w.Name, &w.Published, &triggerJSON, &actionsJSON, &w.CreatedAt, &w.UpdatedAt)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(triggerJSON), &w.Trigger); err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(actionsJSON), &w.Actions); err != nil {
return nil, err
}
workflows = append(workflows, w)
}
return workflows, rows.Err()
}
func UpsertWorkflow(workflow Workflow) error {
triggerJSON, err := json.Marshal(workflow.Trigger)
if err != nil {
return err
}
actionsJSON, err := json.Marshal(workflow.Actions)
if err != nil {
return err
}
query := `
INSERT OR REPLACE INTO workflows (id, name, published, trigger, actions, updated_at)
VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`
_, err = db.Exec(query, workflow.ID, workflow.Name, workflow.Published, string(triggerJSON), string(actionsJSON))
return err
}
func GetWorkflow(id string) (Workflow, error) {
query := `
SELECT w.id, w.name, w.published, w.trigger, w.actions, w.created_at, w.updated_at,
(SELECT COALESCE(JSON_GROUP_ARRAY(JSON_OBJECT(
'id', j.id, 'status', j.status, 'created_at', j.created_at, 'steps', j.steps
)), JSON_ARRAY()) FROM (
SELECT * FROM jobs j
WHERE j.related_workflow = w.id
ORDER BY j.created_at DESC
LIMIT 3000
) j) as history
FROM workflows w
WHERE w.id = ?`
row := db.QueryRow(query, id)
var w Workflow
var triggerJSON, actionsJSON, historyJSON string
if err := row.Scan(&w.ID, &w.Name, &w.Published, &triggerJSON, &actionsJSON, &w.CreatedAt, &w.UpdatedAt, &historyJSON); err != nil {
if err == sql.ErrNoRows {
return Workflow{}, ErrNotFound
}
return Workflow{}, err
}
if err := json.Unmarshal([]byte(triggerJSON), &w.Trigger); err != nil {
return Workflow{}, err
}
if err := json.Unmarshal([]byte(actionsJSON), &w.Actions); err != nil {
return Workflow{}, err
}
if err := json.Unmarshal([]byte(historyJSON), &w.History); err != nil {
return Workflow{}, err
}
return w, nil
}
func DeleteWorkflow(id string) error {
result, err := db.Exec(`DELETE FROM workflows WHERE id = ?`, id)
if err != nil {
return err
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return err
} else if rowsAffected == 0 {
return ErrNotFound
}
return nil
}