seancorfield / next-jdbc

A modern low-level Clojure wrapper for JDBC-based access to databases.
https://cljdoc.org/d/com.github.seancorfield/next.jdbc/
Eclipse Public License 1.0
755 stars 90 forks source link

Make Transactable extensible via metadata #209

Closed vemv closed 2 years ago

vemv commented 2 years ago

This is the only missing piece for a metadata-based no-op Component, which I want for tests that must not hit a database, yet still realistically hit the next.jdbc code as used throughout my codebase.

In specific terms, I have a scenario that looks approximately like this:

(def ^:dynamic *emitted-sql*
  nil)

(def ^:dynamic *sql-results*
  nil)

(defn make-test-system []
  (let [sql-mock-fn (fn [_ q]
                      (some-> *emitted-sql* (swap! conj q))
                      (some-> *sql-results* deref (get q)))
        sql (with-meta {:pool (with-meta {}
                                {`jdbc.protocols/get-datasource (constantly (with-meta {}
                                                                              {`jdbc.protocols/-transact (constantly nil)}))})}
              ;; implementations of a custom application-level protocol (not the next.jdbc protocols)
              {`sql/execute!     sql-mock-fn
               `sql/execute-one! sql-mock-fn})]
    {:sql sql
     :another-component (with-meta {:sql sql}
                          `my-app/do-it (fn [this]
                                          (next.jdbc/with-transaction (-> this :sql :pool)
                                            ,,,)))}))

(deftest works ;; sample usage
  (binding [*emitted-sql* (atom [])
            *sql-results* (atom {})]
    (let [{:keys [another-component] (make-test-system)}]
      (my-app/do-it another-component)
      (is (= *emitted-sql* ,,,)))))

In other words, I want to have a simple app-specific protocol for sql interactions, while still being able to use with-transaction. So bespoke implementations have to implement not only Sourceable, but also Transactable.

(note that I cannot create an application-specific protocol for a macro - macros aren't protocol-able)

I hope you appreciate the highly realistic example. IIRC you don't like to add :extend-via-metadata true where not needed.

Cheers - V

seancorfield commented 2 years ago

Great justification -- thank you!

vemv commented 2 years ago

Cheers 🍻 would appreciate a release!

seancorfield commented 2 years ago

You can use a SNAPSHOT :) https://clojars.org/com.github.seancorfield/next.jdbc/versions/1.2.999-SNAPSHOT

vemv commented 2 years ago

Not ideal in my work setting. Sorry to bother!

seancorfield commented 2 years ago

1.2.796 is up on Clojars.

vemv commented 2 years ago

Thank you!

On Mon, Aug 1, 2022 at 7:01 PM Sean Corfield @.***> wrote:

1.2.796 is up on Clojars.

— Reply to this email directly, view it on GitHub https://github.com/seancorfield/next-jdbc/pull/209#issuecomment-1201470451, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI354QB5STMNB62IISJC5TVW77HTANCNFSM55F4FOBA . You are receiving this because you authored the thread.Message ID: @.***>