我想出了這個版本,是相當接近的版本:
(defmacro create-table-def [table-name key-val-map]
(let [sql-part1 (vector "create table "
(name table-name)
"(")
sql-pre-part2 (apply vector
(map #(str (name (first %))
" "
(second %))
key-val-map))
sql-part2 (butlast (interleave sql-pre-part2 (repeat ", ")))
sql-part3 [");"]]
(apply str (concat sql-part1 sql-part2 sql-part3))))
(create-table-def my-table {foo "varchar(20)" bar "int"})
;"create table my-table(foo varchar(20), bar int);"
如果你真的需要一個序列傳給你可以這樣做:
(defmacro create-table-def2 [[name & pairs]]
`(create-table-def ~name ~(apply array-map pairs)))
(create-table-def2 [my-table foo "varchar(20)" bar "int"])
;"create table my-table(foo varchar(20), bar int);"
或者只是作爲直接參數:
(defmacro create-table-def3 [name & pairs]
`(create-table-def ~name ~(apply array-map pairs)))
(create-table-def3 my-table foo "varchar(20)" bar "int")
;"create table my-table(foo varchar(20), bar int);"
更直接關注解決方案,但是,(ab)使用打印的repr地圖的esentation:下一次
(use '[clojure.contrib.string :as str-utils])
(defmacro table-def [tname & things]
(str-utils/join " "
["create-table" (name tname) "("
(str-utils/drop 1
(str-utils/chop
(print-str (apply array-map things))))
");"]))
(table-def my-table foo "varchar(20)" bar "int")
;"create-table my-table (foo varchar(20), bar int);"
請用四個空格縮進代碼或使用代碼按鈕(一個與1S編輯欄和0)來爲你做它。 – sepp2k 2010-05-27 09:53:40
我不知道你是否更感興趣學習編寫宏或學習如何在Clojure中使用SQL。如果是後者,請查看clojure.contrib.sql,以及針對您問題中的示例,特別是create-table函數。 – 2011-04-23 01:22:59