diff options
Diffstat (limited to 'sql.clj')
-rw-r--r-- | sql.clj | 126 |
1 files changed, 0 insertions, 126 deletions
diff --git a/sql.clj b/sql.clj deleted file mode 100644 index 52f724a1..00000000 --- a/sql.clj +++ /dev/null @@ -1,126 +0,0 @@ -;; Copyright (c) Stephen C. Gilardi. All rights reserved. -;; The use and distribution terms for this software are covered by the -;; Common Public License 1.0 (http://opensource.org/licenses/cpl.php) -;; which can be found in the file CPL.TXT at the root of this distribution. -;; By using this software in any fashion, you are agreeing to be bound by -;; the terms of this license. -;; You must not remove this notice, or any other, from this software. -;; -;; sql.clj -;; -;; A Clojure interface to sql databases via jdbc -;; -;; scgilardi (gmail) -;; 23 April 2008 - -(clojure/in-ns 'sql) -(clojure/refer 'clojure) - -(import '(java.sql DriverManager Connection PreparedStatement ResultSet)) - -(defn get-connection - "Attempts to get a connection to a database via a jdbc URL" - [subprotocol db-name] - (let [url (str "jdbc:" subprotocol ":" db-name)] - (.getConnection DriverManager url))) - -(defmacro with-connection - "Evaluates body in the context of a connection to a database. Any updates - are committed as one transaction after evaluating body or rolled back on - any uncaught exception." - [con init & body] - `(with-open ~con ~init - (try - (.setAutoCommit ~con false)) - ~@body - (.commit ~con) - (catch Exception e# - (.rollback ~con) - (throw (Exception. "transaction rolled back" e#))))) - -(defn execute-commands - "Executes a sequence of SQL commands that do not return results" - [con commands] - (with-open stmt (.createStatement con) - (doseq cmd commands - (.addBatch stmt cmd)) - (.executeBatch stmt))) - -(defn execute-prepared-statement - "Executes a prepared statement with a sequence of parameter sets" - [con sql sets] - (with-open stmt (.prepareStatement con sql) - (doseq set sets - (doseq [index value] (map vector (iterate inc 1) set) - (.setObject stmt index value)) - (.addBatch stmt )) - (.executeBatch stmt))) - -(defmacro with-query-results - "Executes a query and then evaluates body repeatedly with rec bound to - each of the generated results in turn" - [rec con sql & body] - `(with-open stmt# (.prepareStatement ~con ~sql) - (with-open rset# (.executeQuery stmt#) - (doseq ~rec (resultset-seq rset#) - ~@body)))) - -(comment - - ;; Examples - - ;; Simple tests of sql.clj using derby as a JDBC provider. - ;; - ;; Substituting a different database should only affect the definition - ;; of 'db' below (and perhaps suggest the need for more variations of - ;; get-connection). - -(clojure/in-ns 'sql-test) -(clojure/refer 'clojure) - -(lib/use sql) - -(.forName Class "org.apache.derby.jdbc.EmbeddedDriver") - -(defn db [] - (get-connection "derby" "/tmp/test-derby.db;create=true")) - -(defn db-drop [] - (with-connection con (db) - (try - (execute-commands con - ["drop table fruit"]) - (catch Exception e)))) - -(defn db-write [] - (db-drop) - (with-connection con (db) - (execute-commands con - ["create table fruit (name varchar(32), appearance varchar(32), cost int, grade real)"]) - (execute-prepared-statement con - "insert into fruit values (?, ?, ?, ?)" - [["Apple" "red" 59 87] - ["Banana" "yellow" 29 92.2] - ["Peach" "fuzzy" 139 90.0] - ["Orange" "juicy" 89 88.6]]))) - -(defn db-read [] - (with-connection con (db) - (with-query-results rec con - "select * from fruit" - (println rec)))) - -(defn db-grade-a [] - (with-connection con (db) - (with-query-results rec con - "select name, cost from fruit where grade >= 90" - (println rec)))) - -(defn db-exception [] - (with-connection con (db) - (execute-prepared-statement con - "insert into fruit (name, appearance) values (?, ?)" - [["Grape" "yummy"] - ["Pear" "bruised"]]) - (throw (Exception. "an exception")))) -) |