diff --git a/resources/data_readers.clj b/resources/data_readers.clj index 56636a8..14c1a55 100644 --- a/resources/data_readers.clj +++ b/resources/data_readers.clj @@ -1,3 +1,4 @@ {sql/call honeysql.types/read-sql-call sql/raw honeysql.types/read-sql-raw - sql/param honeysql.types/read-sql-param} \ No newline at end of file + sql/param honeysql.types/read-sql-param + sql/array honeysql.types/read-sql-array} diff --git a/src/honeysql/format.clj b/src/honeysql/format.clj index b42b020..5e5a3d7 100644 --- a/src/honeysql/format.clj +++ b/src/honeysql/format.clj @@ -2,7 +2,7 @@ (:refer-clojure :exclude [format]) (:require [honeysql.types :refer [call raw param param-name]] [clojure.string :as string]) - (:import [honeysql.types SqlCall SqlRaw SqlParam])) + (:import [honeysql.types SqlCall SqlRaw SqlParam SqlArray])) ;;(set! *warn-on-reflection* true) @@ -329,6 +329,9 @@ (let [x (first @*input-params*)] (swap! *input-params* rest) (add-param pname x))))) + SqlArray + (-to-sql [x] + (str "ARRAY[" (comma-join (map -to-sql (.values x))) "]")) Object (-to-sql [x] (add-anon-param x))) diff --git a/src/honeysql/types.clj b/src/honeysql/types.clj index 4f63196..0a594ce 100644 --- a/src/honeysql/types.clj +++ b/src/honeysql/types.clj @@ -80,3 +80,31 @@ (defmethod print-dup SqlParam [o w] (print-method o w)) + +;;;; + +(deftype SqlArray [values _meta] + Object + (hashCode [this] (hash-combine (hash (class this)) (hash values))) + (equals [_ x] (and (instance? SqlArray x) (= values (.values ^SqlArray x)))) + clojure.lang.IObj + (meta [_] _meta) + (withMeta [_ m] (SqlArray. values m))) + +(defn array + "Represents a SQL array." + [values] + (SqlArray. values nil)) + +(defn array-vals [^SqlArray a] + (.values a)) + +(defn read-sql-array [form] + ;; late bind, as above + ((resolve `array) form)) + +(defmethod print-method SqlArray [^SqlArray a ^java.io.Writer w] + (.write w (str "#sql/array " (pr-str (.values a))))) + +(defmethod print-dup SqlArray [a w] + (print-method a w)) diff --git a/test/honeysql/format_test.clj b/test/honeysql/format_test.clj index 1a7ee40..ce4a518 100644 --- a/test/honeysql/format_test.clj +++ b/test/honeysql/format_test.clj @@ -33,3 +33,13 @@ "INSERT INTO foo SELECT bar FROM baz")) (is (= (format-clause (first {:insert-into [[:foo [:a :b :c]] {:select [:d :e :f] :from [:baz]}]}) nil) "INSERT INTO foo (a, b, c) SELECT d, e, f FROM baz"))) + +(deftest array-test + (is (= (format {:insert-into :foo + :columns [:baz] + :values [[#sql/array [1 2 3 4]]]}) + ["INSERT INTO foo (baz) VALUES (ARRAY[1, 2, 3, 4])"])) + (is (= (format {:insert-into :foo + :columns [:baz] + :values [[#sql/array ["one" "two" "three"]]]}) + ["INSERT INTO foo (baz) VALUES (ARRAY[?, ?, ?])" "one" "two" "three"])))