diff --git a/node.go b/node.go index aa83ffe..2bf6302 100644 --- a/node.go +++ b/node.go @@ -94,7 +94,8 @@ func GetNode(nodeID int) (node Node, err error) { // {{{ h.id, to_jsonb(s) AS script, ssh, - env + env, + schedule_on_child_update AS ScheduleOnChildUpdate FROM hook h INNER JOIN public.script s ON h.script_id = s.id WHERE diff --git a/script.go b/script.go index f93b199..ce7a8d0 100644 --- a/script.go +++ b/script.go @@ -23,11 +23,12 @@ type Script struct { } type Hook struct { - ID int - Node Node - Script Script - SSH string - Env map[string]string + ID int + Node Node + Script Script + SSH string + Env map[string]string + ScheduleOnChildUpdate bool `db:"schedule_on_child_update"` } func GetScript(scriptID int) (script Script, err error) { // {{{ @@ -135,13 +136,20 @@ func SearchScripts(search string) (scripts []Script, err error) { // {{{ row := db.QueryRow(` SELECT - json_agg(script) AS scripts - FROM public.script - WHERE - name ILIKE $1 - ORDER BY - "group" ASC, - name ASC + COALESCE( + json_agg(scripts), + '[]'::json + ) AS scripts + FROM ( + SELECT + to_json(script) AS scripts + FROM public.script + WHERE + name ILIKE $1 + ORDER BY + "group" ASC, + name ASC + ) scripts `, search, ) @@ -172,11 +180,12 @@ func GetHook(hookID int) (hook Hook, err error) { // {{{ to_json(res) FROM ( SELECT - h.id, - h.ssh, - h.env, - (SELECT to_json(node) FROM node WHERE id = h.node_id) AS node, - (SELECT to_json(script) FROM script WHERE id = h.script_id) AS script + h.id, + h.ssh, + h.env, + h.schedule_on_child_update, + (SELECT to_json(node) FROM node WHERE id = h.node_id) AS node, + (SELECT to_json(script) FROM script WHERE id = h.script_id) AS script FROM hook h WHERE h.id = $1 @@ -198,7 +207,20 @@ func GetHook(hookID int) (hook Hook, err error) { // {{{ } // }}} func UpdateHook(hook Hook) (err error) { // {{{ j, _ := json.Marshal(hook.Env) - _, err = db.Exec(`UPDATE hook SET ssh=$2, env=$3 WHERE id=$1`, hook.ID, strings.TrimSpace(hook.SSH), j) + _, err = db.Exec(` + UPDATE hook + SET + ssh=$2, + env=$3, + schedule_on_child_update=$4 + WHERE + id=$1 + `, + hook.ID, + strings.TrimSpace(hook.SSH), + j, + hook.ScheduleOnChildUpdate, + ) if err != nil { err = werr.Wrap(err) return @@ -259,6 +281,58 @@ func ScheduleHook(hookID int) (err error) { // {{{ return } // }}} +func ScheduleHookRecursivelyUpwards(nodeID int) (err error) { // {{{ + var rows *sql.Rows + rows, err = db.Query(` + WITH RECURSIVE rec AS ( + SELECT + id, + parent_id + FROM public.node + WHERE + id = $1 + + UNION ALL + + SELECT + n.id, + n.parent_id + FROM node n + INNER JOIN rec ON n.id = rec.parent_id + ) + + SELECT + hook.id + FROM rec + INNER JOIN hook ON + hook.node_id = rec.id AND + hook.schedule_on_child_update + `, + nodeID, + ) + if err != nil { + err = werr.Wrap(err) + return + } + defer rows.Close() + + for rows.Next() { + var hookID int + err = rows.Scan(&hookID) + if err != nil { + err = werr.Wrap(err) + return + } + + err = ScheduleHook(hookID) + if err != nil { + err = werr.Wrap(err) + return + } + } + + return +} // }}} func ScriptPreservedID(name, source string) (id int, err error) { // {{{ sum := md5.Sum([]byte(source)) diff --git a/sql/0018.sql b/sql/0018.sql new file mode 100644 index 0000000..f4617ac --- /dev/null +++ b/sql/0018.sql @@ -0,0 +1 @@ +ALTER TABLE public.hook DROP CONSTRAINT hook_unique; diff --git a/sql/0019.sql b/sql/0019.sql new file mode 100644 index 0000000..b9cad16 --- /dev/null +++ b/sql/0019.sql @@ -0,0 +1 @@ +ALTER TABLE public.hook ADD schedule_on_child_update bool DEFAULT false NOT NULL; diff --git a/static/js/app.mjs b/static/js/app.mjs index b449705..dba1c17 100644 --- a/static/js/app.mjs +++ b/static/js/app.mjs @@ -1464,6 +1464,7 @@ class ScriptHookDialog extends Component { this.env = null this.ssh = null + this.schedule_on_child_update = null }// }}} renderComponent() {// {{{ const div = document.createElement('div') @@ -1472,9 +1473,16 @@ class ScriptHookDialog extends Component {