diff --git a/README.md b/README.md index c982b6b..ef11aae 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,12 @@ The latest stable version (1.0.444) on Clojars and on cljdoc (note: `honeysql/ho This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository. -Prerelease builds of the upcoming 2.x version of HoneySQL will soon be available: +Prerelease builds of the upcoming 2.x version of HoneySQL are available for testing: [![Clojars Project](https://clojars.org/seancorfield/honeysql/latest-version.svg)](https://clojars.org/seancorfield/honeysql) [![cljdoc badge](https://cljdoc.org/badge/seancorfield/honeysql?2.0.0-alpha2)](https://cljdoc.org/d/seancorfield/honeysql/2.0.0-alpha2) +HoneySQL 2.x requires Clojure 1.9 or later. + This is the README for the upcoming 2.x version of HoneySQL which provides a streamlined codebase and a simpler method for extending the DSL. It also supports SQL dialects out-of-the-box and will be extended to support vendor-specific language features over time (unlike the 1.x version). See this [summary of differences between v1 and v2](doc/differences-from-1-x.md) if you want to help test v2! @@ -631,7 +633,7 @@ You can also register SQL clauses, specifying the keyword, the formatting functi (sql/register-clause! :foobar (fn [clause x] (let [[sql & params] - (if (keyword? x) + (if (ident? x) (sql/format-expr x) (sql/format-dsl x))] (into [(str (sql/sql-kw clause) " " sql)] params))) diff --git a/deps.edn b/deps.edn index f511376..35a4240 100644 --- a/deps.edn +++ b/deps.edn @@ -1,9 +1,9 @@ {:mvn/repos {"sonatype" {:url "https://oss.sonatype.org/content/repositories/snapshots/"}} :paths ["src"] - :deps {org.clojure/clojure {:mvn/version "1.10.2"}} + :deps {org.clojure/clojure {:mvn/version "1.9.0"}} :aliases {:1.9 {:override-deps {org.clojure/clojure {:mvn/version "1.9.0"}}} - :1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.2"}}} + :1.10 {:override-deps {org.clojure/clojure {:mvn/version "1.10.3"}}} :master {:override-deps {org.clojure/clojure {:mvn/version "1.11.0-master-SNAPSHOT"}}} :test {:extra-paths ["test"]} :runner diff --git a/doc/differences-from-1-x.md b/doc/differences-from-1-x.md index 1103da9..5e5aef2 100644 --- a/doc/differences-from-1-x.md +++ b/doc/differences-from-1-x.md @@ -6,6 +6,8 @@ The goal of HoneySQL 2.x is to provide an easily-extensible DSL for SQL, support The DSL itself -- the data structures that both versions convert to SQL and parameters via the `format` function -- is almost exactly the same between the two versions so that migration is relatively painless. The primary API -- the `format` function -- is preserved in 2.x, although the variadic options from 1.x have changed to an options hash map in 2.x as this is generally considered more idiomatic. See the **Option Changes** section below for the differences in the options supported. +HoneySQL 1.x supported Clojure 1.7 and later. HoneySQL 2.x requires Clojure 1.9 or later. + ## Group, Artifact, and Namespaces HoneySQL 2.x uses the group ID `seancorfield` with the original artifact ID of `honeysql`, in line with the recommendations in Inside Clojure's post about the changes in the Clojure CLI: [Deprecated unqualified lib names](https://insideclojure.org/2020/07/28/clj-exec/). diff --git a/src/honey/sql.cljc b/src/honey/sql.cljc index 6e50bec..dba295f 100644 --- a/src/honey/sql.cljc +++ b/src/honey/sql.cljc @@ -133,16 +133,6 @@ (keyword (name s))) s)) -(defn- kw->sym - "Given a keyword, produce a symbol, retaining the namespace - qualifier, if any." - [k] - (if (keyword? k) - (if-let [n (namespace k)] - (symbol n (name k)) - (symbol (name k))) - k)) - (defn- namespace-_ [x] (some-> (namespace x) (str/replace "-" "_"))) (defn- name-_ [x] (str/replace (name x) "-" "_")) @@ -150,8 +140,7 @@ (cond (nil? x) "NULL" (string? x) (str \' (str/replace x "'" "''") \') - (symbol? x) (sql-kw x) - (keyword? x) (sql-kw x) + (ident? x) (sql-kw x) :else (str x))) (defn format-entity @@ -242,7 +231,7 @@ (into params) (into params'))) - (or (keyword? x) (symbol? x)) + (ident? x) (if aliased [(format-entity x opts)] (format-var x opts)) @@ -417,11 +406,8 @@ [(str (sql-kw k) " " (sql-kw strength) (when tables (str - (cond (and (keyword? tables) - (#{:nowait :skip-locked :wait} tables)) - (str " " (sql-kw tables)) - (and (symbol? tables) - ('#{nowait skip-locked wait} tables)) + (cond (and (ident? tables) + (#{:nowait :skip-locked :wait} (sym->kw tables))) (str " " (sql-kw tables)) (sequential? tables) (str " OF " @@ -493,13 +479,13 @@ (into [(str (sql-kw k) " " (str/join ", " sqls))] params))) (defn- format-on-conflict [k x] - (cond (or (keyword? x) (symbol? x)) + (cond (ident? x) [(str (sql-kw k) " (" (format-entity x) ")")] (map? x) (let [[sql & params] (format-dsl x)] (into [(str (sql-kw k) " " sql)] params)) (and (sequential? x) - (or (keyword? (first x)) (symbol? (first x))) + (ident? (first x)) (map? (second x))) (let [[sql & params] (format-dsl (second x))] (into [(str (sql-kw k) @@ -669,6 +655,16 @@ (set @current-clause-order) (set (keys @clause-format)))) +(defn- kw->sym + "Given a keyword, produce a symbol, retaining the namespace + qualifier, if any." + [k] + (if (keyword? k) + (if-let [n (namespace k)] + (symbol n (name k)) + (symbol (name k))) + k)) + (defn format-dsl "Given a hash map representing a SQL statement and a hash map of options, return a vector containing a string -- the formatted @@ -891,7 +887,7 @@ This is intended to be used when writing your own formatters to extend the DSL supported by HoneySQL." [expr & [{:keys [nested] :as opts}]] - (cond (or (keyword? expr) (symbol? expr)) + (cond (ident? expr) (format-var expr opts) (map? expr) diff --git a/src/honey/sql/helpers.cljc b/src/honey/sql/helpers.cljc index c490519..6de99c7 100644 --- a/src/honey/sql/helpers.cljc +++ b/src/honey/sql/helpers.cljc @@ -12,14 +12,16 @@ (defn- and-merge [current arg] - (if-let [conj' (and (sequential? arg) (#{:and :or} (first arg)))] + (if-let [conj' (and (sequential? arg) + (ident? (first arg)) + (#{:and :or} (keyword (first arg))))] (cond (= conj' (first current)) (into (vec current) (rest arg)) (seq current) (into [conj' current] (rest arg)) :else (into [conj'] (rest arg))) - (cond (= :and (first current)) + (cond (#{:and 'and} (first current)) (conj (vec current) arg) (seq current) (conj [:and current] arg) @@ -30,7 +32,7 @@ [current args] (let [args (remove nil? args) result - (cond (keyword? (first args)) + (cond (ident? (first args)) (and-merges current [args]) (seq args) (let [[arg & args] args]