Skip to content

Commit

Permalink
Updated queries to accept vars with namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Paula Gearon committed Sep 27, 2023
1 parent 1194563 commit 169301f
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 12 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## [2.3.4] - 2023-09-27
### Changed
- Queries can now used variables with namespaces.

## [2.3.3] - 2023-01-27
### Changed
- Moved dependency to ClojureScript 1.11.60.
Expand Down Expand Up @@ -342,7 +346,8 @@
### Added
- Introduced Update Annotations

[Unreleased]: https://github.com/quoll/asami/compare/2.3.3...HEAD
[Unreleased]: https://github.com/quoll/asami/compare/2.3.4...HEAD
[2.3.4]: https://github.com/quoll/asami/compare/2.3.3...2.3.4
[2.3.3]: https://github.com/quoll/asami/compare/2.3.2...2.3.3
[2.3.2]: https://github.com/quoll/asami/compare/2.3.1...2.3.2
[2.3.1]: https://github.com/quoll/asami/compare/2.3.0...2.3.1
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Asami can be made available to clojure by adding the following to a `deps.edn` f
```clojure
{
:deps {
org.clojars.quoll/asami {:mvn/version "2.3.3"}
org.clojars.quoll/asami {:mvn/version "2.3.4"}
}
}
```
Expand All @@ -54,7 +54,7 @@ This makes Asami available to a repl that is launched with the `clj` or `clojure

Alternatively, Asami can be added for the Leiningen build tool by adding this to the `:dependencies` section of the `project.clj` file:
```clojure
[org.clojars.quoll/asami "2.3.3"]
[org.clojars.quoll/asami "2.3.4"]
```

### Important Note for databases before 2.1.0
Expand Down
4 changes: 2 additions & 2 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
(defproject org.clojars.quoll/asami "2.3.3"
(defproject org.clojars.quoll/asami "2.3.4"
:description "An in memory graph store for Clojure and ClojureScript"
:url "http://github.com/threatgrid/asami"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.11.1"]
[prismatic/schema "1.1.12"]
[org.clojure/core.cache "1.0.217"]
[org.clojars.quoll/zuko "0.6.5"]
[org.clojars.quoll/zuko "0.6.7"]
[org.clojars.quoll/qtest "0.1.1"]
[org.clojure/data.priority-map "1.0.0"]
[tailrecursion/cljs-priority-map "1.2.1"]]
Expand Down
8 changes: 6 additions & 2 deletions src/asami/projection.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@
(s/one EntityPropAxiomElt "property")
(s/one EntityPropValAxiomElt "value")])

(def Var (s/constrained s/Symbol (comp #{\? \%} first name)))
(def var-marker? #{\? \%})

(def Var (s/constrained s/Symbol #(or (var-marker? (first (name %)))
(var-marker? (first (namespace %))))))

(s/defn vartest? :- s/Bool
[x]
(and (symbol? x) (boolean (#{\? \%} (first (name x))))))
(and (symbol? x) (boolean (or (var-marker? (first (name x)))
(var-marker? (first (namespace x)))))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
11 changes: 8 additions & 3 deletions src/asami/query.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@
(with-meta (filter filter-fn part) m)
(catch #?(:clj Throwable :cljs :default) e
(throw (if-let [ev (some (partial missing var-index) args)]
(ex-info (str "Unknown variable in filter: " (name ev)) {:vars (keys var-index) :filter-var ev})
(ex-info (str "Unknown variable in filter: " (if-let [nms (namespace ev)]
(str nms \/ (name ev))
(name ev))) {:vars (keys var-index) :filter-var ev})
(ex-info (str "Error executing filter: " e) {:error e})))))))

(s/defn binding-join
Expand Down Expand Up @@ -420,7 +422,7 @@
:default (pattern-error pattern)))

(s/def InSpec (s/conditional #(= '$ %) s/Symbol
#(and (symbol? %) (= \? (first (name %)))) s/Symbol
#(and (symbol? %) (= \? (first (or (namespace %) (name %))))) s/Symbol
#(and sequential? (sequential? (first %))) [[s/Symbol]]
:else [s/Symbol]))

Expand Down Expand Up @@ -722,7 +724,10 @@
(s/defn agg-label :- s/Symbol
"Converts an aggregate operation on a symbol into a symbol name"
[[op v]]
(symbol (str "?" (name op) "-" (if (planner/wildcard? v) "all" (subs (name v) 1)))))
(let [short-name (if-let [nms (namespace v)]
(str (subs (namespace v) 1) \_ (name v))
(subs (name v) 1))]
(symbol (str "?" (name op) "-" (if (planner/wildcard? v) "all" short-name)))))

(s/defn result-label :- s/Symbol
"Convert an element from a select/find clause into an appropriate label.
Expand Down
15 changes: 15 additions & 0 deletions test/asami/core_query_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,28 @@
(is (= (set data) (set results)))
(is (= #{["Paul McCartney"] ["George Harrison"] ["John Lennon"]} (set artists)))))

(deftest test-ns-simple-query
(let [results (q '[:find ?e ?us/a ?v
:where [?e ?us/a ?v]] store)
artists (q '[:find ?artist
:where [?tst/e :artist/name ?artist]] store)]
(is (= (set data) (set results)))
(is (= #{["Paul McCartney"] ["George Harrison"] ["John Lennon"]} (set artists)))))

(deftest test-join-query
(let [results (q '[:find ?name
:where [?r :release/name "My Sweet Lord"]
[?r :release/artists ?a]
[?a :artist/name ?name]] store)]
(is (= [["Paul McCartney"]] results))))

(deftest test-ns-join-query
(let [results (q '[:find ?u/name
:where [?r :release/name "My Sweet Lord"]
[?r :release/artists ?a]
[?a :artist/name ?u/name]] store)]
(is (= [["Paul McCartney"]] results))))

(deftest test-join-multi-query
(let [results (q '[:find ?rname
:where [?a :artist/name "George Harrison"]
Expand Down
22 changes: 20 additions & 2 deletions test/asami/query_internals_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,15 @@
(let [m1 (matching-vars `[?a :rel ?c] `[?a ?b ?c] )
m2 (matching-vars `[?b :rel ?f] `[?a ?b ?c ?d ?e ?f])
m3 (matching-vars `[?b :rel ?f ?b :r2 ?e] `[?a ?b ?c ?d ?e ?f])
m4 (matching-vars `[?x :rel ?f ?x :r2 ?e] `[?a ?b ?c ?d ?e ?f])]
m4 (matching-vars `[?x :rel ?f ?x :r2 ?e] `[?a ?b ?c ?d ?e ?f])
m5 (matching-vars `[?b :rel ?u/f] `[?a ?b ?c ?d ?e ?u/f])
m6 (matching-vars `[?b :rel ?u/f ?u/c ?v/d] `[?a ?b ?c ?u/d ?e ?u/f])]
(is (= m1 {0 0, 2 2}))
(is (= m2 {0 1, 2 5}))
(is (= m3 {0 1, 2 5, 3 1, 5 4}))
(is (= m4 {2 5, 5 4}))))
(is (= m4 {2 5, 5 4}))
(is (= m5 {0 1, 2 5}))
(is (= m6 {0 1, 2 5}))))

(def join-data
[[:b :px :c]
Expand All @@ -55,6 +59,20 @@
(is (= '[?o ?q] (:cols (meta r2))))
(is (= [[:b :c] [:b :d]] r2))))

(deftest ns-test-join
(let [graph (assert-data empty-graph join-data)
part-result (with-meta
[[:p1 :b] [:p2 :z] [:p3 :x] [:p3 :t]]
{:cols '[?p ?u/o]})
r1 (pattern-left-join graph part-result '[?u/o :px :c])
part-result2 (with-meta [[:b]] {:cols '[?u/o]})
r2 (pattern-left-join graph part-result2 '[?u/o :px ?q])]
(is (= '[?p ?u/o] (:cols (meta r1))))
(is (= [[:p1 :b] [:p2 :z] [:p3 :x]] r1))
(is (= '[?u/o ?q] (:cols (meta r2))))
(is (= [[:b :c] [:b :d]] r2))))

(defn bnd [names vals] (with-meta vals {:cols names}))
(defn bnd [names vals] (with-meta vals {:cols names}))

(deftest test-outer-product
Expand Down

0 comments on commit 169301f

Please sign in to comment.