diff --git a/CHANGELOG.md b/CHANGELOG.md index 9560291..8fb0359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,8 @@ Only accretive/fixative changes will be made from now on. * 1.2.next in progress - * _[Experimental! Will change in response to feedback!]_ Add `next.jdbc/with-logging` to create a wrapped connectable that will invoke logging functions with the SQL/parameters and optionally the result for each operation. * Fix #167 by adding `:property-separator` to `next.jdbc.connection/dbtypes` and using it in `jdbc-url`. + * Address #166 by adding `next.jdbc/with-logging` to create a wrapped connectable that will invoke logging functions with the SQL/parameters and optionally the result or exception for each operation. * Fix `:unit_count` references in **Getting Started** (were `:unit_cost`). * Update `test-runner`. diff --git a/doc/getting-started.md b/doc/getting-started.md index f7afb23..22b2693 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -592,7 +592,9 @@ operations directly so they do not produce results). `my-result-logger` will be three arguments: * The fully-qualified symbol identify the operation, * A "state" argument (the result of calling `my-sql-logger`), -* The result set data structure. +* The result set data structure, if the call succeeded, or the exception if it failed. + +The return value of the result logger function is ignored. The symbol will be one of: `next.jdbc/execute!` or `next.jdbc/execute-one!`. The friendly SQL functions invoke `execute!` or `execute-one!` under the hood, so that is how they will @@ -605,7 +607,8 @@ returns `nil`, that will be passed as the second argument to your second logging The result set data structure could be arbitrarily large. It will generally be a vector for calls to `execute!` or a hash map for calls to `execute-one!`, but its shape is determined -by any `:builder-fn` options in effect. +by any `:builder-fn` options in effect. You should check if `(instance? Throwable result)` +to see if the call failed and the logger has been called with the thrown exception. For `plan` and `prepare` calls, only the first logging function is invoked (and the return value is ignored). You can use the symbol passed in to determine this. diff --git a/src/next/jdbc.clj b/src/next/jdbc.clj index 33c51c4..fa098d1 100644 --- a/src/next/jdbc.clj +++ b/src/next/jdbc.clj @@ -390,10 +390,10 @@ The result logging function, if provided, will be called with the same symbol passed to the sql/params logging function, the `state` - returned by the sql/params logging function, and the result of the - `execute!` or `execute-one!` call. The result logging function is - not called for the `plan` or `prepare` call (since they do not produce - result sets directly). + returned by the sql/params logging function, and either the result of + the `execute!` or `execute-one!` call or an exception if the call + failed. The result logging function is not called for the `plan` + or `prepare` call (since they do not produce result sets directly). Bear in mind that `get-datasource`, `get-connection`, and `with-transaction` return plain Java objects, so if you call any of those on this wrapped diff --git a/src/next/jdbc/sql_logging.clj b/src/next/jdbc/sql_logging.clj index 7ee1123..92cb156 100644 --- a/src/next/jdbc/sql_logging.clj +++ b/src/next/jdbc/sql_logging.clj @@ -32,14 +32,22 @@ (merge (:options this) opts))) (-execute-one [this sql-params opts] (let [state ((:sql-logger this) 'next.jdbc/execute-one! sql-params)] - (doto (p/-execute-one (:connectable this) sql-params - (merge (:options this) opts)) - (result-logger-helper this 'next.jdbc/execute-one! state)))) + (try + (doto (p/-execute-one (:connectable this) sql-params + (merge (:options this) opts)) + (result-logger-helper this 'next.jdbc/execute-one! state)) + (catch Throwable t + (result-logger-helper t this 'next.jdbc/execut-one! state) + (throw t))))) (-execute-all [this sql-params opts] (let [state ((:sql-logger this) 'next.jdbc/execute! sql-params)] - (doto (p/-execute-all (:connectable this) sql-params - (merge (:options this) opts)) - (result-logger-helper this 'next.jdbc/execute! state))))) + (try + (doto (p/-execute-all (:connectable this) sql-params + (merge (:options this) opts)) + (result-logger-helper this 'next.jdbc/execute! state)) + (catch Throwable t + (result-logger-helper t this 'next.jdbc/execut-one! state) + (throw t)))))) (extend-protocol p/Preparable SQLLogging