diff --git a/README.md b/README.md index 7602663..b2e6c00 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,16 @@ Keywords that begin with `%` are interpreted as SQL function calls: => ["SELECT COUNT(*) FROM foo"] ``` +Keywords that begin with `?` are interpreted as bindable parameters: + +``clj +(-> (select :id) + (from :foo) + (where [:= :a :?baz]) + (sql/format {:baz "BAZ"})) +=> ["SELECT id FROM foo WHERE a = ?" "BAZ"] +``` + There are helper functions and data literals for SQL function calls, field qualifiers, raw SQL fragments, and named input parameters: ```clj diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index 1420826..227fb3b 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -1,6 +1,6 @@ (ns honeysql.format (:refer-clojure :exclude [format]) - (:require [honeysql.types :refer [call raw param-name]] + (:require [honeysql.types :refer [call raw param param-name]] [clojure.string :as string]) (:import [honeysql.types SqlCall SqlRaw SqlParam])) @@ -155,9 +155,10 @@ (extend-protocol ToSql clojure.lang.Keyword (-to-sql [x] (let [s ^String (name x)] - (if (= \% (.charAt s 0)) - (let [call-args (string/split (subs s 1) #"\." 2)] - (to-sql (apply call (map keyword call-args)))) + (condp = (.charAt s 0) + \% (let [call-args (string/split (subs s 1) #"\." 2)] + (to-sql (apply call (map keyword call-args)))) + \? (to-sql (param (keyword (subs s 1)))) (-> s (string/replace "-" "_"))))) clojure.lang.Symbol (-to-sql [x] (-> x name (string/replace "-" "_"))) diff --git a/test/honeysql/core_test.clj b/test/honeysql/core_test.clj index edd7da4..362d4ac 100644 --- a/test/honeysql/core_test.clj +++ b/test/honeysql/core_test.clj @@ -16,7 +16,7 @@ (left-join [:clod :c] [:= :f.a :c.d]) (right-join :bock [:= :bock.z :c.e]) (where [:or - [:and [:= :f.a "bort"] [:not= :b.baz (sql/param :param1)]] + [:and [:= :f.a "bort"] [:not= :b.baz :?param1]] [:< 1 2 3] [:in :f.e [1 (sql/param :param2) 3]] [:between :f.e 10 20]]) @@ -35,7 +35,7 @@ :left-join [[:clod :c] [:= :f.a :c.d]] :right-join [:bock [:= :bock.z :c.e]] :where [:or - [:and [:= :f.a "bort"] [:not= :b.baz (sql/param :param1)]] + [:and [:= :f.a "bort"] [:not= :b.baz :?param1]] [:< 1 2 3] [:in :f.e [1 (sql/param :param2) 3]] [:between :f.e 10 20]]