{"id":182,"date":"2010-11-11T09:51:30","date_gmt":"2010-11-11T17:51:30","guid":{"rendered":"http:\/\/elliottjohnson.net\/blog\/?p=182"},"modified":"2010-11-12T13:17:56","modified_gmt":"2010-11-12T21:17:56","slug":"quick-lisp-and-clsql-fluid","status":"publish","type":"post","link":"http:\/\/elliottjohnson.net\/blog\/quick-lisp-and-clsql-fluid\/","title":{"rendered":"quicklisp and clsql-fluid"},"content":{"rendered":"<p>This is a tech post and the intended audience is the few people who will bash their heads against a piece of software until it gets installed.  I&#8217;ve just gone through one of these &#8220;sessions&#8221;, so I thought I&#8217;d document it here for the next person.<\/p>\n<p>Zach Beane created <a target=\"_BLANK\" href=\"http:\/\/quicklisp.org\">quicklisp<\/a>, which is a great way to load up <a target=\"_BLANK\" href=\"http:\/\/en.wikipedia.org\/wiki\/Common_Lisp\">common lisp<\/a> libraries without a headache.<\/p>\n<p>To give an example of this, to load my <a href=\"http:\/\/common-lisp.net\/project\/cl-weblocks\/\" target=\"_BLANK\">favorite web programming framework<\/a>, all I need to do is type the following:  <code>(ql:quickload 'weblocks)<\/code><\/p>\n<p>It loads everything I need and I can instantly get started working.  Very cool!  Now after a bit of programming I find that I&#8217;d like to customise the storage layer to use a <a target=\"_BLANK\" href=\"http:\/\/en.wikipedia.org\/wiki\/Mysql\">mysql database<\/a>, but that&#8217;s when it gets hairy&#8230;<\/p>\n<p>First of all, weblocks&#8217; clsql interface depends on <a href=\"http:\/\/common-lisp.net\/project\/clsql-fluid\/\" target=\"_BLANK\">clsql-fluid<\/a>, which as a project doesn&#8217;t package anything&#8230; so this doesn&#8217;t give quicklisp an opportunity to distribute it.  I guess someone could make a package, but I assume Zach would like to have the project maintainers do this instead of himself.<\/p>\n<p>Secondly quicklisp already had installed the clsql library for me and I couldn&#8217;t find a command to remove it. So after looking through the documentation and the source I went and deleted things under my quicklisp directory (and ~\/.cache) to remove quicklisp&#8217;s version of clsql.  A remove command in quicklisp would be a nice touch.  It would also be nice to get some like functionality for quicklisp in managing software beyond installing &#038; searching.  Maybe Zach already has plans for these for when the code goes out of beta&#8230;<\/p>\n<p>Thirdly, I fetched clsql-fluid as described on the website and linked it in and loaded it up&#8230; but got errors:<\/p>\n<p style=\"text-align: center;\"><code>\"The name NIL does not designate any package.\"<\/code><\/p>\n<p>What is happening here is that clsql-uffi tests that it&#8217;s properly loaded by looking for a defined symbol (atol64) to have an associated function.  If that function doesn&#8217;t exist then we havn&#8217;t loaded the foreign libraries and therefore haven&#8217;t successfully loaded.  The problem with this is that the clsql-uffi package doesn&#8217;t exist yet, so we get the error when the test code tries to <code>(find-package #:clsql-uffi)<\/code>.<\/p>\n<p>Since this test is a predicate of sorts I decided that instead of erroring it should just return nil, so I wrapped those probing statements in an: <code>(ignore-errors ...)<\/code> statement.  Once I&#8217;d done this it allowed me to get to the next level of errors :)<\/p>\n<p>Fourthly, the syntax used in the uffi calls seems different than what the uffi installed via quicklisp expects.  After getting beyond the &#8220;nil package&#8221; problem above, I encountered this error:<\/p>\n<p><code>caught ERROR:<br \/>\n;   (in macroexpansion of (UFFI:CONVERT-FROM-FOREIGN-STRING CHAR-PTR<br \/>\n:LOCALE ...))<br \/>\n;   (hint: For more precise location, try *BREAK-ON-SIGNALS*.)<br \/>\n;   error while parsing arguments to DEFMACRO CONVERT-FROM-FOREIGN-STRING:<br \/>\n;     unknown keyword: :LOCALE; expected one of :NULL-TERMINATED-P,<br \/>\n :LENGTH<br \/>\n<\/code><\/p>\n<p>After looking around a bit I got the tip that <a target=\"_BLANK\" href=\"http:\/\/common-lisp.net\/project\/cffi\/\">cffi-uffi-compat<\/a> might be more compatible than quicklisp&#8217;s version of <a target=\"_BLANK\" href=\"http:\/\/uffi.b9.com\/\">uffi<\/a>, so I edited clsq.asd, clsql-mysql.asd, clsql-uffi.asd, and uffi\/clsql-uffi-package.lisp and edited them to use the uffi compatibility layer from cffi.  After all that was done I did another <code>(ql:quickload 'clsql-mysql)<\/code> and the clsql-fluid version loaded. <strong>whew<\/strong><\/p>\n<p>I hope this helps others stuck in a similar situation and here is the result of a <code>git diff<\/code> in the root of the clsql-fluid source:<\/p>\n<pre>diff --git a\/clsql-mysql.asd b\/clsql-mysql.asd\r\nindex a176f85..1263457 100644\r\n--- a\/clsql-mysql.asd\r\n+++ b\/clsql-mysql.asd\r\n@@ -20,8 +20,8 @@\r\n (in-package #:clsql-mysql-system)\r\n \r\n (eval-when (:compile-toplevel :load-toplevel :execute)\r\n-  (unless (find-package 'uffi)\r\n-    (asdf:operate 'asdf:load-op 'uffi)))\r\n+  (unless (find-package 'cffi-uffi-compat)\r\n+    (asdf:operate 'asdf:load-op 'cffi-uffi-compat)))\r\n \r\n (defvar *library-file-dir* (append (pathname-directory *load-truename*)\r\n                                   (list \"db-mysql\")))\r\n@@ -48,8 +48,8 @@\r\n   t)\r\n \r\n (defmethod operation-done-p ((o load-op) (c clsql-mysql-source-file))\r\n-  (and (symbol-function (intern (symbol-name '#:mysql-get-client-info)\r\n-                               (find-package '#:mysql)))\r\n+  (and (ignore-errors (symbol-function (intern (symbol-name '#:mysql-get-client-info)\r\n+                                              (find-package '#:mysql))))\r\n        t)) \r\n \r\n (defmethod perform ((o compile-op) (c clsql-mysql-source-file))\r\n@@ -80,7 +80,7 @@\r\n   :description \"Common Lisp SQL MySQL Driver\"\r\n   :long-description \"cl-sql-mysql package provides a database driver to the MySQL database system.\"\r\n \r\n-  :depends-on (uffi clsql clsql-uffi)\r\n+  :depends-on (cffi-uffi-compat clsql clsql-uffi)\r\n   :components\r\ndiff --git a\/clsql-mysql.asd b\/clsql-mysql.asd\r\nindex a176f85..1263457 100644\r\n--- a\/clsql-mysql.asd\r\n+++ b\/clsql-mysql.asd\r\n@@ -20,8 +20,8 @@\r\n (in-package #:clsql-mysql-system)\r\n \r\n (eval-when (:compile-toplevel :load-toplevel :execute)\r\n-  (unless (find-package 'uffi)\r\n-    (asdf:operate 'asdf:load-op 'uffi)))\r\n+  (unless (find-package 'cffi-uffi-compat)\r\n+    (asdf:operate 'asdf:load-op 'cffi-uffi-compat)))\r\n \r\n (defvar *library-file-dir* (append (pathname-directory *load-truename*)\r\n                                   (list \"db-mysql\")))\r\n@@ -48,8 +48,8 @@\r\n   t)\r\n \r\n (defmethod operation-done-p ((o load-op) (c clsql-mysql-source-file))\r\n-  (and (symbol-function (intern (symbol-name '#:mysql-get-client-info)\r\n-                               (find-package '#:mysql)))\r\n+  (and (ignore-errors (symbol-function (intern (symbol-name '#:mysql-get-client-info)\r\n+                                              (find-package '#:mysql))))\r\n        t)) \r\n \r\n (defmethod perform ((o compile-op) (c clsql-mysql-source-file))\r\n@@ -80,7 +80,7 @@\r\n   :description \"Common Lisp SQL MySQL Driver\"\r\n   :long-description \"cl-sql-mysql package provides a database driver to the MySQL database system.\"\r\n \r\n-  :depends-on (uffi clsql clsql-uffi)\r\n+  :depends-on (cffi-uffi-compat clsql clsql-uffi)\r\n   :components\r\n   ((:module :db-mysql\r\n            :components\r\ndiff --git a\/clsql-uffi.asd b\/clsql-uffi.asd\r\nindex e5a75f6..e78f09e 100644\r\n--- a\/clsql-uffi.asd\r\n+++ b\/clsql-uffi.asd\r\n@@ -50,8 +50,8 @@\r\n   nil) ;;; library will be loaded by a loader file\r\n \r\n (defmethod operation-done-p ((o load-op) (c clsql-uffi-source-file))\r\n-  (and (symbol-function (intern (symbol-name '#:atol64)\r\n-                               (find-package '#:clsql-uffi)))\r\n+  (and (ignore-errors (symbol-function (intern (symbol-name '#:atol64)\r\n+                                              (find-package '#:clsql-uffi))))\r\n        t))\r\n \r\n (defmethod perform ((o compile-op) (c clsql-uffi-source-file))\r\n@@ -79,7 +79,7 @@\r\n   :description \"Common UFFI Helper functions for Common Lisp SQL Interface Library\"\r\n   :long-description \"cl-sql-uffi package provides common helper functions using the UFFI for the CLSQL package.\"\r\n \r\n-  :depends-on (uffi clsql)\r\n+  :depends-on (cffi-uffi-compat clsql)\r\n \r\n   :components\r\n   ((:module :uffi\r\ndiff --git a\/clsql.asd b\/clsql.asd\r\nindex 35e172a..51da309 100644\r\n--- a\/clsql.asd\r\n+++ b\/clsql.asd\r\n@@ -26,8 +26,8 @@\r\n \r\n ;; need to load uffi for below perform :after method\r\n (eval-when (:compile-toplevel :load-toplevel :execute)\r\n-  (unless (find-package 'uffi)\r\n-    (asdf:operate 'asdf:load-op 'uffi)))\r\n+  (unless (find-package 'cffi-uffi-compat)\r\n+    (asdf:operate 'asdf:load-op 'cffi-uffi-compat)))\r\n \r\n (defsystem clsql\r\n     :name \"CLSQL\"\r\ndiff --git a\/uffi\/clsql-uffi-package.lisp b\/uffi\/clsql-uffi-package.lisp\r\nindex be5abf5..153ca1f 100644\r\n--- a\/uffi\/clsql-uffi-package.lisp\r\n+++ b\/uffi\/clsql-uffi-package.lisp\r\n@@ -19,7 +19,7 @@\r\n (in-package #:cl-user)\r\n \r\n (defpackage #:clsql-uffi\r\n-  (:use #:cl #:uffi)\r\n+  (:use #:cl #:cffi-uffi-compat)\r\n   (:export\r\n    #:find-and-load-foreign-library\r\n    #:canonicalize-type-list\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This is a tech post and the intended audience is the few people who will bash their heads against a piece of software until it gets installed. I&#8217;ve just gone through one of these &#8220;sessions&#8221;, so I thought I&#8217;d document &hellip; <a href=\"http:\/\/elliottjohnson.net\/blog\/quick-lisp-and-clsql-fluid\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"footnotes":""},"categories":[12,8],"tags":[],"class_list":["post-182","post","type-post","status-publish","format-standard","hentry","category-lisp","category-tech"],"_links":{"self":[{"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/posts\/182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":29,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"predecessor-version":[{"id":212,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions\/212"}],"wp:attachment":[{"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/elliottjohnson.net\/blog\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}