(add-rule session rule)

Adds a rule to the given session.

Source

(defn add-rule "Adds a rule to the given session." [session rule] (when (get-in session [:rule-name->node-id (:name rule)]) (throw (ex-info (str (:name rule) " already exists in session") {}))) (let [conditions (:conditions rule) session (reduce add-condition session conditions) leaf-node-id (-> session :mem-node-ids last) bindings (:bindings session) session (reduce (fn [session mem-node-id] (update-in session [:beta-nodes mem-node-id] (fn [mem-node] (assoc mem-node :leaf-node-id leaf-node-id :what-fn (:what-fn rule))))) session (:mem-node-ids session)) session (reduce (fn [session join-node-id] (update-in session [:beta-nodes join-node-id] (fn [join-node] (let [joined-key (some (fn [{:keys [field key]}] (when (= :value field) key)) (-> join-node :condition :bindings)) disable-fast-updates (clojure.core/contains? (:joins bindings) joined-key)] (when (and disable-fast-updates (-> (get-in session [:beta-nodes (:child-id join-node)]) :condition :opts :then first (= :func))) (throw (ex-info (str "In " (:name rule) " you are making a join with the symbol `" (symbol joined-key) "`, " "and passing a custom function in the {:then ...} option. This is not allowed due to " "how the implementation works. Luckily, it's easy to fix! Get rid of this join in your :what " "block by giving the symbol a different name, such as `" (symbol (str (name joined-key) 2)) "`, " "and then enforce the join in your :when block like this: " (list '= (symbol joined-key) (symbol (str (name joined-key) 2)))) {}))) (assoc join-node :id-key (some (fn [{:keys [field key]}] (when (and (= :id field) (clojure.core/contains? (:joins bindings) key)) key)) (-> join-node :condition :bindings)) :disable-fast-updates disable-fast-updates))))) session (:join-node-ids session))] (-> session (assoc-in [:beta-nodes leaf-node-id :when-fn] (:when-fn rule)) (assoc-in [:beta-nodes leaf-node-id :then-fn] (:then-fn rule)) (assoc-in [:beta-nodes leaf-node-id :then-finally-fn] (:then-finally-fn rule)) (assoc-in [:rule-name->node-id (:name rule)] leaf-node-id) (assoc-in [:node-id->rule-name leaf-node-id] (:name rule)) (dissoc :mem-node-ids :join-node-ids :bindings))))