|
3 | 3 | #?(:cljs (:require-macros [datascript.parser :refer [deftrecord]])) |
4 | 4 | (:require |
5 | 5 | [clojure.set :as set] |
6 | | - [datascript.db :as db #?(:cljs :refer-macros :clj :refer) [raise]])) |
| 6 | + [datascript.db :as db] |
| 7 | + [datascript.util :as util])) |
7 | 8 |
|
8 | 9 | ;; utils |
9 | 10 |
|
|
103 | 104 |
|
104 | 105 | (defn parse-var-required [form] |
105 | 106 | (or (parse-variable form) |
106 | | - (raise "Cannot parse var, expected symbol starting with ?, got: " form |
| 107 | + (util/raise "Cannot parse var, expected symbol starting with ?, got: " form |
107 | 108 | {:error :parser/rule-var, :form form}))) |
108 | 109 |
|
109 | 110 | (defn parse-src-var [form] |
|
153 | 154 | required* (parse-seq parse-var-required required) |
154 | 155 | free* (parse-seq parse-var-required rest)] |
155 | 156 | (when (and (empty? required*) (empty? free*)) |
156 | | - (raise "Cannot parse rule-vars, expected [ variable+ | ([ variable+ ] variable*) ]" |
| 157 | + (util/raise "Cannot parse rule-vars, expected [ variable+ | ([ variable+ ] variable*) ]" |
157 | 158 | {:error :parser/rule-vars, :form form})) |
158 | 159 | (when-not (distinct? (concat required* free*)) |
159 | | - (raise "Rule variables should be distinct" |
| 160 | + (util/raise "Rule variables should be distinct" |
160 | 161 | {:error :parser/rule-vars, :form form})) |
161 | 162 | (RuleVars. required* free*)) |
162 | | - (raise "Cannot parse rule-vars, expected [ variable+ | ([ variable+ ] variable*) ]" |
| 163 | + (util/raise "Cannot parse rule-vars, expected [ variable+ | ([ variable+ ] variable*) ]" |
163 | 164 | {:error :parser/rule-vars, :form form}))) |
164 | 165 |
|
165 | 166 | (defn flatten-rule-vars [rule-vars] |
|
196 | 197 | (= (second form) '...)) |
197 | 198 | (if-let [sub-bind (parse-binding (first form))] |
198 | 199 | (with-source (BindColl. sub-bind) form) |
199 | | - (raise "Cannot parse collection binding" |
| 200 | + (util/raise "Cannot parse collection binding" |
200 | 201 | {:error :parser/binding, :form form})))) |
201 | 202 |
|
202 | 203 | (defn parse-tuple-el [form] |
|
207 | 208 | (when-let [sub-bindings (parse-seq parse-tuple-el form)] |
208 | 209 | (if-not (empty? sub-bindings) |
209 | 210 | (with-source (BindTuple. sub-bindings) form) |
210 | | - (raise "Tuple binding cannot be empty" |
| 211 | + (util/raise "Tuple binding cannot be empty" |
211 | 212 | {:error :parser/binding, :form form})))) |
212 | 213 |
|
213 | 214 | (defn parse-bind-rel [form] |
|
222 | 223 | (parse-bind-tuple form) |
223 | 224 | (parse-bind-ignore form) |
224 | 225 | (parse-bind-scalar form) |
225 | | - (raise "Cannot parse binding, expected (bind-scalar | bind-tuple | bind-coll | bind-rel)" |
| 226 | + (util/raise "Cannot parse binding, expected (bind-scalar | bind-tuple | bind-coll | bind-rel)" |
226 | 227 | {:error :parser/binding, :form form}))) |
227 | 228 |
|
228 | 229 |
|
|
294 | 295 | args* (parse-seq parse-fn-arg args)] |
295 | 296 | (if (and fn* args*) |
296 | 297 | (Aggregate. fn* args*) |
297 | | - (raise "Cannot parse custom aggregate call, expect ['aggregate' variable fn-arg+]" |
| 298 | + (util/raise "Cannot parse custom aggregate call, expect ['aggregate' variable fn-arg+]" |
298 | 299 | {:error :parser/find, :fragment form}))) |
299 | | - (raise "Cannot parse custom aggregate call, expect ['aggregate' variable fn-arg+]" |
| 300 | + (util/raise "Cannot parse custom aggregate call, expect ['aggregate' variable fn-arg+]" |
300 | 301 | {:error :parser/find, :fragment form})))) |
301 | 302 |
|
302 | 303 | (defn parse-pull-expr [form] |
|
313 | 314 | (parse-constant pattern))] |
314 | 315 | (if (and src* var* pattern*) |
315 | 316 | (Pull. src* var* pattern*) |
316 | | - (raise "Cannot parse pull expression, expect ['pull' src-var? variable (constant | variable | plain-symbol)]" |
| 317 | + (util/raise "Cannot parse pull expression, expect ['pull' src-var? variable (constant | variable | plain-symbol)]" |
317 | 318 | {:error :parser/find, :fragment form}))) |
318 | | - (raise "Cannot parse pull expression, expect ['pull' src-var? variable (constant | variable | plain-symbol)]" |
| 319 | + (util/raise "Cannot parse pull expression, expect ['pull' src-var? variable (constant | variable | plain-symbol)]" |
319 | 320 | {:error :parser/find, :fragment form})))) |
320 | 321 |
|
321 | 322 | (defn parse-find-elem [form] |
|
359 | 360 | (parse-find-coll form) |
360 | 361 | (parse-find-scalar form) |
361 | 362 | (parse-find-tuple form) |
362 | | - (raise "Cannot parse :find, expected: (find-rel | find-coll | find-tuple | find-scalar)" |
| 363 | + (util/raise "Cannot parse :find, expected: (find-rel | find-coll | find-tuple | find-scalar)" |
363 | 364 | {:error :parser/find, :fragment form}))) |
364 | 365 |
|
365 | 366 |
|
|
384 | 385 | (defn parse-with [form] |
385 | 386 | (or |
386 | 387 | (parse-seq parse-variable form) |
387 | | - (raise "Cannot parse :with clause, expected [ variable+ ]" |
| 388 | + (util/raise "Cannot parse :with clause, expected [ variable+ ]" |
388 | 389 | {:error :parser/with, :form form}))) |
389 | 390 |
|
390 | 391 |
|
|
400 | 401 | (defn parse-in [form] |
401 | 402 | (or |
402 | 403 | (parse-seq parse-in-binding form) |
403 | | - (raise "Cannot parse :in clause, expected (src-var | % | plain-symbol | bind-scalar | bind-tuple | bind-coll | bind-rel)" |
| 404 | + (util/raise "Cannot parse :in clause, expected (src-var | % | plain-symbol | bind-scalar | bind-tuple | bind-coll | bind-rel)" |
404 | 405 | {:error :parser/in, :form form}))) |
405 | 406 |
|
406 | 407 |
|
|
442 | 443 | (when-let [pattern* (parse-seq parse-pattern-el next-form)] |
443 | 444 | (if-not (empty? pattern*) |
444 | 445 | (with-source (Pattern. source* pattern*) form) |
445 | | - (raise "Pattern could not be empty" |
| 446 | + (util/raise "Pattern could not be empty" |
446 | 447 | {:error :parser/where, :form form}))))) |
447 | 448 |
|
448 | 449 | (defn parse-call [form] |
|
477 | 478 | (when name* |
478 | 479 | (cond |
479 | 480 | (empty? args) |
480 | | - (raise "rule-expr requires at least one argument" |
| 481 | + (util/raise "rule-expr requires at least one argument" |
481 | 482 | {:error :parser/where, :form form}) |
482 | 483 | (nil? args*) |
483 | | - (raise "Cannot parse rule-expr arguments, expected [ (variable | constant | '_')+ ]" |
| 484 | + (util/raise "Cannot parse rule-expr arguments, expected [ (variable | constant | '_')+ ]" |
484 | 485 | {:error :parser/where, :form form}) |
485 | 486 | :else |
486 | 487 | (RuleExpr. source* name* args*) |
|
508 | 509 |
|
509 | 510 | (defn- validate-join-vars [required free form] |
510 | 511 | (when (and (empty? required) (empty? free)) |
511 | | - (raise "Join variables should not be empty" |
| 512 | + (util/raise "Join variables should not be empty" |
512 | 513 | {:error :parser/where, :form form}))) |
513 | 514 |
|
514 | 515 | (defn- validate-not [clause form] |
|
523 | 524 | (-> (Not. source* (collect-vars-distinct clauses*) clauses*) |
524 | 525 | (with-source form) |
525 | 526 | (validate-not form)) |
526 | | - (raise "Cannot parse 'not' clause, expected [ src-var? 'not' clause+ ]" |
| 527 | + (util/raise "Cannot parse 'not' clause, expected [ src-var? 'not' clause+ ]" |
527 | 528 | {:error :parser/where, :form form})))))) |
528 | 529 |
|
529 | 530 | (defn parse-not-join [form] |
|
536 | 537 | (-> (Not. source* vars* clauses*) |
537 | 538 | (with-source form) |
538 | 539 | (validate-not form)) |
539 | | - (raise "Cannot parse 'not-join' clause, expected [ src-var? 'not-join' [variable+] clause+ ]" |
| 540 | + (util/raise "Cannot parse 'not-join' clause, expected [ src-var? 'not-join' [variable+] clause+ ]" |
540 | 541 | {:error :parser/where, :form form}))))))) |
541 | 542 |
|
542 | 543 | (defn validate-or [clause form] |
|
551 | 552 | (let [clauses* (parse-clauses (next form))] |
552 | 553 | (if (not-empty clauses*) |
553 | 554 | (And. clauses*) |
554 | | - (raise "Cannot parse 'and' clause, expected [ 'and' clause+ ]" |
| 555 | + (util/raise "Cannot parse 'and' clause, expected [ 'and' clause+ ]" |
555 | 556 | {:error :parser/where, :form form}))))) |
556 | 557 |
|
557 | 558 | (defn parse-or [form] |
|
562 | 563 | (-> (Or. source* (RuleVars. nil (collect-vars-distinct clauses*)) clauses*) |
563 | 564 | (with-source form) |
564 | 565 | (validate-or form)) |
565 | | - (raise "Cannot parse 'or' clause, expected [ src-var? 'or' clause+ ]" |
| 566 | + (util/raise "Cannot parse 'or' clause, expected [ src-var? 'or' clause+ ]" |
566 | 567 | {:error :parser/where, :form form})))))) |
567 | 568 |
|
568 | 569 | (defn parse-or-join [form] |
|
575 | 576 | (-> (Or. source* vars* clauses*) |
576 | 577 | (with-source form) |
577 | 578 | (validate-or form)) |
578 | | - (raise "Cannot parse 'or-join' clause, expected [ src-var? 'or-join' [variable+] clause+ ]" |
| 579 | + (util/raise "Cannot parse 'or-join' clause, expected [ src-var? 'or-join' [variable+] clause+ ]" |
579 | 580 | {:error :parser/where, :form form}))))))) |
580 | 581 |
|
581 | 582 |
|
|
617 | 618 | (parse-fn form) |
618 | 619 | (parse-rule-expr form) |
619 | 620 | (parse-pattern form) |
620 | | - (raise "Cannot parse clause, expected (data-pattern | pred-expr | fn-expr | rule-expr | not-clause | not-join-clause | or-clause | or-join-clause)" |
| 621 | + (util/raise "Cannot parse clause, expected (data-pattern | pred-expr | fn-expr | rule-expr | not-clause | not-join-clause | or-clause | or-join-clause)" |
621 | 622 | {:error :parser/where, :form form} ))) |
622 | 623 |
|
623 | 624 | (defn parse-clauses [clauses] |
624 | 625 | (parse-seq parse-clause clauses)) |
625 | 626 |
|
626 | 627 | (defn parse-where [form] |
627 | 628 | (or (parse-clauses form) |
628 | | - (raise "Cannot parse :where clause, expected [clause+]" |
| 629 | + (util/raise "Cannot parse :where clause, expected [clause+]" |
629 | 630 | {:error :parser/where, :form form}))) |
630 | 631 |
|
631 | 632 |
|
|
642 | 643 | (if (sequential? head) |
643 | 644 | (let [[name & vars] head |
644 | 645 | name* (or (parse-plain-symbol name) |
645 | | - (raise "Cannot parse rule name, expected plain-symbol" |
| 646 | + (util/raise "Cannot parse rule name, expected plain-symbol" |
646 | 647 | {:error :parser/rule, :form form})) |
647 | 648 | vars* (parse-rule-vars vars) |
648 | 649 | clauses* (or (not-empty (parse-clauses clauses)) |
649 | | - (raise "Rule branch should have clauses" |
| 650 | + (util/raise "Rule branch should have clauses" |
650 | 651 | {:error :parser/rule, :form form}))] |
651 | 652 | {:name name* |
652 | 653 | :vars vars* |
653 | 654 | :clauses clauses*}) |
654 | | - (raise "Cannot parse rule head, expected [rule-name rule-vars], got: " head |
| 655 | + (util/raise "Cannot parse rule head, expected [rule-name rule-vars], got: " head |
655 | 656 | {:error :parser/rule, :form form}))) |
656 | | - (raise "Cannot parse rule, expected [rule-head clause+]" |
| 657 | + (util/raise "Cannot parse rule, expected [rule-head clause+]" |
657 | 658 | {:error :parser/rule, :form form}))) |
658 | 659 |
|
659 | 660 | (defn validate-arity [name branches] |
|
662 | 663 | (doseq [b (next branches) |
663 | 664 | :let [vars (:vars b)]] |
664 | 665 | (when (not= arity0 (rule-vars-arity vars)) |
665 | | - (raise "Arity mismatch for rule '" (:symbol name) "': " |
| 666 | + (util/raise "Arity mismatch for rule '" (:symbol name) "': " |
666 | 667 | (flatten-rule-vars vars0) " vs. " (flatten-rule-vars vars) |
667 | 668 | {:error :parser/rule, :rule name}))))) |
668 | 669 |
|
|
711 | 712 | (set/union where-vars in-vars)) |
712 | 713 | shared (set/intersection find-vars with-vars)] |
713 | 714 | (when-not (empty? unknown) |
714 | | - (raise "Query for unknown vars: " (mapv :symbol unknown) |
| 715 | + (util/raise "Query for unknown vars: " (mapv :symbol unknown) |
715 | 716 | {:error :parser/query, :vars unknown, :form form})) |
716 | 717 | (when-not (empty? shared) |
717 | | - (raise ":find and :with should not use same variables: " (mapv :symbol shared) |
| 718 | + (util/raise ":find and :with should not use same variables: " (mapv :symbol shared) |
718 | 719 | {:error :parser/query, :vars shared, :form form}))) |
719 | 720 |
|
720 | 721 | (when-some [return-map (:qreturn-map q)] |
721 | 722 | (when (instance? FindScalar (:qfind q)) |
722 | | - (raise (:type return-map) " does not work with single-scalar :find" |
| 723 | + (util/raise (:type return-map) " does not work with single-scalar :find" |
723 | 724 | {:error :parser/query, :form form})) |
724 | 725 | (when (instance? FindColl (:qfind q)) |
725 | | - (raise (:type return-map) " does not work with collection :find" |
| 726 | + (util/raise (:type return-map) " does not work with collection :find" |
726 | 727 | {:error :parser/query, :form form}))) |
727 | 728 |
|
728 | 729 | (when-some [return-symbols (:symbols (:qreturn-map q))] |
729 | 730 | (let [find-elements (find-elements (:qfind q))] |
730 | 731 | (when-not (= (count return-symbols) (count find-elements)) |
731 | | - (raise "Count of " (:type (:qreturn-map q)) " must match count of :find" |
| 732 | + (util/raise "Count of " (:type (:qreturn-map q)) " must match count of :find" |
732 | 733 | {:error :parser/query |
733 | 734 | :return-map (cons (:type (:qreturn-map q)) return-symbols) |
734 | 735 | :find find-elements |
|
737 | 738 | (when (< 1 (->> [(:keys form-map) (:syms form-map) (:strs form-map)] |
738 | 739 | (filter some?) |
739 | 740 | (count))) |
740 | | - (raise "Only one of :keys/:syms/:strs must be present" |
| 741 | + (util/raise "Only one of :keys/:syms/:strs must be present" |
741 | 742 | {:error :parser/query, :form form})) |
742 | 743 |
|
743 | 744 | (let [in-vars (collect-vars (:qin q)) |
|
746 | 747 | (when-not (and (distinct? in-vars) |
747 | 748 | (distinct? in-sources) |
748 | 749 | (distinct? in-rules)) |
749 | | - (raise "Vars used in :in should be distinct" |
| 750 | + (util/raise "Vars used in :in should be distinct" |
750 | 751 | {:error :parser/query, :form form}))) |
751 | 752 |
|
752 | 753 | (let [with-vars (collect-vars (:qwith q))] |
753 | 754 | (when-not (distinct? with-vars) |
754 | | - (raise "Vars used in :with should be distinct" |
| 755 | + (util/raise "Vars used in :with should be distinct" |
755 | 756 | {:error :parser/query, :form form}))) |
756 | 757 |
|
757 | 758 | (let [in-sources (collect #(instance? SrcVar %) (:qin q) #{}) |
758 | 759 | where-sources (collect #(instance? SrcVar %) (:qwhere q) #{}) |
759 | 760 | unknown (set/difference where-sources in-sources)] |
760 | 761 | (when-not (empty? unknown) |
761 | | - (raise "Where uses unknown source vars: " (mapv :symbol unknown) |
| 762 | + (util/raise "Where uses unknown source vars: " (mapv :symbol unknown) |
762 | 763 | {:error :parser/query, :vars unknown, :form form}))) |
763 | 764 |
|
764 | 765 | (let [rule-exprs (collect #(instance? RuleExpr %) (:qwhere q)) |
765 | 766 | rules-vars (collect #(instance? RulesVar %) (:qin q))] |
766 | 767 | (when (and (not (empty? rule-exprs)) |
767 | 768 | (empty? rules-vars)) |
768 | | - (raise "Missing rules var '%' in :in" |
| 769 | + (util/raise "Missing rules var '%' in :in" |
769 | 770 | {:error :parser/query, :form form})))) |
770 | 771 |
|
771 | 772 | (defn parse-query [q] |
772 | 773 | (let [qm (cond |
773 | 774 | (map? q) q |
774 | 775 | (sequential? q) (query->map q) |
775 | | - :else (raise "Query should be a vector or a map" |
| 776 | + :else (util/raise "Query should be a vector or a map" |
776 | 777 | {:error :parser/query, :form q})) |
777 | 778 | qwhere (parse-where (:where qm [])) |
778 | 779 | res (map->Query |
|
0 commit comments