Skip to content

Commit

Permalink
fixed nested maps/reverse refs in js build
Browse files Browse the repository at this point in the history
  • Loading branch information
tonsky committed Jan 19, 2015
1 parent ac4ccdc commit c01a37d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
29 changes: 24 additions & 5 deletions src/datascript/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,32 @@
(update-in [:db-after] with-datom datom)
(update-in [:tx-data] conj datom)))

(defn- reverse-ref? [attr]
(= "_" (nth (name attr) 0)))
(defn- ^boolean reverse-ref? [attr]
(cond
(keyword? attr)
(= "_" (nth (name attr) 0))

(string? attr)
(boolean (re-matches #"(?:([^/]+)/)?_([^/]+)" attr))

:else
(throw (js/Error. "Bad attribute type: " attr ", expected keyword or string"))))

(defn- reverse-ref [attr]
(if (reverse-ref? attr)
(keyword (namespace attr) (subs (name attr) 1))
(keyword (namespace attr) (str "_" (name attr)))))
(cond
(keyword? attr)
(if (reverse-ref? attr)
(keyword (namespace attr) (subs (name attr) 1))
(keyword (namespace attr) (str "_" (name attr))))

(string? attr)
(let [[_ ns name] (re-matches #"(?:([^/]+)/)?([^/]+)" attr)]
(if (= "_" (nth name 0))
(if ns (str ns "/" (subs name 1)) (subs name 1))
(if ns (str ns "/_" name) (str "_" name))))

:else
(throw (js/Error. "Bad attribute type: " attr ", expected keyword or string"))))

(defn- validate-eid [eid at]
(when-not (number? eid)
Expand Down
10 changes: 4 additions & 6 deletions src/datascript/impl/entity.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,11 @@
(get [this attr]
(if (= attr ":db/id")
eid
(if-let [[_ ns name] (re-matches #"(?:([^/]+)/)?_([^/]+)" attr)]
(let [attr (if ns (str ns "/" name) name)]
(-> (-lookup-backwards db eid attr nil)
multival->js))
(if (dc/reverse-ref? attr)
(-> (-lookup-backwards db eid (dc/reverse-ref attr) nil)
multival->js)
(cond-> (-lookup this attr)
(dc/multival? db attr)
multival->js))))
(dc/multival? db attr) multival->js))))
(forEach [this f]
(doseq [[a v] (js-seq this)]
(f v a this)))
Expand Down
25 changes: 22 additions & 3 deletions test/js/tests.html
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,33 @@
function test_db_with() {
var db = d.empty_db();
var db1 = d.db_with(db, [[":db/add", 1, "name", "Ivan"],
[":db/add", 1, "age", 17]]);
[":db/add", 1, "age", 17]]);
var db2 = d.db_with(db1, [{":db/id": 2,
"name": "Igor",
"age": 35}]);
"name": "Igor",
"age": 35}]);
var q = '[:find ?n ?a :where [?e "name" ?n] [?e "age" ?a]]';
assert_eq_set([["Ivan", 17]], d.q(q, db1));
assert_eq_set([["Ivan", 17], ["Igor", 35]], d.q(q, db2));
}

function test_nested_maps() {
var q = '[:find ?e ?a ?v :where [?e ?a ?v]]';

var db0 = d.empty_db({"profile": {":db/valueType": ":db.type/ref"}});
var db = d.db_with(db0, [{"name": "Igor", "profile": {"email": "@2"} }]);
assert_eq_set([[1, "name", "Igor"], [1, "profile", 2], [2, "email", "@2"]], d.q(q, db));

db = d.db_with(db0, [{"email": "@2", "_profile": {"name": "Igor"}}]);
assert_eq_set([[1, "email", "@2"], [2, "name", "Igor"], [2, "profile", 1]], d.q(q, db));

db0 = d.empty_db({"user/profile": {":db/valueType": ":db.type/ref"}});
db = d.db_with(db0, [{"name": "Igor", "user/profile": {"email": "@2"} }]);
assert_eq_set([[1, "name", "Igor"], [1, "user/profile", 2], [2, "email", "@2"]], d.q(q, db));

db = d.db_with(db0, [{"email": "@2", "user/_profile": {"name": "Igor"}}]);
assert_eq_set([[1, "email", "@2"], [2, "name", "Igor"], [2, "user/profile", 1]], d.q(q, db));
}

function test_init_db() {
var q = '[:find ?n ?a ?tx :where [?e "name" ?n ?tx] [?e "age" ?a]]';
var db_ok = function(db) {
Expand Down Expand Up @@ -359,6 +377,7 @@

function run_tests() {
return test_fns([ test_db_with,
test_nested_maps,
test_init_db,
test_dbfn_call,
test_schema,
Expand Down

0 comments on commit c01a37d

Please sign in to comment.