Skip to content

Instantly share code, notes, and snippets.

{:stmt "table1/id > ?" :vars [5]}
(defn- sql-exp
[op p1 p2]
(merge-with concat (paramatize p1) (stmt op) (paramatize p2)))
(defn- paramatize
[x]
(cond
(keyword? x) (stmt (sqlize x))
:else (stmt "?" [x])))
(defn- stmt
[& stmts]
(if (vector? (last stmts))
{:stmt (reduce #(str %1 %2) "" (butlast stmts)) :vars (last stmts)}
{:stmt (reduce #(str %1 %2) "" stmts) :vars []}))
"select * from products where id > ?"
"select * from products where id > 5"
(ns net.groppe.sequel.core
(:require [clojure.contrib.str-utils :as str-utils]))
(defn- sqlize
[x]
(cond
(keyword? x) (str-utils/re-sub #"\/" "." (str-utils/re-sub #"^:" "" (str x)))
(string? x) (str "'" x "'")
:else x))
sequel> (filter (> :projects/id 5) (collect :projects))
"select * from projects where projects.id > 5"
sequel> (filter (and (> :projects/id 2) (= :projects/name "sequel")) (collect :projects))
"select * from projects where projects.id > 2 AND projects.name = 'sequel'"
sequel> (filter (and (in :projects/id [1 2 3 4 5 6 7 8 9 10]) (= :projects/name "sequel")) (collect :projects))
"select * from projects where projects.id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) AND projects.name = 'sequel'"
sequel> (filter (and (in :projects/id [1 2 3 4 5 6 7 8 9 10]) (like :projects/name "seq%")) (collect :projects))
"select * from projects where projects.id IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) AND projects.name like 'seq%'"
sequel> (filter (or (and (> :project/id 5) (= :project/name "sequel")) (= :project/id 15)) (collect :projects))
"select * from projects where project.id > 5 AND project.name = 'sequel' OR project.id = 15"
(defmacro filter
[pred query]
`(let [~'and (fn[& xs#] (apply str (interpose " AND " xs#)))
~'or (fn[& xs#] (apply str (interpose " OR " xs#)))
~'= (fn[x# y#] (sql-exp "=" x# y#))
~'> (fn[x# y#] (sql-exp ">" x# y#))
~'< (fn[x# y#] (sql-exp "<" x# y#))
~'like (fn[x# y#] (sql-exp "like" x# y#))
~'in (fn[x# xs#]
(str (sqlize x#) " IN (" (apply str (interpose ", " xs#)) ")"))]
sequel> (collect :projects)
"select * from projects"
sequel> (collect :projects :invoices)
"select * from projects, invoices"
sequel> (collect :projects :invoices [:projects/id :projects/name (as :inv_id :invoices/id) :invoices/date])
"select projects.id, projects.name, invoices.id AS inv_id, invoices.date from projects, invoices"