Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 132 additions & 80 deletions test/datalevin/main_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
[datalevin.interpret :as i]
[datalevin.lmdb :as l]
[datalevin.test.core :as tdc :refer [db-fixture]]
[taoensso.nippy :as nippy]
[clojure.test :refer [deftest testing is use-fixtures]]
[clojure.test.check.generators :as gen]
[clojure.string :as s])
(:import [java.util UUID Date Arrays]))
[clojure.string :as s]
[clojure.edn :as edn])
(:import [java.util UUID Date Arrays]
[java.net URL]))

(use-fixtures :each db-fixture)

Expand Down Expand Up @@ -141,85 +144,134 @@
(u/delete-files src-dir)
(u/delete-files dest-dir)))


;; some constructors and methods to accompany a #url
;; tagged literal - including nippy (de)serialization

(defn ->url [s] (URL. s))

(defmethod print-method URL [url writer]
(doto writer
(.write "#url ")
(.write "\"")
(.write (.toString url))
(.write "\"")))

(defmethod print-dup URL [url writer]
(doto writer
(.write "#url ")
(.write "\"")
(.write (.toString url))
(.write "\"")))

(nippy/extend-freeze
URL :java.net/URL
[url data-output]
(.writeUTF data-output (pr-str url)))

(nippy/extend-thaw
:java.net/URL
[data-input]
(edn/read-string
{:readers {'url datalevin.main-test/->url}}
(.readUTF data-input)))

(deftest dump-load-datalog-test
(let [analyzer (i/inter-fn [^String text]
(map-indexed (fn [i ^String t]
[t i (.indexOf text t)])
(s/split text #"\s")))
schema {:a/string {:db/valueType :db.type/string
:db/fulltext true}
:a/keyword {:db/valueType :db.type/keyword}
:a/symbol {:db/valueType :db.type/symbol}
:a/boolean {:db/valueType :db.type/boolean}
:a/long {:db/valueType :db.type/long}
:a/double {:db/valueType :db.type/double}
:a/float {:db/valueType :db.type/float}
:a/ref {:db/valueType :db.type/ref}
:a/instant {:db/valueType :db.type/instant}
:a/uuid {:db/valueType :db.type/uuid}
:a/bytes {:db/valueType :db.type/bytes}}
opts {:auto-entity-time? true
:search-engine {:analyzer analyzer}}
src-dir (u/tmp-dir (str "src-dump-dl-" (UUID/randomUUID)))
conn (d/create-conn src-dir schema opts)
dest-dir (u/tmp-dir (str "dest-load-dl-" (UUID/randomUUID)))
dl-file (str (u/tmp-dir) "dl")
s "The quick brown fox jumps over the lazy dog"
now (Date.)
uuid (UUID/randomUUID)
bs (.getBytes ^String s)
vs (repeatedly 10 #(gen/generate gen/any-printable-equatable 1000))
txs (into [{:db/id -1
:hello "Datalevin"}
{:a/keyword :something/nice
:a/symbol 'wonderful/life
:a/string s}
{:a/boolean true
:a/long 42}
{:a/double (double 3.141592)
:a/float (float 2.71828)
:a/ref -1}
{:a/instant now
:a/uuid uuid
:a/bytes bs}]
(mapv (fn [a v] {a v})
(repeat :large/random)
vs))]
(d/transact! conn txs)
(is (= (d/q '[:find ?v .
:in $ ?q
:where [(fulltext $ ?q) [[?e ?a ?v]]]]
(d/db conn) "brown fox") s))
(d/close conn)
(sut/dump src-dir dl-file nil false true false)
(sut/load dest-dir dl-file nil true)
(let [conn1 (d/create-conn dest-dir nil opts)]
;; rebinding *datalevin-data-readers* to ensure support for
;; reading in custom tagged literals works
;; (removing the custom ->url reader will cause the tests to fail)
(binding [sut/*datalevin-data-readers*
(merge sut/datalevin-data-readers
{'url datalevin.main-test/->url})]

(let [analyzer (i/inter-fn [^String text]
(map-indexed (fn [i ^String t]
[t i (.indexOf text t)])
(s/split text #"\s")))
schema {:a/string {:db/valueType :db.type/string
:db/fulltext true}
:a/keyword {:db/valueType :db.type/keyword}
:a/symbol {:db/valueType :db.type/symbol}
:a/boolean {:db/valueType :db.type/boolean}
:a/long {:db/valueType :db.type/long}
:a/double {:db/valueType :db.type/double}
:a/float {:db/valueType :db.type/float}
:a/ref {:db/valueType :db.type/ref}
:a/instant {:db/valueType :db.type/instant}
:a/uuid {:db/valueType :db.type/uuid}
:a/bytes {:db/valueType :db.type/bytes}}
opts {:auto-entity-time? true
:search-engine {:analyzer analyzer}}
src-dir (u/tmp-dir (str "src-dump-dl-" (UUID/randomUUID)))
conn (d/create-conn src-dir schema opts)
dest-dir (u/tmp-dir (str "dest-load-dl-" (UUID/randomUUID)))
dl-file (str (u/tmp-dir) "dl")
s "The quick brown fox jumps over the lazy dog"
now (Date.)
uuid (UUID/randomUUID)
bs (.getBytes ^String s)
vs (repeatedly 10 #(gen/generate gen/any-printable-equatable 1000))
txs (into [{:db/id -1
:hello "Datalevin"}
{:a/keyword :something/nice
:a/symbol 'wonderful/life
:a/string s}
{:a/boolean true
:a/long 42}
{:a/double (double 3.141592)
:a/float (float 2.71828)
:a/ref -1}
{:a/instant now
:a/uuid uuid
:a/bytes bs}
;; reading from string to replicate the error
;; case where a tagged literal is not available
;; on the project classpath
(clojure.edn/read-string
{:readers
{'url datalevin.main-test/->url}}
"{:a/url #url \"https://wikipedia.org\"
:a/string \"def\"}")]
(mapv (fn [a v] {a v})
(repeat :large/random)
vs))]
(d/transact! conn txs)
(is (= (d/q '[:find ?v .
:in $ ?q
:where [(fulltext $ ?q) [[?e ?a ?v]]]]
(d/db conn1) "brown fox") s))

(is (= (d/q '[:find ?v . :where [_ :hello ?v]] @conn1) "Datalevin" ))
(is (= (d/q '[:find ?v . :where [_ :a/keyword ?v]] @conn1)
:something/nice))
(is (= (d/q '[:find ?v . :where [_ :a/symbol ?v]] @conn1)
'wonderful/life))
(is (= (d/q '[:find ?v . :where [_ :a/string ?v]] @conn1) s))
(is (= (d/q '[:find ?v . :where [_ :a/boolean ?v]] @conn1) true))
(is (= (d/q '[:find ?v . :where [_ :a/long ?v]] @conn1) 42))
(is (= (d/q '[:find ?v . :where [_ :a/double ?v]] @conn1)
(double 3.141592)))
(is (= (d/q '[:find ?v . :where [_ :a/float ?v]] @conn1)
(float 2.71828)))
(is (= (d/q '[:find ?v . :where [_ :a/ref ?v]] @conn1)
(d/q '[:find ?e . :where [?e :hello]] @conn1)))
(is (= (d/q '[:find ?v . :where [_ :a/instant ?v]] @conn1) now))
(is (= (d/q '[:find ?v . :where [_ :a/uuid ?v]] @conn1) uuid))
(is (Arrays/equals
^bytes (d/q '[:find ?v . :where [_ :a/bytes ?v]] @conn1)
^bytes bs))
(is (= (set
(d/q '[:find [?v ...] :where [_ :large/random ?v]] @conn1))
(set vs)))
(d/close conn1)
(u/delete-files (str (u/tmp-dir) "dl")))))
(d/db conn) "brown fox") s))
(d/close conn)
(sut/dump src-dir dl-file nil false true false)
(sut/load dest-dir dl-file nil true)
(let [conn1 (d/create-conn dest-dir nil opts)]
(is (= (d/q '[:find ?v .
:in $ ?q
:where [(fulltext $ ?q) [[?e ?a ?v]]]]
(d/db conn1) "brown fox") s))

(is (= (d/q '[:find ?v . :where [_ :hello ?v]] @conn1) "Datalevin" ))
(is (= (d/q '[:find ?v . :where [_ :a/keyword ?v]] @conn1)
:something/nice))
(is (= (d/q '[:find ?v . :where [_ :a/symbol ?v]] @conn1)
'wonderful/life))
(is (= (d/q '[:find ?v . :where [_ :a/string ?v]] @conn1) s))
(is (= (d/q '[:find ?v . :where [_ :a/boolean ?v]] @conn1) true))
(is (= (d/q '[:find ?v . :where [_ :a/long ?v]] @conn1) 42))
(is (= (d/q '[:find ?v . :where [_ :a/double ?v]] @conn1)
(double 3.141592)))
(is (= (d/q '[:find ?v . :where [_ :a/float ?v]] @conn1)
(float 2.71828)))
(is (= (d/q '[:find ?v . :where [_ :a/ref ?v]] @conn1)
(d/q '[:find ?e . :where [?e :hello]] @conn1)))
(is (= (d/q '[:find ?v . :where [_ :a/instant ?v]] @conn1) now))
(is (= (d/q '[:find ?v . :where [_ :a/uuid ?v]] @conn1) uuid))
(is (= (d/q '[:find ?v . :where [_ :a/url ?v]] @conn1)
(->url "https://wikipedia.org")))
(is (Arrays/equals
^bytes (d/q '[:find ?v . :where [_ :a/bytes ?v]] @conn1)
^bytes bs))
(is (= (set
(d/q '[:find [?v ...] :where [_ :large/random ?v]] @conn1))
(set vs)))
(d/close conn1)
(u/delete-files (str (u/tmp-dir) "dl"))))))