Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added tx-middleware capability and schema-middleware #234

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

bamarco
Copy link
Contributor

@bamarco bamarco commented Aug 3, 2017

There are some issues we are solving for datsync to make the datomic/datascript transition smoother and I wanted to get your thoughts on the possiblity of adding tx-middleware to datascript.

This would address issues #193 and #174
We will be using something along these lines in datsync, but I think it fits better in datascript itself.

  • we still need to put the actual validation in as describe in Editable schema #174 but the stub for it is hooked in
  • In init-db I added an options map to turn off validation when it is undesirable which would allow people affected by Allow skipping schema validation #193 to make their own create-conn function in user space that skips validation
  • tx-middleware will allow you to use schema-middleware to check txs for schema changes and put them into the schema map, but this would also open up capabilities like adding validation middleware for all the datomic :db/valueType for people who want type safety rather than speed and other things of that nature
  • right now i put the schema-middleware in datascript.db but it could be put in its own ns if you think that makes more sense
  • brings us closer to full ident support without performance hits on people who don't need that

Usage would look like

(defn test-schema-middleware []
  (let [conn (ds/create-conn)]
    (ds/transact!
      conn
      [{:db/ident :test
        :db/cardinality :db.cardinality/many}]
      {:datascript.db/tx-middleware datascript.db/schema-middleware})
    (ds/transact!
      conn
      [{:db/id -1
        :test :a}
       {:db/id -1
        :test :b}])
    @conn))

This change is Reviewable

@metasoarous
Copy link

FWIW @tonsky, this was the original inspiration behind #150. At the time, Datsync and Posh were both needing to override various behavior of vanilla DataScript, and thought protocols might simplify things. Upon further reflection though, much of the behavior we wanted to override could be expressed via transaction middleware. I think if we get the shape of the tx-middleware idea right, it will be a much more composable way of getting much of the desired flexibility.

@bamarco Would you please describe the signature of the tx-middleware function to clarify how it handles database, tx-data and tx-report?

@tonsky Please let us know if you have any questions or concerns.

@bamarco
Copy link
Contributor Author

bamarco commented Sep 5, 2017

As currently written, tx-middleware is a function which takes a transaction-fn and returns a transaction-fn. The transaction-fn has the signature of datascript.db/transact-tx-data which takes in an initial-tx-report and some txs.

(defn schema-middleware [transact]
  (fn [report txs]
    (let [{:as report :keys [db-after tx-data]} (transact report txs)
          db-after' (transduce
                    (filter schema-datom?)
                    conj-schema-datom
                    db-after
                    tx-data)]
      (if (= (:schema db-after) (:schema db-after'))
        report
        (assoc report
          :db-after (replace-schema db-after (:schema db-after')))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants