From 8e16bee20199974ccd585d3523dc460686f9c2d0 Mon Sep 17 00:00:00 2001 From: Richard Newman Date: Thu, 1 Dec 2016 19:37:09 -0800 Subject: [PATCH] Pass existing idents to datoms->schema-fragment, allowing the 'upgrade' of an existing ident to an attribute. --- src/common/datomish/schema_changes.cljc | 18 ++++++++++++++---- src/common/datomish/transact.cljc | 4 +++- test/datomish/schema_changes_test.cljc | 6 +++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/common/datomish/schema_changes.cljc b/src/common/datomish/schema_changes.cljc index 9fec4712..14ad8c02 100644 --- a/src/common/datomish/schema_changes.cljc +++ b/src/common/datomish/schema_changes.cljc @@ -29,9 +29,14 @@ 4. Map e -> ident; fail if not possible. 5. Return the map, with ident keys. - This would be more pleasant with `q` and pull expressions." + This would be more pleasant with `q` and pull expressions. - [datoms] + Note that this function takes as input an existing map of {entid ident}. + That's because it's possible for an ident to be established in a separate + set of datoms -- we can't re-insert it without uniqueness constraint + violations, so we just provide it here." + + [datoms existing-idents] {:pre [(sequential? datoms)]} (let [db-install? (fn [datom] @@ -57,8 +62,13 @@ (let [->av (juxt :a :v) ;; TODO: transduce! db-avs (into {} (map ->av (filter db-*? datoms)))] - ;; TODO: get ident from existing datom, to allow [:db.part/db :db.install/attribute existing-id]. - (if-let [ident (:db/ident db-avs)] + (if-let [ident (or (:db/ident db-avs) + ;; The schema table wants a keyword, not an entid, and + ;; we need to check the existing idents… + (when (contains? existing-idents e) + (if (keyword? e) + e + (get existing-idents e))))] [ident (dissoc db-avs :db/ident)] (raise ":db.install/attribute requires :db/ident, got " db-avs " for " e {:error :schema/db-install :op db-avs})))))))))) diff --git a/src/common/datomish/transact.cljc b/src/common/datomish/transact.cljc index 74d34f7e..4d2f4a8c 100644 --- a/src/common/datomish/transact.cljc +++ b/src/common/datomish/transact.cljc @@ -691,7 +691,9 @@ tx added)) datoms (map symbolicate-install-datom (:tx-data report)) - schema-fragment (datomish.schema-changes/datoms->schema-fragment datoms)] + schema-fragment (datomish.schema-changes/datoms->schema-fragment + datoms + (:ident-map db))] (assoc-in report [:added-attributes] schema-fragment))) (defn collect-db-alter-assertions diff --git a/test/datomish/schema_changes_test.cljc b/test/datomish/schema_changes_test.cljc index 9ab2e2d4..5048fee9 100644 --- a/test/datomish/schema_changes_test.cljc +++ b/test/datomish/schema_changes_test.cljc @@ -17,7 +17,7 @@ (:require [datomish.api :as d] [datomish.datom :refer [datom]] - [datomish.schema-changes :refer [datoms->schema-fragment]] + [datomish.schema-changes] [datomish.schema :as ds] [datomish.sqlite :as s] [datomish.util :as util #?(:cljs :refer-macros :clj :refer) [raise cond-let]] @@ -43,6 +43,10 @@ #?(:cljs (def Throwable js/Error)) +;; Wrap this so that we can pass the empty second argument. +(defn datoms->schema-fragment [x] + (datomish.schema-changes/datoms->schema-fragment x {})) + (deftest test-datoms->schema-fragment (let [tx 10101 ->datom (fn [xs]