Tuesday, April 20, 2010

java.sql And Clojure

Clojure has a SQL package that wraps the native Java classes with LISP-like syntax. I however want to learn Clojure-Java interop so, this example makes direct calls to the Java API from Clojure. I'll use HSQL and create and populate a table then, with Clojure, attempt to read from the table.

Start HSQL

[greg:hsqldb] java -cp lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:myclojuredb --dbname.0 clojuredb

Start the SqlTool Commandline Client

[greg:hsqldb] java -jar lib/hsqldb.jar --inlineRc URL=jdbc:hsqldb:hsql://localhost,USER=sa

Or, Start the Swing HSQL client

[greg:hsqldb] java -cp lib/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing
In the Swing HSQL client, I connect to the myclojuredb and run these statements:
create table Authors (id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, firstName VARCHAR(50), lastName VARCHAR(50));
insert into Authors VALUES(NULL, 'Kurt', 'Vonnegut');
insert into Authors VALUES(NULL, 'John', 'Steinbeck');
select * from Authors;

Start the Clojure REPL

[greg:clojure-1.1.0] java -cp .:clojure.jar:jline-0.9.94.jar:../hsqldb/lib/hsqldb.jar jline.ConsoleRunner clojure.main

Run the Clojure - Java Interop to Execute the JDBC

user=> (import '(java.sql Connection DriverManager Statement ResultSet))
java.sql.ResultSetMetaData
user=> (Class/forName "org.hsqldb.jdbc.JDBCDriver")                                                    
org.hsqldb.jdbc.JDBCDriver
user=> (def conn (DriverManager/getConnection "jdbc:hsqldb:hsql://localhost/clojuredb", "SA", ""))     
#'user/conn
user=> (def stmt (.createStatement conn))                                                              
#'user/stmt
user=> (def rs (.executeQuery stmt "SELECT * FROM Authors"))                                           
#'user/rs
user=> (.next rs)
true
user=> (.getInt rs 1)
0
user=> (.getString rs 2)
"Kurt"
user=> (.getString rs 3)
"Vonnegut"
user=>