java.jdbc

Variadic keyword arguments don't compose -- provide alternative

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

The more we work with java.jdbc at World Singles in composition with other functions, the more painful the variadic keyword argument approach becomes, especially as the number of optional keyword arguments grows.

The API would be easier to work with if the optional keyword arguments could be passed as simple maps. This will be straightforward for some functions, by introducing multiple arities, but harder for others. The multiple arity approach should be considered to be a bridge only, as a step toward deprecating the current approach.

As an example, query has the following argument list – and a pretty horrendous arglists specification to try to explain it!

[db sql-params & {:keys [result-set-fn row-fn identifiers as-arrays?] ...}]

Instead, it could be:

[db sql-params]
[db sql-params {:keys [result-set-fn row-fn identifiers as-arrays?] ...}]

Then the :arglists metadata could be removed (it's non-standard) and the information about sql-params added to the docstring (where it really belongs).

For backward compatibility, an additional arity could be provided:

[db sql-params k v & kvs]

Alex Miller considers this "the worst of all worlds" but I view it purely as a compatibility bridge between the current API (0.5.0) and the cleaner, future API (0.6.0).

Activity

Hide
Sean Corfield added a comment -

The upcoming 0.5.5 release will add the more composable function signatures and deprecate the unrolled optional keyword argument forms (using them will print a DEPRECATED warning to stdout).

Most of the changes in the API are "obvious" in that where the unrolled optional keyword arguments are allowed, a single map of options is now supported (and preferred). Some of the docstrings have yet to catch up with this. That's a work-in-progress.

insert! was the odd function out since it is already variadic, accepting one or more hash maps representing rows to insert, or a vector of column names followed by one or more vectors of corresponding values to insert. Unrolled optional keyword arguments could then follow those maps / vectors. The approach I've taken here is to introduce an :options keyword to act as a delimiter between the rows/columns and the options (since an options map could be confused with row map to be inserted). This makes the single row insert with options form more verbose:

(insert! db :table {:col1 "val1" :col2 2} :entities (quoted \"))
;; becomes
(insert! db :table {:col1 "val1" :col2 2} :options {:entities (quoted \")})

With hindsight, there are several ways this (and a few other functions in java.jdbc) could have been designed better...

Show
Sean Corfield added a comment - The upcoming 0.5.5 release will add the more composable function signatures and deprecate the unrolled optional keyword argument forms (using them will print a DEPRECATED warning to stdout). Most of the changes in the API are "obvious" in that where the unrolled optional keyword arguments are allowed, a single map of options is now supported (and preferred). Some of the docstrings have yet to catch up with this. That's a work-in-progress. insert! was the odd function out since it is already variadic, accepting one or more hash maps representing rows to insert, or a vector of column names followed by one or more vectors of corresponding values to insert. Unrolled optional keyword arguments could then follow those maps / vectors. The approach I've taken here is to introduce an :options keyword to act as a delimiter between the rows/columns and the options (since an options map could be confused with row map to be inserted). This makes the single row insert with options form more verbose:
(insert! db :table {:col1 "val1" :col2 2} :entities (quoted \"))
;; becomes
(insert! db :table {:col1 "val1" :col2 2} :options {:entities (quoted \")})
With hindsight, there are several ways this (and a few other functions in java.jdbc) could have been designed better...
Hide
Sean Corfield added a comment -

Note to self: once 0.5.5 is released, I need to update all the examples in http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html

Show
Sean Corfield added a comment - Note to self: once 0.5.5 is released, I need to update all the examples in http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html
Hide
Sean Corfield added a comment -

Version 0.5.5 is available on Maven. The Clojure Guides have been updated to reflect the deprecation and introduction of new syntax. I'll create a new issue to remove the deprecated syntax when 0.6.0 is being prepared.

Show
Sean Corfield added a comment - Version 0.5.5 is available on Maven. The Clojure Guides have been updated to reflect the deprecation and introduction of new syntax. I'll create a new issue to remove the deprecated syntax when 0.6.0 is being prepared.
Hide
Sean Corfield added a comment -

Implemented in 0.5.5.

Show
Sean Corfield added a comment - Implemented in 0.5.5.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: