1

Not sure why I get this error when I try the code below to execute a query on a MySQL database from clojure:

user=> (mysql.core/list-users)

ClassNotFoundException mysql.core  java.net.URLClassLoader$1.run (URLClassLoader.java:366)

Here is my project.clj file

(defproject mysql "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
        :url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [
                    [org.clojure/clojure "1.5.1"]
                    [org.clojure/java.jdbc "0.3.3"]
                    [mysql/mysql-connector-java "5.1.25"]
                    [postgresql/postgresql "8.4-702.jdbc4"]
                    [org.xerial/sqlite-jdbc "3.7.2"]
                    [java-jdbc/dsl "0.1.0"]
])

Here is my core.clj file

(ns mysql.core
 (:require [clojure.java.jdbc :as sql]))

(def db {:classname "com.mysql.jdbc.Driver"
     :subprotocol "mysql"
     :subname "//localhost:3306/dummy"
     :user "idf"
     :password "pwd"})

(defn list-users []
  (sql/with-connection db
  (sql/with-query-results rows
  ["select * from user"]
  (println rows))))

HERE IS SOMETHING THAT WORKS (the only thing is you have to get the deps correct without a project file):

$ mysql -u root
  mysql> create database clojure_test;
  grant all on clojure_test.* to clojure_test@localhost identified by "clojure_test”;
  use clojure_test;
  CREATE TABLE fruit (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20),      appearance VARCHAR(20), cost DECIMAL(13,2));

lein repl
user=> (require '[clojure.java.jdbc :as j])
user=> (def mysql-db {:subprotocol "mysql" :subname "//127.0.0.1:3306/clojure_test" :user "clojure_test" :password "clojure_test"})
user=> (j/insert! mysql-db :fruit {:name "Apple" :appearance "rosy" :cost 24} {:name "Orange" :appearance "round" :cost 49})
user=> (j/query mysql-db ["select * from fruit where appearance = ?" "rosy"] :row-fn :cost)
Ivan
  • 7,448
  • 14
  • 69
  • 134

1 Answers1

4

It seems that you run code in the repl, you need change to the namespace and load file:

1, Change the repl's namespace by (ns mysql.core)
2, run (load-file path-to-file)

EDIT:

another solution is to excute (use 'mysql.core) in the repl, then you can run your code.

llj098
  • 1,404
  • 11
  • 13
  • I apologize I am very new to Clojure. Do you mean run (ns mysql.core) after I get the user=> prompt? Also, I don't understand step 2? – Ivan Feb 06 '14 at 01:09
  • step 2 means that you need to load your Clojure file into the context,in your example seems to run `(load-file "src/mysql/core.clj")` – llj098 Feb 06 '14 at 01:14
  • in `user` namespace you can also use `(use 'mysql.core)`, also edited the answer – llj098 Feb 06 '14 at 01:16
  • Ok now I get: CompilerException java.lang.RuntimeException: No such var: sql/with-connection, compiling:(/Users/idf/Documents/clojure/mysql/src/mysql/core.clj:11:3) – Ivan Feb 06 '14 at 01:38
  • `with-connection` is in `clojure.java.jdbc.deprecated`. See http://clojure.github.io/java.jdbc/#clojure.java.jdbc.deprecated – llj098 Feb 06 '14 at 01:53
  • Gotcha. This may seem like a silly question, but how do I access the deprecated parts of clojure.java.jdbc? I did this, but it did not work :require [clojure.java.jdbc.deprecated] FileNotFoundException Could not locate clojure/java/jdbc/deprecated/as__init.class or clojure/java/jdbc/deprecated/as.clj on classpath: clojure.lang.RT.load (RT.java:443) – Ivan Feb 06 '14 at 02:40
  • use `(:use ..)` instead, this link contains more details: http://stackoverflow.com/questions/871997/difference-between-use-and-require . Also it is not a good idea to use function in `deprecated` namespace. You can find some examples in https://github.com/clojure/java.jdbc – llj098 Feb 06 '14 at 03:03
  • Thanks. I finally got something going based on your advice. I posted above a very specific sequence of steps so that others can hopefully gain something from it – Ivan Feb 06 '14 at 18:21