From 659c26339c23af0cadafd260aeebc55924e2ae30 Mon Sep 17 00:00:00 2001 From: Nick Alexander Date: Tue, 6 Sep 2016 12:03:03 -0700 Subject: [PATCH] Serialize and de-serialize non-keyword schema values correctly. Fixes #52. --- src/datomish/db.cljc | 15 ++++++++-- src/datomish/db_factory.cljc | 44 ++++++++++++++-------------- src/datomish/schema.cljc | 7 +++++ src/datomish/sqlite_schema.cljc | 6 ++-- src/datomish/transact/bootstrap.cljc | 2 +- test/datomish/db_test.cljc | 35 ++++++++++++++++++++++ 6 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/datomish/db.cljc b/src/datomish/db.cljc index 3e33ea4b..16b74700 100644 --- a/src/datomish/db.cljc +++ b/src/datomish/db.cljc @@ -656,12 +656,21 @@ (SQLite (partial ds/->SQLite schema) + exec (partial s/execute! (:sqlite-connection db))] ;; TODO: batch insert. (doseq [[ident attr-map] fragment] (doseq [[attr value] attr-map] - (SQLite ident) (sqlite-schema/->SQLite attr) (sqlite-schema/->SQLite value)]))))) + ;; This is a little sloppy. We need to store idents as entids, since they're (mostly) + ;; :db.type/ref attributes. So we use that entid passes through idents it doesn't + ;; recognize, and assuming that we have no :db.type/keyword values that match idents. + ;; This is safe for now. + (let [[v tag] (->SQLite (entid db attr) (entid db value))] + (SQLite ident) (sqlite-schema/->SQLite attr) + v tag])))))) (let [symbolic-schema (merge-with merge (:symbolic-schema db) fragment) schema (ds/schema (into {} (map (fn [[k v]] [(entid db k) v]) symbolic-schema)))] diff --git a/src/datomish/db_factory.cljc b/src/datomish/db_factory.cljc index 1850b8d5..69a4a248 100644 --- a/src/datomish/db_factory.cljc +++ b/src/datomish/db_factory.cljc @@ -28,10 +28,7 @@ Returns a map (keyword ident) -> (integer entid), like {:db/ident 0}." (go-pair - (let [rows (> - {:select [:ident :entid] :from [:idents]} - (s/format) - (s/all-rows sqlite-connection)))] + (let [rows ( {:start integer :idx integer}, like {:db.part/user {start: 0x100 idx: 0x101}}." (go-pair - (let [rows (> - {:select [:part :start :idx] :from [:parts]} - (s/format) - (s/all-rows sqlite-connection)))] + (let [rows ( (map (keyword attribute -> keyword value)), like {:db/ident {:db/cardinality :db.cardinality/one}}." (go-pair - (->> + (let [ident-map (clojure.set/map-invert idents) + ref-tag (sqlite-schema/->tag :db.type/ref) + kw<-SQLite (partial sqlite-schema/<-SQLite :db.type/keyword)] (->> - {:select [:ident :attr :value] :from [:schema]} - (s/format) - (s/all-rows sqlite-connection)) - (